diff options
author | Erik Schilling <ablu.erikschilling@googlemail.com> | 2013-03-30 09:29:08 +0100 |
---|---|---|
committer | Erik Schilling <ablu.erikschilling@googlemail.com> | 2013-04-02 13:19:11 +0200 |
commit | 585a33e221a7ee392791f4fd5a5ec9214b8fe868 (patch) | |
tree | 3aa60a57ff7cdd8f57761d620352fd2ad4d0dd6f /src/game-server/being.cpp | |
parent | 4dfc82415691fe298f21bb2f81fed5c168ee14e5 (diff) | |
download | manaserv-585a33e221a7ee392791f4fd5a5ec9214b8fe868.tar.gz manaserv-585a33e221a7ee392791f4fd5a5ec9214b8fe868.tar.bz2 manaserv-585a33e221a7ee392791f4fd5a5ec9214b8fe868.tar.xz manaserv-585a33e221a7ee392791f4fd5a5ec9214b8fe868.zip |
Moved fighting code into a component
All damage dealing is now handeled via CombatComponent.
Monsters use a derived MonsterCombatComponent since they can have a damage
mutation and have a seperate script callback.
The wirering with Being is still not optional since most of the stuff does
not exist as components.
Things done:
- Seperated the fighting code from Being and only let Characters and Monsters
add the Component (less overhead for npcs)
- Added a getter for Attribute values to prevent searching it all the time in
non Being members
- Fixed the type if the damage mutation to double (no idea why it was int)
I did not want to copy it over incorrectly
- Removed the addAttack/removeAttack overrides in Character and made the
knuckleAttack being added based on newly added signals
Future TODOS:
- Remove depedency on Being as soon all needed dependencies are available
as components of Entity
- Move the monster script callback into the general combatcomponent and
make it usuable for characters too
Diffstat (limited to 'src/game-server/being.cpp')
-rw-r--r-- | src/game-server/being.cpp | 171 |
1 files changed, 15 insertions, 156 deletions
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp index 9112a1b8..42d34046 100644 --- a/src/game-server/being.cpp +++ b/src/game-server/being.cpp @@ -27,6 +27,7 @@ #include "game-server/attributemanager.h" #include "game-server/character.h" #include "game-server/collisiondetection.h" +#include "game-server/combatcomponent.h" #include "game-server/mapcomposite.h" #include "game-server/effect.h" #include "game-server/skillmanager.h" @@ -43,9 +44,7 @@ Script::Ref Being::mRecalculateBaseAttributeCallback; Being::Being(EntityType type): Actor(type), mAction(STAND), - mTarget(NULL), mGender(GENDER_UNSPECIFIED), - mCurrentAttack(0), mDirection(DOWN), mEmoteId(0) { @@ -87,74 +86,7 @@ void Being::triggerEmote(int id) raiseUpdateFlags(UPDATEFLAG_EMOTE); } -int Being::damage(Actor * /* source */, const Damage &damage) -{ - if (mAction == DEAD) - return 0; - - int HPloss = damage.base; - if (damage.delta) - HPloss += rand() * (damage.delta + 1) / RAND_MAX; - - // TODO magical attacks and associated elemental modifiers - switch (damage.type) - { - case DAMAGE_PHYSICAL: - if (!damage.trueStrike && - rand()%((int) getModifiedAttribute(ATTR_DODGE) + 1) > - rand()%(damage.cth + 1)) - { - HPloss = 0; - // TODO Process triggers for a dodged physical attack here. - // If there is an attacker included, also process triggers for the attacker (failed physical strike) - } - else - { - HPloss = HPloss * (1.0 - (0.0159375f * - getModifiedAttribute(ATTR_DEFENSE)) / - (1.0 + 0.017 * - getModifiedAttribute(ATTR_DEFENSE))) + - (rand()%((HPloss >> 4) + 1)); - // TODO Process triggers for receiving damage here. - // If there is an attacker included, also process triggers for the attacker (successful physical strike) - } - break; - case DAMAGE_MAGICAL: -#if 0 - getModifiedAttribute(BASE_ELEM_BEGIN + damage.element); -#else - LOG_WARN("Attempt to use magical type damage! This has not been" - "implemented yet and should not be used!"); - HPloss = 0; -#endif - break; - case DAMAGE_DIRECT: - break; - default: - LOG_WARN("Unknown damage type '" << damage.type << "'!"); - break; - } - - if (HPloss > 0) - { - mHitsTaken.push_back(HPloss); - Attribute &HP = mAttributes.at(ATTR_HP); - LOG_DEBUG("Being " << getPublicID() << " suffered " << HPloss - << " damage. HP: " - << HP.getModifiedAttribute() << "/" - << mAttributes.at(ATTR_MAX_HP).getModifiedAttribute()); - setAttribute(ATTR_HP, HP.getBase() - HPloss); - // No HP regen after being hit if this is set. - mHealthRegenerationTimeout.setSoft( - Configuration::getValue("game_hpRegenBreakAfterHit", 0)); - } - else - { - HPloss = 0; - } - return HPloss; -} void Being::heal() { @@ -191,71 +123,9 @@ void Being::died() // dead beings stay where they are clearDestination(); - // reset target - mTarget = NULL; - signal_died.emit(this); } -void Being::processAttacks() -{ - if (mAction != ATTACK || !mTarget) - return; - - // Ticks attacks even when not attacking to permit cooldowns and warmups. - std::vector<Attack *> attacksReady; - mAttacks.getUsuableAttacks(&attacksReady); - - if (Attack *triggerableAttack = mAttacks.getTriggerableAttack()) - { - processAttack(*triggerableAttack); - mAttacks.markAttackAsTriggered(); - } - - // Deal with the ATTACK action. - if (attacksReady.empty()) - return; - - Attack *highestPriorityAttack = 0; - // Performs all ready attacks. - for (std::vector<Attack *>::const_iterator it = attacksReady.begin(), - it_end = attacksReady.end(); it != it_end; ++it) - { - // check if target is in range using the pythagorean theorem - int distx = this->getPosition().x - mTarget->getPosition().x; - int disty = this->getPosition().y - mTarget->getPosition().y; - int distSquare = (distx * distx + disty * disty); - AttackInfo *info = (*it)->getAttackInfo(); - int maxDist = info->getDamage().range + getSize(); - - if (distSquare <= maxDist * maxDist && - (!highestPriorityAttack || - highestPriorityAttack->getAttackInfo()->getPriority() - < info->getPriority())) - { - highestPriorityAttack = *it; - } - } - if (highestPriorityAttack) - { - mAttacks.startAttack(highestPriorityAttack); - mCurrentAttack = highestPriorityAttack; - setDestination(getPosition()); - // TODO: Turn into direction of enemy - raiseUpdateFlags(UPDATEFLAG_ATTACK); - } -} - -void Being::addAttack(AttackInfo *attackInfo) -{ - mAttacks.add(attackInfo); -} - -void Being::removeAttack(AttackInfo *attackInfo) -{ - mAttacks.remove(attackInfo); -} - void Being::setDestination(const Point &dst) { mDst = dst; @@ -480,23 +350,6 @@ int Being::directionToAngle(int direction) } } -int Being::performAttack(Being *target, const Damage &dmg) -{ - // check target legality - if (!target - || target == this - || target->getAction() == DEAD - || !target->canFight()) - return -1; - - if (getMap()->getPvP() == PVP_NONE - && target->getType() == OBJECT_CHARACTER - && getType() == OBJECT_CHARACTER) - return -1; - - return target->damage(this, dmg); -} - void Being::setAction(BeingAction action) { mAction = action; @@ -547,7 +400,7 @@ void Being::setAttribute(unsigned id, double value) } } -double Being::getAttribute(unsigned id) const +const Attribute *Being::getAttribute(unsigned id) const { AttributeMap::const_iterator ret = mAttributes.find(id); if (ret == mAttributes.end()) @@ -556,6 +409,18 @@ double Being::getAttribute(unsigned id) const << id << " not found! Returning 0."); return 0; } + return &ret->second; +} + +double Being::getAttributeBase(unsigned id) const +{ + AttributeMap::const_iterator ret = mAttributes.find(id); + if (ret == mAttributes.end()) + { + LOG_DEBUG("Being::getAttributeBase: Attribute " + << id << " not found! Returning 0."); + return 0; + } return ret->second.getBase(); } @@ -594,7 +459,7 @@ void Being::recalculateBaseAttribute(unsigned attr) { double newBase = utils::tpsToRawSpeed( getModifiedAttribute(ATTR_MOVE_SPEED_TPS)); - if (newBase != getAttribute(attr)) + if (newBase != getAttributeBase(attr)) setAttribute(attr, newBase); return; } @@ -742,8 +607,6 @@ void Being::update() if (getModifiedAttribute(ATTR_HP) <= 0 && mAction != DEAD) died(); - processAttacks(); - Actor::update(); } @@ -754,7 +617,3 @@ void Being::inserted(Entity *) mOld = getPosition(); } -void Being::processAttack(Attack &attack) -{ - performAttack(mTarget, attack.getAttackInfo()->getDamage()); -} |