summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/being.cpp75
-rw-r--r--src/being.h9
-rw-r--r--src/gui/skilldialog.cpp93
-rw-r--r--src/gui/skilldialog.h37
-rw-r--r--src/net/ea/beinghandler.cpp8
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);
}
}