summaryrefslogtreecommitdiff
path: root/src/game-server/monster.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/game-server/monster.cpp')
-rw-r--r--src/game-server/monster.cpp164
1 files changed, 81 insertions, 83 deletions
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index 0bee4c9a..6bc69b7e 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -118,71 +118,19 @@ Monster::~Monster()
}
}
-void Monster::perform()
-{
- if (mAction == ATTACK)
- {
- if (mTarget)
- {
- if (mCurrentAttack)
- {
- if (!isTimerRunning(T_M_ATTACK_TIME))
- {
- setTimerHard(T_M_ATTACK_TIME, mCurrentAttack->aftDelay
- + mCurrentAttack->preDelay);
- Damage dmg;
- dmg.skill = 0;
- dmg.base = getModifiedAttribute(MOB_ATTR_PHY_ATK_MIN) *
- mCurrentAttack->damageFactor;
- dmg.delta = getModifiedAttribute(MOB_ATTR_PHY_ATK_DELTA) *
- mCurrentAttack->damageFactor;
- dmg.cth = getModifiedAttribute(ATTR_ACCURACY);
- dmg.element = mCurrentAttack->element;
- dmg.range = mCurrentAttack->range;
-
- int hit = performAttack(mTarget, dmg);
-
- if (! mCurrentAttack->scriptEvent.empty()
- && hit > -1)
- {
- Script::Ref function = mSpecy->getEventCallback(mCurrentAttack->scriptEvent);
- if (function.isValid())
- {
- Script *script = ScriptManager::currentState();
- script->setMap(getMap());
- script->prepare(function);
- script->push(this);
- script->push(mTarget);
- script->push(hit);
- script->execute();
- }
- }
- }
- }
- }
- else
- {
- setAction(STAND);
- }
- }
-}
-
void Monster::update()
{
Being::update();
if (isTimerJustFinished(T_M_KILLSTEAL_PROTECTED))
- {
mOwner = NULL;
- }
// If dead, remove it
if (mAction == DEAD)
{
if (!isTimerRunning(T_M_DECAY))
- {
GameState::enqueueRemove(this);
- }
+
return;
}
@@ -199,6 +147,38 @@ void Monster::update()
if (isTimerRunning(T_M_ATTACK_TIME))
return;
+ refreshTarget();
+
+ if (!mTarget)
+ {
+ // We have no target - let's wander around
+ if (!isTimerRunning(T_M_STROLL) && getPosition() == getDestination())
+ {
+ if (!isTimerRunning(T_M_KILLSTEAL_PROTECTED))
+ {
+ unsigned range = mSpecy->getStrollRange();
+ if (range)
+ {
+ Point randomPos(rand() % (range * 2 + 1)
+ - range + getPosition().x,
+ rand() % (range * 2 + 1)
+ - range + getPosition().y);
+ // Don't allow negative destinations, to avoid rounding
+ // problems when divided by tile size
+ if (randomPos.x >= 0 && randomPos.y >= 0)
+ setDestination(randomPos);
+ }
+ setTimerHard(T_M_STROLL, 10 + rand() % 10);
+ }
+ }
+ }
+
+ if (mAction == ATTACK)
+ processAttack();
+}
+
+void Monster::refreshTarget()
+{
// Check potential attack positions
Being *bestAttackTarget = mTarget = NULL;
int bestTargetPriority = 0;
@@ -214,7 +194,7 @@ void Monster::update()
if ((*i)->getType() != OBJECT_CHARACTER)
continue;
- Being *target = static_cast<Being *> (*i);
+ Being *target = static_cast<Being *>(*i);
// Dead characters are ignored
if (target->getAction() == DEAD)
@@ -241,9 +221,9 @@ void Monster::update()
for (std::list<AttackPosition>::iterator j = mAttackPositions.begin();
j != mAttackPositions.end(); j++)
{
- Point attackPosition = (*i)->getPosition();
- attackPosition.x += (*j).x;
- attackPosition.y += (*j).y;
+ Point attackPosition = target->getPosition();
+ attackPosition.x += j->x;
+ attackPosition.y += j->y;
int posPriority = calculatePositionPriority(attackPosition,
targetPriority);
@@ -252,7 +232,7 @@ void Monster::update()
bestAttackTarget = mTarget = target;
bestTargetPriority = posPriority;
bestAttackPosition = attackPosition;
- bestAttackDirection = (*j).direction;
+ bestAttackDirection = j->direction;
}
}
}
@@ -265,16 +245,15 @@ void Monster::update()
std::map<int, MonsterAttack *> workingAttacks;
int prioritySum = 0;
+ const int distX = getPosition().x - bestAttackTarget->getPosition().x;
+ const int distY = getPosition().y - bestAttackTarget->getPosition().y;
+ const int distSquare = (distX * distX + distY * distY);
+
for (MonsterAttacks::iterator i = allAttacks.begin();
i != allAttacks.end();
i++)
{
- int distx = this->getPosition().x
- - bestAttackTarget->getPosition().x;
- int disty = this->getPosition().y
- - bestAttackTarget->getPosition().y;
- int distSquare = (distx * distx + disty * disty);
- int maxDist = (*i)->range + bestAttackTarget->getSize();
+ int maxDist = (*i)->range + bestAttackTarget->getSize();
if (maxDist * maxDist >= distSquare)
{
@@ -301,27 +280,46 @@ void Monster::update()
raiseUpdateFlags(UPDATEFLAG_ATTACK);
}
}
- else
+}
+
+void Monster::processAttack()
+{
+ if (!mTarget)
{
- // We have no target - let's wander around
- if (!isTimerRunning(T_M_STROLL) && getPosition() == getDestination())
+ setAction(STAND);
+ return;
+ }
+
+ if (!mCurrentAttack)
+ return;
+
+ setTimerHard(T_M_ATTACK_TIME, mCurrentAttack->aftDelay
+ + mCurrentAttack->preDelay);
+
+ float damageFactor = mCurrentAttack->damageFactor;
+
+ Damage dmg;
+ dmg.skill = 0;
+ dmg.base = getModifiedAttribute(MOB_ATTR_PHY_ATK_MIN) * damageFactor;
+ dmg.delta = getModifiedAttribute(MOB_ATTR_PHY_ATK_DELTA) * damageFactor;
+ dmg.cth = getModifiedAttribute(ATTR_ACCURACY);
+ dmg.element = mCurrentAttack->element;
+ dmg.range = mCurrentAttack->range;
+
+ int hit = performAttack(mTarget, dmg);
+
+ if (!mCurrentAttack->scriptEvent.empty() && hit > -1)
+ {
+ Script::Ref function = mSpecy->getEventCallback(mCurrentAttack->scriptEvent);
+ if (function.isValid())
{
- if (!isTimerRunning(T_M_KILLSTEAL_PROTECTED))
- {
- unsigned range = mSpecy->getStrollRange();
- if (range)
- {
- Point randomPos(rand() % (range * 2 + 1)
- - range + getPosition().x,
- rand() % (range * 2 + 1)
- - range + getPosition().y);
- // Don't allow negative destinations, to avoid rounding
- // problems when divided by tile size
- if (randomPos.x >= 0 && randomPos.y >= 0)
- setDestination(randomPos);
- }
- setTimerHard(T_M_STROLL, 10 + rand() % 10);
- }
+ Script *script = ScriptManager::currentState();
+ script->setMap(getMap());
+ script->prepare(function);
+ script->push(this);
+ script->push(mTarget);
+ script->push(hit);
+ script->execute();
}
}
}