From 6f287f239e9d94707735b183d6c6b89eea9fef20 Mon Sep 17 00:00:00 2001 From: Erik Schilling Date: Sun, 10 Jun 2012 15:11:01 +0200 Subject: Work on (Auto)Attack system. During the implementation bjorn and I agreed to limit the number of attacks that can be used in the same tick to one. This makes a lot of stuff easier and the client cannot display two frames at the same time Things done: - Implemented setting of attacks when equipping/unequipping items - Single place where the xml attack node is parsed - Finished attack logic - Unified the attack handling of monsters and characters - Added a global cooldown after attack use (not only for next use of same attack) - Removed the temponary attributes for the monster attack values - Priorities for all attacks - Rewrote the attack core: - Attacks now have this attributes: - warmup -> time a attack needs after starting it to actually deal the damage - cooldown -> time a attack needs after dealing damage before another attack can be used - reuse -> time before the same attack can be used again - If no attack is performed at the moment the following is done: - make a list with all ready attacks - check for attack that has the necessarily range and highest priority - start this attack (inform client about it) - when warmup is finished -> trigger damage - when cooldown is finished -> allow to use other (or the same if reusetimer allows) attacks TODO: - sync client with this to allow better timed animations --- src/game-server/item.cpp | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) (limited to 'src/game-server/item.cpp') diff --git a/src/game-server/item.cpp b/src/game-server/item.cpp index 15041ad2..1ca64619 100644 --- a/src/game-server/item.cpp +++ b/src/game-server/item.cpp @@ -47,15 +47,15 @@ void ItemEffectAttrMod::dispell(Being *itemUser) mId, !mDuration); } -bool ItemEffectAttack::apply(Being * /* itemUser */) +bool ItemEffectAttack::apply(Being *itemUser) { - // TODO - STUB + itemUser->addAttack(mAttackInfo); return false; } -void ItemEffectAttack::dispell(Being * /* itemUser */) +void ItemEffectAttack::dispell(Being *itemUser) { - // TODO + itemUser->removeAttack(mAttackInfo); } ItemEffectScript::~ItemEffectScript() @@ -105,12 +105,18 @@ ItemClass::~ItemClass() delete mEffects.begin()->second; mEffects.erase(mEffects.begin()); } + + for (std::vector::iterator it = mAttackInfos.begin(), + it_end = mAttackInfos.end(); + it != it_end; ++it) + { + delete *it; + } } void ItemClass::addEffect(ItemEffectInfo *effect, ItemTriggerType id, ItemTriggerType dispell) -{ mEffects.insert(std::make_pair(id, effect)); if (dispell) mDispells.insert(std::make_pair(dispell, effect)); @@ -121,21 +127,29 @@ bool ItemClass::useTrigger(Being *itemUser, ItemTriggerType trigger) if (!trigger) return false; - std::pair::iterator, - std::multimap< ItemTriggerType, ItemEffectInfo * >::iterator> - rn = mEffects.equal_range(trigger); + std::multimap::iterator it, it_end; + bool ret = false; - while (rn.first != rn.second) - if (rn.first++->second->apply(itemUser)) - ret = true; + for (it = mEffects.begin(), it_end = mEffects.end(); it != it_end; ++it) + if (it->first == trigger) + if (it->second->apply(itemUser)) + ret = true; - rn = mDispells.equal_range(trigger); - while (rn.first != rn.second) - rn.first++->second->dispell(itemUser); + for (it = mDispells.begin(), it_end = mDispells.end(); it != it_end; ++it) + if (it->first == trigger) + it->second->dispell(itemUser); return ret; } +void ItemClass::addAttack(AttackInfo *attackInfo, + ItemTriggerType applyTrigger, + ItemTriggerType dispellTrigger) +{ + mAttackInfos.push_back(attackInfo); + addEffect(new ItemEffectAttack(attackInfo), applyTrigger, dispellTrigger); +} + Item::Item(ItemClass *type, int amount) : Actor(OBJECT_ITEM), mType(type), mAmount(amount) -- cgit v1.2.3-70-g09d2