summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-05-26 23:41:01 +0200
committerYohann Ferreira <yohann_dot_ferreira_at_orange_dot_efer>2011-05-26 23:42:10 +0200
commitb35aef2d924f03d85eb44a2465be5a745444eafd (patch)
tree5de5dc327397f9e970ce1bdfacf850a16da02241
parentb02081c00450d274c23b7198620ee7748756bd72 (diff)
downloadmana-client-b35aef2d924f03d85eb44a2465be5a745444eafd.tar.gz
mana-client-b35aef2d924f03d85eb44a2465be5a745444eafd.tar.bz2
mana-client-b35aef2d924f03d85eb44a2465be5a745444eafd.tar.xz
mana-client-b35aef2d924f03d85eb44a2465be5a745444eafd.zip
Added effects support in monsters attacks.
This is provided through the use of the 'effect-id' property of the <attack> tag. Note that the 'particle-effect' support has been removed as it was redundant, but can be kept for backward compatibility. Now, on both Manaserv and tA, only the attack id 1 is supported, i.e: <monster> ... <attack id="1" effect-id="11" action="attack" /> </monster> More to come with re-enabling of the attack type support. I had to fix a crash in the Being::takeDamage() function when there were no attacker (in Manaserv), and add rotation support to the effectManager to achieve this. Reviwed-by: Jaxad0127.
-rw-r--r--src/being.cpp39
-rw-r--r--src/being.h5
-rw-r--r--src/effectmanager.cpp8
-rw-r--r--src/effectmanager.h12
-rw-r--r--src/resources/beinginfo.cpp13
-rw-r--r--src/resources/beinginfo.h23
-rw-r--r--src/resources/monsterdb.cpp11
7 files changed, 57 insertions, 54 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 40479236..d6c5fd55 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -76,7 +76,6 @@ Being::Being(int id, Type type, int subtype, Map *map):
mInfo(BeingInfo::Unknown),
mActionTime(0),
mSpeechTime(0),
- mAttackType(1),
mAttackSpeed(350),
mAction(STAND),
mSubType(0xFFFF),
@@ -391,8 +390,10 @@ 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->getType() == PLAYER && attackerWeapon)
+ const ItemInfo *attackerWeapon = attacker ?
+ attacker->getEquippedWeapon() : 0;
+
+ if (attackerWeapon && attacker->getType() == PLAYER)
{
if (type != CRITICAL)
hitEffectId = attackerWeapon->getHitEffectId();
@@ -410,10 +411,16 @@ void Being::takeDamage(Being *attacker, int amount, AttackType type)
}
}
-void Being::handleAttack(Being *victim, int damage, AttackType type)
+void Being::handleAttack(Being *victim, int damage, int attackId)
{
+ // Monsters, NPCs and remote players handle the first attack (id="1")
+ // per default.
+ // TODO: Fix this for Manaserv by sending the attack id.
+ // TODO: Add attack type handling, see Attack struct and AttackType
+ // and make use of it by grouping attacks per attack type and add random
+ // attack use on tA, based on normal and critical attack types.
if (this != player_node)
- setAction(Being::ATTACK, 1);
+ setAction(Being::ATTACK, attackId);
if (victim)
lookAt(victim->getPosition());
@@ -421,7 +428,8 @@ void Being::handleAttack(Being *victim, int damage, AttackType type)
if (getType() == PLAYER && victim && mEquippedWeapon)
fireMissile(victim, mEquippedWeapon->getMissileParticleFile());
else
- fireMissile(victim, mInfo->getAttack(mAttackType)->missileParticle);
+ fireMissile(victim,
+ mInfo->getAttack(attackId)->mMissileParticleFilename);
sound.playSfx(mInfo->getSound((damage > 0) ?
SOUND_EVENT_HIT : SOUND_EVENT_MISS),
@@ -585,7 +593,7 @@ void Being::fireMissile(Being *victim, const std::string &particle)
}
-void Being::setAction(Action action, int attackType)
+void Being::setAction(Action action, int attackId)
{
std::string currentAction = SpriteAction::INVALID;
@@ -608,16 +616,14 @@ void Being::setAction(Action action, int attackType)
}
else
{
- mAttackType = attackType;
- currentAction = mInfo->getAttack(attackType)->action;
+ currentAction = mInfo->getAttack(attackId)->mAction;
reset();
- int rotation = 0;
- //attack particle effect
- std::string particleEffect = mInfo->getAttack(attackType)
- ->particleEffect;
- if (!particleEffect.empty() && Particle::enabled)
+ // Attack particle effect
+ if (Particle::enabled)
{
+ int effectId = mInfo->getAttack(attackId)->mEffectId;
+ int rotation = 0;
switch (mSpriteDirection)
{
case DIRECTION_DOWN: rotation = 0; break;
@@ -626,10 +632,7 @@ void Being::setAction(Action action, int attackType)
case DIRECTION_RIGHT: rotation = 270; break;
default: break;
}
- Particle *p;
- p = particleEngine->addEffect(particleEffect, 0, 0,
- rotation);
- controlParticle(p);
+ effectManager->trigger(effectId, this, rotation);
}
}
diff --git a/src/being.h b/src/being.h
index f380e0b8..9ac014e0 100644
--- a/src/being.h
+++ b/src/being.h
@@ -172,9 +172,9 @@ class Being : public ActorSprite, public EventListener
*
* @param victim the victim being
* @param damage the amount of damage dealt (0 means miss)
- * @param type the attack type
+ * @param attackId the attack id
*/
- virtual void handleAttack(Being *victim, int damage, AttackType type);
+ virtual void handleAttack(Being *victim, int damage, int attackId = 1);
const ItemInfo *getEquippedWeapon() const
{ return mEquippedWeapon; }
@@ -471,7 +471,6 @@ class Being : public ActorSprite, public EventListener
/** Time until the last speech sentence disappears */
int mSpeechTime;
- int mAttackType;
int mAttackSpeed; /**< Attack speed */
Action mAction; /**< Action the being is performing */
diff --git a/src/effectmanager.cpp b/src/effectmanager.cpp
index 576d48b6..5ac1dd5a 100644
--- a/src/effectmanager.cpp
+++ b/src/effectmanager.cpp
@@ -63,7 +63,7 @@ EffectManager::~EffectManager()
{
}
-bool EffectManager::trigger(int id, Being* being)
+bool EffectManager::trigger(int id, Being* being, int rotation)
{
bool rValue = false;
for (std::list<EffectDescription>::iterator i = mEffects.begin(); i != mEffects.end(); ++i)
@@ -74,7 +74,7 @@ bool EffectManager::trigger(int id, Being* being)
if (!(*i).GFX.empty())
{
Particle *selfFX;
- selfFX = particleEngine->addEffect((*i).GFX, 0, 0);
+ selfFX = particleEngine->addEffect((*i).GFX, 0, 0, rotation);
being->controlParticle(selfFX);
}
if (!(*i).SFX.empty())
@@ -85,7 +85,7 @@ bool EffectManager::trigger(int id, Being* being)
return rValue;
}
-bool EffectManager::trigger(int id, int x, int y)
+bool EffectManager::trigger(int id, int x, int y, int rotation)
{
bool rValue = false;
for (std::list<EffectDescription>::iterator i = mEffects.begin(); i != mEffects.end(); ++i)
@@ -94,7 +94,7 @@ bool EffectManager::trigger(int id, int x, int y)
{
rValue = true;
if (!(*i).GFX.empty())
- particleEngine->addEffect((*i).GFX, x, y);
+ particleEngine->addEffect((*i).GFX, x, y, rotation);
if (!(*i).SFX.empty())
sound.playSfx((*i).SFX);
break;
diff --git a/src/effectmanager.h b/src/effectmanager.h
index ef1e0f27..8302990e 100644
--- a/src/effectmanager.h
+++ b/src/effectmanager.h
@@ -42,15 +42,19 @@ class EffectManager
/**
* Triggers a effect with the id, at
- * the specified being.
+ * the specified being,
+ * and with the given rotation in degree:
+ * 0° = Down, 90° = left, ...
*/
- bool trigger(int id, Being* being);
+ bool trigger(int id, Being* being, int rotation = 0);
/**
* Triggers a effect with the id, at
- * the specified x and y coordinate.
+ * the specified x and y coordinate,
+ * and with the given rotation in degree:
+ * 0° = Down, 90° = left, ...
*/
- bool trigger(int id, int x, int y);
+ bool trigger(int id, int x, int y, int rotation = 0);
private:
std::list<EffectDescription> mEffects;
diff --git a/src/resources/beinginfo.cpp b/src/resources/beinginfo.cpp
index e8824391..22651f6f 100644
--- a/src/resources/beinginfo.cpp
+++ b/src/resources/beinginfo.cpp
@@ -88,20 +88,19 @@ const std::string &BeingInfo::getSound(SoundEvent event) const
i->second->at(rand() % i->second->size());
}
-const Attack *BeingInfo::getAttack(int type) const
+const Attack *BeingInfo::getAttack(int id) const
{
- static Attack *empty = new Attack(SpriteAction::ATTACK, "", "");
+ static Attack *empty = new Attack(SpriteAction::ATTACK, -1, std::string());
- Attacks::const_iterator i = mAttacks.find(type);
+ Attacks::const_iterator i = mAttacks.find(id);
return (i == mAttacks.end()) ? empty : (*i).second;
}
-void BeingInfo::addAttack(int id, std::string action,
- const std::string &particleEffect,
- const std::string &missileParticle)
+void BeingInfo::addAttack(int id, std::string action, int effectId,
+ const std::string &missileParticleFilename)
{
if (mAttacks[id])
delete mAttacks[id];
- mAttacks[id] = new Attack(action, particleEffect, missileParticle);
+ mAttacks[id] = new Attack(action, effectId, missileParticleFilename);
}
diff --git a/src/resources/beinginfo.h b/src/resources/beinginfo.h
index 52390976..b4529b2f 100644
--- a/src/resources/beinginfo.h
+++ b/src/resources/beinginfo.h
@@ -32,16 +32,16 @@
#include <vector>
struct Attack {
- std::string action;
- std::string particleEffect;
- std::string missileParticle;
+ std::string mAction;
+ int mEffectId;
+ std::string mMissileParticleFilename;
- Attack(std::string action, std::string particleEffect,
- std::string missileParticle)
+ Attack(std::string action, int effectId,
+ std::string missileParticleFilename)
{
- this->action = action;
- this->particleEffect = particleEffect;
- this->missileParticle = missileParticle;
+ mAction = action;
+ mEffectId = effectId;
+ mMissileParticleFilename = missileParticleFilename;
}
};
@@ -95,11 +95,10 @@ class BeingInfo
const std::string &getSound(SoundEvent event) const;
- void addAttack(int id, std::string action,
- const std::string &particleEffect,
- const std::string &missileParticle);
+ void addAttack(int id, std::string action, int effectId,
+ const std::string &missileParticleFilename);
- const Attack *getAttack(int type) const;
+ const Attack *getAttack(int id) const;
void setWalkMask(unsigned char mask)
{ mWalkMask = mask; }
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
index 6bc64a89..ca9b8e83 100644
--- a/src/resources/monsterdb.cpp
+++ b/src/resources/monsterdb.cpp
@@ -124,15 +124,14 @@ void MonsterDB::load()
else if (xmlStrEqual(spriteNode->name, BAD_CAST "attack"))
{
const int id = XML::getProperty(spriteNode, "id", 0);
- const std::string particleEffect = XML::getProperty(
- spriteNode, "particle-effect", "");
+ int effectId = XML::getProperty(spriteNode, "effect-id", -1);
const std::string spriteAction = XML::getProperty(spriteNode,
"action",
"attack");
- const std::string missileParticle = XML::getProperty(
- spriteNode, "missile-particle", "");
- currentInfo->addAttack(id, spriteAction,
- particleEffect, missileParticle);
+ const std::string missileParticleFilename =
+ XML::getProperty(spriteNode, "missile-particle", "");
+ currentInfo->addAttack(id, spriteAction, effectId,
+ missileParticleFilename);
}
else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
{