diff options
author | Philipp Sehmisch <crush@themanaworld.org> | 2009-12-05 18:38:28 +0100 |
---|---|---|
committer | Philipp Sehmisch <crush@themanaworld.org> | 2009-12-05 19:01:54 +0100 |
commit | ef1c2e60facf32f9f55a7bf8dcfb59f7654f18cc (patch) | |
tree | d16da8b202681e721276dd899c4d3f4c65fbc026 /src/game-server | |
parent | 6f0a9c556b099c0658fb3a826593a81194efae27 (diff) | |
download | manaserv-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
Diffstat (limited to 'src/game-server')
-rw-r--r-- | src/game-server/being.cpp | 49 | ||||
-rw-r--r-- | src/game-server/being.hpp | 24 | ||||
-rw-r--r-- | src/game-server/monster.cpp | 41 | ||||
-rw-r--r-- | src/game-server/monster.hpp | 14 |
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; |