From 66f7df70fb03d487ae0c667adec3d5ad6e11721e Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 23 Jul 2013 12:59:18 +0300 Subject: Add new sprite actions for water and sky. New actions: fly, swim, standsky, standwater, sitsky, sitwater, attacksky, attackwater, spawnsky, spawnwater, deadsky, deadwater For now attacksky and attackwater unused. --- src/being.cpp | 74 ++++++++++++++++++++++++++++++++++++++++----- src/being.h | 8 +++++ src/map.cpp | 10 ++++++ src/map.h | 2 ++ src/resources/spritedef.cpp | 12 ++++++++ src/resources/spritedef.h | 39 ++++++++++++++++-------- 6 files changed, 125 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/being.cpp b/src/being.cpp index 1ed1700f4..63ffc0d2f 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -1012,12 +1012,66 @@ std::string Being::getSitAction() const } else { - if (mMap && !mMap->getWalk(mX, mY, Map::BLOCKMASK_GROUNDTOP)) - return SpriteAction::SITTOP; + if (mMap) + { + const unsigned char mask = mMap->getBlockMask(mX, mY); + if (mask & Map::BLOCKMASK_GROUNDTOP) + return SpriteAction::SITTOP; + else if (mask & Map::BLOCKMASK_AIR) + return SpriteAction::SITSKY; + else if (mask & Map::BLOCKMASK_WATER) + return SpriteAction::SITWATER; + } return SpriteAction::SIT; } } + +std::string Being::getMoveAction() const +{ + if (serverVersion < 0) + { + return SpriteAction::MOVE; + } + else + { + if (mMap) + { + const unsigned char mask = mMap->getBlockMask(mX, mY); + if (mask & Map::BLOCKMASK_AIR) + return SpriteAction::FLY; + else if (mask & Map::BLOCKMASK_WATER) + return SpriteAction::SWIM; + } + return SpriteAction::MOVE; + } +} + +#define getSpriteAction(func, action) \ + std::string Being::get##func##Action() const \ +{ \ + if (serverVersion < 0) \ + { \ + return SpriteAction::action; \ + } \ + else \ + { \ + if (mMap) \ + { \ + const unsigned char mask = mMap->getBlockMask(mX, mY); \ + if (mask & Map::BLOCKMASK_AIR) \ + return SpriteAction::action##SKY; \ + else if (mask & Map::BLOCKMASK_WATER) \ + return SpriteAction::action##WATER; \ + } \ + return SpriteAction::action; \ + } \ +} + +getSpriteAction(Dead, DEAD) +getSpriteAction(Stand, STAND) +getSpriteAction(Spawn, SPAWN) + void Being::setAction(const Action &action, const int attackId) { std::string currentAction = SpriteAction::INVALID; @@ -1030,7 +1084,7 @@ void Being::setAction(const Action &action, const int attackId) playSfx(mInfo->getSound( SOUND_EVENT_MOVE), nullptr, true, mX, mY); } - currentAction = SpriteAction::MOVE; + currentAction = getMoveAction(); // Note: When adding a run action, // Differentiate walk and run with action name, // while using only the ACTION_MOVE. @@ -1050,6 +1104,7 @@ void Being::setAction(const Action &action, const int attackId) case ATTACK: if (mEquippedWeapon) { + // +++ for attack need 3 actions: normal, water, air currentAction = mEquippedWeapon->getAttackAction(); reset(); } @@ -1058,6 +1113,7 @@ void Being::setAction(const Action &action, const int attackId) if (!mInfo || !mInfo->getAttack(attackId)) break; + // +++ for attack need 3 actions: normal, water, air currentAction = mInfo->getAttack(attackId)->mAction; reset(); @@ -1096,7 +1152,7 @@ void Being::setAction(const Action &action, const int attackId) } break; case DEAD: - currentAction = SpriteAction::DEAD; + currentAction = getDeadAction(); if (mInfo) { playSfx(mInfo->getSound(SOUND_EVENT_DIE), this, true, mX, mY); @@ -1105,7 +1161,7 @@ void Being::setAction(const Action &action, const int attackId) } break; case STAND: - currentAction = SpriteAction::STAND; + currentAction = getStandAction(); break; case SPAWN: if (mInfo) @@ -1113,7 +1169,7 @@ void Being::setAction(const Action &action, const int attackId) playSfx(mInfo->getSound(SOUND_EVENT_SPAWN), nullptr, true, mX, mY); } - currentAction = SpriteAction::SPAWN; + currentAction = getSpawnAction(); break; default: logger->log("Being::setAction unknown action: " @@ -1132,8 +1188,12 @@ void Being::setAction(const Action &action, const int attackId) mAction = action; } - if (currentAction != SpriteAction::MOVE) + if (currentAction != SpriteAction::MOVE + && currentAction != SpriteAction::FLY + && currentAction != SpriteAction::SWIM) + { mActionTime = tick_time; + } } void Being::setDirection(const uint8_t direction) diff --git a/src/being.h b/src/being.h index e1ffaff31..d01e30bb9 100644 --- a/src/being.h +++ b/src/being.h @@ -654,6 +654,14 @@ class Being : public ActorSprite, public ConfigListener */ std::string getSitAction() const A_WARN_UNUSED; + std::string getMoveAction() const A_WARN_UNUSED; + + std::string getDeadAction() const A_WARN_UNUSED; + + std::string getStandAction() const A_WARN_UNUSED; + + std::string getSpawnAction() const A_WARN_UNUSED; + /** * Whether or not this player is a GM. */ diff --git a/src/map.cpp b/src/map.cpp index aa28a8160..d69375cf4 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -701,6 +701,16 @@ bool Map::getWalk(const int x, const int y, const unsigned char walkmask) const return !(mMetaTiles[x + y * mWidth].blockmask & walkmask); } +unsigned char Map::getBlockMask(const int x, const int y) +{ + // You can't walk outside of the map + if (x < 0 || y < 0 || x >= mWidth || y >= mHeight) + return 0; + + // Check if the tile is walkable + return mMetaTiles[x + y * mWidth].blockmask; +} + void Map::setWalk(const int x, const int y, const bool walkable A_UNUSED) { blockTile(x, y, Map::BLOCKTYPE_GROUNDTOP); diff --git a/src/map.h b/src/map.h index ac9cd5232..e14b3c18d 100644 --- a/src/map.h +++ b/src/map.h @@ -231,6 +231,8 @@ class Map final : public Properties, public ConfigListener void setWalk(const int x, const int y, const bool walkable); + unsigned char getBlockMask(const int x, const int y); + /** * Returns the width of this map in tiles. */ diff --git a/src/resources/spritedef.cpp b/src/resources/spritedef.cpp index cc47e34c0..16d120b0f 100644 --- a/src/resources/spritedef.cpp +++ b/src/resources/spritedef.cpp @@ -158,6 +158,18 @@ void SpriteDef::substituteActions() substituteAction(SpriteAction::HURT, SpriteAction::STAND); substituteAction(SpriteAction::DEAD, SpriteAction::HURT); substituteAction(SpriteAction::SPAWN, SpriteAction::STAND); + substituteAction(SpriteAction::FLY, SpriteAction::MOVE); + substituteAction(SpriteAction::SWIM, SpriteAction::MOVE); + substituteAction(SpriteAction::STANDSKY, SpriteAction::STAND); + substituteAction(SpriteAction::STANDWATER, SpriteAction::STAND); + substituteAction(SpriteAction::SITSKY, SpriteAction::SIT); + substituteAction(SpriteAction::SITWATER, SpriteAction::SIT); + substituteAction(SpriteAction::ATTACKSKY, SpriteAction::ATTACK); + substituteAction(SpriteAction::ATTACKWATER, SpriteAction::ATTACK); + substituteAction(SpriteAction::SPAWNSKY, SpriteAction::SPAWN); + substituteAction(SpriteAction::SPAWNWATER, SpriteAction::SPAWN); + substituteAction(SpriteAction::DEADSKY, SpriteAction::DEAD); + substituteAction(SpriteAction::DEADWATER, SpriteAction::DEAD); } void SpriteDef::loadSprite(const XmlNodePtr spriteNode, const int variant, diff --git a/src/resources/spritedef.h b/src/resources/spritedef.h index 2a01bb9d7..26c768776 100644 --- a/src/resources/spritedef.h +++ b/src/resources/spritedef.h @@ -84,19 +84,32 @@ typedef std::vector::const_iterator SpriteRefs; */ namespace SpriteAction { - static const std::string DEFAULT = "stand"; - static const std::string STAND = "stand"; - static const std::string SIT = "sit"; - static const std::string SITTOP = "sittop"; - static const std::string SLEEP = "sleep"; - static const std::string DEAD = "dead"; - static const std::string MOVE = "walk"; - static const std::string ATTACK = "attack"; - static const std::string HURT = "hurt"; - static const std::string USE_SPECIAL = "special"; - static const std::string CAST_MAGIC = "magic"; - static const std::string USE_ITEM = "item"; - static const std::string SPAWN = "spawn"; + static const std::string DEFAULT("stand"); + static const std::string STAND("stand"); + static const std::string SIT("sit"); + static const std::string SITTOP("sittop"); + static const std::string SLEEP("sleep"); + static const std::string DEAD("dead"); + static const std::string MOVE("walk"); + static const std::string ATTACK("attack"); + static const std::string HURT("hurt"); + static const std::string USE_SPECIAL("special"); + static const std::string CAST_MAGIC("magic"); + static const std::string USE_ITEM("item"); + static const std::string SPAWN("spawn"); + static const std::string FLY("fly"); + static const std::string SWIM("swim"); + static const std::string STANDSKY("standsky"); + static const std::string STANDWATER("standwater"); + static const std::string SITSKY("sitsky"); + static const std::string SITWATER("sitwater"); + static const std::string ATTACKSKY("attacksky"); + static const std::string ATTACKWATER("attackwater"); + static const std::string SPAWNSKY("spawnsky"); + static const std::string SPAWNWATER("spawnwater"); + static const std::string DEADSKY("deadsky"); + static const std::string DEADWATER("deadwater"); + static const std::string INVALID(""); } // namespace SpriteAction -- cgit v1.2.3-60-g2f50