From 91075015ad4b5bd576c1a5668a11ea0227dd6bd1 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Tue, 23 Jul 2013 23:19:30 +0300 Subject: add support for attacksky and attackwater actions. --- src/being.cpp | 52 +++++++++++++++++++++++++++++++++++++++++---- src/being.h | 4 ++++ src/resources/beinginfo.cpp | 11 ++++++---- src/resources/beinginfo.h | 10 +++++++-- src/resources/itemdb.cpp | 6 ++++++ src/resources/iteminfo.cpp | 18 ++++++++++++++++ src/resources/iteminfo.h | 12 +++++++++++ src/resources/monsterdb.cpp | 10 ++++++--- 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")) { -- cgit v1.2.3-70-g09d2