summaryrefslogtreecommitdiff
path: root/src/game-server/monster.cpp
diff options
context:
space:
mode:
authorErik Schilling <ablu.erikschilling@googlemail.com>2013-03-30 09:29:08 +0100
committerErik Schilling <ablu.erikschilling@googlemail.com>2013-04-02 13:19:11 +0200
commit585a33e221a7ee392791f4fd5a5ec9214b8fe868 (patch)
tree3aa60a57ff7cdd8f57761d620352fd2ad4d0dd6f /src/game-server/monster.cpp
parent4dfc82415691fe298f21bb2f81fed5c168ee14e5 (diff)
downloadmanaserv-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/monster.cpp')
-rw-r--r--src/game-server/monster.cpp117
1 files changed, 36 insertions, 81 deletions
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index ceae82ca..25abb68a 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -28,6 +28,7 @@
#include "game-server/item.h"
#include "game-server/map.h"
#include "game-server/mapcomposite.h"
+#include "game-server/monstercombatcomponent.h"
#include "game-server/state.h"
#include "scripting/scriptmanager.h"
#include "utils/logger.h"
@@ -98,9 +99,6 @@ Monster::Monster(MonsterClass *specy):
}
}
- mDamageMutation = mutation ?
- (100 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1;
-
setSize(specy->getSize());
setGender(specy->getGender());
@@ -111,13 +109,16 @@ Monster::Monster(MonsterClass *specy):
mAttackPositions.push_back(AttackPosition(0, -dist, DOWN));
mAttackPositions.push_back(AttackPosition(0, dist, UP));
- // Take attacks from specy
- std::vector<AttackInfo *> &attacks = specy->getAttackInfos();
- for (std::vector<AttackInfo *>::iterator it = attacks.begin(),
- it_end = attacks.end(); it != it_end; ++it)
- {
- addAttack(*it);
- }
+ MonsterCombatComponent *combatComponent =
+ new MonsterCombatComponent(*this);
+ addComponent(combatComponent);
+
+ double damageMutation = mutation ?
+ (100.0 + (rand() % (mutation * 2)) - mutation) / 100.0 : 1.0;
+ combatComponent->setDamageMutation(damageMutation);
+
+ combatComponent->signal_damaged.connect(
+ sigc::mem_fun(this, &Monster::receivedDamage));
}
Monster::~Monster()
@@ -151,7 +152,7 @@ void Monster::update()
refreshTarget();
// Cancel the rest when we have a target
- if (mTarget)
+ if (getComponent<CombatComponent>()->getTarget())
return;
// We have no target - let's wander around
@@ -188,7 +189,7 @@ void Monster::refreshTarget()
Point bestAttackPosition;
// reset Target. We will find a new one if possible
- mTarget = 0;
+ getComponent<CombatComponent>()->clearTarget();
// Iterate through objects nearby
int aroundArea = Configuration::getValue("game_visualRange", 448);
@@ -242,11 +243,11 @@ void Monster::refreshTarget()
}
if (bestTarget)
{
- mTarget = bestTarget;
+ getComponent<CombatComponent>()->setTarget(bestTarget);
if (bestAttackPosition == getPosition())
{
mAction = ATTACK;
- updateDirection(getPosition(), mTarget->getPosition());
+ updateDirection(getPosition(), bestTarget->getPosition());
}
else
{
@@ -255,35 +256,6 @@ void Monster::refreshTarget()
}
}
-void Monster::processAttack(Attack &attack)
-{
- if (!mTarget)
- {
- setAction(STAND);
- return;
- }
-
- Damage dmg = attack.getAttackInfo()->getDamage();
- dmg.skill = 0;
- dmg.base *= mDamageMutation;
- dmg.delta *= mDamageMutation;
-
- int hit = performAttack(mTarget, attack.getAttackInfo()->getDamage());
-
- const Script::Ref &scriptCallback =
- attack.getAttackInfo()->getScriptCallback();
-
- if (scriptCallback.isValid() && hit > -1)
- {
- Script *script = ScriptManager::currentState();
- script->prepare(scriptCallback);
- script->push(this);
- script->push(mTarget);
- script->push(hit);
- script->execute(getMap());
- }
-}
-
int Monster::calculatePositionPriority(Point position, int targetPriority)
{
Point thisPos = getPosition();
@@ -375,44 +347,6 @@ std::map<Being *, int> Monster::getAngerList() const
return result;
}
-int Monster::damage(Actor *source, const Damage &damage)
-{
- Damage newDamage = damage;
- float factor = mSpecy->getVulnerability(newDamage.element);
- newDamage.base = newDamage.base * factor;
- newDamage.delta = newDamage.delta * factor;
- int HPLoss = Being::damage(source, newDamage);
- if (source)
- changeAnger(source, HPLoss);
-
- if (HPLoss && source && source->getType() == OBJECT_CHARACTER)
- {
- Character *s = static_cast< Character * >(source);
-
- mExpReceivers[s].insert(damage.skill);
- if (mKillStealProtectedTimeout.expired() || mOwner == s
- || mOwner->getParty() == s->getParty())
- {
- mOwner = s;
- mLegalExpReceivers.insert(s);
- mKillStealProtectedTimeout.set(KILLSTEAL_PROTECTION_TIME);
- }
- }
-
- if (mSpecy->getDamageCallback().isValid())
- {
- Script *script = ScriptManager::currentState();
- script->prepare(mSpecy->getDamageCallback());
- script->push(this);
- script->push(source);
- script->push(HPLoss);
- // TODO: add exact damage parameters as well
- script->execute(getMap());
- }
-
- return HPLoss;
-}
-
void Monster::died()
{
if (mAction == DEAD)
@@ -467,3 +401,24 @@ void Monster::died()
}
}
}
+
+
+void Monster::receivedDamage(Being *source, const Damage &damage, int hpLoss)
+{
+ if (source)
+ changeAnger(source, hpLoss);
+
+ if (hpLoss && source && source->getType() == OBJECT_CHARACTER)
+ {
+ Character *s = static_cast< Character * >(source);
+
+ mExpReceivers[s].insert(damage.skill);
+ if (mKillStealProtectedTimeout.expired() || mOwner == s
+ || mOwner->getParty() == s->getParty())
+ {
+ mOwner = s;
+ mLegalExpReceivers.insert(s);
+ mKillStealProtectedTimeout.set(KILLSTEAL_PROTECTION_TIME);
+ }
+ }
+}