summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp52
-rw-r--r--src/being.h4
-rw-r--r--src/resources/beinginfo.cpp11
-rw-r--r--src/resources/beinginfo.h10
-rw-r--r--src/resources/itemdb.cpp6
-rw-r--r--src/resources/iteminfo.cpp18
-rw-r--r--src/resources/iteminfo.h12
-rw-r--r--src/resources/monsterdb.cpp10
8 files changed, 110 insertions, 13 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 63ffc0d2f..2fa5b7599 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -1047,6 +1047,52 @@ std::string Being::getMoveAction() const
}
}
+std::string Being::getWeaponAttackAction(const ItemInfo *const weapon) const
+{
+ if (!weapon)
+ return SpriteAction::ATTACK;
+
+ if (serverVersion < 0 || !weapon)
+ {
+ return weapon->getAttackAction();
+ }
+ else
+ {
+ if (mMap)
+ {
+ const unsigned char mask = mMap->getBlockMask(mX, mY);
+ if (mask & Map::BLOCKMASK_AIR)
+ return weapon->getSkyAttackAction();
+ else if (mask & Map::BLOCKMASK_WATER)
+ return weapon->getWaterAttackAction();
+ }
+ return weapon->getAttackAction();
+ }
+}
+
+std::string Being::getAttackAction(const Attack *const attack1) const
+{
+ if (!attack1)
+ return SpriteAction::ATTACK;
+
+ if (serverVersion < 0 || !attack1)
+ {
+ return attack1->mAction;
+ }
+ else
+ {
+ if (mMap)
+ {
+ const unsigned char mask = mMap->getBlockMask(mX, mY);
+ if (mask & Map::BLOCKMASK_AIR)
+ return attack1->mSkyAction;
+ else if (mask & Map::BLOCKMASK_WATER)
+ return attack1->mWaterAction;
+ }
+ return attack1->mAction;
+ }
+}
+
#define getSpriteAction(func, action) \
std::string Being::get##func##Action() const \
{ \
@@ -1104,8 +1150,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();
+ currentAction = getWeaponAttackAction(mEquippedWeapon);
reset();
}
else
@@ -1113,8 +1158,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;
+ currentAction = getAttackAction(mInfo->getAttack(attackId));
reset();
// attack particle effect
diff --git a/src/being.h b/src/being.h
index d01e30bb9..68ef97c10 100644
--- a/src/being.h
+++ b/src/being.h
@@ -662,6 +662,10 @@ class Being : public ActorSprite, public ConfigListener
std::string getSpawnAction() const A_WARN_UNUSED;
+ std::string getWeaponAttackAction(const ItemInfo *const weapon) const;
+
+ std::string getAttackAction(const Attack *const attack) const;
+
/**
* Whether or not this player is a GM.
*/
diff --git a/src/resources/beinginfo.cpp b/src/resources/beinginfo.cpp
index 1d316df5e..48e8b8493 100644
--- a/src/resources/beinginfo.cpp
+++ b/src/resources/beinginfo.cpp
@@ -32,6 +32,7 @@
BeingInfo *BeingInfo::unknown = nullptr;
Attack *BeingInfo::empty = new Attack(SpriteAction::ATTACK,
+ SpriteAction::ATTACKSKY, SpriteAction::ATTACKWATER,
-1, -1, -1, -1, std::string());
BeingInfo::BeingInfo() :
@@ -128,14 +129,16 @@ const Attack *BeingInfo::getAttack(const int id) const
return (i == mAttacks.end()) ? empty : (*i).second;
}
-void BeingInfo::addAttack(const int id, std::string action, const int effectId,
- const int hitEffectId, const int criticalHitEffectId,
+void BeingInfo::addAttack(const int id, std::string action,
+ std::string skyAction, std::string waterAction,
+ const int effectId, const int hitEffectId,
+ const int criticalHitEffectId,
const int missEffectId,
const std::string &missileParticle)
{
delete mAttacks[id];
- mAttacks[id] = new Attack(action, effectId, hitEffectId,
- criticalHitEffectId, missEffectId, missileParticle);
+ mAttacks[id] = new Attack(action, skyAction, waterAction, effectId,
+ hitEffectId, criticalHitEffectId, missEffectId, missileParticle);
}
void BeingInfo::clear()
diff --git a/src/resources/beinginfo.h b/src/resources/beinginfo.h
index 5b2b7b87c..e9f1a6055 100644
--- a/src/resources/beinginfo.h
+++ b/src/resources/beinginfo.h
@@ -35,16 +35,21 @@
struct Attack final
{
std::string mAction;
+ std::string mSkyAction;
+ std::string mWaterAction;
int mEffectId;
int mHitEffectId;
int mCriticalHitEffectId;
int mMissEffectId;
std::string mMissileParticle;
- Attack(const std::string &action, const int effectId,
+ Attack(const std::string &action, const std::string &skyAction,
+ const std::string &waterAction, const int effectId,
const int hitEffectId, const int criticalHitEffectId,
const int missEffectId, const std::string &missileParticle) :
mAction(action),
+ mSkyAction(skyAction),
+ mWaterAction(waterAction),
mEffectId(effectId),
mHitEffectId(hitEffectId),
mCriticalHitEffectId(criticalHitEffectId),
@@ -126,7 +131,8 @@ class BeingInfo final
const SoundInfo &getSound(const SoundEvent event)
const A_WARN_UNUSED;
- void addAttack(const int id, std::string action, const int effectId,
+ void addAttack(const int id, std::string action, std::string skyAttack,
+ std::string waterAttack, const int effectId,
const int hitEffectId, const int criticalHitEffectId,
const int missEffectId,
const std::string &missileParticle);
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 8e5551af3..73a1cf637 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -237,6 +237,10 @@ void ItemDB::loadXmlFile(const std::string &fileName, int &tagNum)
std::string floor = XML::getProperty(node, "floor", "");
std::string description = XML::langProperty(node, "description", "");
std::string attackAction = XML::getProperty(node, "attack-action", "");
+ std::string skyAttackAction = XML::getProperty(
+ node, "skyattack-action", "");
+ std::string waterAttackAction = XML::getProperty(
+ node, "waterattack-action", "");
std::string drawBefore = XML::getProperty(node, "drawBefore", "");
std::string drawAfter = XML::getProperty(node, "drawAfter", "");
const int pet = XML::getProperty(node, "pet", 0);
@@ -338,6 +342,8 @@ void ItemDB::loadXmlFile(const std::string &fileName, int &tagNum)
itemInfo->setView(view);
itemInfo->setWeight(weight);
itemInfo->setAttackAction(attackAction);
+ itemInfo->setSkyAttackAction(skyAttackAction);
+ itemInfo->setWaterAttackAction(waterAttackAction);
itemInfo->setAttackRange(attackRange);
itemInfo->setMissileParticleFile(missileParticle);
itemInfo->setHitEffectId(hitEffectId);
diff --git a/src/resources/iteminfo.cpp b/src/resources/iteminfo.cpp
index 4b85beb64..d788613bf 100644
--- a/src/resources/iteminfo.cpp
+++ b/src/resources/iteminfo.cpp
@@ -49,6 +49,8 @@ ItemInfo::ItemInfo() :
mIsRemoveSprites(false),
mSpriteToItemReplaceList(),
mAttackAction(SpriteAction::INVALID),
+ mSkyAttackAction(SpriteAction::INVALID),
+ mWaterAttackAction(SpriteAction::INVALID),
mAttackRange(0),
mMissileParticle(),
mAnimationFiles(),
@@ -112,6 +114,22 @@ void ItemInfo::setAttackAction(const std::string &attackAction)
mAttackAction = attackAction;
}
+void ItemInfo::setSkyAttackAction(const std::string &attackAction)
+{
+ if (attackAction.empty())
+ mSkyAttackAction = SpriteAction::ATTACKSKY;
+ else
+ mSkyAttackAction = attackAction;
+}
+
+void ItemInfo::setWaterAttackAction(const std::string &attackAction)
+{
+ if (attackAction.empty())
+ mWaterAttackAction = SpriteAction::ATTACKWATER;
+ else
+ mWaterAttackAction = attackAction;
+}
+
void ItemInfo::addSound(const SoundEvent event,
const std::string &filename, const int delay)
{
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index e3dfe29d7..a38f32e66 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -172,6 +172,10 @@ class ItemInfo final
void setAttackAction(const std::string &attackAction);
+ void setSkyAttackAction(const std::string &attackAction);
+
+ void setWaterAttackAction(const std::string &attackAction);
+
// Handlers for seting and getting the string
// used for particles when attacking
void setMissileParticleFile(const std::string &s)
@@ -201,6 +205,12 @@ class ItemInfo final
const std::string &getAttackAction() const
{ return mAttackAction; }
+ const std::string &getSkyAttackAction() const
+ { return mSkyAttackAction; }
+
+ const std::string &getWaterAttackAction() const
+ { return mWaterAttackAction; }
+
int getAttackRange() const A_WARN_UNUSED
{ return mAttackRange; }
@@ -325,6 +335,8 @@ class ItemInfo final
* Attack action sub-types (bow, sword, ...) are defined in items.xml.
*/
std::string mAttackAction;
+ std::string mSkyAttackAction;
+ std::string mWaterAttackAction;
int mAttackRange; /**< Attack range, will be zero if non weapon. */
// Particle to be shown when weapon attacks
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
index 769678ca6..ff7bed370 100644
--- a/src/resources/monsterdb.cpp
+++ b/src/resources/monsterdb.cpp
@@ -213,13 +213,17 @@ void MonsterDB::loadXmlFile(const std::string &fileName)
const std::string spriteAction = XML::getProperty(
spriteNode, "action", "attack");
+ const std::string skySpriteAction = XML::getProperty(
+ spriteNode, "skyaction", "skyattack");
+ const std::string waterSpriteAction = XML::getProperty(
+ spriteNode, "wateraction", "waterattack");
const std::string missileParticle = XML::getProperty(
spriteNode, "missile-particle", "");
- currentInfo->addAttack(id, spriteAction, effectId,
- hitEffectId, criticalHitEffectId, missEffectId,
- missileParticle);
+ currentInfo->addAttack(id, spriteAction, skySpriteAction,
+ waterSpriteAction, effectId, hitEffectId,
+ criticalHitEffectId, missEffectId, missileParticle);
}
else if (xmlNameEqual(spriteNode, "particlefx"))
{