summaryrefslogtreecommitdiffstats
path: root/src/game-server/attack.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server/attack.cpp')
-rw-r--r--src/game-server/attack.cpp124
1 files changed, 93 insertions, 31 deletions
diff --git a/src/game-server/attack.cpp b/src/game-server/attack.cpp
index 4f04255..1825b86 100644
--- a/src/game-server/attack.cpp
+++ b/src/game-server/attack.cpp
@@ -20,58 +20,120 @@
#include "attack.h"
-void Attacks::add(const Attack &attack)
+#include <cassert>
+
+#include "common/defines.h"
+
+#include "game-server/character.h"
+#include "game-server/skillmanager.h"
+
+AttackInfo *AttackInfo::readAttackNode(xmlNodePtr node)
{
- mAttacks.push_back(attack);
- // Slow, but safe.
- mAttacks.sort();
+ std::string skill = XML::getProperty(node, "skill", std::string());
+
+ unsigned skillId;
+ if (utils::isNumeric(skill))
+ skillId = utils::stringToInt(skill);
+ else
+ skillId = skillManager->getId(skill);
+
+ if (!skill.empty() && !skillManager->exists(skillId))
+ {
+ LOG_WARN("Error parsing Attack node: Invalid skill " << skill
+ << " taking default skill");
+ skillId = skillManager->getDefaultSkillId();
+ }
+
+ unsigned id = XML::getProperty(node, "id", 0);
+ unsigned priority = XML::getProperty(node, "priority", 0);
+ unsigned warmupTime = XML::getProperty(node, "warmuptime", 0);
+ unsigned cooldownTime = XML::getProperty(node, "cooldowntime", 0);
+ unsigned reuseTime = XML::getProperty(node, "reusetime", 0);
+ unsigned short baseDamange = XML::getProperty(node, "basedamage", 0);
+ unsigned short deltaDamage = XML::getProperty(node, "deltadamage", 0);
+ unsigned short chanceToHit = XML::getProperty(node, "chancetohit", 0);
+ unsigned short range = XML::getProperty(node, "range", 0);
+ Element element = elementFromString(
+ XML::getProperty(node, "element", "neutral"));
+ DamageType type = damageTypeFromString(
+ XML::getProperty(node, "type", "other"));
+
+ Damage dmg;
+ dmg.id = id;
+ dmg.skill = skillId;
+ dmg.base = baseDamange;
+ dmg.delta = deltaDamage;
+ dmg.cth = chanceToHit;
+ dmg.range = range;
+ dmg.element = element;
+ dmg.type = type;
+ AttackInfo *attack = new AttackInfo(priority, dmg, warmupTime, cooldownTime,
+ reuseTime);
+ return attack;
}
-void Attacks::clear()
+void Attacks::add(AttackInfo *attackInfo)
{
- mAttacks.clear();
+ mAttacks.push_back(Attack(attackInfo));
}
-void Attacks::stop()
+void Attacks::remove(AttackInfo *attackInfo)
{
- for (std::list<Attack>::iterator it = mAttacks.begin();
- it != mAttacks.end(); ++it)
+ for (std::vector<Attack>::iterator it = mAttacks.begin(),
+ it_end = mAttacks.end(); it != it_end; ++it)
{
- it->halt();
+ if ((*it).getAttackInfo() == attackInfo)
+ {
+ if (mCurrentAttack && mCurrentAttack->getAttackInfo() == attackInfo)
+ mCurrentAttack = 0;
+ mAttacks.erase(it);
+ return;
+ }
}
- mActive = false;
}
-void Attacks::start()
+void Attacks::markAttackAsTriggered()
{
- for (std::list<Attack>::iterator it = mAttacks.begin();
- it != mAttacks.end(); ++it)
+ mCurrentAttack->markAsTriggered();
+ mCurrentAttack = 0;
+}
+
+Attack *Attacks::getTriggerableAttack()
+{
+ if (!mCurrentAttack)
+ return 0;
+
+ int cooldownTime = mCurrentAttack->getAttackInfo()->getCooldownTime();
+ if (mAttackTimer.remaining() <= cooldownTime)
{
- // If the attack is inactive, we hard reset it.
- if (!it->getTimer())
- it->reset();
- else
- it->softReset();
+ return mCurrentAttack;
}
- mActive = true;
+
+ return 0;
}
-void Attacks::tick(std::list<Attack> *ret)
+void Attacks::startAttack(Attack *attack)
{
- for (std::list<Attack>::iterator it = mAttacks.begin();
+ mCurrentAttack = attack;
+ mAttackTimer.set(attack->getAttackInfo()->getWarmupTime() +
+ attack->getAttackInfo()->getCooldownTime());
+}
+
+void Attacks::getUsuableAttacks(std::vector<Attack *> *ret)
+{
+ assert(ret != 0);
+
+ // we have a current Attack
+ if ((!mAttackTimer.expired() && mCurrentAttack))
+ return;
+ for (std::vector<Attack>::iterator it = mAttacks.begin();
it != mAttacks.end(); ++it)
{
- if (it->tick())
- {
- if (mActive)
- it->reset();
- else
- it->halt();
- }
+ Attack &attack = *it;
- if (ret && it->isReady())
+ if (attack.isUsuable())
{
- ret->push_back(*it);
+ ret->push_back(&attack);
}
}
}