From 85e7f2a79477712bf3082cb82e6a73c51361abb0 Mon Sep 17 00:00:00 2001 From: Chuck Miller Date: Wed, 10 Feb 2010 23:46:49 -0500 Subject: 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 --- src/being.cpp | 36 ++++++++++++++++++++++-------------- src/being.h | 5 +++++ src/monster.cpp | 6 +++++- src/monster.h | 3 +++ src/particle.cpp | 7 +++++++ src/particle.h | 7 +++++++ src/resources/itemdb.cpp | 2 ++ src/resources/iteminfo.h | 8 ++++++++ src/resources/monsterdb.cpp | 4 +++- src/resources/monsterinfo.cpp | 12 +++++++++++- src/resources/monsterinfo.h | 6 +++++- 11 files changed, 78 insertions(+), 18 deletions(-) (limited to 'src') 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 @@ -441,6 +441,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. */ 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 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::const_iterator i = + mMonsterAttacks.find(attackType); + return (i == mMonsterAttacks.end()) ? empty : (*i).second->missileParticle; +} + SpriteAction MonsterInfo::getAttackAction(int attackType) const { std::map::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& getParticleEffects() const -- cgit v1.2.3-70-g09d2