// This file is part of Glest (www.glest.org) // // Copyright (C) 2001-2008 MartiƱo Figueroa // // You can redistribute this code and/or modify it under // the terms of the GNU General Public License as published // by the Free Software Foundation; either version 2 of the // License, or (at your option) any later version // ============================================================== #ifndef _GLEST_GAME_UNIT_H_ #define _GLEST_GAME_UNIT_H_ #ifdef WIN32 #include #include #endif #include "model.h" #include "upgrade_type.h" #include "particle.h" #include "skill_type.h" #include "game_constants.h" #include "platform_common.h" #include #include "faction.h" #include "leak_dumper.h" //#define LEAK_CHECK_UNITS namespace Glest { namespace Game { using Shared::Graphics::ParticleSystem; using Shared::Graphics::UnitParticleSystem; using Shared::Graphics::Vec4f; using Shared::Graphics::Vec2f; using Shared::Graphics::Vec3f; using Shared::Graphics::Vec2i; using Shared::Graphics::Model; using Shared::PlatformCommon::Chrono; using Shared::PlatformCommon::ValueCheckerVault; class Map; //class Faction; class Unit; class Command; class SkillType; class ResourceType; class CommandType; class SkillType; class UnitType; class TotalUpgrade; class UpgradeType; class Level; class MorphCommandType; class Game; class Unit; class GameSettings; class World; enum CommandResult { crSuccess, crFailRes, crFailReqs, crFailUnitCount, crFailUndefined, crSomeFailed }; enum InterestingUnitType { iutIdleHarvester, iutBuiltBuilding, iutProducer, iutDamaged, iutStore }; enum CauseOfDeathType { ucodNone, ucodAttacked, ucodAttackBoost, ucodStarvedResource, ucodStarvedRegeneration }; class UnitBuildInfo { public: UnitBuildInfo() { unit = NULL; //pos; buildUnit = NULL; } const Unit *unit; CardinalDir facing; Vec2i pos; const UnitType *buildUnit; }; // ===================================================== // class UnitObserver // ===================================================== class UnitObserver { public: enum Event{ eKill }; public: virtual ~UnitObserver() {} virtual void unitEvent(Event event, const Unit *unit)=0; virtual void saveGame(XmlNode *rootNode) const = 0; }; // ===================================================== // class UnitReference // ===================================================== class UnitReference { private: int id; Faction *faction; public: UnitReference(); UnitReference & operator=(const Unit *unit); Unit *getUnit() const; int getUnitId() const { return id; } Faction *getUnitFaction() const { return faction; } void saveGame(XmlNode *rootNode); void loadGame(const XmlNode *rootNode,World *world); }; class UnitPathInterface { public: UnitPathInterface() {} virtual ~UnitPathInterface() {} virtual bool isBlocked() const = 0; virtual bool isEmpty() const = 0; virtual bool isStuck() const = 0; virtual void clear() = 0; virtual void clearBlockCount() = 0; virtual void incBlockCount() = 0; virtual void add(const Vec2i &path) = 0; //virtual Vec2i pop() = 0; virtual int getBlockCount() const = 0; virtual int getQueueCount() const = 0; virtual vector getQueue() const = 0; virtual std::string toString() const = 0; virtual void setMap(Map *value) = 0; virtual Map * getMap() = 0; virtual void saveGame(XmlNode *rootNode) = 0; virtual void loadGame(const XmlNode *rootNode) = 0; virtual void clearCaches() = 0; virtual Checksum getCRC() = 0; }; class UnitPathBasic : public UnitPathInterface { private: static const int maxBlockCount; Map *map; #ifdef LEAK_CHECK_UNITS static std::map mapMemoryList; #endif private: int blockCount; vector pathQueue; public: UnitPathBasic(); virtual ~UnitPathBasic(); #ifdef LEAK_CHECK_UNITS static void dumpMemoryList(); #endif virtual bool isBlocked() const; virtual bool isEmpty() const; virtual bool isStuck() const; virtual void clear(); virtual void clearBlockCount() { blockCount = 0; } virtual void incBlockCount(); virtual void add(const Vec2i &path); Vec2i pop(bool removeFrontPos=true); virtual int getBlockCount() const { return blockCount; } virtual int getQueueCount() const { return (int)pathQueue.size(); } virtual vector getQueue() const { return pathQueue; } virtual void setMap(Map *value) { map = value; } virtual Map * getMap() { return map; } virtual std::string toString() const; virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode); virtual void clearCaches(); virtual Checksum getCRC(); }; // ===================================================== // class UnitPath // ===================================================== /** Holds the next cells of a Unit movement * @extends std::list */ class UnitPath : public list, public UnitPathInterface { private: static const int maxBlockCount = 10; /**< number of command updates to wait on a blocked path */ private: int blockCount; /**< number of command updates this path has been blocked */ Map *map; public: UnitPath() : UnitPathInterface(), blockCount(0), map(NULL) {} /**< Construct path object */ virtual bool isBlocked() const {return blockCount >= maxBlockCount;} /**< is this path blocked */ virtual bool isEmpty() const {return list::empty();} /**< is path empty */ virtual bool isStuck() const {return false; } int size() const {return (int)list::size();} /**< size of path */ virtual void clear() {list::clear(); blockCount = 0;} /**< clear the path */ virtual void clearBlockCount() { blockCount = 0; } virtual void incBlockCount() {++blockCount;} /**< increment block counter */ virtual void push(Vec2i &pos) {push_front(pos);} /**< push onto front of path */ bool empty() const {return list::empty();} /**< is path empty */ virtual void add(const Vec2i &pos) { push_front(pos);} /**< push onto front of path */ #if 0 // old style, to work with original PathFinder Vec2i peek() {return back();} /**< peek at the next position */ void pop() {this->pop_back();} /**< pop the next position off the path */ #else // new style Vec2i peek() {return front();} /**< peek at the next position */ //virtual Vec2i pop() { Vec2i p= front(); erase(begin()); return p; } /**< pop the next position off the path */ void pop() { erase(begin()); } /**< pop the next position off the path */ #endif virtual int getBlockCount() const { return blockCount; } virtual int getQueueCount() const { return this->size(); } virtual vector getQueue() const { vector result; for(list::const_iterator iter = this->begin(); iter != this->end(); ++iter) { result.push_back(*iter); } return result; } virtual void setMap(Map *value) { map = value; } virtual Map * getMap() { return map; } virtual std::string toString() const; virtual void saveGame(XmlNode *rootNode) {}; virtual void loadGame(const XmlNode *rootNode) {}; virtual void clearCaches() {}; virtual Checksum getCRC() { return Checksum(); }; }; class WaypointPath : public list { public: WaypointPath() {} void push(const Vec2i &pos) { push_front(pos); } Vec2i peek() const {return front();} void pop() {erase(begin());} void condense(); }; // =============================== // class Unit // /// A game unit or building // =============================== class UnitAttackBoostEffect { private: int unitId; const Unit *unitPtr; const Unit *source; void applyLoadedAttackBoostParticles(UnitParticleSystemType *upstPtr,const XmlNode* node, Unit* unit); public: UnitAttackBoostEffect(); virtual ~UnitAttackBoostEffect(); const AttackBoost *boost; //const Unit *source; const Unit * getSource(); void setSource(const Unit *unit); UnitParticleSystem *ups; UnitParticleSystemType *upst; virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode, Unit *unit, World *world, bool applyToOriginator); }; class UnitAttackBoostEffectOriginator { public: UnitAttackBoostEffectOriginator(); virtual ~UnitAttackBoostEffectOriginator(); const SkillType *skillType; std::vector currentAttackBoostUnits; UnitAttackBoostEffect *currentAppliedEffect; virtual void saveGame(XmlNode *rootNode); virtual void loadGame(const XmlNode *rootNode, Unit *unit, World *world); }; class Unit : public BaseColorPickEntity, ValueCheckerVault, public ParticleOwner { private: typedef list Commands; typedef list Observers; typedef vector UnitParticleSystems; #ifdef LEAK_CHECK_UNITS static std::map mapMemoryList; #endif static const float ANIMATION_SPEED_MULTIPLIER; static const int64 PROGRESS_SPEED_MULTIPLIER; public: static const int speedDivider; static const int maxDeadCount; static const int invalidId; #ifdef LEAK_CHECK_UNITS static std::map mapMemoryList2; static void dumpMemoryList(); #endif private: const int32 id; int32 hp; int32 ep; int32 loadCount; int32 deadCount; //float progress; //between 0 and 1 int64 progress; //between 0 and 1 int64 lastAnimProgress; //between 0 and 1 int64 animProgress; //between 0 and 1 float highlight; int32 progress2; int32 kills; int32 enemyKills; bool morphFieldsBlocked; UnitReference targetRef; Field currField; Field targetField; const Level *level; Vec2i pos; Vec2i lastPos; Vec2i targetPos; //absolute target pos Vec3f targetVec; Vec2i meetingPos; float lastRotation; //in degrees float targetRotation; float rotation; float targetRotationZ; float targetRotationX; float rotationZ; float rotationX; const UnitType *preMorph_type; const UnitType *type; const ResourceType *loadType; const SkillType *currSkill; int32 lastModelIndexForCurrSkillType; int32 animationRandomCycleCount; bool toBeUndertaken; bool alive; bool showUnitParticles; Faction *faction; ParticleSystem *fire; TotalUpgrade totalUpgrade; Map *map; UnitPathInterface *unitPath; WaypointPath waypointPath; Commands commands; Observers observers; vector unitParticleSystems; vector queuedUnitParticleSystemTypes; UnitParticleSystems damageParticleSystems; std::map damageParticleSystemsInUse; vector fireParticleSystems; vector smokeParticleSystems; vector attackParticleSystems; CardinalDir modelFacing; std::string lastSynchDataString; std::string lastFile; int32 lastLine; std::string lastSource; int32 lastRenderFrame; bool visible; int retryCurrCommandCount; Vec3f screenPos; string currentUnitTitle; bool inBailOutAttempt; // This buffer stores a list of bad harvest cells, along with the start // time of when it was detected. Typically this may be due to a unit // constantly getting blocked from getting to the resource so this // list may be used to tell areas of the game to ignore those cells for a // period of time //std::vector > badHarvestPosList; std::map badHarvestPosList; //time_t lastBadHarvestListPurge; std::pair lastHarvestResourceTarget; //std::pair > currentTargetPathTaken; static Game *game; bool ignoreCheckCommand; uint32 lastStuckFrame; Vec2i lastStuckPos; uint32 lastPathfindFailedFrame; Vec2i lastPathfindFailedPos; bool usePathfinderExtendedMaxNodes; int32 maxQueuedCommandDisplayCount; UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; std::vector currentAttackBoostEffects; Mutex *mutexCommands; //static Mutex mutexDeletedUnits; //static std::map deletedUnits; bool changedActiveCommand; uint32 lastChangedActiveCommandFrame; uint32 changedActiveCommandFrame; int32 lastAttackerUnitId; int32 lastAttackedUnitId; CauseOfDeathType causeOfDeath; uint32 pathfindFailedConsecutiveFrameCount; Vec2i currentPathFinderDesiredFinalPos; RandomGen random; int32 pathFindRefreshCellCount; FowAlphaCellsLookupItem cachedFow; Vec2i cachedFowPos; ExploredCellsLookupItem cacheExploredCells; std::pair cacheExploredCellsKey; Vec2i lastHarvestedResourcePos; string networkCRCLogInfo; string networkCRCParticleLogInfo; vector networkCRCDecHpList; vector networkCRCParticleInfoList; public: Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); virtual ~Unit(); //static bool isUnitDeleted(void *unit); static void setGame(Game *value) { game=value;} inline int getPathFindRefreshCellCount() const { return pathFindRefreshCellCount; } void setCurrentPathFinderDesiredFinalPos(const Vec2i &finalPos) { currentPathFinderDesiredFinalPos = finalPos; } Vec2i getCurrentPathFinderDesiredFinalPos() const { return currentPathFinderDesiredFinalPos; } const UnitAttackBoostEffectOriginator & getAttackBoostOriginatorEffect() const { return currentAttackBoostOriginatorEffect; } bool unitHasAttackBoost(const AttackBoost *boost, const Unit *source); inline uint32 getPathfindFailedConsecutiveFrameCount() const { return pathfindFailedConsecutiveFrameCount; } inline void incrementPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount++; } inline void resetPathfindFailedConsecutiveFrameCount() { pathfindFailedConsecutiveFrameCount=0; } const FowAlphaCellsLookupItem & getCachedFow() const { return cachedFow; } FowAlphaCellsLookupItem getFogOfWarRadius(bool useCache) const; void calculateFogOfWarRadius(); //queries Command *getCurrrentCommandThreadSafe(); void setIgnoreCheckCommand(bool value) { ignoreCheckCommand=value;} inline bool getIgnoreCheckCommand() const {return ignoreCheckCommand;} inline int getId() const {return id;} inline Field getCurrField() const {return currField;} inline int getLoadCount() const {return loadCount;} //inline int getLastAnimProgress() const {return lastAnimProgress;} //inline int getAnimProgress() const {return animProgress;} inline float getLastAnimProgressAsFloat() const {return static_cast(lastAnimProgress) / ANIMATION_SPEED_MULTIPLIER;} inline float getAnimProgressAsFloat() const {return static_cast(animProgress) / ANIMATION_SPEED_MULTIPLIER;} inline float getHightlight() const {return highlight;} inline int getProgress2() const {return progress2;} inline int getFactionIndex() const { return faction->getIndex(); } inline int getTeam() const { return faction->getTeam(); } inline int getHp() const {return hp;} inline int getEp() const {return ep;} int getProductionPercent() const; float getProgressRatio() const; float getHpRatio() const; float getEpRatio() const; inline bool getToBeUndertaken() const {return toBeUndertaken;} inline Vec2i getTargetPos() const {return targetPos;} inline Vec3f getTargetVec() const {return targetVec;} inline Field getTargetField() const {return targetField;} inline Vec2i getMeetingPos() const {return meetingPos;} inline Faction *getFaction() const {return faction;} inline const ResourceType *getLoadType() const {return loadType;} inline const UnitType *getType() const {return type;} void setType(const UnitType *newType); inline const UnitType *getPreMorphType() const {return preMorph_type;} inline const SkillType *getCurrSkill() const {return currSkill;} inline const TotalUpgrade *getTotalUpgrade() const {return &totalUpgrade;} inline float getRotation() const {return rotation;} float getRotationX() const; float getRotationZ() const; ParticleSystem *getFire() const; inline int getKills() const {return kills;} inline int getEnemyKills() const {return enemyKills;} inline const Level *getLevel() const {return level;} const Level *getNextLevel() const; string getFullName(bool translatedValue) const; inline const UnitPathInterface *getPath() const {return unitPath;} inline UnitPathInterface *getPath() {return unitPath;} inline WaypointPath *getWaypointPath() {return &waypointPath;} inline int getLastAttackerUnitId() const { return lastAttackerUnitId; } inline void setLastAttackerUnitId(int unitId) { lastAttackerUnitId = unitId; } inline int getLastAttackedUnitId() const { return lastAttackedUnitId; } inline void setLastAttackedUnitId(int unitId) { lastAttackedUnitId = unitId; } inline CauseOfDeathType getCauseOfDeath() const { return causeOfDeath; } inline void setCauseOfDeath(CauseOfDeathType cause) { causeOfDeath = cause; } //pos inline Vec2i getPosNotThreadSafe() const {return pos;} Vec2i getPos(); Vec2i getPosWithCellMapSet() const; inline Vec2i getLastPos() const {return lastPos;} Vec2i getCenteredPos() const; Vec2f getFloatCenteredPos() const; Vec2i getCellPos() const; //is inline bool isHighlighted() const {return highlight>0.f;} inline bool isDead() const {return !alive;} inline bool isAlive() const {return alive;} bool isOperative() const; bool isBeingBuilt() const; bool isBuilt() const; bool isBuildCommandPending() const; UnitBuildInfo getBuildCommandPendingInfo() const; bool isAnimProgressBound() const; bool isPutrefacting() const { return deadCount!=0; } bool isAlly(const Unit *unit) const; bool isDamaged() const; bool isInteresting(InterestingUnitType iut) const; //set void setCurrField(Field currField); void setCurrSkill(const SkillType *currSkill); void setCurrSkill(SkillClass sc); void setMorphFieldsBlocked ( bool value ) {this->morphFieldsBlocked=value;} bool getMorphFieldsBlocked() const { return morphFieldsBlocked; } inline void setLastHarvestedResourcePos(Vec2i pos) { this->lastHarvestedResourcePos = pos; } inline Vec2i getLastHarvestedResourcePos() const { return this->lastHarvestedResourcePos; } inline void setLoadCount(int loadCount) {this->loadCount= loadCount;} inline void setLoadType(const ResourceType *loadType) {this->loadType= loadType;} inline void setProgress2(int progress2) {this->progress2= progress2;} void setPos(const Vec2i &pos,bool clearPathFinder=false); void refreshPos(); void setTargetPos(const Vec2i &targetPos); void setTarget(const Unit *unit); //void setTargetVec(const Vec3f &targetVec); void setMeetingPos(const Vec2i &meetingPos); void setVisible(const bool visible); inline bool getVisible() const { return visible; } //render related const Model *getCurrentModel(); Model *getCurrentModelPtr(); Vec3f getCurrVector() const; Vec3f getCurrVectorFlat() const; Vec3f getVectorFlat(const Vec2i &lastPosValue, const Vec2i &curPosValue) const; //command related bool anyCommand(bool validateCommandtype=false) const; inline Command *getCurrCommand() const { if(commands.empty() == false) { return commands.front(); } return NULL; } void replaceCurrCommand(Command *cmd); int getCountOfProducedUnits(const UnitType *ut) const; unsigned int getCommandSize() const; std::pair giveCommand(Command *command, bool tryQueue = false); //give a command CommandResult finishCommand(); //command finished CommandResult cancelCommand(); //cancel canceled //lifecycle void create(bool startingUnit= false); void born(const CommandType *ct); void kill(); void undertake(); //observers void addObserver(UnitObserver *unitObserver) ; void removeObserver(UnitObserver *unitObserver); void notifyObservers(UnitObserver::Event event); //other void resetHighlight(); const CommandType *computeCommandType(const Vec2i &pos, const Unit *targetUnit= NULL) const; string getDesc(bool translatedValue) const; string getDescExtension(bool translatedValue) const; bool computeEp(); //bool computeHp(); bool repair(); bool decHp(int i); int update2(); bool update(); void tick(); RandomGen* getRandom() { return &random; } bool applyAttackBoost(const AttackBoost *boost, const Unit *source); void deapplyAttackBoost(const AttackBoost *boost, const Unit *source); void applyUpgrade(const UpgradeType *upgradeType); void computeTotalUpgrade(); void incKills(int team); bool morph(const MorphCommandType *mct); std::pair checkCommand(Command *command) const; void applyCommand(Command *command); void setModelFacing(CardinalDir value); inline CardinalDir getModelFacing() const { return modelFacing; } bool isMeetingPointSettable() const; inline int getLastRenderFrame() const { return lastRenderFrame; } inline void setLastRenderFrame(int value) { lastRenderFrame = value; } inline int getRetryCurrCommandCount() const { return retryCurrCommandCount; } inline void setRetryCurrCommandCount(int value) { retryCurrCommandCount = value; } inline Vec3f getScreenPos() const { return screenPos; } void setScreenPos(Vec3f value) { screenPos = value; } inline string getCurrentUnitTitle() const {return currentUnitTitle;} void setCurrentUnitTitle(string value) { currentUnitTitle = value;} void exploreCells(); inline bool getInBailOutAttempt() const { return inBailOutAttempt; } inline void setInBailOutAttempt(bool value) { inBailOutAttempt = value; } //std::vector > getBadHarvestPosList() const { return badHarvestPosList; } //void setBadHarvestPosList(std::vector > value) { badHarvestPosList = value; } void addBadHarvestPos(const Vec2i &value); void removeBadHarvestPos(const Vec2i &value); inline bool isBadHarvestPos(const Vec2i &value,bool checkPeerUnits=true) const { bool result = false; if(badHarvestPosList.empty() == true) { return result; } std::map::const_iterator iter = badHarvestPosList.find(value); if(iter != badHarvestPosList.end()) { result = true; } else if(checkPeerUnits == true) { // Check if any other units of similar type have this position tagged // as bad? for(int i = 0; i < this->getFaction()->getUnitCount(); ++i) { Unit *peerUnit = this->getFaction()->getUnit(i); if( peerUnit != NULL && peerUnit->getId() != this->getId() && peerUnit->getType()->hasCommandClass(ccHarvest) == true && peerUnit->getType()->getSize() <= this->getType()->getSize()) { if(peerUnit->isBadHarvestPos(value,false) == true) { result = true; break; } } } } return result; } void cleanupOldBadHarvestPos(); void setLastHarvestResourceTarget(const Vec2i *pos); inline std::pair getLastHarvestResourceTarget() const { return lastHarvestResourceTarget;} //std::pair > getCurrentTargetPathTaken() const { return currentTargetPathTaken; } //void addCurrentTargetPathTakenCell(const Vec2i &target,const Vec2i &cell); void logSynchData(string file,int line,string source=""); void logSynchDataThreaded(string file,int line,string source=""); std::string toString(bool crcMode=false) const; bool needToUpdate(); float getProgressAsFloat() const; int64 getUpdateProgress(); int64 getDiagonalFactor(); int64 getHeightFactor(int64 speedMultiplier=PROGRESS_SPEED_MULTIPLIER); int64 getSpeedDenominator(int64 updateFPS); bool isChangedActiveCommand() const { return changedActiveCommand; } bool isLastStuckFrameWithinCurrentFrameTolerance(bool evalMode); inline uint32 getLastStuckFrame() const { return lastStuckFrame; } //inline void setLastStuckFrame(uint32 value) { lastStuckFrame = value; } void setLastStuckFrameToCurrentFrame(); inline Vec2i getLastStuckPos() const { return lastStuckPos; } inline void setLastStuckPos(Vec2i pos) { lastStuckPos = pos; } bool isLastPathfindFailedFrameWithinCurrentFrameTolerance() const; inline uint32 getLastPathfindFailedFrame() const { return lastPathfindFailedFrame; } inline void setLastPathfindFailedFrame(uint32 value) { lastPathfindFailedFrame = value; } void setLastPathfindFailedFrameToCurrentFrame(); inline Vec2i getLastPathfindFailedPos() const { return lastPathfindFailedPos; } inline void setLastPathfindFailedPos(Vec2i pos) { lastPathfindFailedPos = pos; } inline bool getUsePathfinderExtendedMaxNodes() const { return usePathfinderExtendedMaxNodes; } inline void setUsePathfinderExtendedMaxNodes(bool value) { usePathfinderExtendedMaxNodes = value; } void updateTimedParticles(); virtual string getUniquePickName() const; void saveGame(XmlNode *rootNode); static Unit * loadGame(const XmlNode *rootNode,GameSettings *settings,Faction *faction, World *world); void clearCaches(); bool showTranslatedTechTree() const; void addAttackParticleSystem(ParticleSystem *ps); Checksum getCRC(); virtual void end(ParticleSystem *particleSystem); virtual void logParticleInfo(string info); void setNetworkCRCParticleLogInfo(string networkCRCParticleLogInfo) { this->networkCRCParticleLogInfo = networkCRCParticleLogInfo; } void clearParticleInfo(); void addNetworkCRCDecHp(string info); void clearNetworkCRCDecHpList(); private: void cleanupAllParticlesystems(); bool isNetworkCRCEnabled(); string getNetworkCRCDecHpList() const; string getParticleInfo() const; float computeHeight(const Vec2i &pos) const; void calculateXZRotation(); void updateTarget(); void clearCommands(); void deleteQueuedCommand(Command *command); CommandResult undoCommand(Command *command); void stopDamageParticles(bool force); void startDamageParticles(); uint32 getFrameCount() const; void checkCustomizedParticleTriggers(bool force); void checkCustomizedUnitParticleTriggers(); void checkCustomizedUnitParticleListTriggers(vector &unitParticleSystemsList, const UnitParticleSystemTypes &unitParticleSystemTypesList, vector &queuedUnitParticleSystemTypesList); bool checkModelStateInfoForNewHpValue(); void checkUnitLevel(); void morphAttackBoosts(Unit *unit); int64 getUpdatedProgress(int64 currentProgress, int64 updateFPS, int64 speed, int64 diagonalFactor, int64 heightFactor); void logSynchDataCommon(string file,int line,string source="",bool threadedMode=false); void updateAttackBoostProgress(const Game* game); void setAlive(bool value); }; }}// end namespace #endif