summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhilipp Sehmisch <crush@themanaworld.org>2009-12-05 18:38:28 +0100
committerPhilipp Sehmisch <crush@themanaworld.org>2009-12-05 19:01:54 +0100
commitef1c2e60facf32f9f55a7bf8dcfb59f7654f18cc (patch)
treed16da8b202681e721276dd899c4d3f4c65fbc026
parent6f0a9c556b099c0658fb3a826593a81194efae27 (diff)
downloadmanaserv-ef1c2e60facf32f9f55a7bf8dcfb59f7654f18cc.tar.gz
manaserv-ef1c2e60facf32f9f55a7bf8dcfb59f7654f18cc.tar.bz2
manaserv-ef1c2e60facf32f9f55a7bf8dcfb59f7654f18cc.tar.xz
manaserv-ef1c2e60facf32f9f55a7bf8dcfb59f7654f18cc.zip
(refactoring) Replaced various differen tick counting constructs in the being classes with a common timer infrastructure
-rw-r--r--src/game-server/being.cpp49
-rw-r--r--src/game-server/being.hpp24
-rw-r--r--src/game-server/monster.cpp41
-rw-r--r--src/game-server/monster.hpp14
4 files changed, 86 insertions, 42 deletions
diff --git a/src/game-server/being.cpp b/src/game-server/being.cpp
index de7ac69f..fe0190de 100644
--- a/src/game-server/being.cpp
+++ b/src/game-server/being.cpp
@@ -36,8 +36,7 @@ Being::Being(ThingType type):
mAction(STAND),
mTarget(NULL),
mSpeed(0),
- mDirection(0),
- mHpRegenTimer(0)
+ mDirection(0)
{
Attribute attr = { 0, 0 };
mAttributes.resize(NB_BEING_ATTRIBUTES + CHAR_ATTR_NB, attr);
@@ -356,14 +355,20 @@ void Being::setStatusEffectTime(int id, int time)
void Being::update()
{
+ //update timers
+ for (Timers::iterator i = mTimers.begin(); i != mTimers.end(); i++)
+ {
+ if (i->second > -1) i->second--;
+ }
+
int oldHP = getModifiedAttribute(BASE_ATTR_HP);
int newHP = oldHP;
int maxHP = getAttribute(BASE_ATTR_HP);
// Regenerate HP
- if (mAction != DEAD && ++mHpRegenTimer >= TICKS_PER_HP_REGENERATION)
+ if (mAction != DEAD && !isTimerRunning(T_B_HP_REGEN))
{
- mHpRegenTimer = 0;
+ setTimerHard(T_B_HP_REGEN, TICKS_PER_HP_REGENERATION);
newHP += getModifiedAttribute(BASE_ATTR_HP_REGEN);
}
// Cap HP at maximum
@@ -416,3 +421,39 @@ void Being::update()
died();
}
}
+
+void Being::setTimerSoft(TimerID id, int value)
+{
+ Timers::iterator i = mTimers.find(id);
+ if (i == mTimers.end())
+ {
+ mTimers[id] = value;
+ }
+ else if (i->second < value)
+ {
+ i->second = value;
+ }
+}
+
+void Being::setTimerHard(TimerID id, int value)
+{
+ mTimers[id] = value;
+}
+
+int Being::getTimer(TimerID id)
+{
+ Timers::iterator i = mTimers.find(id);
+ if (i == mTimers.end()) return -1;
+ return i->second;
+}
+
+bool Being::isTimerRunning(TimerID id)
+{
+ return (getTimer(id) > 0);
+}
+
+bool Being::isTimerJustFinished(TimerID id)
+{
+ return (getTimer(id) == 0);
+}
+
diff --git a/src/game-server/being.hpp b/src/game-server/being.hpp
index 3116d900..5335d37a 100644
--- a/src/game-server/being.hpp
+++ b/src/game-server/being.hpp
@@ -45,6 +45,17 @@ enum Direction
DIRECTION_RIGHT
};
+enum TimerID
+{
+ T_M_STROLL, // time until monster strolls to new location
+ T_M_KILLSTEAL_PROTECTED, // killsteal protection time
+ T_M_DECAY, // time until dead monster is removed
+ T_B_ATTACK_TIME, // time until being can attack again
+ T_B_HP_REGEN // time until hp is regenerated again
+};
+
+typedef std::map <TimerID, int> Timers;
+
/**
* Methods of damage calculation
*/
@@ -337,6 +348,7 @@ class Being : public Actor
void setTarget(Being *target)
{ mTarget = target; }
+
protected:
static const int TICKS_PER_HP_REGENERATION = 100;
Action mAction;
@@ -345,6 +357,15 @@ class Being : public Actor
Being *mTarget;
Point mOld; /**< Old coordinates. */
Point mDst; /**< Target coordinates. */
+ /**
+ * Timer stuff
+ */
+ void setTimerSoft(TimerID id, int value); /**< sets timer unless already higher */
+ void setTimerHard(TimerID id, int value); /**< sets timer even when already higher (when in doubt this one is faster)*/
+ int getTimer(TimerID id); /**< returns number of ticks left on the timer */
+ bool isTimerRunning(TimerID id); /**< true when timer exists and is > 0 */
+ bool isTimerJustFinished(TimerID id); /**< true during the tick where the timer reaches 0 */
+
private:
Being(const Being &rhs);
@@ -357,7 +378,8 @@ class Being : public Actor
std::string mName;
Hits mHitsTaken; /**< List of punches taken since last update. */
AttributeModifiers mModifiers; /**< Currently modified attributes. */
- int mHpRegenTimer; /**< Timer for hp regeneration. */
+
+ Timers mTimers;
};
#endif // _TMWSERV_BEING_H_
diff --git a/src/game-server/monster.cpp b/src/game-server/monster.cpp
index c6b6079e..fe74ea6a 100644
--- a/src/game-server/monster.cpp
+++ b/src/game-server/monster.cpp
@@ -63,11 +63,8 @@ Monster::Monster(MonsterClass *specy):
Being(OBJECT_MONSTER),
mSpecy(specy),
mScript(NULL),
- mCountDown(0),
mTargetListener(&monsterTargetEventDispatch),
mOwner(NULL),
- mOwnerTimer(0),
- mAttackTime(0),
mCurrentAttack(NULL)
{
LOG_DEBUG("Monster spawned!");
@@ -123,8 +120,9 @@ void Monster::perform()
{
if (mAction == ATTACK && mCurrentAttack && mTarget)
{
- if (mAttackTime == mCurrentAttack->aftDelay)
+ if (!isTimerRunning(T_B_ATTACK_TIME))
{
+ setTimerHard(T_B_ATTACK_TIME, mCurrentAttack->aftDelay + mCurrentAttack->preDelay);
Damage damage;
damage.base = (int) (getModifiedAttribute(BASE_ATTR_PHY_ATK_MIN) * mCurrentAttack->damageFactor);
damage.delta = (int) (getModifiedAttribute(BASE_ATTR_PHY_ATK_DELTA) * mCurrentAttack->damageFactor);
@@ -146,10 +144,10 @@ void Monster::perform()
mScript->execute();
}
}
- if (!mAttackTime)
- {
- setAction(STAND);
- }
+ }
+ if (mAction == ATTACK && !mTarget)
+ {
+ setAction(STAND);
}
}
@@ -157,18 +155,15 @@ void Monster::update()
{
Being::update();
- if (mOwner && mOwnerTimer)
+ if (isTimerJustFinished(T_M_KILLSTEAL_PROTECTED))
{
- mOwnerTimer--;
- } else {
mOwner = NULL;
}
// If dead do nothing but rot
if (mAction == DEAD)
{
- mCountDown--;
- if (mCountDown <= 0)
+ if (!isTimerRunning(T_M_DECAY))
{
GameState::enqueueRemove(this);
}
@@ -182,11 +177,8 @@ void Monster::update()
mScript->execute();
}
- if (mAction == ATTACK)
- {
- mAttackTime--;
- return;
- }
+ // cancle the rest when we are currently performing an attack
+ if (isTimerRunning(T_B_ATTACK_TIME)) return;
// Check potential attack positions
Being *bestAttackTarget = mTarget = NULL;
@@ -279,7 +271,7 @@ void Monster::update()
setDirection(bestAttackDirection);
//perform a random attack based on priority
mCurrentAttack = workingAttacks.upper_bound(rand()%prioritySum)->second;
- mAttackTime = mCurrentAttack->preDelay + mCurrentAttack->aftDelay;
+ setTimerSoft(T_B_ATTACK_TIME, mCurrentAttack->preDelay + mCurrentAttack->aftDelay);
setAction(ATTACK);
raiseUpdateFlags(UPDATEFLAG_ATTACK);
}
@@ -289,8 +281,7 @@ void Monster::update()
// We have no target - let's wander around
if (getPosition() == getDestination())
{
- mCountDown--;
- if (mCountDown <= 0)
+ if (!isTimerRunning(T_M_KILLSTEAL_PROTECTED))
{
unsigned range = mSpecy->getStrollRange();
if (range)
@@ -298,8 +289,8 @@ void Monster::update()
Point randomPos(rand() % (range * 2 + 1) - range + getPosition().x,
rand() % (range * 2 + 1) - range + getPosition().y);
setDestination(randomPos);
- mCountDown = 10 + rand() % 10;
}
+ setTimerHard(T_M_STROLL, 10 + rand() % 10);
}
}
}
@@ -413,11 +404,11 @@ int Monster::damage(Actor *source, const Damage &damage)
if (*iSkill)
{
mExpReceivers[s].insert(*iSkill);
- if (!mOwnerTimer || mOwner == s || mOwner->getParty() == s->getParty())
+ if (!isTimerRunning(T_M_KILLSTEAL_PROTECTED) || mOwner == s || mOwner->getParty() == s->getParty())
{
mOwner = s;
mLegalExpReceivers.insert(s);
- mOwnerTimer = KILLSTEAL_PROTECTION_TIME;
+ setTimerHard(T_M_KILLSTEAL_PROTECTED, KILLSTEAL_PROTECTION_TIME);
}
}
}
@@ -430,7 +421,7 @@ void Monster::died()
if (mAction == DEAD) return;
Being::died();
- mCountDown = 50; // Sets remove time to 5 seconds
+ setTimerHard(T_M_DECAY, Monster::DECAY_TIME);
//drop item
if (ItemClass *drop = mSpecy->getRandomDrop())
diff --git a/src/game-server/monster.hpp b/src/game-server/monster.hpp
index 1d7e958b..f6194e97 100644
--- a/src/game-server/monster.hpp
+++ b/src/game-server/monster.hpp
@@ -302,6 +302,8 @@ class Monster : public Being
{ return Map::BLOCKTYPE_MONSTER; }
private:
+ static const int DECAY_TIME = 50;
+
int calculatePositionPriority(Point position, int targetPriority);
MonsterClass *mSpecy;
@@ -312,9 +314,6 @@ class Monster : public Being
*/
Script *mScript;
- /** Count down till next random movement (temporary). */
- int mCountDown;
-
/** Aggression towards other beings. */
std::map<Being *, int> mAnger;
@@ -326,12 +325,6 @@ class Monster : public Being
*/
Character *mOwner;
- /**
- * Time until someone else can claim this monster (killsteal
- * protection).
- */
- int mOwnerTimer;
-
/** List of characters and their skills that attacked this monster. */
std::map<Character *, std::set <size_t> > mExpReceivers;
@@ -341,9 +334,6 @@ class Monster : public Being
*/
std::set<Character *> mLegalExpReceivers;
- /** Delay until monster can attack. */
- int mAttackTime;
-
/** Attack the monster is currently performing. */
MonsterAttack *mCurrentAttack;