summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuck Miller <shadowmil@gmail.com>2010-02-10 23:46:49 -0500
committerChuck Miller <shadowmil@gmail.com>2010-02-10 23:50:23 -0500
commit85e7f2a79477712bf3082cb82e6a73c51361abb0 (patch)
treec8a42adb06e0c5ba416bd30fcd1808c1e4f26ddc
parent3a761a242436e521c7fa8ef3746551ac7b746308 (diff)
downloadmana-client-85e7f2a79477712bf3082cb82e6a73c51361abb0.tar.gz
mana-client-85e7f2a79477712bf3082cb82e6a73c51361abb0.tar.bz2
mana-client-85e7f2a79477712bf3082cb82e6a73c51361abb0.tar.xz
mana-client-85e7f2a79477712bf3082cb82e6a73c51361abb0.zip
Adds missile-particle attribute to items and monster attacks
To use simply add something like: missile-particle="graphics/particles/arrow.particle.xml" to the item's or monster's xml entry This will only work on equipped weapons, and on specified monster attacks. This patch also fixes a memory leak with target particles
-rw-r--r--src/being.cpp36
-rw-r--r--src/being.h5
-rw-r--r--src/monster.cpp6
-rw-r--r--src/monster.h3
-rw-r--r--src/particle.cpp7
-rw-r--r--src/particle.h7
-rw-r--r--src/resources/itemdb.cpp2
-rw-r--r--src/resources/iteminfo.h8
-rw-r--r--src/resources/monsterdb.cpp4
-rw-r--r--src/resources/monsterinfo.cpp12
-rw-r--r--src/resources/monsterinfo.h6
11 files changed, 78 insertions, 18 deletions
diff --git a/src/being.cpp b/src/being.cpp
index 1c66f673..42fb2d4e 100644
--- a/src/being.cpp
+++ b/src/being.cpp
@@ -327,21 +327,9 @@ void Being::handleAttack(Being *victim, int damage, AttackType type)
setAction(Being::ATTACK, 1);
if (getType() == PLAYER && victim)
{
- if (mEquippedWeapon && mEquippedWeapon->getAttackType() == ACTION_ATTACK_BOW)
+ if (mEquippedWeapon)
{
- Particle *p = new Particle(NULL);
- p->setLifetime(1000);
- p->moveBy(Vector(0.0f, 0.0f, 32.0f));
- victim->controlParticle(p);
-
- Particle *p2 = particleEngine->addEffect("graphics/particles/arrow.particle.xml",
- getPixelX(), getPixelY());
- if (p2)
- {
- p2->setLifetime(900);
- p2->setDestination(p, 7, 0);
- p2->setDieDistance(8);
- }
+ fireMissile(victim, mEquippedWeapon->getMissileParticle());
}
}
if (Net::getNetworkType() == ServerInfo::EATHENA)
@@ -398,6 +386,26 @@ void Being::controlParticle(Particle *particle)
mChildParticleEffects.addLocally(particle);
}
+void Being::fireMissile(Being *victim, const std::string &particle)
+{
+ if (!victim || particle.empty())
+ return;
+
+ Particle *target = particleEngine->createChild();
+ Particle *missile = target->addEffect(particle, getPixelX(), getPixelY());
+
+ if (missile)
+ {
+ target->setLifetime(2000);
+ target->moveBy(Vector(0.0f, 0.0f, 32.0f));
+ victim->controlParticle(target);
+
+ missile->setDestination(target, 7, 0);
+ missile->setDieDistance(8);
+ missile->setLifetime(900);
+ }
+}
+
void Being::setAction(Action action, int attackType)
{
SpriteAction currentAction = ACTION_INVALID;
diff --git a/src/being.h b/src/being.h
index 79ab1df2..404bd8e6 100644
--- a/src/being.h
+++ b/src/being.h
@@ -442,6 +442,11 @@ class Being : public Sprite, public ConfigListener
void controlParticle(Particle *particle);
/**
+ * Shoots a missile particle from this being, to target being
+ */
+ void fireMissile(Being *target, const std::string &particle);
+
+ /**
* Gets the way the object is blocked by other objects.
*/
virtual unsigned char getWalkMask() const
diff --git a/src/monster.cpp b/src/monster.cpp
index 0d0757dd..45af468e 100644
--- a/src/monster.cpp
+++ b/src/monster.cpp
@@ -35,7 +35,8 @@
#include "resources/monsterinfo.h"
Monster::Monster(int id, int job, Map *map):
- Being(id, job, map)
+ Being(id, job, map),
+ mAttackType(1)
{
const MonsterInfo& info = getInfo();
@@ -100,6 +101,7 @@ void Monster::setAction(Action action, int attackType)
sound.playSfx(getInfo().getSound(MONSTER_EVENT_DIE));
break;
case ATTACK:
+ mAttackType = attackType;
currentAction = getInfo().getAttackAction(attackType);
for (SpriteIterator it = mSprites.begin(); it != mSprites.end(); it++)
(*it)->reset();
@@ -148,6 +150,8 @@ void Monster::handleAttack(Being *victim, int damage, AttackType type)
const MonsterInfo &mi = getInfo();
sound.playSfx(mi.getSound((damage > 0) ?
MONSTER_EVENT_HIT : MONSTER_EVENT_MISS));
+
+ fireMissile(victim, mi.getAttackMissileParticle(mAttackType));
}
void Monster::takeDamage(Being *attacker, int amount, AttackType type)
diff --git a/src/monster.h b/src/monster.h
index f2bec72d..b35d908f 100644
--- a/src/monster.h
+++ b/src/monster.h
@@ -88,6 +88,9 @@ class Monster : public Being
void updateCoords();
void showName();
+
+ private:
+ int mAttackType;
};
#endif
diff --git a/src/particle.cpp b/src/particle.cpp
index 3f75943e..69a68efe 100644
--- a/src/particle.cpp
+++ b/src/particle.cpp
@@ -254,6 +254,13 @@ void Particle::moveTo(float x, float y)
moveTo(Vector(x, y, mPos.z));
}
+Particle *Particle::createChild()
+{
+ Particle *newParticle = new Particle(mMap);
+ mChildParticles.push_back(newParticle);
+ return newParticle;
+}
+
Particle *Particle::addEffect(const std::string &particleEffectFile,
int pixelX, int pixelY, int rotation)
{
diff --git a/src/particle.h b/src/particle.h
index 2e48211d..1d2b6526 100644
--- a/src/particle.h
+++ b/src/particle.h
@@ -96,6 +96,13 @@ class Particle : public Sprite
*/
void setMap(Map *map);
+
+ /**
+ * Creates a blank particle as a child of the current particle
+ * Useful for creating target particles
+ */
+ Particle *createChild();
+
/**
* Creates a child particle that hosts some emitters described in the
* particleEffectFile.
diff --git a/src/resources/itemdb.cpp b/src/resources/itemdb.cpp
index 0cb18e76..c215e942 100644
--- a/src/resources/itemdb.cpp
+++ b/src/resources/itemdb.cpp
@@ -150,6 +150,7 @@ void ItemDB::load()
std::string description = XML::getProperty(node, "description", "");
int weaponType = weaponTypeFromString(XML::getProperty(node, "weapon-type", ""));
int attackRange = XML::getProperty(node, "attack-range", 0);
+ std::string missileParticle = XML::getProperty(node, "missile-particle", "");
ItemInfo *itemInfo = new ItemInfo;
itemInfo->setId(id);
@@ -161,6 +162,7 @@ void ItemDB::load()
itemInfo->setWeight(weight);
itemInfo->setWeaponType(weaponType);
itemInfo->setAttackRange(attackRange);
+ itemInfo->setMissileParticle(missileParticle);
std::string effect;
for (int i = 0; i < int(sizeof(fields) / sizeof(fields[0])); ++i)
diff --git a/src/resources/iteminfo.h b/src/resources/iteminfo.h
index 88cdcd85..796382cd 100644
--- a/src/resources/iteminfo.h
+++ b/src/resources/iteminfo.h
@@ -180,6 +180,11 @@ class ItemInfo
void setWeaponType(int);
+ // Handlers for seting and getting the string used for particles when attacking
+ void setMissileParticle(std::string s) { mMissileParticle = s; }
+
+ std::string getMissileParticle() const { return mMissileParticle; }
+
SpriteAction getAttackType() const
{ return mAttackType; }
@@ -208,6 +213,9 @@ class ItemInfo
SpriteAction mAttackType; /**< Attack type, in case of weapon. */
int mAttackRange; /**< Attack range, will be zero if non weapon. */
+ // Particle to be shown when weapon attacks
+ std::string mMissileParticle;
+
/** Maps gender to sprite filenames. */
std::map<int, std::string> mAnimationFiles;
diff --git a/src/resources/monsterdb.cpp b/src/resources/monsterdb.cpp
index 5ccb5dd1..dffac5f5 100644
--- a/src/resources/monsterdb.cpp
+++ b/src/resources/monsterdb.cpp
@@ -133,7 +133,9 @@ void MonsterDB::load()
spriteNode, "particle-effect", "");
SpriteAction spriteAction = SpriteDef::makeSpriteAction(
XML::getProperty(spriteNode, "action", "attack"));
- currentInfo->addMonsterAttack(id, particleEffect, spriteAction);
+ const std::string missileParticle = XML::getProperty(
+ spriteNode, "missile-particle", "");
+ currentInfo->addMonsterAttack(id, particleEffect, spriteAction, missileParticle);
}
else if (xmlStrEqual(spriteNode->name, BAD_CAST "particlefx"))
{
diff --git a/src/resources/monsterinfo.cpp b/src/resources/monsterinfo.cpp
index 2d788a72..fbb93ec1 100644
--- a/src/resources/monsterinfo.cpp
+++ b/src/resources/monsterinfo.cpp
@@ -62,6 +62,14 @@ const std::string &MonsterInfo::getAttackParticleEffect(int attackType) const
return (i == mMonsterAttacks.end()) ? empty : (*i).second->particleEffect;
}
+const std::string &MonsterInfo::getAttackMissileParticle(int attackType) const
+{
+ static std::string empty("");
+ std::map<int, MonsterAttack*>::const_iterator i =
+ mMonsterAttacks.find(attackType);
+ return (i == mMonsterAttacks.end()) ? empty : (*i).second->missileParticle;
+}
+
SpriteAction MonsterInfo::getAttackAction(int attackType) const
{
std::map<int, MonsterAttack*>::const_iterator i =
@@ -71,10 +79,12 @@ SpriteAction MonsterInfo::getAttackAction(int attackType) const
void MonsterInfo::addMonsterAttack(int id,
const std::string &particleEffect,
- SpriteAction action)
+ SpriteAction action,
+ const std::string &missileParticle)
{
MonsterAttack *a = new MonsterAttack;
a->particleEffect = particleEffect;
+ a->missileParticle = missileParticle;
a->action = action;
mMonsterAttacks[id] = a;
}
diff --git a/src/resources/monsterinfo.h b/src/resources/monsterinfo.h
index f6cec609..4e92ad02 100644
--- a/src/resources/monsterinfo.h
+++ b/src/resources/monsterinfo.h
@@ -39,6 +39,7 @@ enum MonsterSoundEvent
struct MonsterAttack
{
+ std::string missileParticle;
std::string particleEffect;
SpriteAction action;
};
@@ -81,10 +82,13 @@ class MonsterInfo
void addMonsterAttack(int id,
const std::string &particleEffect,
- SpriteAction action);
+ SpriteAction action,
+ const std::string &missileParticle);
const std::string &getAttackParticleEffect(int attackType) const;
+ const std::string &getAttackMissileParticle(int attackType) const;
+
SpriteAction getAttackAction(int attackType) const;
const std::list<std::string>& getParticleEffects() const