diff options
-rw-r--r-- | src/being.cpp | 75 | ||||
-rw-r--r-- | src/being.h | 9 | ||||
-rw-r--r-- | src/gui/skilldialog.cpp | 93 | ||||
-rw-r--r-- | src/gui/skilldialog.h | 37 | ||||
-rw-r--r-- | src/net/ea/beinghandler.cpp | 8 |
5 files changed, 146 insertions, 76 deletions
diff --git a/src/being.cpp b/src/being.cpp index 664eecd1d..cbe0a4a5e 100644 --- a/src/being.cpp +++ b/src/being.cpp @@ -52,6 +52,7 @@ #include "gui/speechbubble.h" #include "gui/theme.h" #include "gui/sdlfont.h" +#include "gui/skilldialog.h" #include "gui/userpalette.h" #include "net/charhandler.h" @@ -550,7 +551,7 @@ void Being::setSpeech(const std::string &text, int time) } } -void Being::takeDamage(Being *attacker, int amount, AttackType type) +void Being::takeDamage(Being *attacker, int amount, AttackType type, int id) { if (!userPalette || !attacker) return; @@ -642,7 +643,8 @@ void Being::takeDamage(Being *attacker, int amount, AttackType type) getPixelX(), getPixelY() - 16, color, font, true); } - attacker->updateHit(amount); + if (type != SKILL) + attacker->updateHit(amount); if (amount > 0) { @@ -681,20 +683,28 @@ void Being::takeDamage(Being *attacker, int amount, AttackType type) // Init the particle effect path based on current // weapon or default. int hitEffectId = 0; - const ItemInfo *attackerWeapon = attacker->getEquippedWeapon(); - if (attacker->mType == PLAYER && attackerWeapon) + if (type != SKILL) { - if (type != CRITICAL) - hitEffectId = attackerWeapon->getHitEffectId(); + const ItemInfo *attackerWeapon = attacker->getEquippedWeapon(); + if (attacker->mType == PLAYER && attackerWeapon) + { + if (type != CRITICAL) + hitEffectId = attackerWeapon->getHitEffectId(); + else + hitEffectId = attackerWeapon->getCriticalHitEffectId(); + } else - hitEffectId = attackerWeapon->getCriticalHitEffectId(); + { + if (type != CRITICAL) + hitEffectId = paths.getIntValue("hitEffectId"); + else + hitEffectId = paths.getIntValue("criticalHitEffectId"); + } } else { - if (type != CRITICAL) - hitEffectId = paths.getIntValue("hitEffectId"); - else - hitEffectId = paths.getIntValue("criticalHitEffectId"); + // move skills effects to +100000 in effects list + hitEffectId = id + 100000; } effectManager->trigger(hitEffectId, this); } @@ -736,6 +746,49 @@ void Being::handleAttack(Being *victim, int damage, SOUND_EVENT_HIT : SOUND_EVENT_MISS), mX, mY); } +void Being::handleSkill(Being *victim, int damage, int skillId) +{ + if (!victim || !mInfo || !skillDialog) + return; + + if (this != player_node) + setAction(Being::ATTACK, 1); + + SkillInfo *skill = skillDialog->getSkill(skillId); + if (skill) + fireMissile(victim, skill->particle); + +#ifdef MANASERV_SUPPORT + if (Net::getNetworkType() != ServerInfo::MANASERV) +#endif + { + reset(); + mActionTime = tick_time; + } + + if (this != player_node) + { + Uint8 dir = calcDirection(victim->getTileX(), victim->getTileY()); + if (dir) + setDirection(dir); + } + if (damage && victim->mType == PLAYER && victim->mAction == SIT) + victim->setAction(STAND); + + if (skill) + { + if (damage > 0) + sound.playSfx(skill->soundHit, mX, mY); + else + sound.playSfx(skill->soundMiss, mX, mY); + } + else + { + sound.playSfx(mInfo->getSound((damage > 0) ? + SOUND_EVENT_HIT : SOUND_EVENT_MISS), mX, mY); + } +} + void Being::setName(const std::string &name) { if (mType == NPC) diff --git a/src/being.h b/src/being.h index 859ebf26c..7ad2199ff 100644 --- a/src/being.h +++ b/src/being.h @@ -136,7 +136,8 @@ class Being : public ActorSprite, public ConfigListener CRITICAL = 0x0a, MULTI = 0x08, REFLECT = 0x04, - FLEE = 0x0b + FLEE = 0x0b, + SKILL = 0xff }; enum Reachable @@ -253,8 +254,10 @@ class Being : public ActorSprite, public ConfigListener * @param attacker the attacking being * @param damage the amount of damage recieved (0 means miss) * @param type the attack type + * @param id skill id */ - void takeDamage(Being *attacker, int damage, AttackType type); + void takeDamage(Being *attacker, int damage, + AttackType type, int id = 0); /** * Handles an attack of another being by this being. @@ -265,6 +268,8 @@ class Being : public ActorSprite, public ConfigListener */ virtual void handleAttack(Being *victim, int damage, AttackType type); + virtual void handleSkill(Being *victim, int damage, int skillId); + const ItemInfo *getEquippedWeapon() const { return mEquippedWeapon; } diff --git a/src/gui/skilldialog.cpp b/src/gui/skilldialog.cpp index d5af42aae..023c5a4f0 100644 --- a/src/gui/skilldialog.cpp +++ b/src/gui/skilldialog.cpp @@ -65,64 +65,6 @@ class SkillModel; class SkillEntry; -struct SkillInfo -{ - unsigned short id; - std::string name; - std::string dispName; - Image *icon; - bool modifiable; - bool visible; - SkillModel *model; - - int level; - std::string skillLevel; - int skillLevelWidth; - - std::string skillExp; - float progress; - gcn::Color color; - int range; - - SkillInfo() : - id(0), name(""), dispName(""), icon(nullptr), modifiable(false), - visible(false), model(nullptr), level(0), skillLevel(""), - skillLevelWidth(0), skillExp(""), progress(0.0f), range(0) - { - } - - ~SkillInfo() - { - if (icon) - { - icon->decRef(); - icon = nullptr; - } - } - - void setIcon(const std::string &iconPath) - { - ResourceManager *res = ResourceManager::getInstance(); - if (!iconPath.empty()) - { - icon = res->getImage(iconPath); - } - - if (!icon) - { - icon = Theme::getImageFromTheme( - paths.getStringValue("unknownItemFile")); - } - } - - void update(); - - void draw(Graphics *graphics, int y, int width); -}; - - -typedef std::vector<SkillInfo*> SkillList; - class SkillModel : public gcn::ListModel { public: @@ -477,6 +419,9 @@ void SkillDialog::loadSkills(const std::string &file) skill->setIcon(icon); skill->modifiable = false; skill->visible = false; + skill->particle = XML::getProperty(node, "particle", ""); + skill->soundHit = XML::getProperty(node, "soundHit", ""); + skill->soundMiss = XML::getProperty(node, "soundMiss", ""); skill->model = model; skill->update(); @@ -561,6 +506,38 @@ void SkillModel::updateVisibilities() } } +SkillInfo::SkillInfo() : + id(0), name(""), dispName(""), icon(nullptr), modifiable(false), + visible(false), model(nullptr), level(0), skillLevel(""), + skillLevelWidth(0), skillExp(""), progress(0.0f), range(0), + particle(""), soundHit(""), soundMiss("") +{ +} + +SkillInfo::~SkillInfo() +{ + if (icon) + { + icon->decRef(); + icon = nullptr; + } +} + +void SkillInfo::setIcon(const std::string &iconPath) +{ + ResourceManager *res = ResourceManager::getInstance(); + if (!iconPath.empty()) + { + icon = res->getImage(iconPath); + } + + if (!icon) + { + icon = Theme::getImageFromTheme( + paths.getStringValue("unknownItemFile")); + } +} + void SkillInfo::update() { int baseLevel = PlayerInfo::getStatBase(id); diff --git a/src/gui/skilldialog.h b/src/gui/skilldialog.h index 56858ef5e..1cb832906 100644 --- a/src/gui/skilldialog.h +++ b/src/gui/skilldialog.h @@ -40,7 +40,42 @@ class SkillModel; class Tab; class TabbedArea; -struct SkillInfo; +struct SkillInfo +{ + unsigned short id; + std::string name; + std::string dispName; + Image *icon; + bool modifiable; + bool visible; + SkillModel *model; + + int level; + std::string skillLevel; + int skillLevelWidth; + + std::string skillExp; + float progress; + gcn::Color color; + int range; + std::string particle; + std::string soundHit; + std::string soundMiss; + + SkillInfo(); + + ~SkillInfo(); + + void setIcon(const std::string &iconPath); + + void update(); + + void draw(Graphics *graphics, int y, int width); +}; + + +typedef std::vector<SkillInfo*> SkillList; + /** * The skill dialog. diff --git a/src/net/ea/beinghandler.cpp b/src/net/ea/beinghandler.cpp index d9e7e7506..f1d608717 100644 --- a/src/net/ea/beinghandler.cpp +++ b/src/net/ea/beinghandler.cpp @@ -445,7 +445,7 @@ void BeingHandler::processSkillDamage(Net::MessageIn &msg) Being *dstBeing; int param1; - msg.readInt16(); // Skill Id + int id = msg.readInt16(); // Skill Id srcBeing = actorSpriteManager->findBeing(msg.readInt32()); dstBeing = actorSpriteManager->findBeing(msg.readInt32()); msg.readInt32(); // Server tick @@ -457,16 +457,16 @@ void BeingHandler::processSkillDamage(Net::MessageIn &msg) msg.readInt8(); // Skill hit/type (?) if (dstBeing) { - // Perhaps a new skill attack type should be created and used? // if (dstSpeed) // dstBeing->setAttackDelay(dstSpeed); - dstBeing->takeDamage(srcBeing, param1, Being::HIT); + dstBeing->takeDamage(srcBeing, param1, Being::SKILL, id); } if (srcBeing) { // if (srcSpeed) // srcBeing->setAttackDelay(srcSpeed); - srcBeing->handleAttack(dstBeing, param1, Being::HIT); +// srcBeing->handleAttack(dstBeing, param1, Being::HIT); + srcBeing->handleSkill(dstBeing, param1, id); } } |