summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp74
-rw-r--r--src/being.h8
-rw-r--r--src/map.cpp10
-rw-r--r--src/map.h2
-rw-r--r--src/resources/spritedef.cpp12
-rw-r--r--src/resources/spritedef.h39
6 files changed, 125 insertions, 20 deletions
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<SpriteReference*>::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