diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index fea20fdec..f2757b60a 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -1,12 +1,12 @@ // ============================================================== -// This file is part of Glest (www.glest.org) +// This file is part of Glest (www.glest.org) // -// Copyright (C) 2001-2008 Martiño Figueroa +// 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 +// 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 // ============================================================== #define NOMINMAX @@ -33,4533 +33,6295 @@ using namespace Shared::Graphics; using namespace Shared::Util; -namespace Glest{ namespace Game{ +namespace Glest +{ + namespace Game + { -const int CHANGE_COMMAND_SPEED = 325; -const uint32 MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED = 160; + const int CHANGE_COMMAND_SPEED = 325; + const uint32 MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED = 160; //Mutex Unit::mutexDeletedUnits; //map Unit::deletedUnits; -const int UnitPathBasic::maxBlockCount= GameConstants::updateFps / 2; + const int UnitPathBasic::maxBlockCount = GameConstants::updateFps / 2; #ifdef LEAK_CHECK_UNITS -std::map UnitPathBasic::mapMemoryList; -std::map Unit::mapMemoryList; -std::map Unit::mapMemoryList2; + std::map < UnitPathBasic *, bool > UnitPathBasic::mapMemoryList; + std::map < Unit *, bool > Unit::mapMemoryList; + std::map < UnitPathInterface *, int >Unit::mapMemoryList2; #endif -UnitPathBasic::UnitPathBasic() : UnitPathInterface() { + UnitPathBasic::UnitPathBasic ():UnitPathInterface () + { #ifdef LEAK_CHECK_UNITS - UnitPathBasic::mapMemoryList[this]=true; + UnitPathBasic::mapMemoryList[this] = true; #endif - this->blockCount = 0; - this->pathQueue.clear(); - this->map = NULL; -} + this->blockCount = 0; + this->pathQueue.clear (); + this->map = NULL; + } -UnitPathBasic::~UnitPathBasic() { - this->blockCount = 0; - this->pathQueue.clear(); - this->map = NULL; + UnitPathBasic::~UnitPathBasic () + { + this->blockCount = 0; + this->pathQueue.clear (); + this->map = NULL; #ifdef LEAK_CHECK_UNITS - UnitPathBasic::mapMemoryList.erase(this); + UnitPathBasic::mapMemoryList.erase (this); #endif -} + } #ifdef LEAK_CHECK_UNITS -void UnitPathBasic::dumpMemoryList() { - printf("===== START report of Unfreed UnitPathBasic pointers =====\n"); - for(std::map::iterator iterMap = UnitPathBasic::mapMemoryList.begin(); - iterMap != UnitPathBasic::mapMemoryList.end(); ++iterMap) { - printf("************** ==> Unfreed UnitPathBasic pointer [%p]\n",iterMap->first); + void UnitPathBasic::dumpMemoryList () + { + printf ("===== START report of Unfreed UnitPathBasic pointers =====\n"); + for (std::map < UnitPathBasic *, bool >::iterator iterMap = + UnitPathBasic::mapMemoryList.begin (); + iterMap != UnitPathBasic::mapMemoryList.end (); ++iterMap) + { + printf ("************** ==> Unfreed UnitPathBasic pointer [%p]\n", + iterMap->first); - if(Unit::mapMemoryList2.find(iterMap->first) != Unit::mapMemoryList2.end()) { - printf("Found owner unit id [%d]\n",Unit::mapMemoryList2[iterMap->first]); - } - } -} + if (Unit::mapMemoryList2.find (iterMap->first) != + Unit::mapMemoryList2.end ()) + { + printf ("Found owner unit id [%d]\n", + Unit::mapMemoryList2[iterMap->first]); + } + } + } #endif -void UnitPathBasic::clearCaches() { - this->blockCount = 0; - this->pathQueue.clear(); -} + void UnitPathBasic::clearCaches () + { + this->blockCount = 0; + this->pathQueue.clear (); + } -bool UnitPathBasic::isEmpty() const { - return pathQueue.empty(); -} + bool UnitPathBasic::isEmpty () const + { + return pathQueue.empty (); + } -bool UnitPathBasic::isBlocked() const { - return blockCount >= maxBlockCount; -} + bool UnitPathBasic::isBlocked () const + { + return blockCount >= maxBlockCount; + } -bool UnitPathBasic::isStuck() const { - return (isBlocked() == true && blockCount >= (maxBlockCount * 2)); -} + bool UnitPathBasic::isStuck () const + { + return (isBlocked () == true && blockCount >= (maxBlockCount * 2)); + } -void UnitPathBasic::clear() { - pathQueue.clear(); - blockCount= 0; -} + void UnitPathBasic::clear () + { + pathQueue.clear (); + blockCount = 0; + } -void UnitPathBasic::incBlockCount() { - pathQueue.clear(); - blockCount++; -} + void UnitPathBasic::incBlockCount () + { + pathQueue.clear (); + blockCount++; + } -void UnitPathBasic::add(const Vec2i &path) { - if(this->map != NULL) { - if(this->map->isInside(path) == false) { - throw megaglest_runtime_error("Invalid map path position = " + path.getString() + " map w x h = " + intToStr(map->getW()) + " " + intToStr(map->getH())); - } - else if(this->map->isInsideSurface(this->map->toSurfCoords(path)) == false) { - throw megaglest_runtime_error("Invalid map surface path position = " + path.getString() + " map surface w x h = " + intToStr(map->getSurfaceW()) + " " + intToStr(map->getSurfaceH())); - } - } + void UnitPathBasic::add (const Vec2i & path) + { + if (this->map != NULL) + { + if (this->map->isInside (path) == false) + { + throw megaglest_runtime_error ("Invalid map path position = " + + path.getString () + " map w x h = " + + intToStr (map->getW ()) + " " + + intToStr (map->getH ())); + } + else if (this->map-> + isInsideSurface (this->map->toSurfCoords (path)) == false) + { + throw + megaglest_runtime_error ("Invalid map surface path position = " + + path.getString () + + " map surface w x h = " + + intToStr (map->getSurfaceW ()) + " " + + intToStr (map->getSurfaceH ())); + } + } - if(Thread::isCurrentThreadMainThread() == false) { - throw megaglest_runtime_error("Invalid access to UnitPathBasic add from outside main thread current id = " + - intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); - } + if (Thread::isCurrentThreadMainThread () == false) + { + throw + megaglest_runtime_error + ("Invalid access to UnitPathBasic add from outside main thread current id = " + + intToStr (Thread::getCurrentThreadId ()) + " main = " + + intToStr (Thread::getMainThreadId ())); + } - pathQueue.push_back(path); -} + pathQueue.push_back (path); + } -Vec2i UnitPathBasic::pop(bool removeFrontPos) { - if(pathQueue.empty() == true) { - throw megaglest_runtime_error("pathQueue.size() = " + intToStr(pathQueue.size())); - } - Vec2i p= pathQueue.front(); - if(removeFrontPos == true) { - if(Thread::isCurrentThreadMainThread() == false) { - throw megaglest_runtime_error("Invalid access to UnitPathBasic delete from outside main thread current id = " + - intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); - } + Vec2i UnitPathBasic::pop (bool removeFrontPos) + { + if (pathQueue.empty () == true) + { + throw megaglest_runtime_error ("pathQueue.size() = " + + intToStr (pathQueue.size ())); + } + Vec2i p = pathQueue.front (); + if (removeFrontPos == true) + { + if (Thread::isCurrentThreadMainThread () == false) + { + throw + megaglest_runtime_error + ("Invalid access to UnitPathBasic delete from outside main thread current id = " + + intToStr (Thread::getCurrentThreadId ()) + " main = " + + intToStr (Thread::getMainThreadId ())); + } - pathQueue.erase(pathQueue.begin()); - } - return p; -} -std::string UnitPathBasic::toString() const { - std::string result = "unit path blockCount = " + intToStr(blockCount) + "\npathQueue size = " + intToStr(pathQueue.size()); - for(int idx = 0; idx < (int)pathQueue.size(); ++idx) { - result += " index = " + intToStr(idx) + " value = " + pathQueue[idx].getString(); - } + pathQueue.erase (pathQueue.begin ()); + } + return p; + } + std::string UnitPathBasic::toString ()const + { + std::string result = + "unit path blockCount = " + intToStr (blockCount) + + "\npathQueue size = " + intToStr (pathQueue.size ()); + for (int idx = 0; idx < (int) pathQueue.size (); ++idx) + { + result += + " index = " + intToStr (idx) + " value = " + + pathQueue[idx].getString (); + } - return result; -} + return result; + } -void UnitPathBasic::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *unitPathBasicNode = rootNode->addChild("UnitPathBasic"); + void UnitPathBasic::saveGame (XmlNode * rootNode) + { + std::map < string, string > mapTagReplacements; + XmlNode *unitPathBasicNode = rootNode->addChild ("UnitPathBasic"); -// int blockCount; - unitPathBasicNode->addAttribute("blockCount",intToStr(blockCount), mapTagReplacements); -// vector pathQueue; - for(unsigned int i = 0; i < pathQueue.size(); ++i) { - Vec2i &vec = pathQueue[i]; +// int blockCount; + unitPathBasicNode->addAttribute ("blockCount", intToStr (blockCount), + mapTagReplacements); +// vector pathQueue; + for (unsigned int i = 0; i < pathQueue.size (); ++i) + { + Vec2i & vec = pathQueue[i]; - XmlNode *pathQueueNode = unitPathBasicNode->addChild("pathQueue"); - pathQueueNode->addAttribute("vec",vec.getString(), mapTagReplacements); - } -} + XmlNode *pathQueueNode = unitPathBasicNode->addChild ("pathQueue"); + pathQueueNode->addAttribute ("vec", vec.getString (), + mapTagReplacements); + } + } -void UnitPathBasic::loadGame(const XmlNode *rootNode) { - const XmlNode *unitPathBasicNode = rootNode->getChild("UnitPathBasic"); + void UnitPathBasic::loadGame (const XmlNode * rootNode) + { + const XmlNode *unitPathBasicNode = rootNode->getChild ("UnitPathBasic"); - blockCount = unitPathBasicNode->getAttribute("blockCount")->getIntValue(); + blockCount = + unitPathBasicNode->getAttribute ("blockCount")->getIntValue (); - pathQueue.clear(); - vector pathqueueNodeList = unitPathBasicNode->getChildList("pathQueue"); - for(unsigned int i = 0; i < pathqueueNodeList.size(); ++i) { - XmlNode *node = pathqueueNodeList[i]; + pathQueue.clear (); + vector < XmlNode * >pathqueueNodeList = + unitPathBasicNode->getChildList ("pathQueue"); + for (unsigned int i = 0; i < pathqueueNodeList.size (); ++i) + { + XmlNode *node = pathqueueNodeList[i]; - Vec2i vec = Vec2i::strToVec2(node->getAttribute("vec")->getValue()); - pathQueue.push_back(vec); - } -} + Vec2i vec = + Vec2i::strToVec2 (node->getAttribute ("vec")->getValue ()); + pathQueue.push_back (vec); + } + } -Checksum UnitPathBasic::getCRC() { - Checksum crcForPath; + Checksum UnitPathBasic::getCRC () + { + Checksum crcForPath; - crcForPath.addInt(blockCount); - crcForPath.addInt((int)pathQueue.size()); + crcForPath.addInt (blockCount); + crcForPath.addInt ((int) pathQueue.size ()); - return crcForPath; -} + return crcForPath; + } // ===================================================== -// class UnitPath +// class UnitPath // ===================================================== //void WaypointPath::condense() { -// if (size() < 2) { -// return; -// } -// iterator prev, curr; -// prev = curr = begin(); -// while (++curr != end()) { -// if (prev->dist(*curr) < 3.f) { -// prev = erase(prev); -// } else { -// ++prev; -// } -// } +// if (size() < 2) { +// return; +// } +// iterator prev, curr; +// prev = curr = begin(); +// while (++curr != end()) { +// if (prev->dist(*curr) < 3.f) { +// prev = erase(prev); +// } else { +// ++prev; +// } +// } //} -std::string UnitPath::toString() const { - std::string result = "unit path blockCount = " + intToStr(blockCount) + " pathQueue size = " + intToStr(size()); - result += " path = "; - for (const_iterator it = begin(); it != end(); ++it) { - result += " [" + intToStr(it->x) + "," + intToStr(it->y) + "]"; - } + std::string UnitPath::toString ()const + { + std::string result = + "unit path blockCount = " + intToStr (blockCount) + + " pathQueue size = " + intToStr (size ()); + result += " path = "; + for (const_iterator it = begin (); it != end (); ++it) + { + result += " [" + intToStr (it->x) + "," + intToStr (it->y) + "]"; + } - return result; -} + return result; + } // ===================================================== -// class UnitReference +// class UnitReference // ===================================================== -UnitReference::UnitReference(){ - id= -1; - faction= NULL; -} + UnitReference::UnitReference () + { + id = -1; + faction = NULL; + } -UnitReference & UnitReference::operator=(const Unit *unit){ - if(unit==NULL){ - id= -1; - faction= NULL; - } - else{ - id= unit->getId(); - faction= unit->getFaction(); - } + UnitReference & UnitReference::operator= (const Unit * unit) + { + if (unit == NULL) + { + id = -1; + faction = NULL; + } + else + { + id = unit->getId (); + faction = unit->getFaction (); + } - return *this; -} + return *this; + } -Unit *UnitReference::getUnit() const{ - if(faction!=NULL){ - return faction->findUnit(id); - } - return NULL; -} + Unit *UnitReference::getUnit () const + { + if (faction != NULL) + { + return faction->findUnit (id); + } + return NULL; + } -void UnitReference::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *unitRefNode = rootNode->addChild("UnitReference"); + void UnitReference::saveGame (XmlNode * rootNode) + { + std::map < string, string > mapTagReplacements; + XmlNode *unitRefNode = rootNode->addChild ("UnitReference"); - unitRefNode->addAttribute("id",intToStr(id), mapTagReplacements); - if(faction != NULL) { - unitRefNode->addAttribute("factionIndex",intToStr(faction->getIndex()), mapTagReplacements); - } -} + unitRefNode->addAttribute ("id", intToStr (id), mapTagReplacements); + if (faction != NULL) + { + unitRefNode->addAttribute ("factionIndex", + intToStr (faction->getIndex ()), + mapTagReplacements); + } + } -void UnitReference::loadGame(const XmlNode *rootNode,World *world) { - const XmlNode *unitRefNode = rootNode->getChild("UnitReference"); + void UnitReference::loadGame (const XmlNode * rootNode, World * world) + { + const XmlNode *unitRefNode = rootNode->getChild ("UnitReference"); - id = unitRefNode->getAttribute("id")->getIntValue(); - if(unitRefNode->hasAttribute("factionIndex") == true) { - int factionIndex = unitRefNode->getAttribute("factionIndex")->getIntValue(); - if(factionIndex >= world->getFactionCount()) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"factionIndex >= world->getFactionCount() [%d] : [%d]",factionIndex,world->getFactionCount()); - throw megaglest_runtime_error(szBuf); - } - faction = world->getFaction(factionIndex); - } -} + id = unitRefNode->getAttribute ("id")->getIntValue (); + if (unitRefNode->hasAttribute ("factionIndex") == true) + { + int factionIndex = + unitRefNode->getAttribute ("factionIndex")->getIntValue (); + if (factionIndex >= world->getFactionCount ()) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "factionIndex >= world->getFactionCount() [%d] : [%d]", + factionIndex, world->getFactionCount ()); + throw megaglest_runtime_error (szBuf); + } + faction = world->getFaction (factionIndex); + } + } -const bool checkMemory = false; -static map memoryObjectList; + const bool checkMemory = false; + static map < void *, int >memoryObjectList; -UnitAttackBoostEffect::UnitAttackBoostEffect() { - if(checkMemory) { - printf("++ Create UnitAttackBoostEffect [%p] before count = %d\n",this,memoryObjectList[this]); - memoryObjectList[this]++; - printf("++ Create UnitAttackBoostEffect [%p] after count = %d\n",this,memoryObjectList[this]); - } + UnitAttackBoostEffect::UnitAttackBoostEffect () + { + if (checkMemory) + { + printf ("++ Create UnitAttackBoostEffect [%p] before count = %d\n", + this, memoryObjectList[this]); + memoryObjectList[this]++; + printf ("++ Create UnitAttackBoostEffect [%p] after count = %d\n", + this, memoryObjectList[this]); + } - unitId = -1; - unitPtr = NULL; - boost = NULL; - source = NULL; - ups = NULL; - upst = NULL; -} + unitId = -1; + unitPtr = NULL; + boost = NULL; + source = NULL; + ups = NULL; + upst = NULL; + } -UnitAttackBoostEffect::~UnitAttackBoostEffect() { - if(checkMemory) { - printf("-- Delete UnitAttackBoostEffect [%p] count = %d\n",this,memoryObjectList[this]); - memoryObjectList[this]--; - assert(memoryObjectList[this] == 0); - } + UnitAttackBoostEffect::~UnitAttackBoostEffect () + { + if (checkMemory) + { + printf ("-- Delete UnitAttackBoostEffect [%p] count = %d\n", this, + memoryObjectList[this]); + memoryObjectList[this]--; + assert (memoryObjectList[this] == 0); + } - if(ups != NULL) { - bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(ups,rsGame); - if(particleValid == true) { - ups->fade(); + if (ups != NULL) + { + bool particleValid = + Renderer::getInstance ().validateParticleSystemStillExists (ups, + rsGame); + if (particleValid == true) + { + ups->fade (); - vector particleSystemToRemove; - particleSystemToRemove.push_back(ups); + vector < UnitParticleSystem * >particleSystemToRemove; + particleSystemToRemove.push_back (ups); - Renderer::getInstance().cleanupUnitParticleSystems(particleSystemToRemove,rsGame); - ups = NULL; - } - } + Renderer::getInstance (). + cleanupUnitParticleSystems (particleSystemToRemove, rsGame); + ups = NULL; + } + } - delete upst; - upst = NULL; -} + delete upst; + upst = NULL; + } -const Unit * UnitAttackBoostEffect::getSource() { - if(source == NULL && unitPtr != NULL && unitId > 0) { - source = unitPtr->getFaction()->findUnit(unitId); + const Unit *UnitAttackBoostEffect::getSource () + { + if (source == NULL && unitPtr != NULL && unitId > 0) + { + source = unitPtr->getFaction ()->findUnit (unitId); - //printf("#1 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); - } - //printf("#2 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); - return source; -} + //printf("#1 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); + } + //printf("#2 Get source - boost effect unitId = %d unitPtr = %s source = %p\n",unitId,unitPtr->getFullName(false).c_str(),source); + return source; + } -void UnitAttackBoostEffect::setSource(const Unit *unit) { - source = unit; -} + void UnitAttackBoostEffect::setSource (const Unit * unit) + { + source = unit; + } -void UnitAttackBoostEffect::applyLoadedAttackBoostParticles(UnitParticleSystemType *upstPtr,const XmlNode *node, Unit* unit) { - if (upstPtr != NULL) { - bool showUnitParticles = Config::getInstance().getBool("UnitParticles","true"); - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - showUnitParticles = false; - } - if (showUnitParticles == true) { - upst = new UnitParticleSystemType(); - *upst = *upstPtr; - upst->loadGame(node); + void UnitAttackBoostEffect:: + applyLoadedAttackBoostParticles (UnitParticleSystemType * upstPtr, + const XmlNode * node, Unit * unit) + { + if (upstPtr != NULL) + { + bool showUnitParticles = + Config::getInstance ().getBool ("UnitParticles", "true"); + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) + { + showUnitParticles = false; + } + if (showUnitParticles == true) + { + upst = new UnitParticleSystemType (); + *upst = *upstPtr; + upst->loadGame (node); - ups = new UnitParticleSystem(200); - //ups->loadGame(node2); - ups->setParticleOwner(unit); - ups->setParticleType(upst); + ups = new UnitParticleSystem (200); + //ups->loadGame(node2); + ups->setParticleOwner (unit); + ups->setParticleType (upst); - upst->setValues(ups); - ups->setPos(unit->getCurrVectorForParticlesystems()); - ups->setRotation(unit->getRotation()); - unit->setMeshPosInParticleSystem(ups); - if (unit->getFaction()->getTexture()) { - ups->setFactionColor(unit->getFaction()->getTexture()->getPixmapConst()->getPixel3f(0, 0)); - } - //printf("Adding attack boost particle to deferred buffer: %p\n",ups); - Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); - } - } -} + upst->setValues (ups); + ups->setPos (unit->getCurrVectorForParticlesystems ()); + ups->setRotation (unit->getRotation ()); + unit->setMeshPosInParticleSystem (ups); + if (unit->getFaction ()->getTexture ()) + { + ups->setFactionColor (unit->getFaction ()->getTexture ()-> + getPixmapConst ()->getPixel3f (0, 0)); + } + //printf("Adding attack boost particle to deferred buffer: %p\n",ups); + Renderer::getInstance (). + addToDeferredParticleSystemList (make_pair (ups, rsGame)); + } + } + } -void UnitAttackBoostEffect::loadGame(const XmlNode *rootNode, Unit *unit, World *world, bool applyToOriginator) { - const XmlNode *unitAttackBoostEffectNode = rootNode; + void UnitAttackBoostEffect::loadGame (const XmlNode * rootNode, + Unit * unit, World * world, + bool applyToOriginator) + { + const XmlNode *unitAttackBoostEffectNode = rootNode; - if(unitAttackBoostEffectNode->hasAttribute("source") == true) { - unitId = unitAttackBoostEffectNode->getAttribute("source")->getIntValue(); - unitPtr = unit; - source = unit->getFaction()->findUnit(unitId); + if (unitAttackBoostEffectNode->hasAttribute ("source") == true) + { + unitId = + unitAttackBoostEffectNode->getAttribute ("source")->getIntValue (); + unitPtr = unit; + source = unit->getFaction ()->findUnit (unitId); -// printf("#1 Loaded boost effect unitId = %d unitPtr = [%d - %s] source = %p\n", -// unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(),source); - } +// printf("#1 Loaded boost effect unitId = %d unitPtr = [%d - %s] source = %p\n", +// unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(),source); + } - // Lets determine the originator unit's attack boost based on the skill used to trigger it - if(unitAttackBoostEffectNode->hasAttribute("source-faction") == true) { - string factionName = unitAttackBoostEffectNode->getAttribute("source-faction")->getValue(); - string unitTypeName = unitAttackBoostEffectNode->getAttribute("source-unit-type")->getValue(); - string skillTypeName = unitAttackBoostEffectNode->getAttribute("source-skill-type")->getValue(); - SkillClass skillClass = static_cast(unitAttackBoostEffectNode->getAttribute("source-skill-class")->getIntValue()); + // Lets determine the originator unit's attack boost based on the skill used to trigger it + if (unitAttackBoostEffectNode->hasAttribute ("source-faction") == true) + { + string factionName = + unitAttackBoostEffectNode->getAttribute ("source-faction")-> + getValue (); + string unitTypeName = + unitAttackBoostEffectNode->getAttribute ("source-unit-type")-> + getValue (); + string skillTypeName = + unitAttackBoostEffectNode->getAttribute ("source-skill-type")-> + getValue (); + SkillClass skillClass = + static_cast < SkillClass > + (unitAttackBoostEffectNode->getAttribute ("source-skill-class")-> + getIntValue ()); - const UnitType *unitType = world->findUnitTypeByName(factionName, unitTypeName); - if(unitType != NULL) { - const SkillType *skillType = unitType->getSkillType(skillTypeName,skillClass); - if(skillType != NULL) { - boost = skillType->getAttackBoost(); + const UnitType *unitType = + world->findUnitTypeByName (factionName, unitTypeName); + if (unitType != NULL) + { + const SkillType *skillType = + unitType->getSkillType (skillTypeName, skillClass); + if (skillType != NULL) + { + boost = skillType->getAttackBoost (); -// printf("#2 boost effect unitId = %d unitPtr = [%d - %s] source = %p attackBoost src [%p] dest [%p]\n", -// unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(), -// source,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit); - } - } - } +// printf("#2 boost effect unitId = %d unitPtr = [%d - %s] source = %p attackBoost src [%p] dest [%p]\n", +// unitId,unitPtr->getId(),unitPtr->getType()->getName(false).c_str(), +// source,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit); + } + } + } - if(boost != NULL) { -// printf("unit [%d - %s] applyToOriginator: %d src [%p] dest [%p] Boost attackBoost->enabled = %d:\n%s\n", -// unit->getId(),unit->getType()->getName(false).c_str(),applyToOriginator,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit,boost->enabled,boost->getDesc(false).c_str()); + if (boost != NULL) + { +// printf("unit [%d - %s] applyToOriginator: %d src [%p] dest [%p] Boost attackBoost->enabled = %d:\n%s\n", +// unit->getId(),unit->getType()->getName(false).c_str(),applyToOriginator,boost->unitParticleSystemTypeForSourceUnit,boost->unitParticleSystemTypeForAffectedUnit,boost->enabled,boost->getDesc(false).c_str()); - if(applyToOriginator == true) { - applyLoadedAttackBoostParticles(boost->unitParticleSystemTypeForSourceUnit, - unitAttackBoostEffectNode, unit); - } - else { - applyLoadedAttackBoostParticles(boost->unitParticleSystemTypeForAffectedUnit, - unitAttackBoostEffectNode, unit); - } - } - else { - printf("******!!!! unit [%d - %s] applyToOriginator: %d NO BOOST FOUND!!!\n",unit->getId(),unit->getType()->getName(false).c_str(),applyToOriginator); - } -} + if (applyToOriginator == true) + { + applyLoadedAttackBoostParticles (boost-> + unitParticleSystemTypeForSourceUnit, + unitAttackBoostEffectNode, unit); + } + else + { + applyLoadedAttackBoostParticles (boost-> + unitParticleSystemTypeForAffectedUnit, + unitAttackBoostEffectNode, unit); + } + } + else + { + printf + ("******!!!! unit [%d - %s] applyToOriginator: %d NO BOOST FOUND!!!\n", + unit->getId (), unit->getType ()->getName (false).c_str (), + applyToOriginator); + } + } -void UnitAttackBoostEffect::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *unitAttackBoostEffectNode = rootNode->addChild("UnitAttackBoostEffect"); + void UnitAttackBoostEffect::saveGame (XmlNode * rootNode) + { + std::map < string, string > mapTagReplacements; + XmlNode *unitAttackBoostEffectNode = + rootNode->addChild ("UnitAttackBoostEffect"); -// const AttackBoost *boost; - if(boost != NULL) { - boost->saveGame(unitAttackBoostEffectNode); - } -// const Unit *source; - if(getSource() != NULL) { - unitAttackBoostEffectNode->addAttribute("source",intToStr(getSource()->getId()), mapTagReplacements); +// const AttackBoost *boost; + if (boost != NULL) + { + boost->saveGame (unitAttackBoostEffectNode); + } +// const Unit *source; + if (getSource () != NULL) + { + unitAttackBoostEffectNode->addAttribute ("source", + intToStr (getSource ()-> + getId ()), + mapTagReplacements); - unitAttackBoostEffectNode->addAttribute("source-faction",getSource()->getFaction()->getType()->getName(false), mapTagReplacements); - unitAttackBoostEffectNode->addAttribute("source-unit-type",getSource()->getType()->getName(false), mapTagReplacements); - unitAttackBoostEffectNode->addAttribute("source-skill-type",getSource()->getCurrSkill()->getName(), mapTagReplacements); - unitAttackBoostEffectNode->addAttribute("source-skill-class",intToStr(getSource()->getCurrSkill()->getClass()), mapTagReplacements); - } -// UnitParticleSystem *ups; - if(ups != NULL && Renderer::getInstance().validateParticleSystemStillExists(ups,rsGame) == true) { - ups->saveGame(unitAttackBoostEffectNode); - } + unitAttackBoostEffectNode->addAttribute ("source-faction", + getSource ()->getFaction ()-> + getType ()->getName (false), + mapTagReplacements); + unitAttackBoostEffectNode->addAttribute ("source-unit-type", + getSource ()->getType ()-> + getName (false), + mapTagReplacements); + unitAttackBoostEffectNode->addAttribute ("source-skill-type", + getSource ()-> + getCurrSkill ()->getName (), + mapTagReplacements); + unitAttackBoostEffectNode->addAttribute ("source-skill-class", + intToStr (getSource ()-> + getCurrSkill ()-> + getClass ()), + mapTagReplacements); + } +// UnitParticleSystem *ups; + if (ups != NULL + && Renderer::getInstance ().validateParticleSystemStillExists (ups, + rsGame) + == true) + { + ups->saveGame (unitAttackBoostEffectNode); + } -// UnitParticleSystemType *upst; - if(upst != NULL) { - upst->saveGame(unitAttackBoostEffectNode); - } -} +// UnitParticleSystemType *upst; + if (upst != NULL) + { + upst->saveGame (unitAttackBoostEffectNode); + } + } -UnitAttackBoostEffectOriginator::UnitAttackBoostEffectOriginator() { - skillType = NULL; - currentAppliedEffect = NULL; -} + UnitAttackBoostEffectOriginator::UnitAttackBoostEffectOriginator () + { + skillType = NULL; + currentAppliedEffect = NULL; + } -UnitAttackBoostEffectOriginator::~UnitAttackBoostEffectOriginator() { - delete currentAppliedEffect; - currentAppliedEffect = NULL; -} + UnitAttackBoostEffectOriginator::~UnitAttackBoostEffectOriginator () + { + delete currentAppliedEffect; + currentAppliedEffect = NULL; + } -void UnitAttackBoostEffectOriginator::loadGame(const XmlNode *rootNode, Unit *unit, World *world) { - const XmlNode *unitAttackBoostEffectOriginatorNode = rootNode->getChild("UnitAttackBoostEffectOriginator"); + void UnitAttackBoostEffectOriginator::loadGame (const XmlNode * rootNode, + Unit * unit, + World * world) + { + const XmlNode *unitAttackBoostEffectOriginatorNode = + rootNode->getChild ("UnitAttackBoostEffectOriginator"); - SkillClass skillClass = scStop; - string skillTypeName = unitAttackBoostEffectOriginatorNode->getAttribute("skillType")->getValue(); - if(unitAttackBoostEffectOriginatorNode->hasAttribute("skillClass") == false) { - int skillCount = unit->getType()->getSkillTypeCount(); - for(int index = 0; index < skillCount; ++index) { - const SkillType *st = unit->getType()->getSkillType(index); - if(st->getName() == skillTypeName) { - skillClass = st->getClass(); - break; - } - } - } - else { - skillClass = static_cast(unitAttackBoostEffectOriginatorNode->getAttribute("skillClass")->getIntValue()); - } + SkillClass skillClass = scStop; + string skillTypeName = + unitAttackBoostEffectOriginatorNode->getAttribute ("skillType")-> + getValue (); + if (unitAttackBoostEffectOriginatorNode->hasAttribute ("skillClass") == + false) + { + int skillCount = unit->getType ()->getSkillTypeCount (); + for (int index = 0; index < skillCount; ++index) + { + const SkillType *st = unit->getType ()->getSkillType (index); + if (st->getName () == skillTypeName) + { + skillClass = st->getClass (); + break; + } + } + } + else + { + skillClass = + static_cast < SkillClass > + (unitAttackBoostEffectOriginatorNode->getAttribute ("skillClass")-> + getIntValue ()); + } - this->skillType = unit->getType()->getSkillType(skillTypeName,skillClass); + this->skillType = + unit->getType ()->getSkillType (skillTypeName, skillClass); - if(unitAttackBoostEffectOriginatorNode->hasChild("currentAttackBoostUnits") == true) { - vector currentAttackBoostUnitsNodeList = unitAttackBoostEffectOriginatorNode->getChildList("currentAttackBoostUnits"); - for(unsigned int i = 0; i < currentAttackBoostUnitsNodeList.size(); ++i) { - XmlNode *node = currentAttackBoostUnitsNodeList[i]; + if (unitAttackBoostEffectOriginatorNode-> + hasChild ("currentAttackBoostUnits") == true) + { + vector < XmlNode * >currentAttackBoostUnitsNodeList = + unitAttackBoostEffectOriginatorNode-> + getChildList ("currentAttackBoostUnits"); + for (unsigned int i = 0; i < currentAttackBoostUnitsNodeList.size (); + ++i) + { + XmlNode *node = currentAttackBoostUnitsNodeList[i]; - int unitId = node->getAttribute("value")->getIntValue(); - currentAttackBoostUnits.push_back(unitId); - } - } + int unitId = node->getAttribute ("value")->getIntValue (); + currentAttackBoostUnits.push_back (unitId); + } + } - if(unitAttackBoostEffectOriginatorNode->hasChild("UnitAttackBoostEffect") == true) { - currentAppliedEffect = new UnitAttackBoostEffect(); - currentAppliedEffect->loadGame(unitAttackBoostEffectOriginatorNode, unit,world, true); - } -} + if (unitAttackBoostEffectOriginatorNode-> + hasChild ("UnitAttackBoostEffect") == true) + { + currentAppliedEffect = new UnitAttackBoostEffect (); + currentAppliedEffect->loadGame (unitAttackBoostEffectOriginatorNode, + unit, world, true); + } + } -void UnitAttackBoostEffectOriginator::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *unitAttackBoostEffectOriginatorNode = rootNode->addChild("UnitAttackBoostEffectOriginator"); + void UnitAttackBoostEffectOriginator::saveGame (XmlNode * rootNode) + { + std::map < string, string > mapTagReplacements; + XmlNode *unitAttackBoostEffectOriginatorNode = + rootNode->addChild ("UnitAttackBoostEffectOriginator"); -// const SkillType *skillType; - if(skillType != NULL) { - unitAttackBoostEffectOriginatorNode->addAttribute("skillType",skillType->getName(), mapTagReplacements); - unitAttackBoostEffectOriginatorNode->addAttribute("skillClass",intToStr(skillType->getClass()), mapTagReplacements); - } -// std::vector currentAttackBoostUnits; - for(unsigned int i = 0; i < currentAttackBoostUnits.size(); ++i) { - XmlNode *currentAttackBoostUnitsNode = unitAttackBoostEffectOriginatorNode->addChild("currentAttackBoostUnits"); - currentAttackBoostUnitsNode->addAttribute("value",intToStr(currentAttackBoostUnits[i]), mapTagReplacements); - } -// UnitAttackBoostEffect *currentAppliedEffect; - if(currentAppliedEffect != NULL) { - currentAppliedEffect->saveGame(unitAttackBoostEffectOriginatorNode); - } -} +// const SkillType *skillType; + if (skillType != NULL) + { + unitAttackBoostEffectOriginatorNode->addAttribute ("skillType", + skillType-> + getName (), + mapTagReplacements); + unitAttackBoostEffectOriginatorNode->addAttribute ("skillClass", + intToStr + (skillType-> + getClass ()), + mapTagReplacements); + } +// std::vector currentAttackBoostUnits; + for (unsigned int i = 0; i < currentAttackBoostUnits.size (); ++i) + { + XmlNode *currentAttackBoostUnitsNode = + unitAttackBoostEffectOriginatorNode-> + addChild ("currentAttackBoostUnits"); + currentAttackBoostUnitsNode->addAttribute ("value", + intToStr + (currentAttackBoostUnits + [i]), mapTagReplacements); + } +// UnitAttackBoostEffect *currentAppliedEffect; + if (currentAppliedEffect != NULL) + { + currentAppliedEffect->saveGame (unitAttackBoostEffectOriginatorNode); + } + } // ===================================================== -// class Unit +// class Unit // ===================================================== -const float Unit::ANIMATION_SPEED_MULTIPLIER = 100000.f; + const float Unit::ANIMATION_SPEED_MULTIPLIER = 100000.f; //const float Unit::PROGRESS_SPEED_MULTIPLIER = 100000.f; -const int64 Unit::PROGRESS_SPEED_MULTIPLIER = 100000; + const int64 Unit::PROGRESS_SPEED_MULTIPLIER = 100000; -const int Unit::speedDivider= 100; -const int Unit::maxDeadCount= 1000; //time in until the corpse disapears - should be about 40 seconds -const int Unit::invalidId= -1; + const int Unit::speedDivider = 100; + const int Unit::maxDeadCount = 1000; //time in until the corpse disapears - should be about 40 seconds + const int Unit::invalidId = -1; //set Unit::livingUnits; //set Unit::livingUnitsp; // ============================ Constructor & destructor ============================= -Game *Unit::game = NULL; + Game *Unit::game = NULL; -Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, - const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) : BaseColorPickEntity(), id(id) { + Unit::Unit (int id, UnitPathInterface * unitpath, const Vec2i & pos, + const UnitType * type, Faction * faction, Map * map, + CardinalDir placeFacing):BaseColorPickEntity (), id (id) + { #ifdef LEAK_CHECK_UNITS - Unit::mapMemoryList[this]=true; + Unit::mapMemoryList[this] = true; #endif - mutexCommands = new Mutex(CODE_AT_LINE); - changedActiveCommand = false; - lastChangedActiveCommandFrame = 0; - changedActiveCommandFrame = 0; + mutexCommands = new Mutex (CODE_AT_LINE); + changedActiveCommand = false; + lastChangedActiveCommandFrame = 0; + changedActiveCommandFrame = 0; - lastSynchDataString=""; - modelFacing = CardinalDir(CardinalDir::NORTH); - lastStuckFrame = 0; - lastStuckPos = Vec2i(0,0); - lastPathfindFailedFrame = 0; - lastPathfindFailedPos = Vec2i(0,0); - usePathfinderExtendedMaxNodes = false; - this->currentAttackBoostOriginatorEffect.skillType = NULL; - lastAttackerUnitId = -1; - lastAttackedUnitId = -1; - causeOfDeath = ucodNone; - pathfindFailedConsecutiveFrameCount = 0; + lastSynchDataString = ""; + modelFacing = CardinalDir (CardinalDir::NORTH); + lastStuckFrame = 0; + lastStuckPos = Vec2i (0, 0); + lastPathfindFailedFrame = 0; + lastPathfindFailedPos = Vec2i (0, 0); + usePathfinderExtendedMaxNodes = false; + this->currentAttackBoostOriginatorEffect.skillType = NULL; + lastAttackerUnitId = -1; + lastAttackedUnitId = -1; + causeOfDeath = ucodNone; + pathfindFailedConsecutiveFrameCount = 0; - lastSynchDataString = ""; - lastFile = ""; - lastLine = 0; - lastSource = ""; + lastSynchDataString = ""; + lastFile = ""; + lastLine = 0; + lastSource = ""; - targetRotationZ=.0f; - targetRotationX=.0f; - rotationZ=.0f; - rotationX=.0f; + targetRotationZ = .0f; + targetRotationX = .0f; + rotationZ = .0f; + rotationX = .0f; - this->fire= NULL; - this->unitPath = unitpath; - this->unitPath->setMap(map); + this->fire = NULL; + this->unitPath = unitpath; + this->unitPath->setMap (map); - //RandomGen random; - random.init(id); - random.setDisableLastCallerTracking(isNetworkCRCEnabled() == false); - pathFindRefreshCellCount = random.randRange(10,20,intToStr(__LINE__)); + //RandomGen random; + random.init (id); + random.setDisableLastCallerTracking (isNetworkCRCEnabled () == false); + pathFindRefreshCellCount = + random.randRange (10, 20, intToStr (__LINE__)); - if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { - throw megaglest_runtime_error("#2 Invalid path position = " + pos.getString()); - } + if (map->isInside (pos) == false + || map->isInsideSurface (map->toSurfCoords (pos)) == false) + { + throw megaglest_runtime_error ("#2 Invalid path position = " + + pos.getString ()); + } - this->pos=pos; + this->pos = pos; - this->faction=faction; - this->preMorph_type = NULL; - this->type=type; - setType(this->type); + this->faction = faction; + this->preMorph_type = NULL; + this->type = type; + setType (this->type); - this->map= map; - this->targetRef = NULL; - this->targetField = fLand; - this->targetVec = Vec3f(0.0); - this->targetPos = Vec2i(0); - this->lastRenderFrame = 0; - this->visible = true; - this->retryCurrCommandCount=0; - this->screenPos = Vec3f(0.0); - this->ignoreCheckCommand = false; - this->inBailOutAttempt = false; - this->lastHarvestResourceTarget.first = Vec2i(0); - this->morphFieldsBlocked=false; - //this->lastBadHarvestListPurge = 0; - this->oldTotalSight = 0; + this->map = map; + this->targetRef = NULL; + this->targetField = fLand; + this->targetVec = Vec3f (0.0); + this->targetPos = Vec2i (0); + this->lastRenderFrame = 0; + this->visible = true; + this->retryCurrCommandCount = 0; + this->screenPos = Vec3f (0.0); + this->ignoreCheckCommand = false; + this->inBailOutAttempt = false; + this->lastHarvestResourceTarget.first = Vec2i (0); + this->morphFieldsBlocked = false; + //this->lastBadHarvestListPurge = 0; + this->oldTotalSight = 0; - level= NULL; - loadType= NULL; + level = NULL; + loadType = NULL; - setModelFacing(placeFacing); + setModelFacing (placeFacing); - Config &config= Config::getInstance(); - showUnitParticles = config.getBool("UnitParticles","true"); - maxQueuedCommandDisplayCount = config.getInt("MaxQueuedCommandDisplayCount","15"); + Config & config = Config::getInstance (); + showUnitParticles = config.getBool ("UnitParticles", "true"); + maxQueuedCommandDisplayCount = + config.getInt ("MaxQueuedCommandDisplayCount", "15"); - if(GlobalStaticFlags::getIsNonGraphicalModeEnabled() == true) { - showUnitParticles = false; - } + if (GlobalStaticFlags::getIsNonGraphicalModeEnabled () == true) + { + showUnitParticles = false; + } - lastPos= pos; - progress= 0; - this->lastAnimProgress= 0; - this->animProgress= 0; - progress2= 0; - kills= 0; - enemyKills = 0; - loadCount= 0; - ep= 0; - deadCount= 0; - hp= type->getMaxHp() / 20; - toBeUndertaken= false; + lastPos = pos; + progress = 0; + this->lastAnimProgress = 0; + this->animProgress = 0; + progress2 = 0; + kills = 0; + enemyKills = 0; + loadCount = 0; + ep = 0; + deadCount = 0; + hp = type->getMaxHp () / 20; + toBeUndertaken = false; - highlight= 0.f; - meetingPos= pos; - setAlive(true); + highlight = 0.f; + meetingPos = pos; + setAlive (true); - if (type->hasSkillClass(scBeBuilt) == false) { - float rot= 0.f; - random.init(id); - rot += random.randRange(-5, 5,intToStr(__LINE__)); - rotation= rot; - lastRotation= rot; - targetRotation= rot; - } - // else it was set appropriately in setModelFacing() + if (type->hasSkillClass (scBeBuilt) == false) + { + float rot = 0.f; + random.init (id); + rot += random.randRange (-5, 5, intToStr (__LINE__)); + rotation = rot; + lastRotation = rot; + targetRotation = rot; + } + // else it was set appropriately in setModelFacing() - if(getType()->getField(fAir)) { - currField = fAir; - } - if(getType()->getField(fLand)) { - currField = fLand; + if (getType ()->getField (fAir)) + { + currField = fAir; + } + if (getType ()->getField (fLand)) + { + currField = fLand; + } + + computeTotalUpgrade (); + + //starting skill + this->lastModelIndexForCurrSkillType = -1; + this->animationRandomCycleCount = 0; + this->currSkill = getType ()->getFirstStOfClass (scStop); + this->setCurrSkill (this->currSkill); + this->currentAttackBoostOriginatorEffect.skillType = this->currSkill; + + this->faction->addLivingUnits (id); + this->faction->addLivingUnitsp (this); + + addItemToVault (&this->hp, this->hp); + addItemToVault (&this->ep, this->ep); + + calculateFogOfWarRadius (); + +// if(isUnitDeleted(this) == true) { +// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); +// deletedUnits.erase(this); +// } + + logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), + __LINE__); } - computeTotalUpgrade(); + Unit::~Unit () + { + badHarvestPosList.clear (); - //starting skill - this->lastModelIndexForCurrSkillType = -1; - this->animationRandomCycleCount = 0; - this->currSkill = getType()->getFirstStOfClass(scStop); - this->setCurrSkill(this->currSkill); - this->currentAttackBoostOriginatorEffect.skillType = this->currSkill; + this->faction->deleteLivingUnits (id); + this->faction->deleteLivingUnitsp (this); - this->faction->addLivingUnits(id); - this->faction->addLivingUnitsp(this); + //remove commands + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - addItemToVault(&this->hp,this->hp); - addItemToVault(&this->ep,this->ep); + changedActiveCommand = false; + while (commands.empty () == false) + { + delete commands.back (); + commands.pop_back (); + } + safeMutex.ReleaseLock (); - calculateFogOfWarRadius(); + cleanupAllParticlesystems (); -// if(isUnitDeleted(this) == true) { -// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); -// deletedUnits.erase(this); -// } + while (currentAttackBoostEffects.empty () == false) + { + //UnitAttackBoostEffect &effect = currentAttackBoostEffects.back(); + UnitAttackBoostEffect *ab = currentAttackBoostEffects.back (); + delete ab; + currentAttackBoostEffects.pop_back (); + } - logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -} + delete currentAttackBoostOriginatorEffect.currentAppliedEffect; + currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; -Unit::~Unit() { - badHarvestPosList.clear(); - - this->faction->deleteLivingUnits(id); - this->faction->deleteLivingUnitsp(this); - - //remove commands - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); - - changedActiveCommand = false; - while(commands.empty() == false) { - delete commands.back(); - commands.pop_back(); - } - safeMutex.ReleaseLock(); - - cleanupAllParticlesystems(); - - while(currentAttackBoostEffects.empty() == false) { - //UnitAttackBoostEffect &effect = currentAttackBoostEffects.back(); - UnitAttackBoostEffect *ab = currentAttackBoostEffects.back(); - delete ab; - currentAttackBoostEffects.pop_back(); - } - - delete currentAttackBoostOriginatorEffect.currentAppliedEffect; - currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; - - //Renderer::getInstance().cleanupParticleSystems(attackParticleSystems,rsGame); - Renderer::getInstance().removeParticleSystemsForParticleOwner(this,rsGame); + //Renderer::getInstance().cleanupParticleSystems(attackParticleSystems,rsGame); + Renderer::getInstance ().removeParticleSystemsForParticleOwner (this, + rsGame); #ifdef LEAK_CHECK_UNITS - Unit::mapMemoryList2[this->unitPath] = this->getId(); + Unit::mapMemoryList2[this->unitPath] = this->getId (); #endif - delete this->unitPath; - this->unitPath = NULL; + delete this->unitPath; + this->unitPath = NULL; - Renderer &renderer= Renderer::getInstance(); - renderer.removeUnitFromQuadCache(this); - if(game != NULL) { - game->removeUnitFromSelection(this); - } + Renderer & renderer = Renderer::getInstance (); + renderer.removeUnitFromQuadCache (this); + if (game != NULL) + { + game->removeUnitFromSelection (this); + } - //MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); - //deletedUnits[this]=true; + //MutexSafeWrapper safeMutex1(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); + //deletedUnits[this]=true; - delete mutexCommands; - mutexCommands=NULL; + delete mutexCommands; + mutexCommands = NULL; #ifdef LEAK_CHECK_UNITS - Unit::mapMemoryList.erase(this); + Unit::mapMemoryList.erase (this); #endif -} + } -void Unit::cleanupAllParticlesystems() { + void Unit::cleanupAllParticlesystems () + { - Renderer::getInstance().cleanupUnitParticleSystems(unitParticleSystems,rsGame); + Renderer::getInstance (). + cleanupUnitParticleSystems (unitParticleSystems, rsGame); - Renderer::getInstance().cleanupParticleSystems(fireParticleSystems,rsGame); - // Must set this to null of it will be used below in stopDamageParticles() + Renderer::getInstance ().cleanupParticleSystems (fireParticleSystems, + rsGame); + // Must set this to null of it will be used below in stopDamageParticles() - if(Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) { - this->fire = NULL; - } + if (Renderer::getInstance (). + validateParticleSystemStillExists (this->fire, rsGame) == false) + { + this->fire = NULL; + } - // fade(and by this remove) all unit particle systems - queuedUnitParticleSystemTypes.clear(); - while(unitParticleSystems.empty() == false) { - if(Renderer::getInstance().validateParticleSystemStillExists(unitParticleSystems.back(),rsGame) == true) { - unitParticleSystems.back()->fade(); - } - unitParticleSystems.pop_back(); - } - stopDamageParticles(true); + // fade(and by this remove) all unit particle systems + queuedUnitParticleSystemTypes.clear (); + while (unitParticleSystems.empty () == false) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists (unitParticleSystems.back (), + rsGame) == true) + { + unitParticleSystems.back ()->fade (); + } + unitParticleSystems.pop_back (); + } + stopDamageParticles (true); -} + } -ParticleSystem * Unit::getFire() const { - if(this->fire != NULL && - Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) { - return NULL; - } - return this->fire; -} + ParticleSystem *Unit::getFire () const + { + if (this->fire != NULL && + Renderer::getInstance ().validateParticleSystemStillExists (this-> + fire, + rsGame) + == false) + { + return NULL; + } + return this->fire; + } -void Unit::setType(const UnitType *newType) { - this->faction->notifyUnitTypeChange(this, newType); - this->type = newType; -} + void Unit::setType (const UnitType * newType) + { + this->faction->notifyUnitTypeChange (this, newType); + this->type = newType; + } -void Unit::setAlive(bool value) { - this->alive = value; - this->faction->notifyUnitAliveStatusChange(this); -} + void Unit::setAlive (bool value) + { + this->alive = value; + this->faction->notifyUnitAliveStatusChange (this); + } #ifdef LEAK_CHECK_UNITS -void Unit::dumpMemoryList() { - printf("===== START report of Unfreed Unit pointers =====\n"); - for(std::map::iterator iterMap = Unit::mapMemoryList.begin(); - iterMap != Unit::mapMemoryList.end(); ++iterMap) { - printf("************** ==> Unfreed Unit pointer [%p]\n",iterMap->first); - } -} + void Unit::dumpMemoryList () + { + printf ("===== START report of Unfreed Unit pointers =====\n"); + for (std::map < Unit *, bool >::iterator iterMap = + Unit::mapMemoryList.begin (); + iterMap != Unit::mapMemoryList.end (); ++iterMap) + { + printf ("************** ==> Unfreed Unit pointer [%p]\n", + iterMap->first); + } + } #endif -bool Unit::isNetworkCRCEnabled() { - bool isNetworkCRCEnabled = false; + bool Unit::isNetworkCRCEnabled () + { + bool isNetworkCRCEnabled = false; - if(game != NULL) { - if(game->isFlagType1BitEnabled(ft1_network_synch_checks_verbose) == true) { - isNetworkCRCEnabled = true; - } - else if(game->isFlagType1BitEnabled(ft1_network_synch_checks) == true) { - isNetworkCRCEnabled = true; - } - } - return isNetworkCRCEnabled; -} + if (game != NULL) + { + if (game->isFlagType1BitEnabled (ft1_network_synch_checks_verbose) == + true) + { + isNetworkCRCEnabled = true; + } + else if (game->isFlagType1BitEnabled (ft1_network_synch_checks) == + true) + { + isNetworkCRCEnabled = true; + } + } + return isNetworkCRCEnabled; + } -void Unit::clearNetworkCRCDecHpList() { - if(networkCRCDecHpList.empty() == false) { - networkCRCDecHpList.clear(); - } -} -void Unit::clearParticleInfo() { - if(networkCRCParticleInfoList.empty() == false) { - networkCRCParticleInfoList.clear(); - } -} + void Unit::clearNetworkCRCDecHpList () + { + if (networkCRCDecHpList.empty () == false) + { + networkCRCDecHpList.clear (); + } + } + void Unit::clearParticleInfo () + { + if (networkCRCParticleInfoList.empty () == false) + { + networkCRCParticleInfoList.clear (); + } + } -void Unit::addNetworkCRCDecHp(string info) { - if(isNetworkCRCEnabled() == true) { - networkCRCDecHpList.push_back(info); - } -} + void Unit::addNetworkCRCDecHp (string info) + { + if (isNetworkCRCEnabled () == true) + { + networkCRCDecHpList.push_back (info); + } + } -void Unit::logParticleInfo(string info) { - if(isNetworkCRCEnabled() == true) { - networkCRCParticleInfoList.push_back(info); - } -} -string Unit::getParticleInfo() const { - string result = ""; - if(networkCRCParticleInfoList.empty() == false) { - for(unsigned int index = 0; index < networkCRCParticleInfoList.size(); ++index) { - result += networkCRCParticleInfoList[index] + "|"; - } - } - return result; -} + void Unit::logParticleInfo (string info) + { + if (isNetworkCRCEnabled () == true) + { + networkCRCParticleInfoList.push_back (info); + } + } + string Unit::getParticleInfo () const + { + string result = ""; + if (networkCRCParticleInfoList.empty () == false) + { + for (unsigned int index = 0; + index < networkCRCParticleInfoList.size (); ++index) + { + result += networkCRCParticleInfoList[index] + "|"; + } + } + return result; + } -void Unit::end(ParticleSystem *particleSystem) { - if(particleSystem == fire) { - fire = NULL; - } + void Unit::end (ParticleSystem * particleSystem) + { + if (particleSystem == fire) + { + fire = NULL; + } - vector::iterator iterFind = find(attackParticleSystems.begin(),attackParticleSystems.end(),particleSystem); - if(iterFind != attackParticleSystems.end()) { - attackParticleSystems.erase(iterFind); - return; - } - vector::iterator iterFind1 = find(smokeParticleSystems.begin(),smokeParticleSystems.end(),particleSystem); - if(iterFind1 != smokeParticleSystems.end()) { - smokeParticleSystems.erase(iterFind1); - return; - } - iterFind = find(fireParticleSystems.begin(),fireParticleSystems.end(),particleSystem); - if(iterFind != fireParticleSystems.end()) { - fireParticleSystems.erase(iterFind); - return; - } - iterFind1 = find(damageParticleSystems.begin(),damageParticleSystems.end(),particleSystem); - if(iterFind1 != damageParticleSystems.end()) { - damageParticleSystems.erase(iterFind1); - return; - } + vector < ParticleSystem * >::iterator iterFind = + find (attackParticleSystems.begin (), attackParticleSystems.end (), + particleSystem); + if (iterFind != attackParticleSystems.end ()) + { + attackParticleSystems.erase (iterFind); + return; + } + vector < UnitParticleSystem * >::iterator iterFind1 = + find (smokeParticleSystems.begin (), smokeParticleSystems.end (), + particleSystem); + if (iterFind1 != smokeParticleSystems.end ()) + { + smokeParticleSystems.erase (iterFind1); + return; + } + iterFind = + find (fireParticleSystems.begin (), fireParticleSystems.end (), + particleSystem); + if (iterFind != fireParticleSystems.end ()) + { + fireParticleSystems.erase (iterFind); + return; + } + iterFind1 = + find (damageParticleSystems.begin (), damageParticleSystems.end (), + particleSystem); + if (iterFind1 != damageParticleSystems.end ()) + { + damageParticleSystems.erase (iterFind1); + return; + } - iterFind1 = find(unitParticleSystems.begin(),unitParticleSystems.end(),particleSystem); - if(iterFind1 != unitParticleSystems.end()) { - unitParticleSystems.erase(iterFind1); - return; - } -} + iterFind1 = + find (unitParticleSystems.begin (), unitParticleSystems.end (), + particleSystem); + if (iterFind1 != unitParticleSystems.end ()) + { + unitParticleSystems.erase (iterFind1); + return; + } + } //bool Unit::isUnitDeleted(void *unit) { -// bool result = false; -// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); -// if(deletedUnits.find(unit) != deletedUnits.end()) { -// result = true; -// } -// return result; +// bool result = false; +// MutexSafeWrapper safeMutex(&mutexDeletedUnits,string(__FILE__) + "_" + intToStr(__LINE__)); +// if(deletedUnits.find(unit) != deletedUnits.end()) { +// result = true; +// } +// return result; //} -void Unit::setModelFacing(CardinalDir value) { - modelFacing = value; - lastRotation = targetRotation = rotation = value * 90.f; -} + void Unit::setModelFacing (CardinalDir value) + { + modelFacing = value; + lastRotation = targetRotation = rotation = value * 90.f; + } //void Unit::setCurrField(Field currField) { -// Field original_field = this->currField; +// Field original_field = this->currField; // -// this->currField = currField; +// this->currField = currField; // -// if(original_field != this->currField) { -// //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -// game->getScriptManager()->onUnitTriggerEvent(this,utet_FieldChanged); -// //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -// } +// if(original_field != this->currField) { +// //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); +// game->getScriptManager()->onUnitTriggerEvent(this,utet_FieldChanged); +// //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); +// } //} // ====================================== get ====================================== -Vec2i Unit::getCenteredPos() const { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + Vec2i Unit::getCenteredPos () const + { + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - return pos + Vec2i(type->getSize()/2, type->getSize()/2); -} + return pos + Vec2i (type->getSize () / 2, type->getSize () / 2); + } -Vec2f Unit::getFloatCenteredPos() const { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + Vec2f Unit::getFloatCenteredPos () const + { + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - return Vec2f(truncateDecimal(pos.x-0.5f+type->getSize()/2.f,6), - truncateDecimal(pos.y-0.5f+type->getSize()/2.f,6)); -} + return Vec2f (truncateDecimal < + float >(pos.x - 0.5f + type->getSize () / 2.f, 6), + truncateDecimal < + float >(pos.y - 0.5f + type->getSize () / 2.f, 6)); + } -Vec2i Unit::getCellPos() const { - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + Vec2i Unit::getCellPos () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - if(type->hasCellMap()) { - if( type->hasEmptyCellMap() == false || - type->getAllowEmptyCellMap() == true) { + if (type->hasCellMap ()) + { + if (type->hasEmptyCellMap () == false || + type->getAllowEmptyCellMap () == true) + { - //find nearest pos to center that is free - Vec2i centeredPos= getCenteredPos(); - float nearestDist= -1.f; - Vec2i nearestPos= pos; + //find nearest pos to center that is free + Vec2i centeredPos = getCenteredPos (); + float nearestDist = -1.f; + Vec2i nearestPos = pos; - for(int i=0; igetSize(); ++i){ - for(int j=0; jgetSize(); ++j){ - if(type->getCellMapCell(i, j, modelFacing)){ - Vec2i currPos= pos + Vec2i(i, j); - float dist= currPos.dist(centeredPos); - if(nearestDist == -1.f || dist < nearestDist) { - nearestDist= dist; - nearestPos= currPos; - } - } - } - } - return nearestPos; - } - } - return pos; -} + for (int i = 0; i < type->getSize (); ++i) + { + for (int j = 0; j < type->getSize (); ++j) + { + if (type->getCellMapCell (i, j, modelFacing)) + { + Vec2i currPos = pos + Vec2i (i, j); + float dist = currPos.dist (centeredPos); + if (nearestDist == -1.f || dist < nearestDist) + { + nearestDist = dist; + nearestPos = currPos; + } + } + } + } + return nearestPos; + } + } + return pos; + } -void Unit::calculateXZRotation(){ - //if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ - //if(currSkill->getClass()==scMove) - if(lastPos != pos){ // targetPosCalc ( maybe also sometimes needed if no move ? terrain flatting... ) - SurfaceCell* sc= map->getSurfaceCell(Map::toSurfCoords(pos)); - const Vec3f normal= sc->getNormal(); + void Unit::calculateXZRotation () + { + //if(type->getProperty(UnitType::pRotatedClimb) && currSkill->getClass()==scMove){ + //if(currSkill->getClass()==scMove) + if (lastPos != pos) + { // targetPosCalc ( maybe also sometimes needed if no move ? terrain flatting... ) + SurfaceCell *sc = map->getSurfaceCell (Map::toSurfCoords (pos)); + const Vec3f normal = sc->getNormal (); #ifdef USE_STREFLOP - targetRotationZ= radToDeg(streflop::atan2(static_cast(abs(normal.x)), static_cast(abs(normal.y)))); + targetRotationZ = + radToDeg (streflop:: + atan2 (static_cast < streflop::Simple > (abs (normal.x)), + static_cast < streflop::Simple > + (abs (normal.y)))); #else - targetRotationZ= radToDeg(atan2(abs(normal.x), abs(normal.y))); + targetRotationZ = radToDeg (atan2 (abs (normal.x), abs (normal.y))); #endif - if((normal.y < 0 || normal.x < 0) && !(normal.y < 0 && normal.x < 0)){ - targetRotationZ= targetRotationZ * -1; - } - targetRotationZ= targetRotationZ * -1; + if ((normal.y < 0 || normal.x < 0) && !(normal.y < 0 && normal.x < 0)) + { + targetRotationZ = targetRotationZ * -1; + } + targetRotationZ = targetRotationZ * -1; #ifdef USE_STREFLOP - targetRotationX= radToDeg(streflop::atan2(static_cast(abs(normal.z)), static_cast(abs(normal.y)))); + targetRotationX = + radToDeg (streflop:: + atan2 (static_cast < streflop::Simple > (abs (normal.z)), + static_cast < streflop::Simple > + (abs (normal.y)))); #else - targetRotationX= radToDeg(atan2(abs(normal.z), abs(normal.y))); + targetRotationX = radToDeg (atan2 (abs (normal.z), abs (normal.y))); #endif - if((normal.y < 0 || normal.z < 0) && !(normal.y < 0 && normal.z < 0)){ - targetRotationX= targetRotationX * -1; - } - } + if ((normal.y < 0 || normal.z < 0) && !(normal.y < 0 && normal.z < 0)) + { + targetRotationX = targetRotationX * -1; + } + } - //For smooth rotation we now softly adjust the angle - int adjustStep= 1; - if(rotationZ < targetRotationZ){ - if(rotationZ + adjustStep > targetRotationZ){ - rotationZ= targetRotationZ; - } - else{ - rotationZ= rotationZ + adjustStep; - } - } - else if(rotationZ > targetRotationZ){ - if(rotationZ - adjustStep < targetRotationZ){ - rotationZ= targetRotationZ; - } - else{ - rotationZ= rotationZ - adjustStep; - } - } + //For smooth rotation we now softly adjust the angle + int adjustStep = 1; + if (rotationZ < targetRotationZ) + { + if (rotationZ + adjustStep > targetRotationZ) + { + rotationZ = targetRotationZ; + } + else + { + rotationZ = rotationZ + adjustStep; + } + } + else if (rotationZ > targetRotationZ) + { + if (rotationZ - adjustStep < targetRotationZ) + { + rotationZ = targetRotationZ; + } + else + { + rotationZ = rotationZ - adjustStep; + } + } - if(rotationX < targetRotationX){ - if(rotationX + adjustStep > targetRotationX){ - rotationX= targetRotationX; - } - else{ - rotationX= rotationX + adjustStep; - } - } - else if(rotationX > targetRotationX){ - if(rotationX - adjustStep < targetRotationX){ - rotationX= targetRotationX; - } - else{ - rotationX= rotationX - adjustStep; - } - } -} + if (rotationX < targetRotationX) + { + if (rotationX + adjustStep > targetRotationX) + { + rotationX = targetRotationX; + } + else + { + rotationX = rotationX + adjustStep; + } + } + else if (rotationX > targetRotationX) + { + if (rotationX - adjustStep < targetRotationX) + { + rotationX = targetRotationX; + } + else + { + rotationX = rotationX - adjustStep; + } + } + } -float Unit::getRotationZ() const{ - return rotationZ; -} + float Unit::getRotationZ () const + { + return rotationZ; + } -float Unit::getRotationX() const{ - return rotationX; -} + float Unit::getRotationX () const + { + return rotationX; + } -int Unit::getProductionPercent() const{ - if(anyCommand()){ - const ProducibleType *produced= commands.front()->getCommandType()->getProduced(); - if(produced != NULL) { - if(produced->getProductionTime() == 0) { - return 0; - } - return clamp(progress2 * 100 / produced->getProductionTime(), 0, 100); - } - } - return -1; -} + int Unit::getProductionPercent () const + { + if (anyCommand ()) + { + const ProducibleType *produced = + commands.front ()->getCommandType ()->getProduced (); + if (produced != NULL) + { + if (produced->getProductionTime () == 0) + { + return 0; + } + return clamp (progress2 * 100 / produced->getProductionTime (), 0, + 100); + } + } + return -1; + } -float Unit::getProgressRatio() const{ - if(anyCommand()){ - const ProducibleType *produced= commands.front()->getCommandType()->getProduced(); - if(produced != NULL){ - if(produced->getProductionTime() == 0) { - return 0.f; - } + float Unit::getProgressRatio () const + { + if (anyCommand ()) + { + const ProducibleType *produced = + commands.front ()->getCommandType ()->getProduced (); + if (produced != NULL) + { + if (produced->getProductionTime () == 0) + { + return 0.f; + } - float help = progress2; - return clamp(help / produced->getProductionTime(), 0.f, 1.f); - } - } - return -1; -} + float help = progress2; + return clamp (help / produced->getProductionTime (), 0.f, 1.f); + } + } + return -1; + } -float Unit::getHpRatio() const { - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + float Unit::getHpRatio () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - float maxHpAllowed = type->getTotalMaxHp(&totalUpgrade); - if(maxHpAllowed == 0.f) { - return 0.f; - } - return clamp(static_cast(hp) / maxHpAllowed, 0.f, 1.f); -} + float maxHpAllowed = type->getTotalMaxHp (&totalUpgrade); + if (maxHpAllowed == 0.f) + { + return 0.f; + } + return clamp (static_cast < float >(hp) / maxHpAllowed, 0.f, 1.f); + } -float Unit::getEpRatio() const { - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + float Unit::getEpRatio () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - if(type->getTotalMaxHp(&totalUpgrade) == 0) { - return 0.f; - } - else { - float maxEpAllowed = type->getTotalMaxEp(&totalUpgrade); - if(maxEpAllowed == 0.f) { - return 0.f; - } - return clamp(static_cast(ep) / maxEpAllowed, 0.f, 1.f); - } -} + if (type->getTotalMaxHp (&totalUpgrade) == 0) + { + return 0.f; + } + else + { + float maxEpAllowed = type->getTotalMaxEp (&totalUpgrade); + if (maxEpAllowed == 0.f) + { + return 0.f; + } + return clamp (static_cast < float >(ep) / maxEpAllowed, 0.f, 1.f); + } + } -const Level *Unit::getNextLevel() const{ - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + const Level *Unit::getNextLevel () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - if(level == NULL && type->getLevelCount() > 0) { - return type->getLevel(0); - } - else { - for(int i=1; igetLevelCount(); ++i){ - if(type->getLevel(i-1)==level){ - return type->getLevel(i); - } - } - } - return NULL; -} + if (level == NULL && type->getLevelCount () > 0) + { + return type->getLevel (0); + } + else + { + for (int i = 1; i < type->getLevelCount (); ++i) + { + if (type->getLevel (i - 1) == level) + { + return type->getLevel (i); + } + } + } + return NULL; + } -string Unit::getFullName(bool translatedValue) const{ - string str=""; - if(level != NULL){ - str += (level->getName(translatedValue) + " "); - } - if(type == NULL) { - throw megaglest_runtime_error("type == NULL in Unit::getFullName()!"); - } - str += type->getName(translatedValue); - return str; -} + string Unit::getFullName (bool translatedValue) const + { + string str = ""; + if (level != NULL) + { + str += (level->getName (translatedValue) + " "); + } + if (type == NULL) + { + throw + megaglest_runtime_error ("type == NULL in Unit::getFullName()!"); + } + str += type->getName (translatedValue); + return str; + } // ====================================== is ====================================== -bool Unit::isOperative() const{ - return isAlive() && isBuilt(); -} - -bool Unit::isAnimProgressBound() const{ - if(currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - bool result = false; - if(currSkill->getClass() == scBeBuilt) { - const BeBuiltSkillType *skill = dynamic_cast(currSkill); - if(skill != NULL) { - result = skill->getAnimProgressBound(); - } + bool Unit::isOperative () const + { + return isAlive () && isBuilt (); } - else if(currSkill->getClass() == scProduce) { - const ProduceSkillType *skill = dynamic_cast(currSkill); - if(skill != NULL) { - result = skill->getAnimProgressBound(); - } + + bool Unit::isAnimProgressBound () const + { + if (currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + bool result = false; + if (currSkill->getClass () == scBeBuilt) + { + const BeBuiltSkillType *skill = + dynamic_cast < const BeBuiltSkillType * >(currSkill); + if (skill != NULL) + { + result = skill->getAnimProgressBound (); + } + } + else if (currSkill->getClass () == scProduce) + { + const ProduceSkillType *skill = + dynamic_cast < const ProduceSkillType * >(currSkill); + if (skill != NULL) + { + result = skill->getAnimProgressBound (); + } + } + else if (currSkill->getClass () == scUpgrade) + { + const UpgradeSkillType *skill = + dynamic_cast < const UpgradeSkillType * >(currSkill); + if (skill != NULL) + { + result = skill->getAnimProgressBound (); + } + } + else if (currSkill->getClass () == scMorph) + { + const MorphSkillType *skill = + dynamic_cast < const MorphSkillType * >(currSkill); + if (skill != NULL) + { + result = skill->getAnimProgressBound (); + } + } + return result; } - else if(currSkill->getClass() == scUpgrade) { - const UpgradeSkillType *skill = dynamic_cast(currSkill); - if(skill != NULL) { - result = skill->getAnimProgressBound(); - } + + bool Unit::isBeingBuilt () const + { + if (currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + return (currSkill->getClass () == scBeBuilt); } - else if(currSkill->getClass() == scMorph) { - const MorphSkillType *skill = dynamic_cast(currSkill); - if(skill != NULL) { - result = skill->getAnimProgressBound(); - } + + bool Unit::isBuilt () const + { + return (isBeingBuilt () == false); } - return result; -} -bool Unit::isBeingBuilt() const{ - if(currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + bool Unit::isBuildCommandPending () const + { + bool result = false; - return (currSkill->getClass() == scBeBuilt); -} + Command *command = this->getCurrCommand (); + if (command != NULL) + { + const BuildCommandType *bct = + dynamic_cast < + const BuildCommandType * >(command->getCommandType ()); + if (bct != NULL) + { + if (this->getCurrSkill ()->getClass () != scBuild) + { + result = true; + } + } + } -bool Unit::isBuilt() const{ - return (isBeingBuilt() == false); -} + return result; + } -bool Unit::isBuildCommandPending() const { - bool result = false; + UnitBuildInfo Unit::getBuildCommandPendingInfo () const + { + UnitBuildInfo result; - Command *command= this->getCurrCommand(); - if(command != NULL) { - const BuildCommandType *bct= dynamic_cast(command->getCommandType()); - if(bct != NULL) { - if(this->getCurrSkill()->getClass() != scBuild) { - result = true; - } - } - } + Command *command = this->getCurrCommand (); + if (command != NULL) + { + const BuildCommandType *bct = + dynamic_cast < + const BuildCommandType * >(command->getCommandType ()); + if (bct != NULL) + { + result.pos = command->getOriginalPos (); + result.facing = command->getFacing (); + result.buildUnit = command->getUnitType (); + result.unit = this; + } + } - return result; -} + return result; + } -UnitBuildInfo Unit::getBuildCommandPendingInfo() const { - UnitBuildInfo result; + bool Unit::isAlly (const Unit * unit) const + { + if (unit == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - Command *command= this->getCurrCommand(); - if(command != NULL) { - const BuildCommandType *bct= dynamic_cast(command->getCommandType()); - if(bct != NULL) { - result.pos = command->getOriginalPos(); - result.facing = command->getFacing(); - result.buildUnit = command->getUnitType(); - result.unit = this; - } - } + return faction->isAlly (unit->getFaction ()); + } - return result; -} + bool Unit::isDamaged () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } -bool Unit::isAlly(const Unit *unit) const { - if(unit == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + return hp < type->getTotalMaxHp (&totalUpgrade); + } - return faction->isAlly(unit->getFaction()); -} + bool Unit::isInteresting (InterestingUnitType iut) const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } -bool Unit::isDamaged() const { - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + switch (iut) + { + case iutIdleHarvester: + if (type->hasCommandClass (ccHarvest)) + { + if (commands.empty () == false) + { + const CommandType *ct = commands.front ()->getCommandType (); + if (ct != NULL) + { + return ct->getClass () == ccStop; + } + } + } + return false; - return hp < type->getTotalMaxHp(&totalUpgrade); -} - -bool Unit::isInteresting(InterestingUnitType iut) const { - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - switch(iut) { - case iutIdleHarvester: - if(type->hasCommandClass(ccHarvest)) { - if(commands.empty() == false) { - const CommandType *ct= commands.front()->getCommandType(); - if(ct != NULL){ - return ct->getClass() == ccStop; - } - } - } - return false; - - case iutBuiltBuilding: - return type->hasSkillClass(scBeBuilt) && isBuilt(); - case iutProducer: - return type->hasSkillClass(scProduce); - case iutDamaged: - return isDamaged(); - case iutStore: - return type->getStoredResourceCount()>0; - default: - return false; - } -} + case iutBuiltBuilding: + return type->hasSkillClass (scBeBuilt) && isBuilt (); + case iutProducer: + return type->hasSkillClass (scProduce); + case iutDamaged: + return isDamaged (); + case iutStore: + return type->getStoredResourceCount () > 0; + default: + return false; + } + } // ====================================== set ====================================== -void Unit::setCurrSkill(const SkillType *currSkill) { - if(currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - if(this->currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: this->currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + void Unit::setCurrSkill (const SkillType * currSkill) + { + if (currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + if (this->currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: this->currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - if(this->currSkill->getClass() == scMove && - currSkill->getClass() != scMove) { - faction->removeUnitFromMovingList(this->getId()); - } - else if(this->currSkill->getClass() != scMove && - currSkill->getClass() == scMove) { - faction->addUnitToMovingList(this->getId()); - } + if (this->currSkill->getClass () == scMove && + currSkill->getClass () != scMove) + { + faction->removeUnitFromMovingList (this->getId ()); + } + else if (this->currSkill->getClass () != scMove && + currSkill->getClass () == scMove) + { + faction->addUnitToMovingList (this->getId ()); + } - changedActiveCommand = false; - if( currSkill->getClass() != this->currSkill->getClass() || - currSkill->getName() != this->currSkill->getName()) { - this->animProgress= 0; - this->lastAnimProgress= 0; + changedActiveCommand = false; + if (currSkill->getClass () != this->currSkill->getClass () || + currSkill->getName () != this->currSkill->getName ()) + { + this->animProgress = 0; + this->lastAnimProgress = 0; - queuedUnitParticleSystemTypes.clear(); - while(unitParticleSystems.empty() == false) { - if(Renderer::getInstance().validateParticleSystemStillExists(unitParticleSystems.back(),rsGame) == true) { - unitParticleSystems.back()->fade(); - } - unitParticleSystems.pop_back(); - } + queuedUnitParticleSystemTypes.clear (); + while (unitParticleSystems.empty () == false) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists (unitParticleSystems.back (), + rsGame) == true) + { + unitParticleSystems.back ()->fade (); + } + unitParticleSystems.pop_back (); + } - Command *cmd = getCurrrentCommandThreadSafe(); + Command *cmd = getCurrrentCommandThreadSafe (); - // Set mew fog of war skill type if need be - if(cmd != NULL && cmd->getCommandType() != NULL && - cmd->getCommandType()->hasFogOfWarSkillType(currSkill->getName())) { - const FogOfWarSkillType *fowst = cmd->getCommandType()->getFogOfWarSkillType(); + // Set mew fog of war skill type if need be + if (cmd != NULL && cmd->getCommandType () != NULL && + cmd->getCommandType ()->hasFogOfWarSkillType (currSkill-> + getName ())) + { + const FogOfWarSkillType *fowst = + cmd->getCommandType ()->getFogOfWarSkillType (); - // Remove old fog of war skill type if need be - game->getWorld()->removeFogOfWarSkillTypeFromList(this); + // Remove old fog of war skill type if need be + game->getWorld ()->removeFogOfWarSkillTypeFromList (this); - game->getWorld()->addFogOfWarSkillType(this,fowst); - } - else { - // Remove old fog of war skill type if need be - game->getWorld()->removeFogOfWarSkillType(this); - } - } - if(showUnitParticles == true && - currSkill->unitParticleSystemTypes.empty() == false && - unitParticleSystems.empty() == true) { - //printf("START - particle system type\n"); + game->getWorld ()->addFogOfWarSkillType (this, fowst); + } + else + { + // Remove old fog of war skill type if need be + game->getWorld ()->removeFogOfWarSkillType (this); + } + } + if (showUnitParticles == true && + currSkill->unitParticleSystemTypes.empty () == false && + unitParticleSystems.empty () == true) + { + //printf("START - particle system type\n"); - /* - for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); - it != currSkill->unitParticleSystemTypes.end(); ++it) { - if((*it)->getStartTime() == 0.0) { - //printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); + /* + for(UnitParticleSystemTypes::const_iterator it= currSkill->unitParticleSystemTypes.begin(); + it != currSkill->unitParticleSystemTypes.end(); ++it) { + if((*it)->getStartTime() == 0.0) { + //printf("Adding NON-queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); - UnitParticleSystem *ups = new UnitParticleSystem(200); - ups->setParticleOwner(this); - ups->setParticleType((*it)); + UnitParticleSystem *ups = new UnitParticleSystem(200); + ups->setParticleOwner(this); + ups->setParticleType((*it)); - (*it)->setValues(ups); - ups->setPos(getCurrVector()); - ups->setRotation(getRotation()); - ups->setUnitModel(getCurrentModelPtr()); - if(getFaction()->getTexture()) { - ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - unitParticleSystems.push_back(ups); - Renderer::getInstance().manageParticleSystem(ups, rsGame); - } - else { - //printf("Adding queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); + (*it)->setValues(ups); + ups->setPos(getCurrVector()); + ups->setRotation(getRotation()); + ups->setUnitModel(getCurrentModelPtr()); + if(getFaction()->getTexture()) { + ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); + } + unitParticleSystems.push_back(ups); + Renderer::getInstance().manageParticleSystem(ups, rsGame); + } + else { + //printf("Adding queued particle system type [%s] [%f] [%f]\n",(*it)->getType().c_str(),(*it)->getStartTime(),(*it)->getEndTime()); - queuedUnitParticleSystemTypes.push_back(*it); - } - } - */ - checkCustomizedUnitParticleListTriggers(currSkill->unitParticleSystemTypes,true); - } + queuedUnitParticleSystemTypes.push_back(*it); + } + } + */ + checkCustomizedUnitParticleListTriggers (currSkill-> + unitParticleSystemTypes, + true); + } - if(this->currSkill != currSkill) { - this->lastModelIndexForCurrSkillType = -1; - this->animationRandomCycleCount = 0; - } + if (this->currSkill != currSkill) + { + this->lastModelIndexForCurrSkillType = -1; + this->animationRandomCycleCount = 0; + } - if(faction != NULL) faction->notifyUnitSkillTypeChange(this, currSkill); - const SkillType *original_skill = this->currSkill; - this->currSkill= currSkill; + if (faction != NULL) + faction->notifyUnitSkillTypeChange (this, currSkill); + const SkillType *original_skill = this->currSkill; + this->currSkill = currSkill; - if(original_skill != this->currSkill) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_SkillChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } -} + if (original_skill != this->currSkill) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_SkillChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + } -void Unit::setCurrSkill(SkillClass sc) { - if(getType() == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + void Unit::setCurrSkill (SkillClass sc) + { + if (getType () == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - setCurrSkill(getType()->getFirstStOfClass(sc)); -} + setCurrSkill (getType ()->getFirstStOfClass (sc)); + } -void Unit::setTarget(const Unit *unit){ + void Unit::setTarget (const Unit * unit) + { - if(unit == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + if (unit == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: unit == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - //find a free pos in cellmap - setTargetPos(unit->getCellPos()); + //find a free pos in cellmap + setTargetPos (unit->getCellPos ()); - //ser field and vector - targetField= unit->getCurrField(); - targetVec= unit->getCurrVectorAsTarget(); - targetRef= unit; -} + //ser field and vector + targetField = unit->getCurrField (); + targetVec = unit->getCurrVectorAsTarget (); + targetRef = unit; + } -RandomGen* Unit::getRandom(bool threadAccessAllowed) { - if(threadAccessAllowed == false && Thread::isCurrentThreadMainThread() == false) { - throw megaglest_runtime_error("Invalid access to unit random from outside main thread current id = " + - intToStr(Thread::getCurrentThreadId()) + " main = " + intToStr(Thread::getMainThreadId())); - } - return &random; -} + RandomGen *Unit::getRandom (bool threadAccessAllowed) + { + if (threadAccessAllowed == false + && Thread::isCurrentThreadMainThread () == false) + { + throw + megaglest_runtime_error + ("Invalid access to unit random from outside main thread current id = " + + intToStr (Thread::getCurrentThreadId ()) + " main = " + + intToStr (Thread::getMainThreadId ())); + } + return &random; + } -void Unit::setPos(const Vec2i &pos, bool clearPathFinder, bool threaded) { - if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { - throw megaglest_runtime_error("#3 Invalid path position = " + pos.getString()); - } + void Unit::setPos (const Vec2i & pos, bool clearPathFinder, bool threaded) + { + if (map->isInside (pos) == false + || map->isInsideSurface (map->toSurfCoords (pos)) == false) + { + throw megaglest_runtime_error ("#3 Invalid path position = " + + pos.getString ()); + } - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - if(threaded) { - logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - else { - logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } + if (threaded) + { + logSynchDataThreaded (extractFileFromDirectoryPath (__FILE__). + c_str (), __LINE__); + } + else + { + logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), + __LINE__); + } - if(clearPathFinder == true && this->unitPath != NULL) { - this->unitPath->clear(); - } - //Vec2i oldLastPos = this->lastPos; - this->lastPos= this->pos; - this->pos= pos; + if (clearPathFinder == true && this->unitPath != NULL) + { + this->unitPath->clear (); + } + //Vec2i oldLastPos = this->lastPos; + this->lastPos = this->pos; + this->pos = pos; - map->clampPos(this->pos); - this->meetingPos= pos - Vec2i(1); - map->clampPos(this->meetingPos); + map->clampPos (this->pos); + this->meetingPos = pos - Vec2i (1); + map->clampPos (this->meetingPos); - safeMutex.ReleaseLock(); + safeMutex.ReleaseLock (); - refreshPos(); + refreshPos (); - if(threaded) { - logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - else { - logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } -} + if (threaded) + { + logSynchDataThreaded (extractFileFromDirectoryPath (__FILE__). + c_str (), __LINE__); + } + else + { + logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), + __LINE__); + } + } -void Unit::refreshPos(bool forceRefresh) { - // Attempt to improve performance - this->exploreCells(forceRefresh); - calculateFogOfWarRadius(forceRefresh); -} + void Unit::refreshPos (bool forceRefresh) + { + // Attempt to improve performance + this->exploreCells (forceRefresh); + calculateFogOfWarRadius (forceRefresh); + } -FowAlphaCellsLookupItem Unit::getFogOfWarRadius(bool useCache) const { - if(useCache == true) { - return cachedFow; - } + FowAlphaCellsLookupItem Unit::getFogOfWarRadius (bool useCache) const + { + if (useCache == true) + { + return cachedFow; + } - //iterate through all cells - int sightRange= this->getType()->getTotalSight(this->getTotalUpgrade()); - int radius = sightRange + World::indirectSightRange; - PosCircularIterator pci(map, this->getPosNotThreadSafe(), radius); - FowAlphaCellsLookupItem result; - while(pci.next()){ - const Vec2i sightpos= pci.getPos(); - Vec2i surfPos= Map::toSurfCoords(sightpos); + //iterate through all cells + int sightRange = + this->getType ()->getTotalSight (this->getTotalUpgrade ()); + int radius = sightRange + World::indirectSightRange; + PosCircularIterator pci (map, this->getPosNotThreadSafe (), radius); + FowAlphaCellsLookupItem result; + while (pci.next ()) + { + const Vec2i sightpos = pci.getPos (); + Vec2i surfPos = Map::toSurfCoords (sightpos); - //compute max alpha - float maxAlpha= 0.0f; - if(surfPos.x > 1 && surfPos.y > 1 && - surfPos.x < map->getSurfaceW() -2 && - surfPos.y < map->getSurfaceH() -2) { - maxAlpha= 1.f; - } - else if(surfPos.x > 0 && surfPos.y > 0 && - surfPos.x < map->getSurfaceW() -1 && - surfPos.y < map->getSurfaceH() -1) { - maxAlpha= 0.3f; - } + //compute max alpha + float maxAlpha = 0.0f; + if (surfPos.x > 1 && surfPos.y > 1 && + surfPos.x < map->getSurfaceW () - 2 && + surfPos.y < map->getSurfaceH () - 2) + { + maxAlpha = 1.f; + } + else if (surfPos.x > 0 && surfPos.y > 0 && + surfPos.x < map->getSurfaceW () - 1 && + surfPos.y < map->getSurfaceH () - 1) + { + maxAlpha = 0.3f; + } - //compute alpha - float alpha = maxAlpha; - float dist = this->getPosNotThreadSafe().dist(sightpos); - if(dist > sightRange) { - alpha= clamp(1.f-(dist - sightRange) / (World::indirectSightRange), 0.f, maxAlpha); - } - result.surfPosAlphaList[surfPos] = alpha; - } - return result; -} + //compute alpha + float alpha = maxAlpha; + float dist = this->getPosNotThreadSafe ().dist (sightpos); + if (dist > sightRange) + { + alpha = + clamp (1.f - (dist - sightRange) / (World::indirectSightRange), + 0.f, maxAlpha); + } + result.surfPosAlphaList[surfPos] = alpha; + } + return result; + } -void Unit::calculateFogOfWarRadius(bool forceRefresh) { - if(game->getWorld()->getFogOfWar() == true) { - if(forceRefresh || this->pos != this->cachedFowPos) { - cachedFow = getFogOfWarRadius(false); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); - this->cachedFowPos = this->pos; - } - } -} + void Unit::calculateFogOfWarRadius (bool forceRefresh) + { + if (game->getWorld ()->getFogOfWar () == true) + { + if (forceRefresh || this->pos != this->cachedFowPos) + { + cachedFow = getFogOfWarRadius (false); + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); + this->cachedFowPos = this->pos; + } + } + } -void Unit::setTargetPos(const Vec2i &targetPos, bool threaded) { + void Unit::setTargetPos (const Vec2i & targetPos, bool threaded) + { - if(map->isInside(targetPos) == false || map->isInsideSurface(map->toSurfCoords(targetPos)) == false) { - throw megaglest_runtime_error("#4 Invalid path position = " + targetPos.getString()); - } + if (map->isInside (targetPos) == false + || map->isInsideSurface (map->toSurfCoords (targetPos)) == false) + { + throw megaglest_runtime_error ("#4 Invalid path position = " + + targetPos.getString ()); + } - Vec2i relPos= targetPos - pos; - //map->clampPos(relPos); + Vec2i relPos = targetPos - pos; + //map->clampPos(relPos); - Vec2f relPosf= Vec2f((float)relPos.x, (float)relPos.y); + Vec2f relPosf = Vec2f ((float) relPos.x, (float) relPos.y); #ifdef USE_STREFLOP - targetRotation= radToDeg(streflop::atan2(static_cast(relPosf.x), static_cast(relPosf.y))); + targetRotation = + radToDeg (streflop:: + atan2 (static_cast < streflop::Simple > (relPosf.x), + static_cast < streflop::Simple > (relPosf.y))); #else - targetRotation= radToDeg(atan2(relPosf.x, relPosf.y)); + targetRotation = radToDeg (atan2 (relPosf.x, relPosf.y)); #endif - targetRotation = truncateDecimal(targetRotation,6); + targetRotation = truncateDecimal < float >(targetRotation, 6); - targetRef= NULL; + targetRef = NULL; - this->targetPos= targetPos; - map->clampPos(this->targetPos); + this->targetPos = targetPos; + map->clampPos (this->targetPos); - if(threaded) { - logSynchDataThreaded(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - else { - logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } -} + if (threaded) + { + logSynchDataThreaded (extractFileFromDirectoryPath (__FILE__). + c_str (), __LINE__); + } + else + { + logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), + __LINE__); + } + } -void Unit::addAttackParticleSystem(ParticleSystem *ps) { - attackParticleSystems.push_back(ps); -} + void Unit::addAttackParticleSystem (ParticleSystem * ps) + { + attackParticleSystems.push_back (ps); + } -void Unit::setVisible(const bool visible) { - this->visible = visible; + void Unit::setVisible (const bool visible) + { + this->visible = visible; - if(unitParticleSystems.empty() == false) { - for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) { - if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setVisible(visible); - } - } - } - if(damageParticleSystems.empty() == false) { - for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) { - if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setVisible(visible); - } - } - } - if(smokeParticleSystems.empty() == false) { - for(UnitParticleSystems::iterator it= smokeParticleSystems.begin(); it != smokeParticleSystems.end(); ++it) { - if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - if((*it)->getVisible() != visible) { - //printf("Changing visibility for smoke particle system to: %d\n",visible); - (*it)->setVisible(visible); - } - } - } - } + if (unitParticleSystems.empty () == false) + { + for (UnitParticleSystems::iterator it = unitParticleSystems.begin (); + it != unitParticleSystems.end (); ++it) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists ((*it), rsGame) == true) + { + (*it)->setVisible (visible); + } + } + } + if (damageParticleSystems.empty () == false) + { + for (UnitParticleSystems::iterator it = + damageParticleSystems.begin (); + it != damageParticleSystems.end (); ++it) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists ((*it), rsGame) == true) + { + (*it)->setVisible (visible); + } + } + } + if (smokeParticleSystems.empty () == false) + { + for (UnitParticleSystems::iterator it = smokeParticleSystems.begin (); + it != smokeParticleSystems.end (); ++it) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists ((*it), rsGame) == true) + { + if ((*it)->getVisible () != visible) + { + //printf("Changing visibility for smoke particle system to: %d\n",visible); + (*it)->setVisible (visible); + } + } + } + } - //if(attackParticleSystems.empty() == false) { - // for(vector::iterator it= attackParticleSystems.begin(); it != attackParticleSystems.end(); ++it) { - // if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - // Not sure this is a good idea since the unit be not be visible but the attack particle might be. - // This means you won't see the attacking projectile until the unit moves into view. - //(*it)->setVisible(visible); - // } - // } - //} + //if(attackParticleSystems.empty() == false) { + // for(vector::iterator it= attackParticleSystems.begin(); it != attackParticleSystems.end(); ++it) { + // if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { + // Not sure this is a good idea since the unit be not be visible but the attack particle might be. + // This means you won't see the attacking projectile until the unit moves into view. + //(*it)->setVisible(visible); + // } + // } + //} - if(currentAttackBoostEffects.empty() == false) { - for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if(effect != NULL && effect->ups != NULL) { - bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(effect->ups,rsGame); - if(particleValid == true) { - effect->ups->setVisible(visible); - } - } - } - } - if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) { - if(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != NULL) { - bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups,rsGame); - if(particleValid == true) { - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setVisible(visible); - } - } - } -} + if (currentAttackBoostEffects.empty () == false) + { + for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) + { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->ups != NULL) + { + bool particleValid = + Renderer::getInstance (). + validateParticleSystemStillExists (effect->ups, rsGame); + if (particleValid == true) + { + effect->ups->setVisible (visible); + } + } + } + } + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) + { + if (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != + NULL) + { + bool particleValid = + Renderer::getInstance (). + validateParticleSystemStillExists + (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, + rsGame); + if (particleValid == true) + { + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setVisible (visible); + } + } + } + } // =============================== Render related ================================== -Model *Unit::getCurrentModelPtr() { - if(currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + Model *Unit::getCurrentModelPtr () + { + if (currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; - Model *result = currSkill->getAnimation(getAnimProgressAsFloat(),this,&lastModelIndexForCurrSkillType, &animationRandomCycleCount); - if(currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) { - animationRandomCycleCount++; - if(currSkill != NULL && animationRandomCycleCount >= currSkill->getAnimationCount()) { - animationRandomCycleCount = 0; - } - } - return result; -} + int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; + Model *result = + currSkill->getAnimation (getAnimProgressAsFloat (), this, + &lastModelIndexForCurrSkillType, + &animationRandomCycleCount); + if (currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) + { + animationRandomCycleCount++; + if (currSkill != NULL + && animationRandomCycleCount >= currSkill->getAnimationCount ()) + { + animationRandomCycleCount = 0; + } + } + return result; + } //const Model *Unit::getCurrentModel() { -// if(currSkill == NULL) { -// char szBuf[8096]=""; -// snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); -// throw megaglest_runtime_error(szBuf); -// } +// if(currSkill == NULL) { +// char szBuf[8096]=""; +// snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); +// throw megaglest_runtime_error(szBuf); +// } // -// int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; -// const Model *result = currSkill->getAnimation(getAnimProgressAsFloat(),this,&lastModelIndexForCurrSkillType, &animationRandomCycleCount); -// if(currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) { -// animationRandomCycleCount++; -// if(currSkill != NULL && animationRandomCycleCount >= currSkill->getAnimationCount()) { -// animationRandomCycleCount = 0; -// } -// } -// return result; +// int currentModelIndexForCurrSkillType = lastModelIndexForCurrSkillType; +// const Model *result = currSkill->getAnimation(getAnimProgressAsFloat(),this,&lastModelIndexForCurrSkillType, &animationRandomCycleCount); +// if(currentModelIndexForCurrSkillType != lastModelIndexForCurrSkillType) { +// animationRandomCycleCount++; +// if(currSkill != NULL && animationRandomCycleCount >= currSkill->getAnimationCount()) { +// animationRandomCycleCount = 0; +// } +// } +// return result; //} -bool Unit::checkModelStateInfoForNewHpValue() { - bool result = false; - if(currSkill != NULL && currSkill->getAnimationCount() > 1) { - if(lastModelIndexForCurrSkillType >= 0) { - const AnimationAttributes attributes = currSkill->getAnimationAttribute(lastModelIndexForCurrSkillType); - if(attributes.fromHp != 0 || attributes.toHp != 0) { - //printf("Check for RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); - //if(this->getHp() >= attributes.fromHp && this->getHp() <= attributes.toHp) { - if(this->getHp() < attributes.fromHp || this->getHp() > attributes.toHp) { - //printf("RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); + bool Unit::checkModelStateInfoForNewHpValue () + { + bool result = false; + if (currSkill != NULL && currSkill->getAnimationCount () > 1) + { + if (lastModelIndexForCurrSkillType >= 0) + { + const AnimationAttributes attributes = + currSkill->getAnimationAttribute (lastModelIndexForCurrSkillType); + if (attributes.fromHp != 0 || attributes.toHp != 0) + { + //printf("Check for RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); + //if(this->getHp() >= attributes.fromHp && this->getHp() <= attributes.toHp) { + if (this->getHp () < attributes.fromHp + || this->getHp () > attributes.toHp) + { + //printf("RESET model state for [%d - %s] HP = %d [%d to %d]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp); - lastModelIndexForCurrSkillType = -1; - animationRandomCycleCount = 0; - result = true; - } - } - else { - //printf("Check for RESET #2 model state for [%d - %s] HP = %d [%d to %d] for skill [%s]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp,currSkill->getName().c_str()); - } - } - } + lastModelIndexForCurrSkillType = -1; + animationRandomCycleCount = 0; + result = true; + } + } + else + { + //printf("Check for RESET #2 model state for [%d - %s] HP = %d [%d to %d] for skill [%s]\n",this->id,this->getType()->getName().c_str(),this->getHp(),attributes.fromHp,attributes.toHp,currSkill->getName().c_str()); + } + } + } - return result; -} - -Vec3f Unit::getCurrVectorForParticlesystems() const{ - if(getFaction()->getType()->isFlatParticlePositions()){ - return getCurrVectorFlat(); - } - else { - return getCurrMidHeightVector(); - } -} - -Vec3f Unit::getCurrMidHeightVector() const{ - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - Vec3f result = getCurrVectorFlat() + Vec3f(0.f, type->getHeight() / 2.f, 0.f); - result.x = truncateDecimal(result.x,6); - result.y = truncateDecimal(result.y,6); - result.z = truncateDecimal(result.z,6); - - return result; -} - -Vec3f Unit::getCurrVectorAsTarget() const{ - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - Vec3f result = getCurrVectorFlat() + Vec3f(0.f, type->getTargetHeight() / 2.f, 0.f); - result.x = truncateDecimal(result.x,6); - result.y = truncateDecimal(result.y,6); - result.z = truncateDecimal(result.z,6); - - return result; -} - -Vec3f Unit::getCurrBurnVector() const{ - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - Vec3f result = getCurrVectorFlat() + Vec3f(0.f, type->getBurnHeight() / 2.f, 0.f); - result.x = truncateDecimal(result.x,6); - result.y = truncateDecimal(result.y,6); - result.z = truncateDecimal(result.z,6); - - return result; -} - -Vec3f Unit::getCurrVectorFlat() const{ - return getVectorFlat(lastPos, pos); -} - -float Unit::getProgressAsFloat() const { - float result = (static_cast(progress) / static_cast(PROGRESS_SPEED_MULTIPLIER)); - result = truncateDecimal(result,6); - return result; -} - -Vec3f Unit::getVectorFlat(const Vec2i &lastPosValue, const Vec2i &curPosValue) const { - Vec3f v; - - float y1= computeHeight(lastPosValue); - float y2= computeHeight(curPosValue); - - if(currSkill->getClass() == scMove) { - float progressAsFloat = getProgressAsFloat(); - - v.x = lastPosValue.x + progressAsFloat * (curPosValue.x - lastPosValue.x); - v.z = lastPosValue.y + progressAsFloat * (curPosValue.y - lastPosValue.y); - v.y = y1 + progressAsFloat * (y2-y1); - - v.x = truncateDecimal(v.x,6); - v.y = truncateDecimal(v.y,6); - v.z = truncateDecimal(v.z,6); + return result; } - else { - v.x = static_cast(curPosValue.x); - v.z = static_cast(curPosValue.y); + + Vec3f Unit::getCurrVectorForParticlesystems () const + { + if (getFaction ()->getType ()->isFlatParticlePositions ()) + { + return getCurrVectorFlat (); + } + else + { + return getCurrMidHeightVector (); + } + } + + Vec3f Unit::getCurrMidHeightVector () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + Vec3f result = + getCurrVectorFlat () + Vec3f (0.f, type->getHeight () / 2.f, 0.f); + result.x = truncateDecimal < float >(result.x, 6); + result.y = truncateDecimal < float >(result.y, 6); + result.z = truncateDecimal < float >(result.z, 6); + + return result; + } + + Vec3f Unit::getCurrVectorAsTarget () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + Vec3f result = + getCurrVectorFlat () + Vec3f (0.f, type->getTargetHeight () / 2.f, + 0.f); + result.x = truncateDecimal < float >(result.x, 6); + result.y = truncateDecimal < float >(result.y, 6); + result.z = truncateDecimal < float >(result.z, 6); + + return result; + } + + Vec3f Unit::getCurrBurnVector () const + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + Vec3f result = + getCurrVectorFlat () + Vec3f (0.f, type->getBurnHeight () / 2.f, 0.f); + result.x = truncateDecimal < float >(result.x, 6); + result.y = truncateDecimal < float >(result.y, 6); + result.z = truncateDecimal < float >(result.z, 6); + + return result; + } + + Vec3f Unit::getCurrVectorFlat () const + { + return getVectorFlat (lastPos, pos); + } + + float Unit::getProgressAsFloat () const + { + float result = + (static_cast < float >(progress) / static_cast < + float >(PROGRESS_SPEED_MULTIPLIER)); + result = truncateDecimal < float >(result, 6); + return result; + } + + Vec3f Unit::getVectorFlat (const Vec2i & lastPosValue, + const Vec2i & curPosValue) const + { + Vec3f v; + + float y1 = computeHeight (lastPosValue); + float y2 = computeHeight (curPosValue); + + if (currSkill->getClass () == scMove) + { + float progressAsFloat = getProgressAsFloat (); + + v.x = + lastPosValue.x + progressAsFloat * (curPosValue.x - lastPosValue.x); + v.z = + lastPosValue.y + progressAsFloat * (curPosValue.y - lastPosValue.y); + v.y = y1 + progressAsFloat * (y2 - y1); + + v.x = truncateDecimal < float >(v.x, 6); + v.y = truncateDecimal < float >(v.y, 6); + v.z = truncateDecimal < float >(v.z, 6); + } + else + { + v.x = static_cast < float >(curPosValue.x); + v.z = static_cast < float >(curPosValue.y); v.y = y2; - v.x = truncateDecimal(v.x,6); - v.y = truncateDecimal(v.y,6); - v.z = truncateDecimal(v.z,6); + v.x = truncateDecimal < float >(v.x, 6); + v.y = truncateDecimal < float >(v.y, 6); + v.z = truncateDecimal < float >(v.z, 6); + } + v.x += type->getSize () / 2.f - 0.5f; + v.z += type->getSize () / 2.f - 0.5f; + + v.x = truncateDecimal < float >(v.x, 6); + v.z = truncateDecimal < float >(v.z, 6); + + return v; } - v.x += type->getSize() / 2.f - 0.5f; - v.z += type->getSize() / 2.f - 0.5f; - - v.x = truncateDecimal(v.x,6); - v.z = truncateDecimal(v.z,6); - - return v; -} // =================== Command list related =================== //any command -bool Unit::anyCommand(bool validateCommandtype) const { - bool result = false; - if(validateCommandtype == false) { - result = (commands.empty() == false); - } - else { - for(Commands::const_iterator it= commands.begin(); it != commands.end(); ++it) { - const CommandType *ct = (*it)->getCommandType(); - if(ct != NULL && ct->getClass() != ccStop) { - result = true; - break; - } - } - } + bool Unit::anyCommand (bool validateCommandtype) const + { + bool result = false; + if (validateCommandtype == false) + { + result = (commands.empty () == false); + } + else + { + for (Commands::const_iterator it = commands.begin (); + it != commands.end (); ++it) + { + const CommandType *ct = (*it)->getCommandType (); + if (ct != NULL && ct->getClass () != ccStop) + { + result = true; + break; + } + } + } - return result; -} + return result; + } //return current command, assert that there is always one command -Command *Unit::getCurrrentCommandThreadSafe() { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + Command *Unit::getCurrrentCommandThreadSafe () + { + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - if(commands.empty() == false) { - return commands.front(); - } + if (commands.empty () == false) + { + return commands.front (); + } - return NULL; -} + return NULL; + } -void Unit::replaceCurrCommand(Command *cmd) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + void Unit::replaceCurrCommand (Command * cmd) + { + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - assert(commands.empty() == false); - commands.front() = cmd; - this->setCurrentUnitTitle(""); -} + assert (commands.empty () == false); + commands.front () = cmd; + this->setCurrentUnitTitle (""); + } //returns the size of the commands -unsigned int Unit::getCommandSize() const { - return (unsigned int)commands.size(); -} + unsigned int Unit::getCommandSize () const + { + return (unsigned int) commands.size (); + } //return current command, assert that there is always one command -int Unit::getCountOfProducedUnits(const UnitType *ut) const{ - int count=0; - for(Commands::const_iterator it= commands.begin(); it!=commands.end(); ++it){ - const CommandType* ct=(*it)->getCommandType(); - if(ct->getClass()==ccProduce || ct->getClass()==ccMorph ){ - const UnitType *producedUnitType= static_cast(ct->getProduced()); - if(producedUnitType==ut) - { - count++; - } - } - if(ct->getClass()==ccBuild){ - const UnitType *builtUnitType= (*it)->getUnitType(); - if(builtUnitType==ut) - { - count++; - } - } - } - return count; -} + int Unit::getCountOfProducedUnits (const UnitType * ut) const + { + int count = 0; + for (Commands::const_iterator it = commands.begin (); + it != commands.end (); ++it) + { + const CommandType *ct = (*it)->getCommandType (); + if (ct->getClass () == ccProduce || ct->getClass () == ccMorph) + { + const UnitType *producedUnitType = + static_cast < const UnitType * >(ct->getProduced ()); + if (producedUnitType == ut) + { + count++; + } + } + if (ct->getClass () == ccBuild) + { + const UnitType *builtUnitType = (*it)->getUnitType (); + if (builtUnitType == ut) + { + count++; + } + } + } + return count; + } //give one command (clear, and push back) -std::pair Unit::giveCommand(Command *command, bool tryQueue) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"\n======================\nUnit Command tryQueue = %d\nUnit Info:\n%s\nCommand Info:\n%s\n",tryQueue,this->toString().c_str(),command->toString(false).c_str()); + std::pair < CommandResult, string > Unit::giveCommand (Command * command, + bool tryQueue) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugUnitCommands). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, + "\n======================\nUnit Command tryQueue = %d\nUnit Info:\n%s\nCommand Info:\n%s\n", + tryQueue, this->toString ().c_str (), + command->toString (false).c_str ()); - std::pair result(crFailUndefined,""); - changedActiveCommand = false; + std::pair < CommandResult, string > result (crFailUndefined, ""); + changedActiveCommand = false; - Chrono chrono; - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled) chrono.start(); + Chrono chrono; + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled) + chrono.start (); - if(command == NULL) { - throw megaglest_runtime_error("command == NULL"); + if (command == NULL) + { + throw megaglest_runtime_error ("command == NULL"); + } + if (command->getCommandType () == NULL) + { + throw megaglest_runtime_error ("command->getCommandType() == NULL"); + } + + const int command_priority = command->getPriority (); + + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + + //printf("In [%s::%s] Line: %d unit [%d - %s] command [%s] tryQueue = %d command->getCommandType()->isQueuable(tryQueue) = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getId(),this->getType()->getName().c_str(), command->getCommandType()->getName().c_str(), tryQueue,command->getCommandType()->isQueuable(tryQueue)); + + + if (command->getCommandType ()->isQueuable (tryQueue)) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + if (SystemFlags:: + getSystemSettingType (SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Command is Queable\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); + + if (command->getCommandType ()->isQueuable () == qAlways && tryQueue) + { + // Its a produce or upgrade command called without queued key + // in this case we must NOT delete lower priority commands! + // we just queue it! + + } + else + { + //Delete all lower-prioirty commands + for (list < Command * >::iterator i = commands.begin (); + i != commands.end ();) + { + if ((*i)->getPriority () < command_priority) + { + if (SystemFlags:: + getSystemSettingType (SystemFlags::debugUnitCommands). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Deleting lower priority command [%s]\n", + extractFileFromDirectoryPath + (__FILE__).c_str (), __FUNCTION__, + __LINE__, + (*i)->toString (false).c_str ()); + + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); + + deleteQueuedCommand (*i); + i = commands.erase (i); + + safeMutex.ReleaseLock (); + } + else + { + ++i; + } + } + } + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + + //cancel current command if it is not queuable + if (commands.empty () == false && + commands.back ()->getCommandType ()->isQueueAppendable () == + false) + { + if (SystemFlags:: + getSystemSettingType (SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Cancel command because last one is NOT queable [%s]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + commands.back ()->toString (false). + c_str ()); + + cancelCommand (); + } + + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + } + else + { + //empty command queue + if (SystemFlags:: + getSystemSettingType (SystemFlags::debugUnitCommands).enabled) + SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] Clear commands because current is NOT queable.\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); + + bool willChangedActiveCommand = (commands.empty () == false); + if (willChangedActiveCommand == true) + { + + CommandClass currCommandClass = + getCurrCommand ()->getCommandType ()->getClass (); + CommandClass commandClass = command->getCommandType ()->getClass (); + if (currCommandClass == commandClass) + { + + willChangedActiveCommand = false; + } + else if (currCommandClass == ccAttack || + currCommandClass == ccAttackStopped || + commandClass == ccAttack || + commandClass == ccAttackStopped) + { + + willChangedActiveCommand = true; + } + else + { + willChangedActiveCommand = false; + } + } + + if (willChangedActiveCommand == true) + { + + lastChangedActiveCommandFrame = changedActiveCommandFrame; + changedActiveCommandFrame = getFrameCount (); + + //printf("Line: %d getCurrCommand() [%s] command [%s]\n",__LINE__,getCurrCommand()->toString(false).c_str(),command->toString(false).c_str()); + } + + clearCommands (); + changedActiveCommand = willChangedActiveCommand; + + //printf("In [%s::%s] Line: %d cleared existing commands\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + } + + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + + //check command + result = checkCommand (command); + if (SystemFlags::getSystemSettingType (SystemFlags::debugUnitCommands). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugUnitCommands, + "In [%s::%s Line: %d] checkCommand returned: [%d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + result.first); + + //printf("In [%s::%s] Line: %d check command returned %d, commands.size() = %d\n[%s]\n\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,commands.size(),command->toString().c_str()); + + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + + if (result.first == crSuccess) + { + applyCommand (command); + } + + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + + //push back command + if (result.first == crSuccess) + { + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); + + commands.push_back (command); + + safeMutex.ReleaseLock (); + } + else + { + delete command; + changedActiveCommand = false; + } + + if (SystemFlags::getSystemSettingType (SystemFlags::debugPerformance). + enabled && chrono.getMillis () > 0) + SystemFlags::OutputDebug (SystemFlags::debugPerformance, + "In [%s::%s] Line: %d took msecs: %lld\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + chrono.getMillis ()); + + return result; } - if(command->getCommandType() == NULL) { - throw megaglest_runtime_error("command->getCommandType() == NULL"); - } - - const int command_priority = command->getPriority(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - //printf("In [%s::%s] Line: %d unit [%d - %s] command [%s] tryQueue = %d command->getCommandType()->isQueuable(tryQueue) = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->getId(),this->getType()->getName().c_str(), command->getCommandType()->getName().c_str(), tryQueue,command->getCommandType()->isQueuable(tryQueue)); - - - if(command->getCommandType()->isQueuable(tryQueue)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Command is Queable\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(command->getCommandType()->isQueuable() == qAlways && tryQueue){ - // Its a produce or upgrade command called without queued key - // in this case we must NOT delete lower priority commands! - // we just queue it! - - } - else { - //Delete all lower-prioirty commands - for(list::iterator i= commands.begin(); i != commands.end();){ - if((*i)->getPriority() < command_priority){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) - SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Deleting lower priority command [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,(*i)->toString(false).c_str()); - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); - - deleteQueuedCommand(*i); - i= commands.erase(i); - - safeMutex.ReleaseLock(); - } - else { - ++i; - } - } - } - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - //cancel current command if it is not queuable - if(commands.empty() == false && - commands.back()->getCommandType()->isQueueAppendable() == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Cancel command because last one is NOT queable [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,commands.back()->toString(false).c_str()); - - cancelCommand(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - } - else { - //empty command queue - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] Clear commands because current is NOT queable.\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - bool willChangedActiveCommand = (commands.empty() == false); - if(willChangedActiveCommand == true) { - - CommandClass currCommandClass = getCurrCommand()->getCommandType()->getClass(); - CommandClass commandClass = command->getCommandType()->getClass(); - if(currCommandClass == commandClass) { - - willChangedActiveCommand = false; - } - else if(currCommandClass == ccAttack || - currCommandClass == ccAttackStopped || - commandClass == ccAttack || - commandClass == ccAttackStopped) { - - willChangedActiveCommand= true; - } - else { - willChangedActiveCommand= false; - } - } - - if(willChangedActiveCommand == true) { - - lastChangedActiveCommandFrame = changedActiveCommandFrame; - changedActiveCommandFrame = getFrameCount(); - - //printf("Line: %d getCurrCommand() [%s] command [%s]\n",__LINE__,getCurrCommand()->toString(false).c_str(),command->toString(false).c_str()); - } - - clearCommands(); - changedActiveCommand = willChangedActiveCommand; - - //printf("In [%s::%s] Line: %d cleared existing commands\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - //check command - result= checkCommand(command); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] checkCommand returned: [%d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result.first); - - //printf("In [%s::%s] Line: %d check command returned %d, commands.size() = %d\n[%s]\n\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,result,commands.size(),command->toString().c_str()); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - if(result.first == crSuccess) { - applyCommand(command); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - //push back command - if(result.first == crSuccess) { - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); - - commands.push_back(command); - - safeMutex.ReleaseLock(); - } - else { - delete command; - changedActiveCommand = false; - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chrono.getMillis()); - - return result; -} //pop front (used when order is done) -CommandResult Unit::finishCommand() { - changedActiveCommand = false; - retryCurrCommandCount=0; - // Reset the progress when task completed. - resetProgress2(); - this->setCurrentUnitTitle(""); - //is empty? - if(commands.empty()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__, __LINE__); - return crFailUndefined; - } + CommandResult Unit::finishCommand () + { + changedActiveCommand = false; + retryCurrCommandCount = 0; + // Reset the progress when task completed. + resetProgress2 (); + this->setCurrentUnitTitle (""); + //is empty? + if (commands.empty ()) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug (SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); + return crFailUndefined; + } - //pop front - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + //pop front + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - delete commands.front(); - commands.erase(commands.begin()); + delete commands.front (); + commands.erase (commands.begin ()); - safeMutex.ReleaseLock(true); + safeMutex.ReleaseLock (true); - this->unitPath->clear(); + this->unitPath->clear (); - while (commands.empty() == false) { - if (commands.front()->getUnit() != NULL && this->faction->isUnitInLivingUnitsp(commands.front()->getUnit()) == false) { - safeMutex.Lock(); - delete commands.front(); - commands.erase(commands.begin()); - safeMutex.ReleaseLock(true); - } - else { - break; - } - } + while (commands.empty () == false) + { + if (commands.front ()->getUnit () != NULL + && this->faction->isUnitInLivingUnitsp (commands.front ()-> + getUnit ()) == false) + { + safeMutex.Lock (); + delete commands.front (); + commands.erase (commands.begin ()); + safeMutex.ReleaseLock (true); + } + else + { + break; + } + } - return crSuccess; -} + return crSuccess; + } //to cancel a command -CommandResult Unit::cancelCommand() { - changedActiveCommand = false; - retryCurrCommandCount=0; - // Reset the progress if the command (possibly a task) is cancelled. - /// TODO: this is not an optimal solution because progress is reset even if the task does not track progression - /// e.g. production/ upgrades keep track of progression but walking/ attacking does not. - resetProgress2(); - this->setCurrentUnitTitle(""); + CommandResult Unit::cancelCommand () + { + changedActiveCommand = false; + retryCurrCommandCount = 0; + // Reset the progress if the command (possibly a task) is cancelled. + /// TODO: this is not an optimal solution because progress is reset even if the task does not track progression + /// e.g. production/ upgrades keep track of progression but walking/ attacking does not. + resetProgress2 (); + this->setCurrentUnitTitle (""); - //is empty? - if(commands.empty()){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__, __LINE__); - return crFailUndefined; - } + //is empty? + if (commands.empty ()) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug (SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); + return crFailUndefined; + } - //undo command - undoCommand(commands.back()); + //undo command + undoCommand (commands.back ()); - //delete ans pop command - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); + //delete ans pop command + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); - delete commands.back(); - commands.pop_back(); + delete commands.back (); + commands.pop_back (); - safeMutex.ReleaseLock(); + safeMutex.ReleaseLock (); - //clear routes - this->unitPath->clear(); + //clear routes + this->unitPath->clear (); - return crSuccess; -} + return crSuccess; + } // =================== route stack =================== -void Unit::create(bool startingUnit) { - faction->addUnit(this); - map->putUnitCells(this, pos); - if(startingUnit) { - faction->applyStaticCosts(type,NULL); - } -} + void Unit::create (bool startingUnit) + { + faction->addUnit (this); + map->putUnitCells (this, pos); + if (startingUnit) + { + faction->applyStaticCosts (type, NULL); + } + } -void Unit::born(const CommandType *ct) { - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + void Unit::born (const CommandType * ct) + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - faction->addStore(type); - faction->applyStaticProduction(type,ct); - setCurrSkill(scStop); + faction->addStore (type); + faction->applyStaticProduction (type, ct); + setCurrSkill (scStop); - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; - //set hp from start hp - checkItemInVault(&this->ep,this->ep); - if(type->getStartHpType() == UnitType::stValue) { - this->hp= type->getStartHpValue(); - } - else { - this->hp= type->getTotalMaxHp(&totalUpgrade) * type->getStartHpPercentage() / 100; - } + //set hp from start hp + checkItemInVault (&this->ep, this->ep); + if (type->getStartHpType () == UnitType::stValue) + { + this->hp = type->getStartHpValue (); + } + else + { + this->hp = + type->getTotalMaxHp (&totalUpgrade) * + type->getStartHpPercentage () / 100; + } - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); - //set ep from start ep - checkItemInVault(&this->ep,this->ep); - if(type->getStartEpType() == UnitType::stValue) { - this->ep= type->getStartEpValue(); - } - else { - this->ep= type->getTotalMaxEp(&totalUpgrade) * type->getStartEpPercentage() / 100; - } -} + //set ep from start ep + checkItemInVault (&this->ep, this->ep); + if (type->getStartEpType () == UnitType::stValue) + { + this->ep = type->getStartEpValue (); + } + else + { + this->ep = + type->getTotalMaxEp (&totalUpgrade) * + type->getStartEpPercentage () / 100; + } + } -void Unit::kill() { - //no longer needs static resources - if(isBeingBuilt()) { - faction->deApplyStaticConsumption(type,(getCurrCommand() != NULL ? getCurrCommand()->getCommandType() : NULL)); - } - else { - faction->deApplyStaticCosts(type,(getCurrCommand() != NULL ? getCurrCommand()->getCommandType() : NULL)); - } + void Unit::kill () + { + //no longer needs static resources + if (isBeingBuilt ()) + { + faction->deApplyStaticConsumption (type, + (getCurrCommand () != + NULL ? getCurrCommand ()-> + getCommandType () : NULL)); + } + else + { + faction->deApplyStaticCosts (type, + (getCurrCommand () != + NULL ? getCurrCommand ()-> + getCommandType () : NULL)); + } - //do the cleaning - //clear commands ( and their blocking fields ) - clearCommands(); + //do the cleaning + //clear commands ( and their blocking fields ) + clearCommands (); - map->clearUnitCells(this, pos, true); - if(isBeingBuilt() == false) { - faction->removeStore(type); - } - setCurrSkill(scDie); + map->clearUnitCells (this, pos, true); + if (isBeingBuilt () == false) + { + faction->removeStore (type); + } + setCurrSkill (scDie); - notifyObservers(UnitObserver::eKill); + notifyObservers (UnitObserver::eKill); - UnitUpdater *unitUpdater = game->getWorld()->getUnitUpdater(); - //unitUpdater->clearUnitPrecache(this); - unitUpdater->removeUnitPrecache(this); -} + UnitUpdater *unitUpdater = game->getWorld ()->getUnitUpdater (); + //unitUpdater->clearUnitPrecache(this); + unitUpdater->removeUnitPrecache (this); + } -void Unit::undertake() { - try { - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] about to undertake unit id = %d [%s] [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->id, this->getFullName(false).c_str(),this->getDesc(false).c_str()); + void Unit::undertake () + { + try + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugSystem, + "In [%s::%s Line: %d] about to undertake unit id = %d [%s] [%s]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + this->id, + this->getFullName (false).c_str (), + this->getDesc (false).c_str ()); - // Remove any units that were previously in attack-boost range - if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false && currentAttackBoostOriginatorEffect.skillType != NULL) { - for(unsigned int i = 0; i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); ++i) { - // Remove attack boost upgrades from unit - int findUnitId = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); - if(affectedUnit != NULL) { - affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this); - } + // Remove any units that were previously in attack-boost range + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty () == false + && currentAttackBoostOriginatorEffect.skillType != NULL) + { + for (unsigned int i = 0; + i < + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size (); ++i) + { + // Remove attack boost upgrades from unit + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + Unit *affectedUnit = game->getWorld ()->findUnitById (findUnitId); + if (affectedUnit != NULL) + { + affectedUnit-> + deapplyAttackBoost (currentAttackBoostOriginatorEffect. + skillType->getAttackBoost (), this); + } - //printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear(); - } + //printf("!!!! DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear (); + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); - UnitUpdater *unitUpdater = game->getWorld()->getUnitUpdater(); + UnitUpdater *unitUpdater = game->getWorld ()->getUnitUpdater (); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); - //unitUpdater->clearUnitPrecache(this); - unitUpdater->removeUnitPrecache(this); + //unitUpdater->clearUnitPrecache(this); + unitUpdater->removeUnitPrecache (this); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); - this->faction->deleteLivingUnits(id); - this->faction->deleteLivingUnitsp(this); + this->faction->deleteLivingUnits (id); + this->faction->deleteLivingUnitsp (this); - if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); + if (SystemFlags::getSystemSettingType (SystemFlags::debugSystem). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugSystem, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); - faction->removeUnit(this); - } - catch(const megaglest_runtime_error &ex) { - string sErrBuf = ""; - if(ex.wantStackTrace() == true) { - char szErrBuf[8096]=""; - snprintf(szErrBuf,8096,"In [%s::%s %d]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); - } - else { - sErrBuf = ex.what(); - } - SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str()); + faction->removeUnit (this); + } + catch (const megaglest_runtime_error & ex) + { + string sErrBuf = ""; + if (ex.wantStackTrace () == true) + { + char szErrBuf[8096] = ""; + snprintf (szErrBuf, 8096, "In [%s::%s %d]", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__); + sErrBuf = + string (szErrBuf) + string ("\nerror [") + string (ex.what ()) + + string ("]\n"); + } + else + { + sErrBuf = ex.what (); + } + SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - throw; - } - catch(const std::exception &ex) { - char szErrBuf[8096]=""; - snprintf(szErrBuf,8096,"In [%s::%s %d]",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__); - string sErrBuf = string(szErrBuf) + string("\nerror [") + string(ex.what()) + string("]\n"); - SystemFlags::OutputDebug(SystemFlags::debugError,sErrBuf.c_str()); + throw; + } + catch (const std::exception & ex) + { + char szErrBuf[8096] = ""; + snprintf (szErrBuf, 8096, "In [%s::%s %d]", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__); + string sErrBuf = + string (szErrBuf) + string ("\nerror [") + string (ex.what ()) + + string ("]\n"); + SystemFlags::OutputDebug (SystemFlags::debugError, sErrBuf.c_str ()); - throw; - } -} + throw; + } + } // =================== Referencers =================== -void Unit::addObserver(UnitObserver *unitObserver){ - observers.push_back(unitObserver); -} + void Unit::addObserver (UnitObserver * unitObserver) + { + observers.push_back (unitObserver); + } //void Unit::removeObserver(UnitObserver *unitObserver){ -// observers.remove(unitObserver); +// observers.remove(unitObserver); //} -void Unit::notifyObservers(UnitObserver::Event event){ - for(Observers::iterator it= observers.begin(); it!=observers.end(); ++it){ - (*it)->unitEvent(event, this); - } -} + void Unit::notifyObservers (UnitObserver::Event event) + { + for (Observers::iterator it = observers.begin (); + it != observers.end (); ++it) + { + (*it)->unitEvent (event, this); + } + } // =================== Other =================== -void Unit::resetHighlight(){ - highlight= 1.f; -} - -const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *targetUnit) const{ - const CommandType *commandType= NULL; - - if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { - throw megaglest_runtime_error("#6 Invalid path position = " + pos.getString()); - } - - SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(pos)); - - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)")); - if(targetUnit != NULL) { - //attack enemies - if(isAlly(targetUnit) == false) { - commandType= type->getFirstAttackCommand(targetUnit->getCurrField()); - } - //repair allies - else { - if(targetUnit->isBuilt() == false || targetUnit->isDamaged() == true) { - commandType= type->getFirstRepairCommand(targetUnit->getType()); - } - - //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s] commandType [%p]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)"),commandType); - - if(commandType == NULL && targetUnit != NULL) { - //Command *command= this->getCurrCommand(); - //const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); - - // Check if we can return whatever resources we have - if(targetUnit->getFactionIndex() == this->getFactionIndex() && - targetUnit->isOperative() == true && - this->getLoadType() != NULL && this->getLoadCount() != 0 && - targetUnit->getType() != NULL && - targetUnit->getType()->getStore(this->getLoadType()) > 0) { - - commandType = type->getFirstHarvestEmergencyReturnCommand(); - } - } - } - } - else { - //check harvest command - Resource *resource= sc->getResource(); - if(resource != NULL) { - commandType= type->getFirstHarvestCommand(resource->getType(),this->getFaction()); - } - } - - if(targetUnit == NULL && commandType == NULL) { - const Vec2i unitTargetPos = pos; - Cell *cell= map->getCell(unitTargetPos); - if(cell != NULL && cell->getUnit(this->getCurrField()) != NULL) { - Unit *targetUnit = cell->getUnit(this->getCurrField()); - if(targetUnit != NULL) { - // Check if we want to help build (repair) any buildings instead of just moving - if(targetUnit->getFactionIndex() == this->getFactionIndex() && - (targetUnit->isBuilt() == false || targetUnit->isDamaged() == true)) { - const RepairCommandType *rct= this->getType()->getFirstRepairCommand(targetUnit->getType()); - if(rct != NULL) { - commandType= type->getFirstRepairCommand(targetUnit->getType()); - //printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged()); - } - } - } - } - } - - // Default command is the class of the unit (i.e. attack for attackers, walk for walkers). - // The default command is executed when a unit is produced and sent to a meeting point - // or when the unit is selected and right clicked to a position. - if(commandType == NULL) { - // The default command is move command - commandType= type->getFirstCtOfClass(ccMove); - - // To change the default to attack, comment the line above, and uncomment - // the line of code below - - // Is the unit class warrior? if yes, attack by default, else walk. - //commandType = type->getFirstCtOfClass(this->getType()->isOfClass(ucWarrior) ? ccAttack : ccMove); - - // FIXME: I think a better solution would be to have a hotkey for this, - // the user can decide, and toggle in-game -andy5995 2018-02-03 - } - - return commandType; -} - -int64 Unit::getUpdateProgress() { - if(progress > PROGRESS_SPEED_MULTIPLIER) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: progress > " MG_I64_SPECIFIER ", progress = [" MG_I64_SPECIFIER "]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,PROGRESS_SPEED_MULTIPLIER,progress); - throw megaglest_runtime_error(szBuf); - } - - if(currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - int64 newProgress = progress; - if(currSkill->getClass() != scDie) { - //speed - int speed = currSkill->getTotalSpeed(&totalUpgrade); - - if(changedActiveCommand == true) { - if(changedActiveCommandFrame - lastChangedActiveCommandFrame >= MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) { - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); - speed = CHANGE_COMMAND_SPEED; - } - } - - //speed modifier - int64 diagonalFactor = getDiagonalFactor(); - int64 heightFactor = getHeightFactor(PROGRESS_SPEED_MULTIPLIER); - - //update progresses -// const Game *game = Renderer::getInstance().getGame(); -// if(game == NULL) { -// throw megaglest_runtime_error("game == NULL"); -// } -// if(game->getWorld() == NULL) { -// throw megaglest_runtime_error("game->getWorld() == NULL"); -// } - - newProgress = getUpdatedProgress(progress, GameConstants::updateFps, - speed, diagonalFactor, heightFactor); - - } - return newProgress; -} - -bool Unit::needToUpdate() { - bool return_value = false; - if(currSkill->getClass() != scDie) { - int newProgress = getUpdateProgress(); - if(newProgress >= PROGRESS_SPEED_MULTIPLIER) { - return_value = true; - } - } - return return_value; -} - -int64 Unit::getDiagonalFactor() { - //speed modifier - int64 diagonalFactor= PROGRESS_SPEED_MULTIPLIER; - if(currSkill->getClass() == scMove) { - //if moving in diagonal move slower - Vec2i dest= pos - lastPos; - if(abs(dest.x) + abs(dest.y) == 2) { - //diagonalFactor = 0.71f * PROGRESS_SPEED_MULTIPLIER; - diagonalFactor = 71 * (PROGRESS_SPEED_MULTIPLIER / 100); - } - } - return diagonalFactor; -} - -int64 Unit::getHeightFactor(int64 speedMultiplier) { - int64 heightFactor = speedMultiplier; - if(currSkill->getClass() == scMove) { - //if moving to an higher cell move slower else move faster - Cell *unitCell = map->getCell(pos); - if(unitCell == NULL) { - throw megaglest_runtime_error("unitCell == NULL"); - } - - Cell *targetCell = map->getCell(targetPos); - if(targetCell == NULL) { - throw megaglest_runtime_error("targetCell == NULL"); - } - - int64 heightDiff= ((truncateDecimal(unitCell->getHeight(),2) * speedMultiplier) - - (truncateDecimal(targetCell->getHeight(),2) * speedMultiplier)); - //heightFactor= clamp(speedMultiplier + heightDiff / (5.f * speedMultiplier), 0.2f * speedMultiplier, 5.f * speedMultiplier); - heightFactor= clamp(speedMultiplier + heightDiff / (5 * speedMultiplier), (2 * (speedMultiplier / 10)), 5 * speedMultiplier); - } - - return heightFactor; -} - -int64 Unit::getSpeedDenominator(int64 updateFPS) { - int64 speedDenominator = (speedDivider * updateFPS) * PROGRESS_SPEED_MULTIPLIER; - return speedDenominator; -} -int64 Unit::getUpdatedProgress(int64 currentProgress, int64 updateFPS, int64 speed, - int64 diagonalFactor, int64 heightFactor) { - - int64 speedDenominator = getSpeedDenominator(updateFPS); - int64 newProgress = currentProgress; - int64 progressIncrease = ((speed * diagonalFactor * heightFactor) / speedDenominator); - // Ensure we increment at least a value of 1 of the action will be stuck infinitely - if(speed > 0 && diagonalFactor > 0 && heightFactor > 0 && progressIncrease == 0) { - progressIncrease = 1; - } - - if(isNetworkCRCEnabled() == true) { - float height = map->getCell(pos)->getHeight(); - float airHeight = game->getWorld()->getTileset()->getAirHeight(); - int cellUnitHeight = -1; - int cellObjectHeight = -1; - - Unit *unit = map->getCell(pos)->getUnit(fLand); - if(unit != NULL && unit->getType()->getHeight() > airHeight) { - cellUnitHeight = unit->getType()->getHeight(); - } - else { - SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(pos)); - if(sc != NULL && sc->getObject() != NULL && sc->getObject()->getType() != NULL) { - if(sc->getObject()->getType()->getHeight() > airHeight) { - cellObjectHeight = sc->getObject()->getType()->getHeight(); - } - } - } - - - char szBuf[8096]=""; - snprintf(szBuf,8095,"currentProgress = " MG_I64_SPECIFIER " updateFPS = " MG_I64_SPECIFIER " speed = " MG_I64_SPECIFIER " diagonalFactor = " MG_I64_SPECIFIER " heightFactor = " MG_I64_SPECIFIER " speedDenominator = " MG_I64_SPECIFIER " progressIncrease = " MG_I64_SPECIFIER " [" MG_I64_SPECIFIER "] height [%f] airHeight [%f] cellUnitHeight [%d] cellObjectHeight [%d] skill [%s] pos [%s] lastpos [%s]", - currentProgress,updateFPS,speed,diagonalFactor,heightFactor,speedDenominator,progressIncrease,((speed * diagonalFactor * heightFactor) / speedDenominator),height,airHeight,cellUnitHeight,cellObjectHeight,(currSkill != NULL ? currSkill->getName().c_str() : "none"),pos.getString().c_str(),lastPos.getString().c_str()); - networkCRCLogInfo = szBuf; - - //printf("%s\n",szBuf); - } - - newProgress += progressIncrease; - -// if(currSkill->getClass() == scMove || (currSkill->getClass() == scStop && this->loadCount > 0)) { -// printf("speedDenominator: " MG_I64_SPECIFIER " currentProgress: " MG_I64_SPECIFIER " speed: " MG_I64_SPECIFIER " diagonalFactor: " MG_I64_SPECIFIER " heightFactor: " MG_I64_SPECIFIER " progressIncrease: " MG_I64_SPECIFIER " newProgress: " MG_I64_SPECIFIER " TOP #: " MG_I64_SPECIFIER "\n",speedDenominator,currentProgress,speed,diagonalFactor,heightFactor,progressIncrease,newProgress,(speed * diagonalFactor * heightFactor)); -// } - - return newProgress; -} - -void Unit::updateAttackBoostProgress(const Game* game) { - const bool debugBoost = false; - if(debugBoost) printf("===================== START Unit [%d - %s] skill: %s affected unit size: " MG_SIZE_T_SPECIFIER "\n", - this->id,this->getType()->getName(false).c_str(),currSkill->getBoostDesc(false).c_str(), - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size()); - - if (currSkill != currentAttackBoostOriginatorEffect.skillType) { - - if(debugBoost) printf("Line: %d new [%s]\n",__LINE__,(currentAttackBoostOriginatorEffect.skillType != NULL ? currentAttackBoostOriginatorEffect.skillType->getBoostDesc(false).c_str() : "")); - - if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) { - delete currentAttackBoostOriginatorEffect.currentAppliedEffect; - currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; - - //printf("- #1 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - - // Remove any units that were previously in range - if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false && - currentAttackBoostOriginatorEffect.skillType != NULL) { - for (unsigned int i = 0; - i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); - ++i) { - // Remove attack boost upgrades from unit - - int findUnitId = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); - if (affectedUnit != NULL) { - affectedUnit->deapplyAttackBoost( - currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), - this); - } - - //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear(); - } - - if(debugBoost) printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n",__LINE__,currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size()); - - currentAttackBoostOriginatorEffect.skillType = currSkill; - - if (currSkill->isAttackBoostEnabled() == true) { - if(debugBoost) printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n",__LINE__,currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size()); - - // Search for units in range of this unit which apply to the - // attack-boost and temporarily upgrade them - UnitUpdater *unitUpdater = this->game->getWorld()->getUnitUpdater(); - - const AttackBoost *attackBoost = currSkill->getAttackBoost(); - vector candidates = unitUpdater->findUnitsInRange(this, - attackBoost->radius); - - if(debugBoost) printf("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER " attackBoost: %s\n",__LINE__,candidates.size(),attackBoost->getDesc(false).c_str()); - for (unsigned int i = 0; i < candidates.size(); ++i) { - Unit *affectedUnit = candidates[i]; - if (attackBoost->isAffected(this, affectedUnit) == true) { - if (affectedUnit->applyAttackBoost(attackBoost, this) == true) { - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back(affectedUnit->getId()); - //printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } - } - - if(debugBoost) printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n",__LINE__,currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size()); - - if (showUnitParticles == true) { - if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false) { - if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL) { - currentAttackBoostOriginatorEffect.currentAppliedEffect = new UnitAttackBoostEffect(); - currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = new UnitParticleSystemType(); - *currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = *attackBoost->unitParticleSystemTypeForSourceUnit; - //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; - - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleOwner(this); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleType(currentAttackBoostOriginatorEffect.currentAppliedEffect->upst); - - currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues( - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos( - getCurrVectorForParticlesystems()); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setRotation(getRotation()); - setMeshPosInParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); - - if (getFaction()->getTexture()) { - currentAttackBoostOriginatorEffect. - currentAppliedEffect->ups->setFactionColor( - getFaction()->getTexture()-> - getPixmapConst()->getPixel3f( - 0, 0)); - } - Renderer::getInstance().manageParticleSystem( - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, - rsGame); - //printf("+ #1 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - } - } - } - } - else { - if (currSkill->isAttackBoostEnabled() == true) { - if(debugBoost) printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n",__LINE__,currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size()); - - // Search for units in range of this unit which apply to the - // attack-boost and temporarily upgrade them - UnitUpdater *unitUpdater = this->game->getWorld()->getUnitUpdater(); - - const AttackBoost *attackBoost = currSkill->getAttackBoost(); - vector candidates = unitUpdater->findUnitsInRange(this,attackBoost->radius); - vector candidateValidIdList; - candidateValidIdList.reserve(candidates.size()); - - if(debugBoost) printf("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER " attackBoost: %s\n",__LINE__,candidates.size(),attackBoost->getDesc(false).c_str()); - - for (unsigned int i = 0; i < candidates.size(); ++i) { - Unit *affectedUnit = candidates[i]; - candidateValidIdList.push_back(affectedUnit->getId()); - - std::vector::iterator iterFound = std::find( - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin(), - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end(), - affectedUnit->getId()); - - if (attackBoost->isAffected(this, affectedUnit) == true) { - if (iterFound == currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) { - if (affectedUnit->applyAttackBoost(attackBoost, this) == true) { - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.push_back( - affectedUnit->getId()); - - //printf("+ #2 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } - } - else { - if (iterFound != currentAttackBoostOriginatorEffect.currentAttackBoostUnits.end()) { - affectedUnit->deapplyAttackBoost( - currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), - this); - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.erase( - iterFound); - - //printf("- #2 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } - } - - // Now remove any units that were in the list of boosted units but - // are no longer in range - if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false) { - for (int i = (int)currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() -1; i >= 0; --i) { - int findUnitId = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - - std::vector::iterator iterFound = std::find( - candidateValidIdList.begin(), - candidateValidIdList.end(), - findUnitId); - if(iterFound == candidateValidIdList.end()) { - Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); - if (affectedUnit != NULL) { - affectedUnit->deapplyAttackBoost( - currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), - this); - - if(debugBoost) printf("Removed attack boost from Unit [%d - %s] since they are NO LONGER in range\n", - affectedUnit->id,affectedUnit->getType()->getName(false).c_str()); - - } - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.erase( - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin()+i); - } - } - } - - if(debugBoost) printf("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n",__LINE__,currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size()); - - if (showUnitParticles == true) { - if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false) { - if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL - && currentAttackBoostOriginatorEffect.currentAppliedEffect == NULL) { - - currentAttackBoostOriginatorEffect.currentAppliedEffect = new UnitAttackBoostEffect(); - currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = new UnitParticleSystemType(); - *currentAttackBoostOriginatorEffect.currentAppliedEffect->upst = *attackBoost->unitParticleSystemTypeForSourceUnit; - //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; - - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = new UnitParticleSystem(200); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleOwner(this); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setParticleType(currentAttackBoostOriginatorEffect.currentAppliedEffect->upst); - - currentAttackBoostOriginatorEffect.currentAppliedEffect->upst->setValues( - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos( - getCurrVectorForParticlesystems()); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setRotation(getRotation()); - setMeshPosInParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); - - if (getFaction()->getTexture()) { - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setFactionColor( - getFaction()->getTexture()->getPixmapConst()->getPixel3f( - 0, 0)); - } - Renderer::getInstance().manageParticleSystem( - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, - rsGame); - - //printf("+ #2 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - } - else if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == true) { - if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) { - delete currentAttackBoostOriginatorEffect.currentAppliedEffect; - currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; - - //printf("- #2 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); - } - } - } - } - } - - if(debugBoost) { - if (currSkill->isAttackBoostEnabled() == true) { - printf("Unit [%d - %s] has attackboost enabled: %s\n",this->id,this->getType()->getName(false).c_str(),currSkill->getBoostDesc(false).c_str()); - - if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false) { - printf("Found affected units currentAttackBoostOriginatorEffect.skillType [%p]\n",currentAttackBoostOriginatorEffect.skillType); - - for(unsigned int i = 0; i < currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size(); ++i) { - int unitnum = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - printf("affected unit #: %u - %d\n",i,unitnum); - } - } - } - } -} - -bool Unit::update() { - assert(progress <= PROGRESS_SPEED_MULTIPLIER); - - //highlight - if(highlight > 0.f) { - const Game *game = Renderer::getInstance().getGame(); - highlight -= 1.f / (Game::highlightTime * game->getWorld()->getUpdateFps(this->getFactionIndex())); - } - - if(currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - //speed - int speed= currSkill->getTotalSpeed(&totalUpgrade); - - if( oldTotalSight != getType()->getTotalSight(this->getTotalUpgrade())){ - oldTotalSight= getType()->getTotalSight(this->getTotalUpgrade()); - // refresh FogOfWar and so on, because sight ha changed since last update - refreshPos(true); - } - - if(changedActiveCommand) { - if(changedActiveCommandFrame - lastChangedActiveCommandFrame >= MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) { - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); - //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); - speed = CHANGE_COMMAND_SPEED; - } - } - - //speed modifier - int64 diagonalFactor = getDiagonalFactor(); - int64 heightFactor = getHeightFactor(PROGRESS_SPEED_MULTIPLIER); - - //update progresses - this->lastAnimProgress= this->animProgress; - const Game *game = Renderer::getInstance().getGame(); - - if(animProgress==0){ - AnimCycleStarts(); - } - progress = getUpdatedProgress(progress, - GameConstants::updateFps, - speed, diagonalFactor, heightFactor); - - //printf("Test progress = %d for unit [%d - %s]\n",progress,id,getType()->getName().c_str()); - - if(isAnimProgressBound() == true) { - float targetProgress=0; - if(currSkill->getClass() == scBeBuilt) { - targetProgress = this->getHpRatio(); - } - if(currSkill->getClass() == scProduce) { - targetProgress = this->getProgressRatio(); - } - if(currSkill->getClass() == scUpgrade) { - targetProgress = this->getProgressRatio(); - } - if(currSkill->getClass() == scMorph) { - targetProgress = this->getProgressRatio(); - } - - float targetProgressIntValue = targetProgress * ANIMATION_SPEED_MULTIPLIER; - if(this->animProgress < targetProgressIntValue) { - float diff = targetProgressIntValue - this->animProgress; - float progressIncrease = static_cast(this->animProgress) + diff / static_cast(GameConstants::updateFps); - // Ensure we increment at least a value of 1 of the action will be stuck infinitely - if(diff > 0.f && GameConstants::updateFps > 0 && progressIncrease == 0.f) { - progressIncrease = 1.f; - } - - //if(currSkill->getClass() == scBeBuilt) { - // printf("targetProgress: %.10f this->animProgress: %d diff: %.10f GameConstants::updateFps: %d progressIncrease: %.10f\n",targetProgress,this->animProgress,diff,GameConstants::updateFps,progressIncrease); - //} - - this->animProgress = progressIncrease; - - //if(currSkill->getClass() == scBeBuilt) { - // printf("Unit build progress: %d anim: %d\n",progress,this->animProgress); - //} - } - } - else { - int64 heightFactor = getHeightFactor(ANIMATION_SPEED_MULTIPLIER); - int64 speedDenominator = speedDivider * - game->getWorld()->getUpdateFps(this->getFactionIndex()); - - // Override the animation speed for attacks that have upgraded the attack speed - int animSpeed = currSkill->getAnimSpeed(); - if(currSkill->getClass() == scAttack) { - int animSpeedBoost = ((AttackSkillType *) currSkill)->getAnimSpeedBoost(&totalUpgrade); - animSpeed += animSpeedBoost; - } - - int64 progressIncrease = (animSpeed * heightFactor) / speedDenominator; - // Ensure we increment at least a value of 1 of the action will be stuck infinitely - if(currSkill->getAnimSpeed() > 0 && heightFactor > 0 && progressIncrease == 0) { - progressIncrease = 1; - } - this->animProgress += progressIncrease; - //this->animProgress += (currSkill->getAnimSpeed() * heightFactor) / speedDenominator; - - //if(currSkill->getClass() == scDie) { - // printf("Unit died progress: %d anim: %d\n",progress,this->animProgress); - //} - } - //update target - updateTarget(); - - //rotation - if(currSkill->getClass() != scStop) { - const int rotFactor= 2; - if(getProgressAsFloat() < 1.f / rotFactor) { - if(type->getFirstStOfClass(scMove)){ - if(abs((int)(lastRotation-targetRotation)) < 180) - rotation= lastRotation + (targetRotation - lastRotation) * - getProgressAsFloat() * rotFactor; - else { - float rotationTerm = targetRotation > lastRotation ? -360.f: +360.f; - rotation = lastRotation + (targetRotation - lastRotation + rotationTerm) * - getProgressAsFloat() * rotFactor; - } - } - } - } - - if(type->getProperty(UnitType::pRotatedClimb)){ - calculateXZRotation(); - } - else { - rotationZ=.0f; - rotationX=.0f; - } - - if(Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) { - this->fire = NULL; - } - - if (this->fire != NULL) { - this->fire->setPos(getCurrBurnVector()); - } - for(UnitParticleSystems::iterator it= unitParticleSystems.begin(); it != unitParticleSystems.end(); ++it) { - if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setPos(getCurrVectorForParticlesystems()); - (*it)->setRotation(getRotation()); - setMeshPosInParticleSystem(*it); - } - } - for(UnitParticleSystems::iterator it= damageParticleSystems.begin(); it != damageParticleSystems.end(); ++it) { - if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setPos(getCurrVectorForParticlesystems()); - (*it)->setRotation(getRotation()); - setMeshPosInParticleSystem(*it); - } - } - - for(UnitParticleSystems::iterator it= smokeParticleSystems.begin(); it != smokeParticleSystems.end(); ++it) { - if(Renderer::getInstance().validateParticleSystemStillExists((*it),rsGame) == true) { - (*it)->setPos(getCurrMidHeightVector()); - (*it)->setRotation(getRotation()); - setMeshPosInParticleSystem(*it); - } - } - - //printf("Unit has attack boost? unit = [%d - %s] size = %d\n",this->getId(), this->getType()->getName(false).c_str(),(int)currentAttackBoostEffects.size()); - for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if(effect != NULL && effect->ups != NULL) { - bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(effect->ups,rsGame); - if(particleValid == true) { - effect->ups->setPos(getCurrVectorForParticlesystems()); - effect->ups->setRotation(getRotation()); - setMeshPosInParticleSystem(effect->ups); - } - - //printf("i = %d particleValid = %d\n",i,particleValid); - } - //printf("i = %d effect = %p effect->ups = %p\n",i,effect,(effect ? effect->ups : NULL)); - } - - - if(currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) { - if(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != NULL) { - bool particleValid = Renderer::getInstance().validateParticleSystemStillExists(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups,rsGame); - if(particleValid == true) { - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setPos(getCurrVectorForParticlesystems()); - currentAttackBoostOriginatorEffect.currentAppliedEffect->ups->setRotation(getRotation()); - setMeshPosInParticleSystem(currentAttackBoostOriginatorEffect.currentAppliedEffect->ups); - } - } - } - - //checks - if(this->animProgress > ANIMATION_SPEED_MULTIPLIER) { - bool canCycle = currSkill->CanCycleNextRandomAnimation(&animationRandomCycleCount); - this->animProgress = currSkill->getClass() == scDie ? ANIMATION_SPEED_MULTIPLIER : 0; - if(canCycle == true) { - this->lastModelIndexForCurrSkillType = -1; - } - } - - bool return_value = false; - //checks - if(progress >= PROGRESS_SPEED_MULTIPLIER) { - lastRotation= targetRotation; - if(currSkill->getClass() != scDie) { - progress = 0; - return_value = true; - } - else { - progress= PROGRESS_SPEED_MULTIPLIER; - deadCount++; - if(deadCount >= maxDeadCount) { - toBeUndertaken= true; - return_value = false; - } - } - } - - updateAttackBoostProgress(game); - - if(return_value) { - changedActiveCommand = false; - } - - return return_value; -} - -void Unit::updateTimedParticles() { - //!!! - // Start new particle systems based on start time - if(queuedUnitParticleSystemTypes.empty() == false) { - for(int i = (int)queuedUnitParticleSystemTypes.size() - 1; i >= 0; i--) { - UnitParticleSystemType *pst = queuedUnitParticleSystemTypes[i]; - if(pst != NULL) { - if(truncateDecimal(pst->getStartTime(),6) <= truncateDecimal(getAnimProgressAsFloat(),6)) { - - UnitParticleSystem *ups = new UnitParticleSystem(200); - ups->setParticleOwner(this); - ups->setParticleType(pst); - - pst->setValues(ups); - ups->setPos(getCurrVectorForParticlesystems()); - ups->setRotation(getRotation()); - setMeshPosInParticleSystem(ups); - - if(getFaction()->getTexture()) { - ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - unitParticleSystems.push_back(ups); - Renderer::getInstance().manageParticleSystem(ups, rsGame); - - queuedUnitParticleSystemTypes.erase(queuedUnitParticleSystemTypes.begin() + i); - } - } - else { - queuedUnitParticleSystemTypes.erase(queuedUnitParticleSystemTypes.begin() + i); - } - } - } - - // End existing systems based on end time - if(unitParticleSystems.empty() == false) { - for(int i = (int)unitParticleSystems.size() - 1; i >= 0; i--) { - UnitParticleSystem *ps = unitParticleSystems[i]; - if(ps != NULL) { - if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - float pst = ps->getStartTime(); - float pet = ps->getEndTime(); - float particleStartTime = truncateDecimal(pst,6); - float particleEndTime = truncateDecimal(pet,6); - - if(particleStartTime != 0.0 || particleEndTime != 1.0) { - float animProgressTime = truncateDecimal(getAnimProgressAsFloat(),6); - if(animProgressTime >= 0.99 || animProgressTime >= particleEndTime) { - - ps->fade(); - unitParticleSystems.erase(unitParticleSystems.begin() + i); - } - } - } - } - } - } -} - -bool Unit::unitHasAttackBoost(const AttackBoost *boost, const Unit *source) { - bool result = false; - for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if( effect != NULL && effect->boost->name == boost->name && - effect->getSource()->getType()->getId() == source->getType()->getId()) { - result = true; - break; - } - } - - //printf("Unit has attack boost? source = [%d - %s] [%p] boost [%s] result = %d\n",source->getId(), source->getType()->getName(false).c_str(),source,boost->name.c_str(),result); - - return result; -} - -bool Unit::applyAttackBoost(const AttackBoost *boost, const Unit *source) { - if(boost == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - //printf("APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - - bool shouldApplyAttackBoost = true; - if(boost->allowMultipleBoosts == false) { - // Check if we already have this boost from this unit type and multiples - // are not allowed - bool alreadyHasAttackBoost = this->unitHasAttackBoost(boost, source); - if(alreadyHasAttackBoost == true) { - shouldApplyAttackBoost = false; - } - } - - if(shouldApplyAttackBoost == true) { - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("=== APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n",this->getType()->getName(false).c_str(),this->getId(),source->getType()->getName(false).c_str(),source->getId(),hp); - - UnitAttackBoostEffect *effect = new UnitAttackBoostEffect(); - effect->boost = boost; - effect->setSource(source); - - bool wasAlive = alive; - int originalHp = hp; - int prevMaxHp = totalUpgrade.getMaxHp(); - int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); - //printf("#1 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); - - totalUpgrade.apply(source->getId(),&boost->boostUpgrade, this); - - checkItemInVault(&this->hp,this->hp); - //hp += boost->boostUpgrade.getMaxHp(); - int original_hp = this->hp; - this->hp += (totalUpgrade.getMaxHp() - prevMaxHp); - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - - //regenerate hp upgrade / or boost - if(totalUpgrade.getMaxHpRegeneration() != 0) { - checkItemInVault(&this->hp,this->hp); - - //printf("BEFORE Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - int original_hp = this->hp; - this->hp += (totalUpgrade.getMaxHpRegeneration() - prevMaxHpRegen); - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - //if(hp > type->getTotalMaxHp(&totalUpgrade)) { - // hp = type->getTotalMaxHp(&totalUpgrade); - //} - addItemToVault(&this->hp,this->hp); - - //printf("AFTER Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - } - - checkModelStateInfoForNewHpValue(); - - if(originalHp < hp) { - this->setLastAttackerUnitId(source->getId()); - } - //printf("#2 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); - - if(showUnitParticles == true) { - if(boost->unitParticleSystemTypeForAffectedUnit != NULL) { - effect->upst = new UnitParticleSystemType(); - *effect->upst = *boost->unitParticleSystemTypeForAffectedUnit; - //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; - - effect->ups = new UnitParticleSystem(200); - effect->ups->setParticleOwner(this); - effect->ups->setParticleType(effect->upst); - - effect->upst->setValues(effect->ups); - effect->ups->setPos(getCurrVectorForParticlesystems()); - effect->ups->setRotation(getRotation()); - setMeshPosInParticleSystem(effect->ups); - if(getFaction()->getTexture()) { - effect->ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - Renderer::getInstance().manageParticleSystem(effect->ups, rsGame); - } - } - currentAttackBoostEffects.push_back(effect); - - if(wasAlive == true) { - //startDamageParticles - - if(originalHp > this->hp) { - startDamageParticles(); - } - - //stop DamageParticles on death - if(this->hp <= 0) { - setAlive(false); - this->hp=0; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - addItemToVault(&this->hp,this->hp); - checkModelStateInfoForNewHpValue(); - - stopDamageParticles(true); - - this->setLastAttackerUnitId(source->getId()); - this->setCauseOfDeath(ucodAttackBoost); - Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats()); - game->getScriptManager()->onUnitDied(this); - - StaticSound *sound= static_cast(this->getType()->getFirstStOfClass(scDie))->getSound(); - if(sound != NULL && - (this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) { - SoundRenderer::getInstance().playFx(sound); - } - - if(this->isDead() && this->getCurrSkill()->getClass() != scDie) { - this->kill(); - } - } - } - - //printf("APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n",this->getType()->getName(false).c_str(),this->getId(),source->getType()->getName(false).c_str(),source->getId(),hp); - - return shouldApplyAttackBoost; -} - -void Unit::deapplyAttackBoost(const AttackBoost *boost, const Unit *source) { - if(boost == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("=== DE-APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n",this->getType()->getName(false).c_str(),this->getId(),source->getType()->getName(false).c_str(),source->getId(),hp); - - bool wasAlive = alive; - int originalHp = hp; - int prevMaxHp = totalUpgrade.getMaxHp(); - int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration(); - totalUpgrade.deapply(source->getId(),&boost->boostUpgrade, this->getId()); - - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - //hp -= boost->boostUpgrade.getMaxHp(); - this->hp -= (prevMaxHp - totalUpgrade.getMaxHp()); - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - - //regenerate hp upgrade / or boost - if(totalUpgrade.getMaxHpRegeneration() != 0) { - checkItemInVault(&this->hp,this->hp); - - //printf("BEFORE DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - int original_hp = this->hp; - this->hp -= (totalUpgrade.getMaxHpRegeneration() - prevMaxHpRegen); - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - //if(hp > totalUpgrade.getMaxHp()) { - // hp = totalUpgrade.getMaxHp(); - //} - addItemToVault(&this->hp,this->hp); - - //printf("AFTER DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); - } - - if(originalHp < hp) { - this->setLastAttackerUnitId(source->getId()); - } - - if(wasAlive == true) { - //printf("DE-APPLYING ATTACK BOOST wasalive = true to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - - //startDamageParticles - if(originalHp > this->hp) { - startDamageParticles(); - } - - //stop DamageParticles on death - if(this->hp <= 0) { - setAlive(false); - this->hp=0; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - addItemToVault(&this->hp,this->hp); - - checkModelStateInfoForNewHpValue(); - - stopDamageParticles(true); - - this->setLastAttackerUnitId(source->getId()); - this->setCauseOfDeath(ucodAttackBoost); - - Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats()); - game->getScriptManager()->onUnitDied(this); - - StaticSound *sound= static_cast(this->getType()->getFirstStOfClass(scDie))->getSound(); - if(sound != NULL && - (this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) { - SoundRenderer::getInstance().playFx(sound); - } - - if(this->isDead() && this->getCurrSkill()->getClass() != scDie) { - this->kill(); - } - } - } - - checkModelStateInfoForNewHpValue(); - - //printf("DE-APPLYING ATTACK BOOST BEFORE END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); - - for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if(effect != NULL && effect->boost == boost && effect->getSource() == source) { - delete effect; - currentAttackBoostEffects.erase(currentAttackBoostEffects.begin() + i); - break; - } - } - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("DE-APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n",this->getType()->getName(false).c_str(),this->getId(),source->getType()->getName(false).c_str(),source->getId(),hp); - - //printf("DE-APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); -} - -void Unit::tick() { - - if(isAlive()) { - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - //if(this->getType()->getName() == "spearman") printf("Unit [%d - %s] start tick hp = %d\n",this->getId(),this->getType()->getName().c_str(),hp); - - - //regenerate hp upgrade / or boost - if(type->getTotalMaxHpRegeneration(&totalUpgrade) != 0) { - if( currSkill->getClass() != scBeBuilt){ - if(type->getTotalMaxHpRegeneration(&totalUpgrade) >= 0) { - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - this->hp += type->getTotalMaxHpRegeneration(&totalUpgrade); - if(this->hp > type->getTotalMaxHp(&totalUpgrade)) { - this->hp = type->getTotalMaxHp(&totalUpgrade); - } - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - - checkModelStateInfoForNewHpValue(); - //if(this->getType()->getName() == "spearman") printf("tick hp#2 [type->getTotalMaxHpRegeneration(&totalUpgrade)] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getTotalMaxHpRegeneration(&totalUpgrade),type->getTotalMaxHp(&totalUpgrade),hp); - } - // If we have negative regeneration then check if the unit should die - else { - bool decHpResult = decHp(-type->getTotalMaxHpRegeneration(&totalUpgrade)); - if(decHpResult) { - this->setCauseOfDeath(ucodStarvedRegeneration); - - Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats()); - game->getScriptManager()->onUnitDied(this); - } - StaticSound *sound= static_cast(this->getType()->getFirstStOfClass(scDie))->getSound(); - if(sound != NULL && - (this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) { - SoundRenderer::getInstance().playFx(sound); - } - } - } - } - //regenerate hp - else { - if(type->getTotalMaxHpRegeneration(&totalUpgrade) >= 0) { - if( currSkill->getClass() != scBeBuilt){ - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - this->hp += type->getTotalMaxHpRegeneration(&totalUpgrade); - if(this->hp > type->getTotalMaxHp(&totalUpgrade)) { - this->hp = type->getTotalMaxHp(&totalUpgrade); - } - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - - checkModelStateInfoForNewHpValue(); - //if(this->getType()->getName() == "spearman") printf("tick hp#1 [type->getHpRegeneration()] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getHpRegeneration(),type->getTotalMaxHp(&totalUpgrade),hp); - } - } - // If we have negative regeneration then check if the unit should die - else { - bool decHpResult = decHp(-type->getTotalMaxHpRegeneration(&totalUpgrade)); - if(decHpResult) { - this->setCauseOfDeath(ucodStarvedRegeneration); - - Unit::game->getWorld()->getStats()->die(getFactionIndex(),getType()->getCountUnitDeathInStats()); - game->getScriptManager()->onUnitDied(this); - } - StaticSound *sound= static_cast(this->getType()->getFirstStOfClass(scDie))->getSound(); - if(sound != NULL && - (this->getFactionIndex() == Unit::game->getWorld()->getThisFactionIndex() || - (game->getWorld()->showWorldForPlayer(game->getWorld()->getThisTeamIndex()) == true))) { - SoundRenderer::getInstance().playFx(sound); - } - } - } - - //stop DamageParticles - stopDamageParticles(false); - - checkItemInVault(&this->ep,this->ep); - //regenerate ep -// ep += type->getEpRegeneration(); -// if(ep > type->getTotalMaxEp(&totalUpgrade)){ -// ep = type->getTotalMaxEp(&totalUpgrade); -// } -// addItemToVault(&this->ep,this->ep); - - if(!isBeingBuilt()){ - //regenerate ep upgrade / or boost - checkItemInVault(&this->ep,this->ep); - //regenerate ep - int original_ep = this->ep; - this->ep += type->getTotalMaxEpRegeneration(&totalUpgrade); - if(this->ep > type->getTotalMaxEp(&totalUpgrade)){ - this->ep = type->getTotalMaxEp(&totalUpgrade); - } - if(original_ep != this->ep) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_EPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->ep,this->ep); - } - } -} - -int Unit::update2() { - progress2++; - return progress2; -} - -bool Unit::computeEp() { - - if(currSkill == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - //if not enough ep - if(this->ep - currSkill->getEpCost() < 0) { - return true; + void Unit::resetHighlight () + { + highlight = 1.f; } - checkItemInVault(&this->ep,this->ep); - int original_ep = this->ep; - //decrease ep - this->ep -= currSkill->getEpCost(); - if(original_ep != this->ep) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_EPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->ep,this->ep); + const CommandType *Unit::computeCommandType (const Vec2i & pos, + const Unit * + targetUnit) const + { + const CommandType *commandType = NULL; - if(getType() == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + if (map->isInside (pos) == false + || map->isInsideSurface (map->toSurfCoords (pos)) == false) + { + throw megaglest_runtime_error ("#6 Invalid path position = " + + pos.getString ()); + } - if(this->ep > getType()->getTotalMaxEp(&totalUpgrade)){ - int original_ep = this->ep; - this->ep = getType()->getTotalMaxEp(&totalUpgrade); - if(original_ep != this->ep) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_EPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - } - addItemToVault(&this->ep,this->ep); + SurfaceCell *sc = map->getSurfaceCell (Map::toSurfCoords (pos)); - return false; -} + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } -bool Unit::repair(){ + //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)")); + if (targetUnit != NULL) + { + //attack enemies + if (isAlly (targetUnit) == false) + { + commandType = + type->getFirstAttackCommand (targetUnit->getCurrField ()); + } + //repair allies + else + { + if (targetUnit->isBuilt () == false + || targetUnit->isDamaged () == true) + { + commandType = + type->getFirstRepairCommand (targetUnit->getType ()); + } - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + //printf("Line: %d Unit::computeCommandType pos [%s] targetUnit [%s] commandType [%p]\n",__LINE__,pos.getString().c_str(),(targetUnit != NULL ? targetUnit->getType()->getName().c_str() : "(null)"),commandType); - //increase hp - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - if(type->getProductionTime() + 1 == 0) { - throw megaglest_runtime_error("Detected divide by 0 condition: type->getProductionTime() + 1 == 0"); - } - this->hp += getType()->getMaxHp() / type->getProductionTime() + 1; - if(this->hp > (getType()->getTotalMaxHp(&totalUpgrade))) { - this->hp = getType()->getTotalMaxHp(&totalUpgrade); - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - return true; + if (commandType == NULL && targetUnit != NULL) + { + //Command *command= this->getCurrCommand(); + //const HarvestCommandType *hct= dynamic_cast((command != NULL ? command->getCommandType() : NULL)); + + // Check if we can return whatever resources we have + if (targetUnit->getFactionIndex () == this->getFactionIndex () && + targetUnit->isOperative () == true && + this->getLoadType () != NULL && this->getLoadCount () != 0 && + targetUnit->getType () != NULL && + targetUnit->getType ()->getStore (this->getLoadType ()) > 0) + { + + commandType = type->getFirstHarvestEmergencyReturnCommand (); + } + } + } + } + else + { + //check harvest command + Resource *resource = sc->getResource (); + if (resource != NULL) + { + commandType = + type->getFirstHarvestCommand (resource->getType (), + this->getFaction ()); + } + } + + if (targetUnit == NULL && commandType == NULL) + { + const Vec2i unitTargetPos = pos; + Cell *cell = map->getCell (unitTargetPos); + if (cell != NULL && cell->getUnit (this->getCurrField ()) != NULL) + { + Unit *targetUnit = cell->getUnit (this->getCurrField ()); + if (targetUnit != NULL) + { + // Check if we want to help build (repair) any buildings instead of just moving + if (targetUnit->getFactionIndex () == this->getFactionIndex () && + (targetUnit->isBuilt () == false + || targetUnit->isDamaged () == true)) + { + const RepairCommandType *rct = + this->getType ()->getFirstRepairCommand (targetUnit-> + getType ()); + if (rct != NULL) + { + commandType = + type->getFirstRepairCommand (targetUnit->getType ()); + //printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged()); + } + } + } + } + } + + // Default command is the class of the unit (i.e. attack for attackers, walk for walkers). + // The default command is executed when a unit is produced and sent to a meeting point + // or when the unit is selected and right clicked to a position. + if (commandType == NULL) + { + // The default command is move command + commandType = type->getFirstCtOfClass (ccMove); + + // To change the default to attack, comment the line above, and uncomment + // the line of code below + + // Is the unit class warrior? if yes, attack by default, else walk. + //commandType = type->getFirstCtOfClass(this->getType()->isOfClass(ucWarrior) ? ccAttack : ccMove); + + // FIXME: I think a better solution would be to have a hotkey for this, + // the user can decide, and toggle in-game -andy5995 2018-02-03 + } + + return commandType; } - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - checkModelStateInfoForNewHpValue(); + int64 Unit::getUpdateProgress () + { + if (progress > PROGRESS_SPEED_MULTIPLIER) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: progress > " MG_I64_SPECIFIER + ", progress = [" MG_I64_SPECIFIER "]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, PROGRESS_SPEED_MULTIPLIER, + progress); + throw megaglest_runtime_error (szBuf); + } - //stop DamageParticles - stopDamageParticles(false); + if (currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } - return false; -} + int64 newProgress = progress; + if (currSkill->getClass () != scDie) + { + //speed + int speed = currSkill->getTotalSpeed (&totalUpgrade); + + if (changedActiveCommand == true) + { + if (changedActiveCommandFrame - lastChangedActiveCommandFrame >= + MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) + { + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); + speed = CHANGE_COMMAND_SPEED; + } + } + + //speed modifier + int64 diagonalFactor = getDiagonalFactor (); + int64 heightFactor = getHeightFactor (PROGRESS_SPEED_MULTIPLIER); + + //update progresses +// const Game *game = Renderer::getInstance().getGame(); +// if(game == NULL) { +// throw megaglest_runtime_error("game == NULL"); +// } +// if(game->getWorld() == NULL) { +// throw megaglest_runtime_error("game->getWorld() == NULL"); +// } + + newProgress = getUpdatedProgress (progress, GameConstants::updateFps, + speed, diagonalFactor, + heightFactor); + + } + return newProgress; + } + + bool Unit::needToUpdate () + { + bool return_value = false; + if (currSkill->getClass () != scDie) + { + int newProgress = getUpdateProgress (); + if (newProgress >= PROGRESS_SPEED_MULTIPLIER) + { + return_value = true; + } + } + return return_value; + } + + int64 Unit::getDiagonalFactor () + { + //speed modifier + int64 diagonalFactor = PROGRESS_SPEED_MULTIPLIER; + if (currSkill->getClass () == scMove) + { + //if moving in diagonal move slower + Vec2i dest = pos - lastPos; + if (abs (dest.x) + abs (dest.y) == 2) + { + //diagonalFactor = 0.71f * PROGRESS_SPEED_MULTIPLIER; + diagonalFactor = 71 * (PROGRESS_SPEED_MULTIPLIER / 100); + } + } + return diagonalFactor; + } + + int64 Unit::getHeightFactor (int64 speedMultiplier) + { + int64 heightFactor = speedMultiplier; + if (currSkill->getClass () == scMove) + { + //if moving to an higher cell move slower else move faster + Cell *unitCell = map->getCell (pos); + if (unitCell == NULL) + { + throw megaglest_runtime_error ("unitCell == NULL"); + } + + Cell *targetCell = map->getCell (targetPos); + if (targetCell == NULL) + { + throw megaglest_runtime_error ("targetCell == NULL"); + } + + int64 heightDiff = + ((truncateDecimal < + float >(unitCell->getHeight (), + 2) * speedMultiplier) -(truncateDecimal < + float >(targetCell->getHeight (), + 2) * speedMultiplier)); + //heightFactor= clamp(speedMultiplier + heightDiff / (5.f * speedMultiplier), 0.2f * speedMultiplier, 5.f * speedMultiplier); + heightFactor = + clamp (speedMultiplier + heightDiff / (5 * speedMultiplier), + (2 * (speedMultiplier / 10)), 5 * speedMultiplier); + } + + return heightFactor; + } + + int64 Unit::getSpeedDenominator (int64 updateFPS) + { + int64 speedDenominator = + (speedDivider * updateFPS) * PROGRESS_SPEED_MULTIPLIER; + return speedDenominator; + } + int64 Unit::getUpdatedProgress (int64 currentProgress, int64 updateFPS, + int64 speed, int64 diagonalFactor, + int64 heightFactor) + { + + int64 speedDenominator = getSpeedDenominator (updateFPS); + int64 newProgress = currentProgress; + int64 progressIncrease = + ((speed * diagonalFactor * heightFactor) / speedDenominator); + // Ensure we increment at least a value of 1 of the action will be stuck infinitely + if (speed > 0 && diagonalFactor > 0 && heightFactor > 0 + && progressIncrease == 0) + { + progressIncrease = 1; + } + + if (isNetworkCRCEnabled () == true) + { + float height = map->getCell (pos)->getHeight (); + float airHeight = game->getWorld ()->getTileset ()->getAirHeight (); + int cellUnitHeight = -1; + int cellObjectHeight = -1; + + Unit *unit = map->getCell (pos)->getUnit (fLand); + if (unit != NULL && unit->getType ()->getHeight () > airHeight) + { + cellUnitHeight = unit->getType ()->getHeight (); + } + else + { + SurfaceCell *sc = map->getSurfaceCell (map->toSurfCoords (pos)); + if (sc != NULL && sc->getObject () != NULL + && sc->getObject ()->getType () != NULL) + { + if (sc->getObject ()->getType ()->getHeight () > airHeight) + { + cellObjectHeight = sc->getObject ()->getType ()->getHeight (); + } + } + } + + + char szBuf[8096] = ""; + snprintf (szBuf, 8095, + "currentProgress = " MG_I64_SPECIFIER " updateFPS = " + MG_I64_SPECIFIER " speed = " MG_I64_SPECIFIER + " diagonalFactor = " MG_I64_SPECIFIER " heightFactor = " + MG_I64_SPECIFIER " speedDenominator = " MG_I64_SPECIFIER + " progressIncrease = " MG_I64_SPECIFIER " [" + MG_I64_SPECIFIER + "] height [%f] airHeight [%f] cellUnitHeight [%d] cellObjectHeight [%d] skill [%s] pos [%s] lastpos [%s]", + currentProgress, updateFPS, speed, diagonalFactor, + heightFactor, speedDenominator, progressIncrease, + ((speed * diagonalFactor * heightFactor) / + speedDenominator), height, airHeight, cellUnitHeight, + cellObjectHeight, + (currSkill != + NULL ? currSkill->getName ().c_str () : "none"), + pos.getString ().c_str (), lastPos.getString ().c_str ()); + networkCRCLogInfo = szBuf; + + //printf("%s\n",szBuf); + } + + newProgress += progressIncrease; + +// if(currSkill->getClass() == scMove || (currSkill->getClass() == scStop && this->loadCount > 0)) { +// printf("speedDenominator: " MG_I64_SPECIFIER " currentProgress: " MG_I64_SPECIFIER " speed: " MG_I64_SPECIFIER " diagonalFactor: " MG_I64_SPECIFIER " heightFactor: " MG_I64_SPECIFIER " progressIncrease: " MG_I64_SPECIFIER " newProgress: " MG_I64_SPECIFIER " TOP #: " MG_I64_SPECIFIER "\n",speedDenominator,currentProgress,speed,diagonalFactor,heightFactor,progressIncrease,newProgress,(speed * diagonalFactor * heightFactor)); +// } + + return newProgress; + } + + void Unit::updateAttackBoostProgress (const Game * game) + { + const bool debugBoost = false; + if (debugBoost) + printf + ("===================== START Unit [%d - %s] skill: %s affected unit size: " + MG_SIZE_T_SPECIFIER "\n", this->id, + this->getType ()->getName (false).c_str (), + currSkill->getBoostDesc (false).c_str (), + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size ()); + + if (currSkill != currentAttackBoostOriginatorEffect.skillType) + { + + if (debugBoost) + printf ("Line: %d new [%s]\n", __LINE__, + (currentAttackBoostOriginatorEffect.skillType != + NULL ? currentAttackBoostOriginatorEffect.skillType-> + getBoostDesc (false).c_str () : "")); + + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) + { + delete currentAttackBoostOriginatorEffect.currentAppliedEffect; + currentAttackBoostOriginatorEffect.currentAppliedEffect = NULL; + + //printf("- #1 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + + // Remove any units that were previously in range + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty () == false + && currentAttackBoostOriginatorEffect.skillType != NULL) + { + for (unsigned int i = 0; + i < + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size (); ++i) + { + // Remove attack boost upgrades from unit + + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + Unit *affectedUnit = game->getWorld ()->findUnitById (findUnitId); + if (affectedUnit != NULL) + { + affectedUnit-> + deapplyAttackBoost (currentAttackBoostOriginatorEffect. + skillType->getAttackBoost (), this); + } + + //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + currentAttackBoostOriginatorEffect.currentAttackBoostUnits.clear (); + } + + if (debugBoost) + printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size ()); + + currentAttackBoostOriginatorEffect.skillType = currSkill; + + if (currSkill->isAttackBoostEnabled () == true) + { + if (debugBoost) + printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size ()); + + // Search for units in range of this unit which apply to the + // attack-boost and temporarily upgrade them + UnitUpdater *unitUpdater = + this->game->getWorld ()->getUnitUpdater (); + + const AttackBoost *attackBoost = currSkill->getAttackBoost (); + vector < Unit * >candidates = unitUpdater->findUnitsInRange (this, + attackBoost-> + radius); + + if (debugBoost) + printf ("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER + " attackBoost: %s\n", __LINE__, candidates.size (), + attackBoost->getDesc (false).c_str ()); + for (unsigned int i = 0; i < candidates.size (); ++i) + { + Unit *affectedUnit = candidates[i]; + if (attackBoost->isAffected (this, affectedUnit) == true) + { + if (affectedUnit->applyAttackBoost (attackBoost, this) == true) + { + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + push_back (affectedUnit->getId ()); + //printf("+ #1 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } + + if (debugBoost) + printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size ()); + + if (showUnitParticles == true) + { + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty () == false) + { + if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL) + { + currentAttackBoostOriginatorEffect.currentAppliedEffect = + new UnitAttackBoostEffect (); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst = new UnitParticleSystemType (); + *currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst = *attackBoost->unitParticleSystemTypeForSourceUnit; + //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; + + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = + new UnitParticleSystem (200); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setParticleOwner (this); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setParticleType (currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst); + + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst->setValues (currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setPos (getCurrVectorForParticlesystems ()); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setRotation (getRotation ()); + setMeshPosInParticleSystem + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups); + + if (getFaction ()->getTexture ()) + { + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setFactionColor (getFaction ()-> + getTexture ()->getPixmapConst ()-> + getPixel3f (0, 0)); + } + Renderer::getInstance (). + manageParticleSystem (currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups, rsGame); + //printf("+ #1 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + } + } + } + } + else + { + if (currSkill->isAttackBoostEnabled () == true) + { + if (debugBoost) + printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size ()); + + // Search for units in range of this unit which apply to the + // attack-boost and temporarily upgrade them + UnitUpdater *unitUpdater = + this->game->getWorld ()->getUnitUpdater (); + + const AttackBoost *attackBoost = currSkill->getAttackBoost (); + vector < Unit * >candidates = + unitUpdater->findUnitsInRange (this, attackBoost->radius); + vector < int >candidateValidIdList; + candidateValidIdList.reserve (candidates.size ()); + + if (debugBoost) + printf ("Line: %d candidates unit size: " MG_SIZE_T_SPECIFIER + " attackBoost: %s\n", __LINE__, candidates.size (), + attackBoost->getDesc (false).c_str ()); + + for (unsigned int i = 0; i < candidates.size (); ++i) + { + Unit *affectedUnit = candidates[i]; + candidateValidIdList.push_back (affectedUnit->getId ()); + + std::vector < int >::iterator iterFound = + std::find (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.begin (), + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.end (), + affectedUnit->getId ()); + + if (attackBoost->isAffected (this, affectedUnit) == true) + { + if (iterFound == + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + end ()) + { + if (affectedUnit->applyAttackBoost (attackBoost, this) == + true) + { + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + push_back (affectedUnit->getId ()); + + //printf("+ #2 APPLY ATTACK BOOST to unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } + else + { + if (iterFound != + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + end ()) + { + affectedUnit-> + deapplyAttackBoost (currentAttackBoostOriginatorEffect. + skillType->getAttackBoost (), this); + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + erase (iterFound); + + //printf("- #2 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } + + // Now remove any units that were in the list of boosted units but + // are no longer in range + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty () == false) + { + for (int i = + (int)currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size () - 1; i >= 0; --i) + { + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + + std::vector < int >::iterator iterFound = + std::find (candidateValidIdList.begin (), + candidateValidIdList.end (), + findUnitId); + if (iterFound == candidateValidIdList.end ()) + { + Unit *affectedUnit = + game->getWorld ()->findUnitById (findUnitId); + if (affectedUnit != NULL) + { + affectedUnit-> + deapplyAttackBoost (currentAttackBoostOriginatorEffect. + skillType->getAttackBoost (), this); + + if (debugBoost) + printf + ("Removed attack boost from Unit [%d - %s] since they are NO LONGER in range\n", + affectedUnit->id, + affectedUnit->getType ()->getName (false).c_str ()); + + } + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + erase (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.begin () + i); + } + } + } + + if (debugBoost) + printf ("Line: %d affected unit size: " MG_SIZE_T_SPECIFIER "\n", + __LINE__, + currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size ()); + + if (showUnitParticles == true) + { + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty () == false) + { + if (attackBoost->unitParticleSystemTypeForSourceUnit != NULL + && currentAttackBoostOriginatorEffect. + currentAppliedEffect == NULL) + { + + currentAttackBoostOriginatorEffect.currentAppliedEffect = + new UnitAttackBoostEffect (); + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst = new UnitParticleSystemType (); + *currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst = *attackBoost->unitParticleSystemTypeForSourceUnit; + //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; + + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups = + new UnitParticleSystem (200); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setParticleOwner (this); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setParticleType (currentAttackBoostOriginatorEffect. + currentAppliedEffect->upst); + + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + upst->setValues (currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setPos (getCurrVectorForParticlesystems ()); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setRotation (getRotation ()); + setMeshPosInParticleSystem + (currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups); + + if (getFaction ()->getTexture ()) + { + currentAttackBoostOriginatorEffect.currentAppliedEffect-> + ups->setFactionColor (getFaction ()->getTexture ()-> + getPixmapConst ()->getPixel3f (0, + 0)); + } + Renderer::getInstance (). + manageParticleSystem (currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups, rsGame); + + //printf("+ #2 APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + } + else if (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.empty () == true) + { + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != + NULL) + { + delete currentAttackBoostOriginatorEffect. + currentAppliedEffect; + currentAttackBoostOriginatorEffect.currentAppliedEffect = + NULL; + + //printf("- #2 DE-APPLY ATTACK BOOST SELF PARTICLE to unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId()); + } + } + } + } + } + + if (debugBoost) + { + if (currSkill->isAttackBoostEnabled () == true) + { + printf ("Unit [%d - %s] has attackboost enabled: %s\n", this->id, + this->getType ()->getName (false).c_str (), + currSkill->getBoostDesc (false).c_str ()); + + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty () == false) + { + printf + ("Found affected units currentAttackBoostOriginatorEffect.skillType [%p]\n", + currentAttackBoostOriginatorEffect.skillType); + + for (unsigned int i = 0; + i < + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size (); ++i) + { + int unitnum = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + printf ("affected unit #: %u - %d\n", i, unitnum); + } + } + } + } + } + + bool Unit::update () + { + assert (progress <= PROGRESS_SPEED_MULTIPLIER); + + //highlight + if (highlight > 0.f) + { + const Game *game = Renderer::getInstance ().getGame (); + highlight -= + 1.f / (Game::highlightTime * + game->getWorld ()->getUpdateFps (this->getFactionIndex ())); + } + + if (currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + //speed + int speed = currSkill->getTotalSpeed (&totalUpgrade); + + if (oldTotalSight != + getType ()->getTotalSight (this->getTotalUpgrade ())) + { + oldTotalSight = getType ()->getTotalSight (this->getTotalUpgrade ()); + // refresh FogOfWar and so on, because sight ha changed since last update + refreshPos (true); + } + + if (changedActiveCommand) + { + if (changedActiveCommandFrame - lastChangedActiveCommandFrame >= + MIN_FRAMECOUNT_CHANGE_COMMAND_SPEED) + { + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] skill [%s] command [%s]\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,currSkill->toString(false).c_str(),getCurrCommand()->toString(false).c_str()); + //printf("Line: %d speed = %d changedActiveCommandFrame [%u] lastChangedActiveCommandFrame [%u] total = %u\n",__LINE__,speed,changedActiveCommandFrame,lastChangedActiveCommandFrame,(changedActiveCommandFrame - lastChangedActiveCommandFrame)); + speed = CHANGE_COMMAND_SPEED; + } + } + + //speed modifier + int64 diagonalFactor = getDiagonalFactor (); + int64 heightFactor = getHeightFactor (PROGRESS_SPEED_MULTIPLIER); + + //update progresses + this->lastAnimProgress = this->animProgress; + const Game *game = Renderer::getInstance ().getGame (); + + if (animProgress == 0) + { + AnimCycleStarts (); + } + progress = getUpdatedProgress (progress, + GameConstants::updateFps, + speed, diagonalFactor, heightFactor); + + //printf("Test progress = %d for unit [%d - %s]\n",progress,id,getType()->getName().c_str()); + + if (isAnimProgressBound () == true) + { + float targetProgress = 0; + if (currSkill->getClass () == scBeBuilt) + { + targetProgress = this->getHpRatio (); + } + if (currSkill->getClass () == scProduce) + { + targetProgress = this->getProgressRatio (); + } + if (currSkill->getClass () == scUpgrade) + { + targetProgress = this->getProgressRatio (); + } + if (currSkill->getClass () == scMorph) + { + targetProgress = this->getProgressRatio (); + } + + float targetProgressIntValue = + targetProgress * ANIMATION_SPEED_MULTIPLIER; + if (this->animProgress < targetProgressIntValue) + { + float diff = targetProgressIntValue - this->animProgress; + float progressIncrease = + static_cast < float >(this->animProgress) + diff / static_cast < + float >(GameConstants::updateFps); + // Ensure we increment at least a value of 1 of the action will be stuck infinitely + if (diff > 0.f && GameConstants::updateFps > 0 + && progressIncrease == 0.f) + { + progressIncrease = 1.f; + } + + //if(currSkill->getClass() == scBeBuilt) { + // printf("targetProgress: %.10f this->animProgress: %d diff: %.10f GameConstants::updateFps: %d progressIncrease: %.10f\n",targetProgress,this->animProgress,diff,GameConstants::updateFps,progressIncrease); + //} + + this->animProgress = progressIncrease; + + //if(currSkill->getClass() == scBeBuilt) { + // printf("Unit build progress: %d anim: %d\n",progress,this->animProgress); + //} + } + } + else + { + int64 heightFactor = getHeightFactor (ANIMATION_SPEED_MULTIPLIER); + int64 speedDenominator = speedDivider * + game->getWorld ()->getUpdateFps (this->getFactionIndex ()); + + // Override the animation speed for attacks that have upgraded the attack speed + int animSpeed = currSkill->getAnimSpeed (); + if (currSkill->getClass () == scAttack) + { + int animSpeedBoost = + ((AttackSkillType *) currSkill)-> + getAnimSpeedBoost (&totalUpgrade); + animSpeed += animSpeedBoost; + } + + int64 progressIncrease = + (animSpeed * heightFactor) / speedDenominator; + // Ensure we increment at least a value of 1 of the action will be stuck infinitely + if (currSkill->getAnimSpeed () > 0 && heightFactor > 0 + && progressIncrease == 0) + { + progressIncrease = 1; + } + this->animProgress += progressIncrease; + //this->animProgress += (currSkill->getAnimSpeed() * heightFactor) / speedDenominator; + + //if(currSkill->getClass() == scDie) { + // printf("Unit died progress: %d anim: %d\n",progress,this->animProgress); + //} + } + //update target + updateTarget (); + + //rotation + if (currSkill->getClass () != scStop) + { + const int rotFactor = 2; + if (getProgressAsFloat () < 1.f / rotFactor) + { + if (type->getFirstStOfClass (scMove)) + { + if (abs ((int) (lastRotation - targetRotation)) < 180) + rotation = lastRotation + (targetRotation - lastRotation) * + getProgressAsFloat () * rotFactor; + else + { + float rotationTerm = + targetRotation > lastRotation ? -360.f : +360.f; + rotation = + lastRotation + (targetRotation - lastRotation + + rotationTerm) * getProgressAsFloat () * + rotFactor; + } + } + } + } + + if (type->getProperty (UnitType::pRotatedClimb)) + { + calculateXZRotation (); + } + else + { + rotationZ = .0f; + rotationX = .0f; + } + + if (Renderer::getInstance (). + validateParticleSystemStillExists (this->fire, rsGame) == false) + { + this->fire = NULL; + } + + if (this->fire != NULL) + { + this->fire->setPos (getCurrBurnVector ()); + } + for (UnitParticleSystems::iterator it = unitParticleSystems.begin (); + it != unitParticleSystems.end (); ++it) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists ((*it), rsGame) == true) + { + (*it)->setPos (getCurrVectorForParticlesystems ()); + (*it)->setRotation (getRotation ()); + setMeshPosInParticleSystem (*it); + } + } + for (UnitParticleSystems::iterator it = damageParticleSystems.begin (); + it != damageParticleSystems.end (); ++it) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists ((*it), rsGame) == true) + { + (*it)->setPos (getCurrVectorForParticlesystems ()); + (*it)->setRotation (getRotation ()); + setMeshPosInParticleSystem (*it); + } + } + + for (UnitParticleSystems::iterator it = smokeParticleSystems.begin (); + it != smokeParticleSystems.end (); ++it) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists ((*it), rsGame) == true) + { + (*it)->setPos (getCurrMidHeightVector ()); + (*it)->setRotation (getRotation ()); + setMeshPosInParticleSystem (*it); + } + } + + //printf("Unit has attack boost? unit = [%d - %s] size = %d\n",this->getId(), this->getType()->getName(false).c_str(),(int)currentAttackBoostEffects.size()); + for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) + { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->ups != NULL) + { + bool particleValid = + Renderer::getInstance (). + validateParticleSystemStillExists (effect->ups, rsGame); + if (particleValid == true) + { + effect->ups->setPos (getCurrVectorForParticlesystems ()); + effect->ups->setRotation (getRotation ()); + setMeshPosInParticleSystem (effect->ups); + } + + //printf("i = %d particleValid = %d\n",i,particleValid); + } + //printf("i = %d effect = %p effect->ups = %p\n",i,effect,(effect ? effect->ups : NULL)); + } + + + if (currentAttackBoostOriginatorEffect.currentAppliedEffect != NULL) + { + if (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups != + NULL) + { + bool particleValid = + Renderer::getInstance (). + validateParticleSystemStillExists + (currentAttackBoostOriginatorEffect.currentAppliedEffect->ups, + rsGame); + if (particleValid == true) + { + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setPos (getCurrVectorForParticlesystems ()); + currentAttackBoostOriginatorEffect.currentAppliedEffect->ups-> + setRotation (getRotation ()); + setMeshPosInParticleSystem (currentAttackBoostOriginatorEffect. + currentAppliedEffect->ups); + } + } + } + + //checks + if (this->animProgress > ANIMATION_SPEED_MULTIPLIER) + { + bool canCycle = + currSkill->CanCycleNextRandomAnimation (&animationRandomCycleCount); + this->animProgress = + currSkill->getClass () == scDie ? ANIMATION_SPEED_MULTIPLIER : 0; + if (canCycle == true) + { + this->lastModelIndexForCurrSkillType = -1; + } + } + + bool return_value = false; + //checks + if (progress >= PROGRESS_SPEED_MULTIPLIER) + { + lastRotation = targetRotation; + if (currSkill->getClass () != scDie) + { + progress = 0; + return_value = true; + } + else + { + progress = PROGRESS_SPEED_MULTIPLIER; + deadCount++; + if (deadCount >= maxDeadCount) + { + toBeUndertaken = true; + return_value = false; + } + } + } + + updateAttackBoostProgress (game); + + if (return_value) + { + changedActiveCommand = false; + } + + return return_value; + } + + void Unit::updateTimedParticles () + { + //!!! + // Start new particle systems based on start time + if (queuedUnitParticleSystemTypes.empty () == false) + { + for (int i = (int)queuedUnitParticleSystemTypes.size () - 1; i >= 0; + i--) + { + UnitParticleSystemType *pst = queuedUnitParticleSystemTypes[i]; + if (pst != NULL) + { + if (truncateDecimal < float >(pst->getStartTime (), 6) <= + truncateDecimal < float >(getAnimProgressAsFloat (), 6)) + { + + UnitParticleSystem *ups = new UnitParticleSystem (200); + ups->setParticleOwner (this); + ups->setParticleType (pst); + + pst->setValues (ups); + ups->setPos (getCurrVectorForParticlesystems ()); + ups->setRotation (getRotation ()); + setMeshPosInParticleSystem (ups); + + if (getFaction ()->getTexture ()) + { + ups->setFactionColor (getFaction ()->getTexture ()-> + getPixmapConst ()->getPixel3f (0, 0)); + } + unitParticleSystems.push_back (ups); + Renderer::getInstance ().manageParticleSystem (ups, rsGame); + + queuedUnitParticleSystemTypes. + erase (queuedUnitParticleSystemTypes.begin () + i); + } + } + else + { + queuedUnitParticleSystemTypes. + erase (queuedUnitParticleSystemTypes.begin () + i); + } + } + } + + // End existing systems based on end time + if (unitParticleSystems.empty () == false) + { + for (int i = (int)unitParticleSystems.size () - 1; i >= 0; i--) + { + UnitParticleSystem *ps = unitParticleSystems[i]; + if (ps != NULL) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + float pst = ps->getStartTime (); + float pet = ps->getEndTime (); + float particleStartTime = truncateDecimal < float >(pst, 6); + float particleEndTime = truncateDecimal < float >(pet, 6); + + if (particleStartTime != 0.0 || particleEndTime != 1.0) + { + float animProgressTime = + truncateDecimal < float >(getAnimProgressAsFloat (), 6); + if (animProgressTime >= 0.99 + || animProgressTime >= particleEndTime) + { + + ps->fade (); + unitParticleSystems.erase (unitParticleSystems.begin () + + i); + } + } + } + } + } + } + } + + bool Unit::unitHasAttackBoost (const AttackBoost * boost, + const Unit * source) + { + bool result = false; + for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) + { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->boost->name == boost->name && + effect->getSource ()->getType ()->getId () == + source->getType ()->getId ()) + { + result = true; + break; + } + } + + //printf("Unit has attack boost? source = [%d - %s] [%p] boost [%s] result = %d\n",source->getId(), source->getType()->getName(false).c_str(),source,boost->name.c_str(),result); + + return result; + } + + bool Unit::applyAttackBoost (const AttackBoost * boost, + const Unit * source) + { + if (boost == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + //printf("APPLYING ATTACK BOOST to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + + bool shouldApplyAttackBoost = true; + if (boost->allowMultipleBoosts == false) + { + // Check if we already have this boost from this unit type and multiples + // are not allowed + bool alreadyHasAttackBoost = this->unitHasAttackBoost (boost, source); + if (alreadyHasAttackBoost == true) + { + shouldApplyAttackBoost = false; + } + } + + if (shouldApplyAttackBoost == true) + { + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("=== APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType ()->getName (false).c_str (), this->getId (), + source->getType ()->getName (false).c_str (), source->getId (), + hp); + + UnitAttackBoostEffect *effect = new UnitAttackBoostEffect (); + effect->boost = boost; + effect->setSource (source); + + bool wasAlive = alive; + int originalHp = hp; + int prevMaxHp = totalUpgrade.getMaxHp (); + int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration (); + //printf("#1 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); + + totalUpgrade.apply (source->getId (), &boost->boostUpgrade, this); + + checkItemInVault (&this->hp, this->hp); + //hp += boost->boostUpgrade.getMaxHp(); + int original_hp = this->hp; + this->hp += (totalUpgrade.getMaxHp () - prevMaxHp); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + //regenerate hp upgrade / or boost + if (totalUpgrade.getMaxHpRegeneration () != 0) + { + checkItemInVault (&this->hp, this->hp); + + //printf("BEFORE Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + int original_hp = this->hp; + this->hp += (totalUpgrade.getMaxHpRegeneration () - prevMaxHpRegen); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + //if(hp > type->getTotalMaxHp(&totalUpgrade)) { + // hp = type->getTotalMaxHp(&totalUpgrade); + //} + addItemToVault (&this->hp, this->hp); + + //printf("AFTER Apply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + } + + checkModelStateInfoForNewHpValue (); + + if (originalHp < hp) + { + this->setLastAttackerUnitId (source->getId ()); + } + //printf("#2 wasAlive = %d hp = %d boosthp = %d\n",wasAlive,hp,boost->boostUpgrade.getMaxHp()); + + if (showUnitParticles == true) + { + if (boost->unitParticleSystemTypeForAffectedUnit != NULL) + { + effect->upst = new UnitParticleSystemType (); + *effect->upst = *boost->unitParticleSystemTypeForAffectedUnit; + //effect.upst = boost->unitParticleSystemTypeForAffectedUnit; + + effect->ups = new UnitParticleSystem (200); + effect->ups->setParticleOwner (this); + effect->ups->setParticleType (effect->upst); + + effect->upst->setValues (effect->ups); + effect->ups->setPos (getCurrVectorForParticlesystems ()); + effect->ups->setRotation (getRotation ()); + setMeshPosInParticleSystem (effect->ups); + if (getFaction ()->getTexture ()) + { + effect->ups->setFactionColor (getFaction ()->getTexture ()-> + getPixmapConst ()->getPixel3f (0, + 0)); + } + Renderer::getInstance ().manageParticleSystem (effect->ups, + rsGame); + } + } + currentAttackBoostEffects.push_back (effect); + + if (wasAlive == true) + { + //startDamageParticles + + if (originalHp > this->hp) + { + startDamageParticles (); + } + + //stop DamageParticles on death + if (this->hp <= 0) + { + setAlive (false); + this->hp = 0; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + addItemToVault (&this->hp, this->hp); + checkModelStateInfoForNewHpValue (); + + stopDamageParticles (true); + + this->setLastAttackerUnitId (source->getId ()); + this->setCauseOfDeath (ucodAttackBoost); + Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), + getType ()-> + getCountUnitDeathInStats + ()); + game->getScriptManager ()->onUnitDied (this); + + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType ()->getFirstStOfClass (scDie))->getSound (); + if (sound != NULL + && (this->getFactionIndex () == + Unit::game->getWorld ()->getThisFactionIndex () + || (game->getWorld ()-> + showWorldForPlayer (game->getWorld ()-> + getThisTeamIndex ()) == true))) + { + SoundRenderer::getInstance ().playFx (sound); + } + + if (this->isDead () + && this->getCurrSkill ()->getClass () != scDie) + { + this->kill (); + } + } + } + + //printf("APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType ()->getName (false).c_str (), this->getId (), + source->getType ()->getName (false).c_str (), source->getId (), + hp); + + return shouldApplyAttackBoost; + } + + void Unit::deapplyAttackBoost (const AttackBoost * boost, + const Unit * source) + { + if (boost == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: boost == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("=== DE-APPLYING ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType ()->getName (false).c_str (), this->getId (), + source->getType ()->getName (false).c_str (), source->getId (), + hp); + + bool wasAlive = alive; + int originalHp = hp; + int prevMaxHp = totalUpgrade.getMaxHp (); + int prevMaxHpRegen = totalUpgrade.getMaxHpRegeneration (); + totalUpgrade.deapply (source->getId (), &boost->boostUpgrade, + this->getId ()); + + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + //hp -= boost->boostUpgrade.getMaxHp(); + this->hp -= (prevMaxHp - totalUpgrade.getMaxHp ()); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + //regenerate hp upgrade / or boost + if (totalUpgrade.getMaxHpRegeneration () != 0) + { + checkItemInVault (&this->hp, this->hp); + + //printf("BEFORE DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + int original_hp = this->hp; + this->hp -= (totalUpgrade.getMaxHpRegeneration () - prevMaxHpRegen); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + //if(hp > totalUpgrade.getMaxHp()) { + // hp = totalUpgrade.getMaxHp(); + //} + addItemToVault (&this->hp, this->hp); + + //printf("AFTER DeApply Hp Regen max = %d, prev = %d, hp = %d\n",totalUpgrade.getMaxHpRegeneration(),prevMaxHpRegen,hp); + } + + if (originalHp < hp) + { + this->setLastAttackerUnitId (source->getId ()); + } + + if (wasAlive == true) + { + //printf("DE-APPLYING ATTACK BOOST wasalive = true to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + + //startDamageParticles + if (originalHp > this->hp) + { + startDamageParticles (); + } + + //stop DamageParticles on death + if (this->hp <= 0) + { + setAlive (false); + this->hp = 0; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + addItemToVault (&this->hp, this->hp); + + checkModelStateInfoForNewHpValue (); + + stopDamageParticles (true); + + this->setLastAttackerUnitId (source->getId ()); + this->setCauseOfDeath (ucodAttackBoost); + + Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), + getType ()-> + getCountUnitDeathInStats + ()); + game->getScriptManager ()->onUnitDied (this); + + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType ()->getFirstStOfClass (scDie))->getSound (); + if (sound != NULL + && (this->getFactionIndex () == + Unit::game->getWorld ()->getThisFactionIndex () + || (game->getWorld ()-> + showWorldForPlayer (game->getWorld ()-> + getThisTeamIndex ()) == true))) + { + SoundRenderer::getInstance ().playFx (sound); + } + + if (this->isDead () && this->getCurrSkill ()->getClass () != scDie) + { + this->kill (); + } + } + } + + checkModelStateInfoForNewHpValue (); + + //printf("DE-APPLYING ATTACK BOOST BEFORE END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + + for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) + { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL && effect->boost == boost + && effect->getSource () == source) + { + delete effect; + currentAttackBoostEffects.erase (currentAttackBoostEffects. + begin () + i); + break; + } + } + + if (SystemFlags::VERBOSE_MODE_ENABLED) + printf + ("DE-APPLIED ATTACK BOOST START to unit [%s - %d] from unit [%s - %d] hp: %d\n", + this->getType ()->getName (false).c_str (), this->getId (), + source->getType ()->getName (false).c_str (), source->getId (), + hp); + + //printf("DE-APPLYING ATTACK BOOST END to unit [%s - %d] from unit [%s - %d]\n",this->getType()->getName().c_str(),this->getId(),source->getType()->getName().c_str(),source->getId()); + } + + void Unit::tick () + { + + if (isAlive ()) + { + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + //if(this->getType()->getName() == "spearman") printf("Unit [%d - %s] start tick hp = %d\n",this->getId(),this->getType()->getName().c_str(),hp); + + + //regenerate hp upgrade / or boost + if (type->getTotalMaxHpRegeneration (&totalUpgrade) != 0) + { + if (currSkill->getClass () != scBeBuilt) + { + if (type->getTotalMaxHpRegeneration (&totalUpgrade) >= 0) + { + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + this->hp += type->getTotalMaxHpRegeneration (&totalUpgrade); + if (this->hp > type->getTotalMaxHp (&totalUpgrade)) + { + this->hp = type->getTotalMaxHp (&totalUpgrade); + } + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + checkModelStateInfoForNewHpValue (); + //if(this->getType()->getName() == "spearman") printf("tick hp#2 [type->getTotalMaxHpRegeneration(&totalUpgrade)] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getTotalMaxHpRegeneration(&totalUpgrade),type->getTotalMaxHp(&totalUpgrade),hp); + } + // If we have negative regeneration then check if the unit should die + else + { + bool decHpResult = + decHp (-type->getTotalMaxHpRegeneration (&totalUpgrade)); + if (decHpResult) + { + this->setCauseOfDeath (ucodStarvedRegeneration); + + Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), + getType ()-> + getCountUnitDeathInStats + ()); + game->getScriptManager ()->onUnitDied (this); + } + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType ()->getFirstStOfClass (scDie))->getSound (); + if (sound != NULL + && (this->getFactionIndex () == + Unit::game->getWorld ()->getThisFactionIndex () + || (game->getWorld ()-> + showWorldForPlayer (game->getWorld ()-> + getThisTeamIndex ()) == true))) + { + SoundRenderer::getInstance ().playFx (sound); + } + } + } + } + //regenerate hp + else + { + if (type->getTotalMaxHpRegeneration (&totalUpgrade) >= 0) + { + if (currSkill->getClass () != scBeBuilt) + { + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + this->hp += type->getTotalMaxHpRegeneration (&totalUpgrade); + if (this->hp > type->getTotalMaxHp (&totalUpgrade)) + { + this->hp = type->getTotalMaxHp (&totalUpgrade); + } + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + checkModelStateInfoForNewHpValue (); + //if(this->getType()->getName() == "spearman") printf("tick hp#1 [type->getHpRegeneration()] = %d type->getTotalMaxHp(&totalUpgrade) [%d] newhp = %d\n",type->getHpRegeneration(),type->getTotalMaxHp(&totalUpgrade),hp); + } + } + // If we have negative regeneration then check if the unit should die + else + { + bool decHpResult = + decHp (-type->getTotalMaxHpRegeneration (&totalUpgrade)); + if (decHpResult) + { + this->setCauseOfDeath (ucodStarvedRegeneration); + + Unit::game->getWorld ()->getStats ()->die (getFactionIndex (), + getType ()-> + getCountUnitDeathInStats + ()); + game->getScriptManager ()->onUnitDied (this); + } + StaticSound *sound = + static_cast < + const DieSkillType * + >(this->getType ()->getFirstStOfClass (scDie))->getSound (); + if (sound != NULL + && (this->getFactionIndex () == + Unit::game->getWorld ()->getThisFactionIndex () + || (game->getWorld ()-> + showWorldForPlayer (game->getWorld ()-> + getThisTeamIndex ()) == true))) + { + SoundRenderer::getInstance ().playFx (sound); + } + } + } + + //stop DamageParticles + stopDamageParticles (false); + + checkItemInVault (&this->ep, this->ep); + //regenerate ep +// ep += type->getEpRegeneration(); +// if(ep > type->getTotalMaxEp(&totalUpgrade)){ +// ep = type->getTotalMaxEp(&totalUpgrade); +// } +// addItemToVault(&this->ep,this->ep); + + if (!isBeingBuilt ()) + { + //regenerate ep upgrade / or boost + checkItemInVault (&this->ep, this->ep); + //regenerate ep + int original_ep = this->ep; + this->ep += type->getTotalMaxEpRegeneration (&totalUpgrade); + if (this->ep > type->getTotalMaxEp (&totalUpgrade)) + { + this->ep = type->getTotalMaxEp (&totalUpgrade); + } + if (original_ep != this->ep) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_EPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->ep, this->ep); + } + } + } + + int Unit::update2 () + { + progress2++; + return progress2; + } + + bool Unit::computeEp () + { + + if (currSkill == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: currSkill == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + //if not enough ep + if (this->ep - currSkill->getEpCost () < 0) + { + return true; + } + + checkItemInVault (&this->ep, this->ep); + int original_ep = this->ep; + //decrease ep + this->ep -= currSkill->getEpCost (); + if (original_ep != this->ep) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, utet_EPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->ep, this->ep); + + if (getType () == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: getType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + if (this->ep > getType ()->getTotalMaxEp (&totalUpgrade)) + { + int original_ep = this->ep; + this->ep = getType ()->getTotalMaxEp (&totalUpgrade); + if (original_ep != this->ep) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_EPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + } + addItemToVault (&this->ep, this->ep); + + return false; + } + + bool Unit::repair () + { + + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + //increase hp + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + if (type->getProductionTime () + 1 == 0) + { + throw + megaglest_runtime_error + ("Detected divide by 0 condition: type->getProductionTime() + 1 == 0"); + } + this->hp += getType ()->getMaxHp () / type->getProductionTime () + 1; + if (this->hp > (getType ()->getTotalMaxHp (&totalUpgrade))) + { + this->hp = getType ()->getTotalMaxHp (&totalUpgrade); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + return true; + } + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + checkModelStateInfoForNewHpValue (); + + //stop DamageParticles + stopDamageParticles (false); + + return false; + } //decrements HP and returns if dead -bool Unit::decHp(int decrementValue) { - char szBuf[8096]=""; - snprintf(szBuf,8095,"this->hp = %d, decrementValue = %d",this->hp,decrementValue); - addNetworkCRCDecHp(szBuf); + bool Unit::decHp (int decrementValue) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8095, "this->hp = %d, decrementValue = %d", this->hp, + decrementValue); + addNetworkCRCDecHp (szBuf); - if(this->hp == 0) { - return false; - } + if (this->hp == 0) + { + return false; + } - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - this->hp -= decrementValue; - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - - checkModelStateInfoForNewHpValue(); - - if(type == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - //startDamageParticles - startDamageParticles(); - - //stop DamageParticles on death - if(this->hp <= 0) { - setAlive(false); - this->hp = 0; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + this->hp -= decrementValue; + if (original_hp != this->hp) + { //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - addItemToVault(&this->hp,this->hp); + game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); - checkModelStateInfoForNewHpValue(); + checkModelStateInfoForNewHpValue (); - stopDamageParticles(true); - return true; - } - return false; -} + if (type == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } -string Unit::getDescExtension(bool translatedValue) const{ - Lang &lang= Lang::getInstance(); - string str= "\n"; + //startDamageParticles + startDamageParticles (); - if(commands.empty() == false && commands.size() > 1 ){ - Commands::const_iterator it= commands.begin(); - for(unsigned int i= 0; i < min((size_t) maxQueuedCommandDisplayCount, commands.size()); ++i){ - const CommandType *ct= (*it)->getCommandType(); - if(i == 0){ - str+= "\n" + lang.getString("OrdersOnQueue") + ": "; - } - str+= "\n#" + intToStr(i + 1) + " " + ct->getName(translatedValue); - ++it; - } - } + //stop DamageParticles on death + if (this->hp <= 0) + { + setAlive (false); + this->hp = 0; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + addItemToVault (&this->hp, this->hp); - return str; -} + checkModelStateInfoForNewHpValue (); -string Unit::getDesc(bool translatedValue) const { - - Lang &lang= Lang::getInstance(); - - //hp - string str= "\n"; - - //maxUnitCount - if(type->getMaxUnitCount()>0){ - str += lang.getString("MaxUnitCount")+ ": " + intToStr(faction->getCountForMaxUnitCount(type)) + "/" + intToStr(type->getMaxUnitCount()); - } - - str += "\n"+lang.getString("Hp")+ ": " + intToStr(hp) + "/" + intToStr(type->getTotalMaxHp(&totalUpgrade)); - if(type->getHpRegeneration() != 0 || totalUpgrade.getMaxHpRegeneration() != 0) { - str+= " (" + lang.getString("Regeneration") + ": " + intToStr(type->getHpRegeneration()); - if(totalUpgrade.getMaxHpRegeneration() != 0) { - str+= "+" + intToStr(totalUpgrade.getMaxHpRegeneration()); - } - str+= ")"; - } - - //ep - if(getType()->getMaxEp()!=0){ - str+= "\n" + lang.getString("Ep")+ ": " + intToStr(ep) + "/" + intToStr(type->getTotalMaxEp(&totalUpgrade)); - } - if(type->getEpRegeneration() != 0 || totalUpgrade.getMaxEpRegeneration() != 0) { - str+= " (" + lang.getString("Regeneration") + ": " + intToStr(type->getEpRegeneration()); - if(totalUpgrade.getMaxEpRegeneration() != 0) { - str += "+" + intToStr(totalUpgrade.getMaxEpRegeneration()); - } - str+= ")"; - } - - //armor - str+= "\n" + lang.getString("Armor")+ ": " + intToStr(getType()->getArmor()); - if(totalUpgrade.getArmor()!=0){ - str+="+"+intToStr(totalUpgrade.getArmor()); - } - str+= " ("+getType()->getArmorType()->getName(translatedValue)+")"; - - //sight - str+="\n"+ lang.getString("Sight")+ ": " + intToStr(getType()->getSight()); - if(totalUpgrade.getSight()!=0){ - str+="+"+intToStr(totalUpgrade.getSight()); - } - - //kills - const Level *nextLevel= getNextLevel(); - if(enemyKills > 0 || nextLevel != NULL) { - str+= "\n" + lang.getString("Kills") +": " + intToStr(enemyKills); - if(nextLevel != NULL) { - str+= " (" + nextLevel->getName(translatedValue) + ": " + intToStr(nextLevel->getKills()) + ")"; - } - } - - //str+= "\nskl: "+scToStr(currSkill->getClass()); - - //load - if(loadCount!=0){ - str+= "\n" + lang.getString("Load")+ ": " + intToStr(loadCount) +" " + loadType->getName(translatedValue); - } - - //consumable production - for(int i=0; i < getType()->getCostCount(); ++i) { - const Resource *r= getType()->getCost(i); - if(r->getType()->getClass() == rcConsumable) { - str+= "\n"; - str+= r->getAmount() < 0 ? lang.getString("Produce")+": ": lang.getString("Consume")+": "; - str+= intToStr(abs(r->getAmount())) + " " + r->getType()->getName(translatedValue); - } - } - - //command info - if(commands.empty() == false) { - str+= "\n" + commands.front()->getCommandType()->getName(translatedValue); - if(commands.size() > 1) { - str+= "\n" + lang.getString("OrdersOnQueue") + ": " + intToStr(commands.size()); - } - } - else{ - //can store - if(getType()->getStoredResourceCount() > 0) { - for(int i = 0; i < getType()->getStoredResourceCount(); ++i) { - const Resource *r= getType()->getStoredResource(i); - str+= "\n" + lang.getString("Store") + ": "; - str+= intToStr(r->getAmount()) + " " + r->getType()->getName(translatedValue); - } - } - } - - return str; -} - -void Unit::applyUpgrade(const UpgradeType *upgradeType){ - if(upgradeType == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: upgradeType == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - if(upgradeType->isAffected(type)){ - totalUpgrade.sum(upgradeType, this); - - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - this->hp += upgradeType->getMaxHp(); - this->hp = max(0,this->hp); - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - - checkModelStateInfoForNewHpValue(); - } -} - -void Unit::computeTotalUpgrade(){ - faction->getUpgradeManager()->computeTotalUpgrade(this, &totalUpgrade); -} - -void Unit::incKills(int team) { - ++kills; - if(team != this->getTeam()) { - ++enemyKills; - } - - checkUnitLevel(); -} - -void Unit::checkUnitLevel() { - const Level *nextLevel= getNextLevel(); - if(nextLevel != NULL && this->enemyKills >= nextLevel->getKills()) { - this->level= nextLevel; - - int maxHp= this->totalUpgrade.getMaxHp(); - totalUpgrade.incLevel(type); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_LevelChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - this->hp += totalUpgrade.getMaxHp() - maxHp; - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); - - checkModelStateInfoForNewHpValue(); - } -} - -void Unit::morphAttackBoosts(Unit *unit) { - // Remove any units that were previously in range - if(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.empty() == false && currentAttackBoostOriginatorEffect.skillType != NULL) { - for(int i = (int)currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size() - 1; i >= 0; --i) { - // Remove attack boost upgrades from unit - - int findUnitId = currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; - Unit *affectedUnit = game->getWorld()->findUnitById(findUnitId); - if(affectedUnit != NULL && affectedUnit->getId() == unit->getId()) { - affectedUnit->deapplyAttackBoost(currentAttackBoostOriginatorEffect.skillType->getAttackBoost(), this); - - currentAttackBoostOriginatorEffect.currentAttackBoostUnits.erase(currentAttackBoostOriginatorEffect.currentAttackBoostUnits.begin() + i); - } - - //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); - } - } -} - -bool Unit::morph(const MorphCommandType *mct, int frameIndex) { - - if(mct == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: mct == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - const UnitType *morphUnitType= mct->getMorphUnit(); - - if(morphUnitType == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: morphUnitType == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - Field morphUnitField = fLand; - if(morphUnitType->getField(fAir)) { - morphUnitField = fAir; - } - if(morphUnitType->getField(fLand)) { - morphUnitField = fLand; + stopDamageParticles (true); + return true; + } + return false; } - map->clearUnitCells(this, pos, false); - if(map->canMorph(pos,this,morphUnitType)) { - map->clearUnitCells(this, pos, true); - faction->deApplyStaticCosts(type,mct); + string Unit::getDescExtension (bool translatedValue) const + { + Lang & lang = Lang::getInstance (); + string str = "\n"; - //printf("Now unapply attack-boost for unit [%d - %s]\n",this->getId(),this->getType()->getName().c_str()); - // De apply attack boosts for morphed unit - for(int i = (int)currentAttackBoostEffects.size() - 1; i >= 0; --i) { - UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; - if(effect != NULL) { - Unit *sourceUnit = game->getWorld()->findUnitById(effect->getSource()->getId()); - if(sourceUnit == NULL) { - throw megaglest_runtime_error("sourceUnit == NULL"); - } - sourceUnit->morphAttackBoosts(this); - } - } + if (commands.empty () == false && commands.size () > 1) + { + Commands::const_iterator it = commands.begin (); + for (unsigned int i = 0; + i < min ((size_t) maxQueuedCommandDisplayCount, + commands.size ()); ++i) + { + const CommandType *ct = (*it)->getCommandType (); + if (i == 0) + { + str += "\n" + lang.getString ("OrdersOnQueue") + ": "; + } + str += + "\n#" + intToStr (i + 1) + " " + ct->getName (translatedValue); + ++it; + } + } - //stopDamageParticles(true); - cleanupAllParticlesystems(); + return str; + } - checkItemInVault(&this->hp,this->hp); - int original_hp = this->hp; - this->hp += morphUnitType->getMaxHp() - type->getMaxHp(); - if(original_hp != this->hp) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_HPChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } - addItemToVault(&this->hp,this->hp); + string Unit::getDesc (bool translatedValue) const + { - checkModelStateInfoForNewHpValue(); + Lang & lang = Lang::getInstance (); - this->preMorph_type = this->type; - this->setType(morphUnitType); - Field original_field = this->currField; - this->currField=morphUnitField; - computeTotalUpgrade(); - map->putUnitCells(this, this->pos, false, frameIndex < 0); + //hp + string str = "\n"; - this->faction->applyDiscount(morphUnitType, mct->getDiscount()); - // add new storage - this->faction->addStore(this->type); - // remove former storage - this->faction->removeStore(this->preMorph_type); - this->faction->applyStaticProduction(morphUnitType,mct); + //maxUnitCount + if (type->getMaxUnitCount () > 0) + { + str += + lang.getString ("MaxUnitCount") + ": " + + intToStr (faction->getCountForMaxUnitCount (type)) + "/" + + intToStr (type->getMaxUnitCount ()); + } - this->level= NULL; - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_LevelChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - checkUnitLevel(); + str += + "\n" + lang.getString ("Hp") + ": " + intToStr (hp) + "/" + + intToStr (type->getTotalMaxHp (&totalUpgrade)); + if (type->getHpRegeneration () != 0 + || totalUpgrade.getMaxHpRegeneration () != 0) + { + str += + " (" + lang.getString ("Regeneration") + ": " + + intToStr (type->getHpRegeneration ()); + if (totalUpgrade.getMaxHpRegeneration () != 0) + { + str += "+" + intToStr (totalUpgrade.getMaxHpRegeneration ()); + } + str += ")"; + } - if(original_field != this->currField) { - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - game->getScriptManager()->onUnitTriggerEvent(this,utet_FieldChanged); - //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); - } + //ep + if (getType ()->getMaxEp () != 0) + { + str += + "\n" + lang.getString ("Ep") + ": " + intToStr (ep) + "/" + + intToStr (type->getTotalMaxEp (&totalUpgrade)); + } + if (type->getEpRegeneration () != 0 + || totalUpgrade.getMaxEpRegeneration () != 0) + { + str += + " (" + lang.getString ("Regeneration") + ": " + + intToStr (type->getEpRegeneration ()); + if (totalUpgrade.getMaxEpRegeneration () != 0) + { + str += "+" + intToStr (totalUpgrade.getMaxEpRegeneration ()); + } + str += ")"; + } - return true; - } - else{ - return false; - } -} + //armor + str += + "\n" + lang.getString ("Armor") + ": " + + intToStr (getType ()->getArmor ()); + if (totalUpgrade.getArmor () != 0) + { + str += "+" + intToStr (totalUpgrade.getArmor ()); + } + str += + " (" + getType ()->getArmorType ()->getName (translatedValue) + ")"; + + //sight + str += + "\n" + lang.getString ("Sight") + ": " + + intToStr (getType ()->getSight ()); + if (totalUpgrade.getSight () != 0) + { + str += "+" + intToStr (totalUpgrade.getSight ()); + } + + //kills + const Level *nextLevel = getNextLevel (); + if (enemyKills > 0 || nextLevel != NULL) + { + str += "\n" + lang.getString ("Kills") + ": " + intToStr (enemyKills); + if (nextLevel != NULL) + { + str += + " (" + nextLevel->getName (translatedValue) + ": " + + intToStr (nextLevel->getKills ()) + ")"; + } + } + + //str+= "\nskl: "+scToStr(currSkill->getClass()); + + //load + if (loadCount != 0) + { + str += + "\n" + lang.getString ("Load") + ": " + intToStr (loadCount) + + " " + loadType->getName (translatedValue); + } + + //consumable production + for (int i = 0; i < getType ()->getCostCount (); ++i) + { + const Resource *r = getType ()->getCost (i); + if (r->getType ()->getClass () == rcConsumable) + { + str += "\n"; + str += + r->getAmount () < + 0 ? lang.getString ("Produce") + + ": " : lang.getString ("Consume") + ": "; + str += + intToStr (abs (r->getAmount ())) + " " + + r->getType ()->getName (translatedValue); + } + } + + //command info + if (commands.empty () == false) + { + str += + "\n" + + commands.front ()->getCommandType ()->getName (translatedValue); + if (commands.size () > 1) + { + str += + "\n" + lang.getString ("OrdersOnQueue") + ": " + + intToStr (commands.size ()); + } + } + else + { + //can store + if (getType ()->getStoredResourceCount () > 0) + { + for (int i = 0; i < getType ()->getStoredResourceCount (); ++i) + { + const Resource *r = getType ()->getStoredResource (i); + str += "\n" + lang.getString ("Store") + ": "; + str += + intToStr (r->getAmount ()) + " " + + r->getType ()->getName (translatedValue); + } + } + } + + return str; + } + + void Unit::applyUpgrade (const UpgradeType * upgradeType) + { + if (upgradeType == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: upgradeType == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + if (upgradeType->isAffected (type)) + { + totalUpgrade.sum (upgradeType, this); + + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + this->hp += upgradeType->getMaxHp (); + this->hp = max (0, this->hp); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + checkModelStateInfoForNewHpValue (); + } + } + + void Unit::computeTotalUpgrade () + { + faction->getUpgradeManager ()->computeTotalUpgrade (this, + &totalUpgrade); + } + + void Unit::incKills (int team) + { + ++kills; + if (team != this->getTeam ()) + { + ++enemyKills; + } + + checkUnitLevel (); + } + + void Unit::checkUnitLevel () + { + const Level *nextLevel = getNextLevel (); + if (nextLevel != NULL && this->enemyKills >= nextLevel->getKills ()) + { + this->level = nextLevel; + + int maxHp = this->totalUpgrade.getMaxHp (); + totalUpgrade.incLevel (type); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_LevelChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + this->hp += totalUpgrade.getMaxHp () - maxHp; + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + checkModelStateInfoForNewHpValue (); + } + } + + void Unit::morphAttackBoosts (Unit * unit) + { + // Remove any units that were previously in range + if (currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + empty () == false + && currentAttackBoostOriginatorEffect.skillType != NULL) + { + for (int i = + (int)currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + size () - 1; i >= 0; --i) + { + // Remove attack boost upgrades from unit + + int findUnitId = + currentAttackBoostOriginatorEffect.currentAttackBoostUnits[i]; + Unit *affectedUnit = game->getWorld ()->findUnitById (findUnitId); + if (affectedUnit != NULL + && affectedUnit->getId () == unit->getId ()) + { + affectedUnit-> + deapplyAttackBoost (currentAttackBoostOriginatorEffect. + skillType->getAttackBoost (), this); + + currentAttackBoostOriginatorEffect.currentAttackBoostUnits. + erase (currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.begin () + i); + } + + //printf("- #1 DE-APPLY ATTACK BOOST from unit [%s - %d]\n",affectedUnit->getType()->getName().c_str(),affectedUnit->getId()); + } + } + } + + bool Unit::morph (const MorphCommandType * mct, int frameIndex) + { + + if (mct == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: mct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + const UnitType *morphUnitType = mct->getMorphUnit (); + + if (morphUnitType == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: morphUnitType == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + Field morphUnitField = fLand; + if (morphUnitType->getField (fAir)) + { + morphUnitField = fAir; + } + if (morphUnitType->getField (fLand)) + { + morphUnitField = fLand; + } + + map->clearUnitCells (this, pos, false); + if (map->canMorph (pos, this, morphUnitType)) + { + map->clearUnitCells (this, pos, true); + faction->deApplyStaticCosts (type, mct); + + //printf("Now unapply attack-boost for unit [%d - %s]\n",this->getId(),this->getType()->getName().c_str()); + // De apply attack boosts for morphed unit + for (int i = (int)currentAttackBoostEffects.size () - 1; i >= 0; --i) + { + UnitAttackBoostEffect *effect = currentAttackBoostEffects[i]; + if (effect != NULL) + { + Unit *sourceUnit = + game->getWorld ()->findUnitById (effect->getSource ()-> + getId ()); + if (sourceUnit == NULL) + { + throw megaglest_runtime_error ("sourceUnit == NULL"); + } + sourceUnit->morphAttackBoosts (this); + } + } + + //stopDamageParticles(true); + cleanupAllParticlesystems (); + + checkItemInVault (&this->hp, this->hp); + int original_hp = this->hp; + this->hp += morphUnitType->getMaxHp () - type->getMaxHp (); + if (original_hp != this->hp) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_HPChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + addItemToVault (&this->hp, this->hp); + + checkModelStateInfoForNewHpValue (); + + this->preMorph_type = this->type; + this->setType (morphUnitType); + Field original_field = this->currField; + this->currField = morphUnitField; + computeTotalUpgrade (); + map->putUnitCells (this, this->pos, false, frameIndex < 0); + + this->faction->applyDiscount (morphUnitType, mct->getDiscount ()); + // add new storage + this->faction->addStore (this->type); + // remove former storage + this->faction->removeStore (this->preMorph_type); + this->faction->applyStaticProduction (morphUnitType, mct); + + this->level = NULL; + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_LevelChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + checkUnitLevel (); + + if (original_field != this->currField) + { + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + game->getScriptManager ()->onUnitTriggerEvent (this, + utet_FieldChanged); + //printf("File: %s line: %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); + } + + return true; + } + else + { + return false; + } + } // ==================== PRIVATE ==================== -float Unit::computeHeight(const Vec2i &pos) const { - //printf("CRASHING FOR UNIT: %d alive = %d\n",this->getId(),this->isAlive()); - //printf("[%s]\n",this->getType()->getName().c_str()); - if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { - //printf("CRASHING FOR UNIT: %d [%s] alive = %d\n",this->getId(),this->getType()->getName().c_str(),this->isAlive()); - //abort(); - throw megaglest_runtime_error("#7 Invalid path position = " + pos.getString()); - } + float Unit::computeHeight (const Vec2i & pos) const + { + //printf("CRASHING FOR UNIT: %d alive = %d\n",this->getId(),this->isAlive()); + //printf("[%s]\n",this->getType()->getName().c_str()); + if (map->isInside (pos) == false + || map->isInsideSurface (map->toSurfCoords (pos)) == false) + { + //printf("CRASHING FOR UNIT: %d [%s] alive = %d\n",this->getId(),this->getType()->getName().c_str(),this->isAlive()); + //abort(); + throw megaglest_runtime_error ("#7 Invalid path position = " + + pos.getString ()); + } - float height= map->getCell(pos)->getHeight(); + float height = map->getCell (pos)->getHeight (); - if(currField == fAir) { - float airHeight = game->getWorld()->getTileset()->getAirHeight(); - airHeight = truncateDecimal(airHeight,6); + if (currField == fAir) + { + float airHeight = game->getWorld ()->getTileset ()->getAirHeight (); + airHeight = truncateDecimal < float >(airHeight, 6); - height += airHeight; - height = truncateDecimal(height,6); + height += airHeight; + height = truncateDecimal < float >(height, 6); - Unit *unit = map->getCell(pos)->getUnit(fLand); - if(unit != NULL && unit->getType()->getHeight() > airHeight) { - height += (std::min((float)unit->getType()->getHeight(),Tileset::standardAirHeight * 3) - airHeight); - height = truncateDecimal(height,6); - } - else { - SurfaceCell *sc = map->getSurfaceCell(map->toSurfCoords(pos)); - if(sc != NULL && sc->getObject() != NULL && sc->getObject()->getType() != NULL) { - if(sc->getObject()->getType()->getHeight() > airHeight) { - height += (std::min((float)sc->getObject()->getType()->getHeight(),Tileset::standardAirHeight * 3) - airHeight); - height = truncateDecimal(height,6); - } - } - } - } + Unit *unit = map->getCell (pos)->getUnit (fLand); + if (unit != NULL && unit->getType ()->getHeight () > airHeight) + { + height += + (std:: + min ((float) unit->getType ()->getHeight (), + Tileset::standardAirHeight * 3) - airHeight); + height = truncateDecimal < float >(height, 6); + } + else + { + SurfaceCell *sc = map->getSurfaceCell (map->toSurfCoords (pos)); + if (sc != NULL && sc->getObject () != NULL + && sc->getObject ()->getType () != NULL) + { + if (sc->getObject ()->getType ()->getHeight () > airHeight) + { + height += + (std:: + min ((float) sc->getObject ()->getType ()->getHeight (), + Tileset::standardAirHeight * 3) - airHeight); + height = truncateDecimal < float >(height, 6); + } + } + } + } - return height; -} + return height; + } -void Unit::AnimCycleStarts(){ - // we need to queue timed particles if progress starts - queueTimedParticles(currSkill->unitParticleSystemTypes); -} + void Unit::AnimCycleStarts () + { + // we need to queue timed particles if progress starts + queueTimedParticles (currSkill->unitParticleSystemTypes); + } -void Unit::updateTarget(){ - Unit *target= targetRef.getUnit(); - if(target!=NULL){ + void Unit::updateTarget () + { + Unit *target = targetRef.getUnit (); + if (target != NULL) + { - //update target pos - targetPos= target->getCellPos(); - Vec2i relPos= targetPos - pos; - Vec2f relPosf= Vec2f((float)relPos.x, (float)relPos.y); + //update target pos + targetPos = target->getCellPos (); + Vec2i relPos = targetPos - pos; + Vec2f relPosf = Vec2f ((float) relPos.x, (float) relPos.y); #ifdef USE_STREFLOP - targetRotation= radToDeg(streflop::atan2(static_cast(relPosf.x), static_cast(relPosf.y))); + targetRotation = + radToDeg (streflop:: + atan2 (static_cast < streflop::Simple > (relPosf.x), + static_cast < streflop::Simple > (relPosf.y))); #else - targetRotation= radToDeg(atan2(relPosf.x, relPosf.y)); + targetRotation = radToDeg (atan2 (relPosf.x, relPosf.y)); #endif - targetVec= target->getCurrVectorAsTarget(); - } -} - -void Unit::clearCommands() { - - this->setCurrentUnitTitle(""); - this->unitPath->clear(); - while(commands.empty() == false) { - undoCommand(commands.back()); - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); - - delete commands.back(); - commands.pop_back(); - - safeMutex.ReleaseLock(); - } - changedActiveCommand = false; -} - -void Unit::deleteQueuedCommand(Command *command) { - if(getCurrCommand() == command) { - this->setCurrentUnitTitle(""); - this->unitPath->clear(); - } - undoCommand(command); - delete command; -} - - -std::pair Unit::checkCommand(Command *command) const { - std::pair result(crSuccess,""); - - if(command == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - //if not operative or has not command type => fail - if(isOperative() == false || - command->getUnit() == this || - getType()->hasCommandType(command->getCommandType()) == false || - (ignoreCheckCommand == false && this->getFaction()->reqsOk(command->getCommandType()) == false)) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d] isOperative() = %d, command->getUnit() = %p, getType()->hasCommandType(command->getCommandType()) = %d, this->getFaction()->reqsOk(command->getCommandType()) = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__, __LINE__,isOperative(),command->getUnit(),getType()->hasCommandType(command->getCommandType()),this->getFaction()->reqsOk(command->getCommandType())); - - // Allow self healing if able to heal own unit type - if( command->getUnit() == this && - command->getCommandType()->getClass() == ccRepair && - this->getType()->getFirstRepairCommand(this->getType()) != NULL) { - - } - else { - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - - result.first = crFailUndefined; - return result; - } - } - - //if pos is not inside the world (if comand has not a pos, pos is (0, 0) and is inside world - if(map->isInside(command->getPos()) == false) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__, __LINE__); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - - result.first = crFailUndefined; - return result; - } - - //check produced - if(command->getCommandType() == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - const ProducibleType *produced= command->getCommandType()->getProduced(); - if(produced != NULL) { - if(ignoreCheckCommand == false && faction->reqsOk(produced) == false) { - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - //printf("To produce this unit you need:\n%s\n",produced->getUnitAndUpgradeReqDesc().c_str()); - result.first = crFailReqs; - - Lang &lang= Lang::getInstance(); - result.second = " - " + lang.getString("Reqs") + " : " + produced->getUnitAndUpgradeReqDesc(false,this->showTranslatedTechTree()); - return result; - } - - if(ignoreCheckCommand == false && - faction->checkCosts(produced,command->getCommandType()) == false) { - //printf("To produce this unit you need:\n%s\n",produced->getResourceReqDesc().c_str()); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailRes; - Lang &lang= Lang::getInstance(); - result.second = " - " + lang.getString("Reqs") + " : " + produced->getResourceReqDesc(false,this->showTranslatedTechTree()); - return result; - } - } - - //build command specific, check resources and requirements for building - if(command->getCommandType()->getClass() == ccBuild) { - const UnitType *builtUnit= command->getUnitType(); - - if(builtUnit == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: builtUnit == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - if(faction->reqsOk(builtUnit) == false) { - //printf("To build this unit you need:\n%s\n",builtUnit->getUnitAndUpgradeReqDesc().c_str()); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailReqs; - Lang &lang= Lang::getInstance(); - result.second = " - " + lang.getString("Reqs") + " : " + builtUnit->getUnitAndUpgradeReqDesc(false,this->showTranslatedTechTree()); - return result; - } - if(faction->checkCosts(builtUnit,NULL) == false) { - //printf("To build this unit you need:\n%s\n",builtUnit->getResourceReqDesc().c_str()); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailRes; - Lang &lang= Lang::getInstance(); - result.second = " - " + lang.getString("Reqs") + " : " + builtUnit->getResourceReqDesc(false,this->showTranslatedTechTree()); - return result; - } + targetVec = target->getCurrVectorAsTarget (); + } } - //upgrade command specific, check that upgrade is not upgraded - else if(command->getCommandType()->getClass() == ccUpgrade) { - const UpgradeCommandType *uct= static_cast(command->getCommandType()); - if(uct == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + void Unit::clearCommands () + { - if(faction->getUpgradeManager()->isUpgradingOrUpgraded(uct->getProducedUpgrade())){ - if(SystemFlags::getSystemSettingType(SystemFlags::debugLUA).enabled) SystemFlags::OutputDebug(SystemFlags::debugLUA,"In [%s::%s Line: %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__, __LINE__); - //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); - result.first = crFailUndefined; - return result; - } - } + this->setCurrentUnitTitle (""); + this->unitPath->clear (); + while (commands.empty () == false) + { + undoCommand (commands.back ()); - return result; -} + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); -void Unit::applyCommand(Command *command){ - if(command == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - else if(command->getCommandType() == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } + delete commands.back (); + commands.pop_back (); - //check produced - const ProducibleType *produced= command->getCommandType()->getProduced(); - if(produced!=NULL) { - faction->applyCosts(produced,command->getCommandType()); - } - - //build command specific - if(command->getCommandType()->getClass()==ccBuild){ - faction->applyCosts(command->getUnitType(),command->getCommandType()); + safeMutex.ReleaseLock (); + } + changedActiveCommand = false; } - //upgrade command specific - else if(command->getCommandType()->getClass()==ccUpgrade){ - const UpgradeCommandType *uct= static_cast(command->getCommandType()); - - if(uct == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - faction->startUpgrade(uct->getProducedUpgrade()); - } -} - -CommandResult Unit::undoCommand(Command *command){ - - if(command == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - else if(command->getCommandType() == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - if(getCurrCommand() == command && command->getCommandType()->getClass()==ccMorph - && this->currSkill->getClass() == scMorph ){ - // clear cells of morphed unit and set those of current unit! - map->clearUnitCells(this, this->getPos()); - map->putUnitCells(this, this->getPos(),true); - } - //return cost - const ProducibleType *produced= command->getCommandType()->getProduced(); - if(produced!=NULL){ - faction->deApplyCosts(produced,command->getCommandType()); - } - - //return building cost if not already building it or dead - if(command->getCommandType()->getClass() == ccBuild){ - if(currSkill->getClass() != scBuild && currSkill->getClass() != scDie) { - faction->deApplyCosts(command->getUnitType(),command->getCommandType()); - } - } - - //upgrade command cancel from list - if(command->getCommandType()->getClass() == ccUpgrade){ - const UpgradeCommandType *uct= static_cast(command->getCommandType()); - if(uct == NULL) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,this->toString().c_str()); - throw megaglest_runtime_error(szBuf); - } - - faction->cancelUpgrade(uct->getProducedUpgrade()); - } - - retryCurrCommandCount=0; - this->setCurrentUnitTitle(""); - - return crSuccess; -} - -void Unit::stopDamageParticles(bool force) { - if(force == true || (hp > type->getTotalMaxHp(&totalUpgrade) / 2) ) { - //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); - - if(Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) { - this->fire = NULL; - } - - // stop fire - if(this->fire != NULL) { - this->fire->fade(); - this->fire = NULL; - } - // stop additional particles - - - if(smokeParticleSystems.empty() == false) { - //printf("Checking to stop smokeparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); - - for(int i = (int)smokeParticleSystems.size()-1; i >= 0; --i) { - UnitParticleSystem *ps = smokeParticleSystems[i]; - if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - ps->fade(); - } - smokeParticleSystems.pop_back(); - } - } - - if(damageParticleSystems.empty() == false) { - //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); - - for(int i = (int)damageParticleSystems.size()-1; i >= 0; --i) { - UnitParticleSystem *ps = damageParticleSystems[i]; - UnitParticleSystemType *pst = NULL; - int foundParticleIndexType = -2; - if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - for(std::map::iterator iterMap = damageParticleSystemsInUse.begin(); - iterMap != damageParticleSystemsInUse.end(); ++iterMap) { - if(iterMap->second == ps) { - foundParticleIndexType = iterMap->first; - if(foundParticleIndexType >= 0) { - pst = type->damageParticleSystemTypes[foundParticleIndexType]; - break; - } - } - } - } - if(force == true || ( pst !=NULL && pst->getMinmaxEnabled() == false )) { - damageParticleSystemsInUse.erase(foundParticleIndexType); - if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - ps->fade(); - } - damageParticleSystems.pop_back(); - } - } - } - } - - checkCustomizedParticleTriggers(force); -} - -void Unit::checkCustomizedUnitParticleListTriggers(const UnitParticleSystemTypes &unitParticleSystemTypesList, - bool applySkillChangeParticles) { - if(showUnitParticles == true) { - vector systemTypesInUse; - - if(unitParticleSystems.empty() == false) { - for(int index = (int)unitParticleSystems.size() - 1; index >= 0; index--) { - UnitParticleSystem *ps = unitParticleSystems[index]; - if(ps != NULL) { - if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - - bool stopParticle = false; - if((ps->getParticleType() != NULL && - ps->getParticleType()->getMinmaxEnabled())) { - - if(ps->getParticleType() != NULL) { - if(ps->getParticleType()->getMinmaxIsPercent() == false) { - if(hp < ps->getParticleType()->getMinHp() || hp > ps->getParticleType()->getMaxHp()) { - stopParticle = true; - - //printf("STOP Particle line: %d\n",__LINE__); - } - } - else { - int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); - if(hpPercent < ps->getParticleType()->getMinHp() || hpPercent > ps->getParticleType()->getMaxHp()) { - stopParticle = true; - - //printf("STOP Particle line: %d\n",__LINE__); - } - } - } - - if(stopParticle == true) { - ps->fade(); - unitParticleSystems.erase(unitParticleSystems.begin() + index); - } - } - - if(ps->getParticleType() != NULL && stopParticle == false) { - systemTypesInUse.push_back(ps->getParticleType()); - } - } - } - } - } - - //printf("Check Particle start line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypesList.size()); - - if(unitParticleSystemTypesList.empty() == false) { - - //for(unsigned int index = 0; index < unitParticleSystemTypesList.size(); ++index) { - for(UnitParticleSystemTypes::const_iterator iterParticleType = unitParticleSystemTypesList.begin(); - iterParticleType != unitParticleSystemTypesList.end(); ++iterParticleType) { - UnitParticleSystemType *pst = *iterParticleType; - - vector::iterator iterFind = std::find(systemTypesInUse.begin(),systemTypesInUse.end(),pst); - - //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind == systemTypesInUse.end())); - - bool showParticle = applySkillChangeParticles; - if(pst->getMinmaxEnabled() == true) { - - //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind != systemTypesInUse.end())); - - showParticle = false; - if(iterFind == systemTypesInUse.end()) { - if(pst->getMinmaxIsPercent() == false) { - if(hp >= pst->getMinHp() && hp <= pst->getMaxHp()) { - showParticle = true; - - //printf("START Particle line: %d\n",__LINE__); - } - } - else { - int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); - if(hpPercent >= pst->getMinHp() && hpPercent <= pst->getMaxHp()) { - showParticle = true; - - //printf("START Particle line: %d\n",__LINE__); - } - } - } - } - if(showParticle == true){ - if(pst->getStartTime() == 0.0) { - UnitParticleSystem *ups = new UnitParticleSystem(200); - ups->setParticleOwner(this); - ups->setParticleType(pst); - - pst->setValues(ups); - ups->setPos(getCurrVectorForParticlesystems()); - ups->setRotation(getRotation()); - setMeshPosInParticleSystem(ups); - if(getFaction()->getTexture()) { - ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - unitParticleSystems.push_back(ups); - Renderer::getInstance().manageParticleSystem(ups, rsGame); - } - else { - // do nothing, timed particles are handled below in queueTimedParticles() - } - } - } - } - } -} - -void Unit::queueTimedParticles(const UnitParticleSystemTypes &unitParticleSystemTypesList){ - if(showUnitParticles == true) { - for(UnitParticleSystemTypes::const_iterator iterParticleType = unitParticleSystemTypesList.begin(); - iterParticleType != unitParticleSystemTypesList.end(); ++iterParticleType) { - UnitParticleSystemType *pst = *iterParticleType; - if(pst->getMinmaxEnabled() == false) { - if(pst->getStartTime() != 0.0) { - queuedUnitParticleSystemTypes.push_back(pst); - } - } - } - } -} - -void Unit::setMeshPosInParticleSystem(UnitParticleSystem *ups){ - if(ups->getMeshName()!=""){ - string meshName=ups->getMeshName(); - Model *model= getCurrentModelPtr(); - - // as it can happen that anim progress is a bit out of range we correct it to get something valid for the particle positions. - float currentAnimProgress=getAnimProgressAsFloat(); - if( currentAnimProgress>1.f || currentAnimProgress<0.f) { - currentAnimProgress=0.f; - } - model->updateInterpolationVertices(currentAnimProgress, isAlive() && !isAnimProgressBound()); - - bool foundMesh=false; - for(unsigned int i=0; igetMeshCount() ; i++){ - //printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str()); - if(model->getMesh(i)->getName()==meshName){ - const InterpolationData *data=model->getMesh(i)->getInterpolationData(); - const Vec3f *verticepos=data->getVertices(); - ups->setMeshPos(Vec3f(verticepos->x,verticepos->y,verticepos->z)); - foundMesh=true; - break; - } - } - if( foundMesh == false ) { - string meshesFound = model->getMesh(0)->getName(); - for(unsigned i=1; igetMeshCount() ; i++){ - meshesFound+= ", "+model->getMesh(i)->getName(); - } - - string errorString = "Warning: Particle system is trying to find mesh '"+meshName+"', but just found:\n'"+meshesFound+"' in file:\n'"+model->getFileName()+"'\n"; - //throw megaglest_runtime_error(errorString); - printf("%s",errorString.c_str()); - } - } -} - -void Unit::checkCustomizedUnitParticleTriggers() { - if(currSkill != NULL) { - checkCustomizedUnitParticleListTriggers(currSkill->unitParticleSystemTypes,false); - } -} - -void Unit::checkCustomizedParticleTriggers(bool force) { - // - // Now check if we have special pre-exisitng hp triggered particles and - // end those that should no longer display - // - // end s particles - if(damageParticleSystems.empty() == false) { - for(int i = (int)damageParticleSystems.size()-1; i >= 0; --i) { - UnitParticleSystem *ps = damageParticleSystems[i]; - UnitParticleSystemType *pst = NULL; - int foundParticleIndexType = -2; - if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - for(std::map::iterator iterMap = damageParticleSystemsInUse.begin(); - iterMap != damageParticleSystemsInUse.end(); ++iterMap) { - if(iterMap->second == ps) { - foundParticleIndexType = iterMap->first; - if(foundParticleIndexType >= 0) { - pst = type->damageParticleSystemTypes[foundParticleIndexType]; - break; - } - } - } - } - - if(force == true || (pst != NULL && pst->getMinmaxEnabled() == true)) { - bool stopParticle = force; - if(force == false) { - if(pst->getMinmaxIsPercent() == false) { - if(hp < pst->getMinHp() || hp > pst->getMaxHp()) { - stopParticle = true; - } - } - else { - int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); - if(hpPercent < pst->getMinHp() || hpPercent > pst->getMaxHp()) { - stopParticle = true; - } - } - } - - //printf("CHECKING to STOP customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d stopParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,stopParticle); - - if(stopParticle == true) { - //printf("STOPPING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); - - damageParticleSystemsInUse.erase(foundParticleIndexType); - if(Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - ps->fade(); - } - damageParticleSystems.pop_back(); - } - } - } - } - - // - // Now check if we have new special hp triggered particles to display - // - //start additional particles - if(showUnitParticles && - type->damageParticleSystemTypes.empty() == false && - force == false && alive == true) { - for(unsigned int i = 0; i < type->damageParticleSystemTypes.size(); ++i) { - UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; - - if(pst->getMinmaxEnabled() == true && damageParticleSystemsInUse.find(i) == damageParticleSystemsInUse.end()) { - bool showParticle = false; - if(pst->getMinmaxIsPercent() == false) { - if(hp >= pst->getMinHp() && hp <= pst->getMaxHp()) { - showParticle = true; - } - } - else { - int hpPercent = (hp / type->getTotalMaxHp(&totalUpgrade) * 100); - if(hpPercent >= pst->getMinHp() && hpPercent <= pst->getMaxHp()) { - showParticle = true; - } - } - - //printf("CHECKING to START customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d showParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,showParticle); - - if(showParticle == true) { - //printf("STARTING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); - - UnitParticleSystem *ups = new UnitParticleSystem(200); - ups->setParticleOwner(this); - ups->setParticleType(pst); - - pst->setValues(ups); - ups->setPos(getCurrVectorForParticlesystems()); - ups->setRotation(getRotation()); - setMeshPosInParticleSystem(ups); - if(getFaction()->getTexture()) { - ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - damageParticleSystems.push_back(ups); - damageParticleSystemsInUse[i] = ups; - Renderer::getInstance().manageParticleSystem(ups, rsGame); - } - } - } - } - - checkCustomizedUnitParticleTriggers(); -} - -void Unit::startDamageParticles() { - if(hp < type->getTotalMaxHp(&totalUpgrade) / 2 && hp > 0 && alive == true) { - //start additional particles - if( showUnitParticles && - type->damageParticleSystemTypes.empty() == false ) { - for(unsigned int i = 0; i < type->damageParticleSystemTypes.size(); ++i) { - UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; - - if(pst->getMinmaxEnabled() == false && damageParticleSystemsInUse.find(i) == damageParticleSystemsInUse.end()) { - UnitParticleSystem *ups = new UnitParticleSystem(200); - ups->setParticleOwner(this); - ups->setParticleType(pst); - - pst->setValues(ups); - ups->setPos(getCurrVectorForParticlesystems()); - ups->setRotation(getRotation()); - setMeshPosInParticleSystem(ups); - if(getFaction()->getTexture()) { - ups->setFactionColor(getFaction()->getTexture()->getPixmapConst()->getPixel3f(0,0)); - } - damageParticleSystems.push_back(ups); - damageParticleSystemsInUse[i] = ups; - Renderer::getInstance().manageParticleSystem(ups, rsGame); - } - } - } - - // start fire - if(type->getProperty(UnitType::pBurnable) && this->fire == NULL) { - FireParticleSystem *fps = new FireParticleSystem(200); - fps->setParticleOwner(this); - const Game *game = Renderer::getInstance().getGame(); - fps->setSpeed(2.5f / game->getWorld()->getUpdateFps(this->getFactionIndex())); - fps->setPos(getCurrBurnVector()); - fps->setRadius(type->getSize()/3.f); - fps->setTexture(CoreData::getInstance().getFireTexture()); - fps->setParticleSize(type->getSize()/3.f); - this->fire= fps; - fireParticleSystems.push_back(fps); - - Renderer::getInstance().manageParticleSystem(fps, rsGame); - if(showUnitParticles == true) { - // smoke - UnitParticleSystem *ups= new UnitParticleSystem(400); - ups->setParticleOwner(this); - ups->setColorNoEnergy(Vec4f(0.0f, 0.0f, 0.0f, 0.13f)); - ups->setColor(Vec4f(0.115f, 0.115f, 0.115f, 0.22f)); - ups->setPos(getCurrBurnVector()); - ups->setRotation(getRotation()); - setMeshPosInParticleSystem(ups); - ups->setBlendMode(ups->strToBlendMode("black")); - ups->setOffset(Vec3f(0,2,0)); - ups->setDirection(Vec3f(0,1,-0.2f)); - ups->setRadius(type->getSize()/3.f); - ups->setShape(::Shared::Graphics::UnitParticleSystem::sLinear); - ups->setTexture(CoreData::getInstance().getFireTexture()); - const Game *game = Renderer::getInstance().getGame(); - ups->setSpeed(2.0f / game->getWorld()->getUpdateFps(this->getFactionIndex())); - ups->setGravity(0.0004f); - ups->setEmissionRate(1); - ups->setMaxParticleEnergy(150); - ups->setSizeNoEnergy(type->getSize()*0.6f); - ups->setParticleSize(type->getSize()*0.8f); - smokeParticleSystems.push_back(ups); - //damageParticleSystemsInUse[-1] = ups; - Renderer::getInstance().manageParticleSystem(ups, rsGame); - } - } - } - - checkCustomizedParticleTriggers(false); -} - -void Unit::setMeetingPos(const Vec2i &meetingPos) { - this->meetingPos= meetingPos; - map->clampPos(this->meetingPos); - - if(map->isInside(this->meetingPos) == false || map->isInsideSurface(map->toSurfCoords(this->meetingPos)) == false) { - throw megaglest_runtime_error("#8 Invalid path position = " + this->meetingPos.getString()); - } - - logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__); -} - -bool Unit::isMeetingPointSettable() const { - return (type != NULL ? type->getMeetingPoint() : false); -} - -uint32 Unit::getFrameCount() const { - uint32 frameCount = 0; - //const Game *game = Renderer::getInstance().getGame(); - if(game != NULL && game->getWorld() != NULL) { - int frameCountAsInt = game->getWorld()->getFrameCount(); - if(frameCountAsInt >= 0) { - frameCount = frameCountAsInt; - } - } - - return frameCount; -} - -void Unit::exploreCells(bool forceRefresh) { - if(this->isOperative() == true) { - const Vec2i &newPos = this->getCenteredPos(); - int sightRange = this->getType()->getTotalSight(this->getTotalUpgrade()); - int teamIndex = this->getTeam(); - - if(game == NULL) { - throw megaglest_runtime_error("game == NULL"); - } - else if(game->getWorld() == NULL) { - throw megaglest_runtime_error("game->getWorld() == NULL"); - } - - // Try the local unit exploration cache - if( !forceRefresh && - cacheExploredCellsKey.first == newPos && - cacheExploredCellsKey.second == sightRange) { - game->getWorld()->exploreCells(teamIndex, cacheExploredCells); - } - else { - // Try the world exploration scan or possible cache - cacheExploredCells = game->getWorld()->exploreCells(newPos, sightRange, teamIndex, this); - - // Cache the result for this unit - cacheExploredCellsKey.first = newPos; - cacheExploredCellsKey.second = sightRange; - } - } -} - -void Unit::logSynchData(string file,int line,string source) { - logSynchDataCommon(file,line,source,false); -} -void Unit::logSynchDataThreaded(string file,int line,string source) { - logSynchDataCommon(file,line,source,true); -} -void Unit::logSynchDataCommon(string file,int line,string source,bool threadedMode) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096, - "FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, progress [" MG_I64_SPECIFIER "], progress2 [%d] random [%d]\nUnit Path [%s]\n", - getFrameCount(), - id, - getFullName(false).c_str(), - faction->getType()->getName(false).c_str(), - //getDesc().c_str(), - pos.getString().c_str(), - lastPos.getString().c_str(), - targetPos.getString().c_str(), - targetVec.getString().c_str(), - meetingPos.getString().c_str(), -// lastRotation, -// targetRotation, -// rotation, - progress, - progress2, - random.getLastNumber(), - (unitPath != NULL ? unitPath->toString().c_str() : "NULL")); - - if( lastSynchDataString != string(szBuf) || - lastFile != file || - lastLine != line || - lastSource != source) { - lastSynchDataString = string(szBuf); - lastFile = file; - lastSource = source; - - char szBufDataText[8096]=""; - snprintf(szBufDataText,8096,"----------------------------------- START [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName(false).c_str()); - string logDataText = szBufDataText; - - snprintf(szBufDataText,8096,"[%s::%d]\n",extractFileFromDirectoryPath(file).c_str(),line); - logDataText += szBufDataText; - - if(source != "") { - snprintf(szBufDataText,8096,"%s ",source.c_str()); - logDataText += szBufDataText; - } - snprintf(szBufDataText,8096,"%s\n",szBuf); - logDataText += szBufDataText; - snprintf(szBufDataText,8096,"------------------------------------ END [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName(false).c_str()); - logDataText += szBufDataText; + + void Unit::deleteQueuedCommand (Command * command) + { + if (getCurrCommand () == command) + { + this->setCurrentUnitTitle (""); + this->unitPath->clear (); + } + undoCommand (command); + delete command; + } + + + std::pair < CommandResult, string > Unit::checkCommand (Command * command) const + { + std::pair < CommandResult, string > result (crSuccess, ""); + + if (command == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + //if not operative or has not command type => fail + if (isOperative () == false || + command->getUnit () == this || + getType ()->hasCommandType (command->getCommandType ()) == false || + (ignoreCheckCommand == false + && this->getFaction ()->reqsOk (command->getCommandType ()) == + false)) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug (SystemFlags::debugLUA, + "In [%s::%s Line: %d] isOperative() = %d, command->getUnit() = %p, getType()->hasCommandType(command->getCommandType()) = %d, this->getFaction()->reqsOk(command->getCommandType()) = %d\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__, + isOperative (), command->getUnit (), + getType ()->hasCommandType (command-> + getCommandType + ()), + this->getFaction ()->reqsOk (command-> + getCommandType + ())); + + // Allow self healing if able to heal own unit type + if (command->getUnit () == this && + command->getCommandType ()->getClass () == ccRepair && + this->getType ()->getFirstRepairCommand (this->getType ()) != + NULL) + { + + } + else + { + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + + result.first = crFailUndefined; + return result; + } + } + + //if pos is not inside the world (if comand has not a pos, pos is (0, 0) and is inside world + if (map->isInside (command->getPos ()) == false) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA).enabled) + SystemFlags::OutputDebug (SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + + result.first = crFailUndefined; + return result; + } + + //check produced + if (command->getCommandType () == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + const ProducibleType *produced = + command->getCommandType ()->getProduced (); + if (produced != NULL) + { + if (ignoreCheckCommand == false + && faction->reqsOk (produced) == false) + { + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + //printf("To produce this unit you need:\n%s\n",produced->getUnitAndUpgradeReqDesc().c_str()); + result.first = crFailReqs; + + Lang & lang = Lang::getInstance (); + result.second = + " - " + lang.getString ("Reqs") + " : " + + produced->getUnitAndUpgradeReqDesc (false, + this-> + showTranslatedTechTree ()); + return result; + } + + if (ignoreCheckCommand == false && + faction->checkCosts (produced, + command->getCommandType ()) == false) + { + //printf("To produce this unit you need:\n%s\n",produced->getResourceReqDesc().c_str()); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailRes; + Lang & lang = Lang::getInstance (); + result.second = + " - " + lang.getString ("Reqs") + " : " + + produced->getResourceReqDesc (false, + this->showTranslatedTechTree ()); + return result; + } + } + + //build command specific, check resources and requirements for building + if (command->getCommandType ()->getClass () == ccBuild) + { + const UnitType *builtUnit = command->getUnitType (); + + if (builtUnit == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: builtUnit == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + if (faction->reqsOk (builtUnit) == false) + { + //printf("To build this unit you need:\n%s\n",builtUnit->getUnitAndUpgradeReqDesc().c_str()); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailReqs; + Lang & lang = Lang::getInstance (); + result.second = + " - " + lang.getString ("Reqs") + " : " + + builtUnit->getUnitAndUpgradeReqDesc (false, + this-> + showTranslatedTechTree ()); + return result; + } + if (faction->checkCosts (builtUnit, NULL) == false) + { + //printf("To build this unit you need:\n%s\n",builtUnit->getResourceReqDesc().c_str()); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailRes; + Lang & lang = Lang::getInstance (); + result.second = + " - " + lang.getString ("Reqs") + " : " + + builtUnit->getResourceReqDesc (false, + this->showTranslatedTechTree ()); + return result; + } + } + //upgrade command specific, check that upgrade is not upgraded + else if (command->getCommandType ()->getClass () == ccUpgrade) + { + const UpgradeCommandType *uct = + static_cast < + const UpgradeCommandType * >(command->getCommandType ()); + + if (uct == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + if (faction->getUpgradeManager ()-> + isUpgradingOrUpgraded (uct->getProducedUpgrade ())) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugLUA). + enabled) + SystemFlags::OutputDebug (SystemFlags::debugLUA, + "In [%s::%s Line: %d]\n", + extractFileFromDirectoryPath (__FILE__). + c_str (), __FUNCTION__, __LINE__); + //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); + result.first = crFailUndefined; + return result; + } + } + + return result; + } + + void Unit::applyCommand (Command * command) + { + if (command == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + else if (command->getCommandType () == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + //check produced + const ProducibleType *produced = + command->getCommandType ()->getProduced (); + if (produced != NULL) + { + faction->applyCosts (produced, command->getCommandType ()); + } + + //build command specific + if (command->getCommandType ()->getClass () == ccBuild) + { + faction->applyCosts (command->getUnitType (), + command->getCommandType ()); + } + //upgrade command specific + else if (command->getCommandType ()->getClass () == ccUpgrade) + { + const UpgradeCommandType *uct = + static_cast < + const UpgradeCommandType * >(command->getCommandType ()); + + if (uct == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + faction->startUpgrade (uct->getProducedUpgrade ()); + } + } + + CommandResult Unit::undoCommand (Command * command) + { + + if (command == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + else if (command->getCommandType () == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: command->getCommandType() == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + if (getCurrCommand () == command + && command->getCommandType ()->getClass () == ccMorph + && this->currSkill->getClass () == scMorph) + { + // clear cells of morphed unit and set those of current unit! + map->clearUnitCells (this, this->getPos ()); + map->putUnitCells (this, this->getPos (), true); + } + //return cost + const ProducibleType *produced = + command->getCommandType ()->getProduced (); + if (produced != NULL) + { + faction->deApplyCosts (produced, command->getCommandType ()); + } + + //return building cost if not already building it or dead + if (command->getCommandType ()->getClass () == ccBuild) + { + if (currSkill->getClass () != scBuild + && currSkill->getClass () != scDie) + { + faction->deApplyCosts (command->getUnitType (), + command->getCommandType ()); + } + } + + //upgrade command cancel from list + if (command->getCommandType ()->getClass () == ccUpgrade) + { + const UpgradeCommandType *uct = + static_cast < + const UpgradeCommandType * >(command->getCommandType ()); + if (uct == NULL) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "In [%s::%s Line: %d] ERROR: uct == NULL, Unit = [%s]\n", + extractFileFromDirectoryPath (__FILE__).c_str (), + __FUNCTION__, __LINE__, this->toString ().c_str ()); + throw megaglest_runtime_error (szBuf); + } + + faction->cancelUpgrade (uct->getProducedUpgrade ()); + } + + retryCurrCommandCount = 0; + this->setCurrentUnitTitle (""); + + return crSuccess; + } + + void Unit::stopDamageParticles (bool force) + { + if (force == true || (hp > type->getTotalMaxHp (&totalUpgrade) / 2)) + { + //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); + + if (Renderer::getInstance (). + validateParticleSystemStillExists (this->fire, rsGame) == false) + { + this->fire = NULL; + } + + // stop fire + if (this->fire != NULL) + { + this->fire->fade (); + this->fire = NULL; + } + // stop additional particles + + + if (smokeParticleSystems.empty () == false) + { + //printf("Checking to stop smokeparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); + + for (int i = (int)smokeParticleSystems.size () - 1; i >= 0; --i) + { + UnitParticleSystem *ps = smokeParticleSystems[i]; + if (Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + ps->fade (); + } + smokeParticleSystems.pop_back (); + } + } + + if (damageParticleSystems.empty () == false) + { + //printf("Checking to stop damageparticles for unit [%s - %d] hp = %d\n",this->getType()->getName().c_str(),this->getId(),hp); + + for (int i = (int)damageParticleSystems.size () - 1; i >= 0; --i) + { + UnitParticleSystem *ps = damageParticleSystems[i]; + UnitParticleSystemType *pst = NULL; + int foundParticleIndexType = -2; + if (Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + for (std::map < int, UnitParticleSystem * >::iterator iterMap = + damageParticleSystemsInUse.begin (); + iterMap != damageParticleSystemsInUse.end (); ++iterMap) + { + if (iterMap->second == ps) + { + foundParticleIndexType = iterMap->first; + if (foundParticleIndexType >= 0) + { + pst = + type->damageParticleSystemTypes[foundParticleIndexType]; + break; + } + } + } + } + if (force == true + || (pst != NULL && pst->getMinmaxEnabled () == false)) + { + damageParticleSystemsInUse.erase (foundParticleIndexType); + if (Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + ps->fade (); + } + damageParticleSystems.pop_back (); + } + } + } + } + + checkCustomizedParticleTriggers (force); + } + + void Unit:: + checkCustomizedUnitParticleListTriggers (const UnitParticleSystemTypes & + unitParticleSystemTypesList, + bool applySkillChangeParticles) + { + if (showUnitParticles == true) + { + vector < ParticleSystemTypeInterface * >systemTypesInUse; + + if (unitParticleSystems.empty () == false) + { + for (int index = (int)unitParticleSystems.size () - 1; index >= 0; + index--) + { + UnitParticleSystem *ps = unitParticleSystems[index]; + if (ps != NULL) + { + if (Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + + bool stopParticle = false; + if ((ps->getParticleType () != NULL && + ps->getParticleType ()->getMinmaxEnabled ())) + { + + if (ps->getParticleType () != NULL) + { + if (ps->getParticleType ()->getMinmaxIsPercent () == + false) + { + if (hp < ps->getParticleType ()->getMinHp () + || hp > ps->getParticleType ()->getMaxHp ()) + { + stopParticle = true; + + //printf("STOP Particle line: %d\n",__LINE__); + } + } + else + { + int hpPercent = + (hp / type->getTotalMaxHp (&totalUpgrade) * 100); + if (hpPercent < ps->getParticleType ()->getMinHp () + || hpPercent > ps->getParticleType ()->getMaxHp ()) + { + stopParticle = true; + + //printf("STOP Particle line: %d\n",__LINE__); + } + } + } + + if (stopParticle == true) + { + ps->fade (); + unitParticleSystems.erase (unitParticleSystems.begin () + + index); + } + } + + if (ps->getParticleType () != NULL && stopParticle == false) + { + systemTypesInUse.push_back (ps->getParticleType ()); + } + } + } + } + } + + //printf("Check Particle start line: %d size: %d\n",__LINE__,(int)unitParticleSystemTypesList.size()); + + if (unitParticleSystemTypesList.empty () == false) + { + + //for(unsigned int index = 0; index < unitParticleSystemTypesList.size(); ++index) { + for (UnitParticleSystemTypes::const_iterator iterParticleType = + unitParticleSystemTypesList.begin (); + iterParticleType != unitParticleSystemTypesList.end (); + ++iterParticleType) + { + UnitParticleSystemType *pst = *iterParticleType; + + vector < ParticleSystemTypeInterface * >::iterator iterFind = + std::find (systemTypesInUse.begin (), systemTypesInUse.end (), + pst); + + //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind == systemTypesInUse.end())); + + bool showParticle = applySkillChangeParticles; + if (pst->getMinmaxEnabled () == true) + { + + //printf("Check Particle line: %d isenabled: %d already in use: %d\n",__LINE__,pst->getMinmaxEnabled(),(iterFind != systemTypesInUse.end())); + + showParticle = false; + if (iterFind == systemTypesInUse.end ()) + { + if (pst->getMinmaxIsPercent () == false) + { + if (hp >= pst->getMinHp () && hp <= pst->getMaxHp ()) + { + showParticle = true; + + //printf("START Particle line: %d\n",__LINE__); + } + } + else + { + int hpPercent = + (hp / type->getTotalMaxHp (&totalUpgrade) * 100); + if (hpPercent >= pst->getMinHp () + && hpPercent <= pst->getMaxHp ()) + { + showParticle = true; + + //printf("START Particle line: %d\n",__LINE__); + } + } + } + } + if (showParticle == true) + { + if (pst->getStartTime () == 0.0) + { + UnitParticleSystem *ups = new UnitParticleSystem (200); + ups->setParticleOwner (this); + ups->setParticleType (pst); + + pst->setValues (ups); + ups->setPos (getCurrVectorForParticlesystems ()); + ups->setRotation (getRotation ()); + setMeshPosInParticleSystem (ups); + if (getFaction ()->getTexture ()) + { + ups->setFactionColor (getFaction ()->getTexture ()-> + getPixmapConst ()->getPixel3f (0, 0)); + } + unitParticleSystems.push_back (ups); + Renderer::getInstance ().manageParticleSystem (ups, rsGame); + } + else + { + // do nothing, timed particles are handled below in queueTimedParticles() + } + } + } + } + } + } + + void Unit:: + queueTimedParticles (const UnitParticleSystemTypes & + unitParticleSystemTypesList) + { + if (showUnitParticles == true) + { + for (UnitParticleSystemTypes::const_iterator iterParticleType = + unitParticleSystemTypesList.begin (); + iterParticleType != unitParticleSystemTypesList.end (); + ++iterParticleType) + { + UnitParticleSystemType *pst = *iterParticleType; + if (pst->getMinmaxEnabled () == false) + { + if (pst->getStartTime () != 0.0) + { + queuedUnitParticleSystemTypes.push_back (pst); + } + } + } + } + } + + void Unit::setMeshPosInParticleSystem (UnitParticleSystem * ups) + { + if (ups->getMeshName () != "") + { + string meshName = ups->getMeshName (); + Model *model = getCurrentModelPtr (); + + // as it can happen that anim progress is a bit out of range we correct it to get something valid for the particle positions. + float currentAnimProgress = getAnimProgressAsFloat (); + if (currentAnimProgress > 1.f || currentAnimProgress < 0.f) + { + currentAnimProgress = 0.f; + } + model->updateInterpolationVertices (currentAnimProgress, isAlive () + && !isAnimProgressBound ()); + + bool foundMesh = false; + for (unsigned int i = 0; i < model->getMeshCount (); i++) + { + //printf("meshName=%s\n",unitModel->getMesh(i)->getName().c_str()); + if (model->getMesh (i)->getName () == meshName) + { + const InterpolationData *data = + model->getMesh (i)->getInterpolationData (); + const Vec3f *verticepos = data->getVertices (); + ups-> + setMeshPos (Vec3f + (verticepos->x, verticepos->y, verticepos->z)); + foundMesh = true; + break; + } + } + if (foundMesh == false) + { + string meshesFound = model->getMesh (0)->getName (); + for (unsigned i = 1; i < model->getMeshCount (); i++) + { + meshesFound += ", " + model->getMesh (i)->getName (); + } + + string errorString = + "Warning: Particle system is trying to find mesh '" + meshName + + "', but just found:\n'" + meshesFound + "' in file:\n'" + + model->getFileName () + "'\n"; + //throw megaglest_runtime_error(errorString); + printf ("%s", errorString.c_str ()); + } + } + } + + void Unit::checkCustomizedUnitParticleTriggers () + { + if (currSkill != NULL) + { + checkCustomizedUnitParticleListTriggers (currSkill-> + unitParticleSystemTypes, + false); + } + } + + void Unit::checkCustomizedParticleTriggers (bool force) + { + // + // Now check if we have special pre-exisitng hp triggered particles and + // end those that should no longer display + // + // end s particles + if (damageParticleSystems.empty () == false) + { + for (int i = (int)damageParticleSystems.size () - 1; i >= 0; --i) + { + UnitParticleSystem *ps = damageParticleSystems[i]; + UnitParticleSystemType *pst = NULL; + int foundParticleIndexType = -2; + if (Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + for (std::map < int, UnitParticleSystem * >::iterator iterMap = + damageParticleSystemsInUse.begin (); + iterMap != damageParticleSystemsInUse.end (); ++iterMap) + { + if (iterMap->second == ps) + { + foundParticleIndexType = iterMap->first; + if (foundParticleIndexType >= 0) + { + pst = + type->damageParticleSystemTypes[foundParticleIndexType]; + break; + } + } + } + } + + if (force == true + || (pst != NULL && pst->getMinmaxEnabled () == true)) + { + bool stopParticle = force; + if (force == false) + { + if (pst->getMinmaxIsPercent () == false) + { + if (hp < pst->getMinHp () || hp > pst->getMaxHp ()) + { + stopParticle = true; + } + } + else + { + int hpPercent = + (hp / type->getTotalMaxHp (&totalUpgrade) * 100); + if (hpPercent < pst->getMinHp () + || hpPercent > pst->getMaxHp ()) + { + stopParticle = true; + } + } + } + + //printf("CHECKING to STOP customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d stopParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,stopParticle); + + if (stopParticle == true) + { + //printf("STOPPING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); + + damageParticleSystemsInUse.erase (foundParticleIndexType); + if (Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + ps->fade (); + } + damageParticleSystems.pop_back (); + } + } + } + } + + // + // Now check if we have new special hp triggered particles to display + // + //start additional particles + if (showUnitParticles && + type->damageParticleSystemTypes.empty () == false && + force == false && alive == true) + { + for (unsigned int i = 0; i < type->damageParticleSystemTypes.size (); + ++i) + { + UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; + + if (pst->getMinmaxEnabled () == true + && damageParticleSystemsInUse.find (i) == + damageParticleSystemsInUse.end ()) + { + bool showParticle = false; + if (pst->getMinmaxIsPercent () == false) + { + if (hp >= pst->getMinHp () && hp <= pst->getMaxHp ()) + { + showParticle = true; + } + } + else + { + int hpPercent = + (hp / type->getTotalMaxHp (&totalUpgrade) * 100); + if (hpPercent >= pst->getMinHp () + && hpPercent <= pst->getMaxHp ()) + { + showParticle = true; + } + } + + //printf("CHECKING to START customized particle trigger by HP [%d to %d percentbased = %d] current hp = %d showParticle = %d\n",pst->getMinHp(),pst->getMaxHp(),pst->getMinmaxIsPercent(),hp,showParticle); + + if (showParticle == true) + { + //printf("STARTING customized particle trigger by HP [%d to %d] current hp = %d\n",pst->getMinHp(),pst->getMaxHp(),hp); + + UnitParticleSystem *ups = new UnitParticleSystem (200); + ups->setParticleOwner (this); + ups->setParticleType (pst); + + pst->setValues (ups); + ups->setPos (getCurrVectorForParticlesystems ()); + ups->setRotation (getRotation ()); + setMeshPosInParticleSystem (ups); + if (getFaction ()->getTexture ()) + { + ups->setFactionColor (getFaction ()->getTexture ()-> + getPixmapConst ()->getPixel3f (0, 0)); + } + damageParticleSystems.push_back (ups); + damageParticleSystemsInUse[i] = ups; + Renderer::getInstance ().manageParticleSystem (ups, rsGame); + } + } + } + } + + checkCustomizedUnitParticleTriggers (); + } + + void Unit::startDamageParticles () + { + if (hp < type->getTotalMaxHp (&totalUpgrade) / 2 && hp > 0 + && alive == true) + { + //start additional particles + if (showUnitParticles && + type->damageParticleSystemTypes.empty () == false) + { + for (unsigned int i = 0; + i < type->damageParticleSystemTypes.size (); ++i) + { + UnitParticleSystemType *pst = type->damageParticleSystemTypes[i]; + + if (pst->getMinmaxEnabled () == false + && damageParticleSystemsInUse.find (i) == + damageParticleSystemsInUse.end ()) + { + UnitParticleSystem *ups = new UnitParticleSystem (200); + ups->setParticleOwner (this); + ups->setParticleType (pst); + + pst->setValues (ups); + ups->setPos (getCurrVectorForParticlesystems ()); + ups->setRotation (getRotation ()); + setMeshPosInParticleSystem (ups); + if (getFaction ()->getTexture ()) + { + ups->setFactionColor (getFaction ()->getTexture ()-> + getPixmapConst ()->getPixel3f (0, 0)); + } + damageParticleSystems.push_back (ups); + damageParticleSystemsInUse[i] = ups; + Renderer::getInstance ().manageParticleSystem (ups, rsGame); + } + } + } + + // start fire + if (type->getProperty (UnitType::pBurnable) && this->fire == NULL) + { + FireParticleSystem *fps = new FireParticleSystem (200); + fps->setParticleOwner (this); + const Game *game = Renderer::getInstance ().getGame (); + fps->setSpeed (2.5f / + game->getWorld ()->getUpdateFps (this-> + getFactionIndex + ())); + fps->setPos (getCurrBurnVector ()); + fps->setRadius (type->getSize () / 3.f); + fps->setTexture (CoreData::getInstance ().getFireTexture ()); + fps->setParticleSize (type->getSize () / 3.f); + this->fire = fps; + fireParticleSystems.push_back (fps); + + Renderer::getInstance ().manageParticleSystem (fps, rsGame); + if (showUnitParticles == true) + { + // smoke + UnitParticleSystem *ups = new UnitParticleSystem (400); + ups->setParticleOwner (this); + ups->setColorNoEnergy (Vec4f (0.0f, 0.0f, 0.0f, 0.13f)); + ups->setColor (Vec4f (0.115f, 0.115f, 0.115f, 0.22f)); + ups->setPos (getCurrBurnVector ()); + ups->setRotation (getRotation ()); + setMeshPosInParticleSystem (ups); + ups->setBlendMode (ups->strToBlendMode ("black")); + ups->setOffset (Vec3f (0, 2, 0)); + ups->setDirection (Vec3f (0, 1, -0.2f)); + ups->setRadius (type->getSize () / 3.f); + ups->setShape (::Shared::Graphics::UnitParticleSystem::sLinear); + ups->setTexture (CoreData::getInstance ().getFireTexture ()); + const Game *game = Renderer::getInstance ().getGame (); + ups->setSpeed (2.0f / + game->getWorld ()->getUpdateFps (this-> + getFactionIndex + ())); + ups->setGravity (0.0004f); + ups->setEmissionRate (1); + ups->setMaxParticleEnergy (150); + ups->setSizeNoEnergy (type->getSize () * 0.6f); + ups->setParticleSize (type->getSize () * 0.8f); + smokeParticleSystems.push_back (ups); + //damageParticleSystemsInUse[-1] = ups; + Renderer::getInstance ().manageParticleSystem (ups, rsGame); + } + } + } + + checkCustomizedParticleTriggers (false); + } + + void Unit::setMeetingPos (const Vec2i & meetingPos) + { + this->meetingPos = meetingPos; + map->clampPos (this->meetingPos); + + if (map->isInside (this->meetingPos) == false + || map->isInsideSurface (map->toSurfCoords (this->meetingPos)) == + false) + { + throw megaglest_runtime_error ("#8 Invalid path position = " + + this->meetingPos.getString ()); + } + + logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), + __LINE__); + } + + bool Unit::isMeetingPointSettable () const + { + return (type != NULL ? type->getMeetingPoint () : false); + } + + uint32 Unit::getFrameCount () const + { + uint32 frameCount = 0; + //const Game *game = Renderer::getInstance().getGame(); + if (game != NULL && game->getWorld () != NULL) + { + int frameCountAsInt = game->getWorld ()->getFrameCount (); + if (frameCountAsInt >= 0) + { + frameCount = frameCountAsInt; + } + } + + return frameCount; + } + + void Unit::exploreCells (bool forceRefresh) + { + if (this->isOperative () == true) + { + const Vec2i & newPos = this->getCenteredPos (); + int sightRange = + this->getType ()->getTotalSight (this->getTotalUpgrade ()); + int teamIndex = this->getTeam (); + + if (game == NULL) + { + throw megaglest_runtime_error ("game == NULL"); + } + else if (game->getWorld () == NULL) + { + throw megaglest_runtime_error ("game->getWorld() == NULL"); + } + + // Try the local unit exploration cache + if (!forceRefresh && + cacheExploredCellsKey.first == newPos && + cacheExploredCellsKey.second == sightRange) + { + game->getWorld ()->exploreCells (teamIndex, cacheExploredCells); + } + else + { + // Try the world exploration scan or possible cache + cacheExploredCells = + game->getWorld ()->exploreCells (newPos, sightRange, teamIndex, + this); + + // Cache the result for this unit + cacheExploredCellsKey.first = newPos; + cacheExploredCellsKey.second = sightRange; + } + } + } + + void Unit::logSynchData (string file, int line, string source) + { + logSynchDataCommon (file, line, source, false); + } + void Unit::logSynchDataThreaded (string file, int line, string source) + { + logSynchDataCommon (file, line, source, true); + } + void Unit::logSynchDataCommon (string file, int line, string source, + bool threadedMode) + { + if (SystemFlags::getSystemSettingType (SystemFlags::debugWorldSynch). + enabled == true) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "FrameCount [%d] Unit = %d [%s][%s] pos = %s, lastPos = %s, targetPos = %s, targetVec = %s, meetingPos = %s, progress [" + MG_I64_SPECIFIER + "], progress2 [%d] random [%d]\nUnit Path [%s]\n", + getFrameCount (), id, getFullName (false).c_str (), + faction->getType ()->getName (false).c_str (), + //getDesc().c_str(), + pos.getString ().c_str (), + lastPos.getString ().c_str (), + targetPos.getString ().c_str (), + targetVec.getString ().c_str (), + meetingPos.getString ().c_str (), +// lastRotation, +// targetRotation, +// rotation, + progress, + progress2, + random.getLastNumber (), + (unitPath != + NULL ? unitPath->toString ().c_str () : "NULL")); + + if (lastSynchDataString != string (szBuf) || + lastFile != file || lastLine != line || lastSource != source) + { + lastSynchDataString = string (szBuf); + lastFile = file; + lastSource = source; + + char szBufDataText[8096] = ""; + snprintf (szBufDataText, 8096, + "----------------------------------- START [FRAME %d UNIT: %d - %s] ------------------------------------------------\n", + getFrameCount (), this->id, + this->getType ()->getName (false).c_str ()); + string logDataText = szBufDataText; + + snprintf (szBufDataText, 8096, "[%s::%d]\n", + extractFileFromDirectoryPath (file).c_str (), line); + logDataText += szBufDataText; + + if (source != "") + { + snprintf (szBufDataText, 8096, "%s ", source.c_str ()); + logDataText += szBufDataText; + } + snprintf (szBufDataText, 8096, "%s\n", szBuf); + logDataText += szBufDataText; + snprintf (szBufDataText, 8096, + "------------------------------------ END [FRAME %d UNIT: %d - %s] ------------------------------------------------\n", + getFrameCount (), this->id, + this->getType ()->getName (false).c_str ()); + logDataText += szBufDataText; /* SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"----------------------------------- START [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName().c_str()); SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"[%s::%d]\n",extractFileFromDirectoryPath(file).c_str(),line); @@ -4569,1360 +6331,1799 @@ void Unit::logSynchDataCommon(string file,int line,string source,bool threadedMo SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s\n",szBuf); SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"------------------------------------ END [FRAME %d UNIT: %d - %s] ------------------------------------------------\n",getFrameCount(),this->id,this->getType()->getName().c_str()); */ - if(threadedMode == false) { - SystemFlags::OutputDebug(SystemFlags::debugWorldSynch,"%s",logDataText.c_str()); - } - else { - this->faction->addWorldSynchThreadedLogList(logDataText); - } - } - } -} + if (threadedMode == false) + { + SystemFlags::OutputDebug (SystemFlags::debugWorldSynch, "%s", + logDataText.c_str ()); + } + else + { + this->faction->addWorldSynchThreadedLogList (logDataText); + } + } + } + } -void Unit::addBadHarvestPos(const Vec2i &value) { - //Chrono chron; - //chron.start(); - badHarvestPosList[value] = getFrameCount(); - cleanupOldBadHarvestPos(); -} + void Unit::addBadHarvestPos (const Vec2i & value) + { + //Chrono chron; + //chron.start(); + badHarvestPosList[value] = getFrameCount (); + cleanupOldBadHarvestPos (); + } //void Unit::removeBadHarvestPos(const Vec2i &value) { -// std::map::iterator iter = badHarvestPosList.find(value); -// if(iter != badHarvestPosList.end()) { -// badHarvestPosList.erase(value); -// } -// cleanupOldBadHarvestPos(); +// std::map::iterator iter = badHarvestPosList.find(value); +// if(iter != badHarvestPosList.end()) { +// badHarvestPosList.erase(value); +// } +// cleanupOldBadHarvestPos(); //} -void Unit::cleanupOldBadHarvestPos() { - const unsigned int cleanupInterval = (GameConstants::updateFps * 5); - bool needToCleanup = (getFrameCount() % cleanupInterval == 0); + void Unit::cleanupOldBadHarvestPos () + { + const unsigned int cleanupInterval = (GameConstants::updateFps * 5); + bool needToCleanup = (getFrameCount () % cleanupInterval == 0); - //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld] cleanupInterval [%d] getFrameCount() [%d] needToCleanup [%d]\n",getFrameCount(),badHarvestPosList.size(),cleanupInterval,getFrameCount(),needToCleanup); + //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld] cleanupInterval [%d] getFrameCount() [%d] needToCleanup [%d]\n",getFrameCount(),badHarvestPosList.size(),cleanupInterval,getFrameCount(),needToCleanup); - if(needToCleanup == true) { - //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld]\n",getFrameCount(),badHarvestPosList.size()); + if (needToCleanup == true) + { + //printf("========================> cleanupOldBadHarvestPos() [%d] badHarvestPosList.size [%ld]\n",getFrameCount(),badHarvestPosList.size()); - std::vector purgeList; - for(std::map::iterator iter = badHarvestPosList.begin(); iter != badHarvestPosList.end(); ++iter) { - if(getFrameCount() - iter->second >= cleanupInterval) { - //printf("cleanupOldBadHarvestPos() [%d][%d]\n",getFrameCount(),iter->second); - purgeList.push_back(iter->first); - } - } + std::vector < Vec2i > purgeList; + for (std::map < Vec2i, int >::iterator iter = + badHarvestPosList.begin (); iter != badHarvestPosList.end (); + ++iter) + { + if (getFrameCount () - iter->second >= cleanupInterval) + { + //printf("cleanupOldBadHarvestPos() [%d][%d]\n",getFrameCount(),iter->second); + purgeList.push_back (iter->first); + } + } - if(purgeList.empty() == false) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[cleaning old bad harvest targets] purgeList.size() [" MG_SIZE_T_SPECIFIER "]",purgeList.size()); - logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + if (purgeList.empty () == false) + { + char szBuf[8096] = ""; + snprintf (szBuf, 8096, + "[cleaning old bad harvest targets] purgeList.size() [" + MG_SIZE_T_SPECIFIER "]", purgeList.size ()); + logSynchData (extractFileFromDirectoryPath (__FILE__).c_str (), + __LINE__, szBuf); - for(int i = 0; i < (int)purgeList.size(); ++i) { - const Vec2i &item = purgeList[i]; - badHarvestPosList.erase(item); - } - } - } -} + for (int i = 0; i < (int) purgeList.size (); ++i) + { + const Vec2i & item = purgeList[i]; + badHarvestPosList.erase (item); + } + } + } + } -void Unit::setLastHarvestResourceTarget(const Vec2i *pos) { - if(pos == NULL) { - lastHarvestResourceTarget.first = Vec2i(0); - //lastHarvestResourceTarget.second = 0; - } - else { - const Vec2i resourceLocation = *pos; - if(resourceLocation != lastHarvestResourceTarget.first) { - lastHarvestResourceTarget.first = resourceLocation; + void Unit::setLastHarvestResourceTarget (const Vec2i * pos) + { + if (pos == NULL) + { + lastHarvestResourceTarget.first = Vec2i (0); + //lastHarvestResourceTarget.second = 0; + } + else + { + const Vec2i resourceLocation = *pos; + if (resourceLocation != lastHarvestResourceTarget.first) + { + lastHarvestResourceTarget.first = resourceLocation; - //Chrono chron; - //chron.start(); - lastHarvestResourceTarget.second = getFrameCount(); - } - else { - // If we cannot harvest for > 10 seconds tag the position - // as a bad one - const unsigned int addInterval = (GameConstants::updateFps * 5); - if(lastHarvestResourceTarget.second - getFrameCount() >= addInterval) { - //printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second); - addBadHarvestPos(resourceLocation); - } - } - } -} + //Chrono chron; + //chron.start(); + lastHarvestResourceTarget.second = getFrameCount (); + } + else + { + // If we cannot harvest for > 10 seconds tag the position + // as a bad one + const unsigned int addInterval = (GameConstants::updateFps * 5); + if (lastHarvestResourceTarget.second - getFrameCount () >= + addInterval) + { + //printf("-----------------------> setLastHarvestResourceTarget() [%d][%d]\n",getFrameCount(),lastHarvestResourceTarget.second); + addBadHarvestPos (resourceLocation); + } + } + } + } //void Unit::addCurrentTargetPathTakenCell(const Vec2i &target,const Vec2i &cell) { -// if(currentTargetPathTaken.first != target) { -// currentTargetPathTaken.second.clear(); -// } -// currentTargetPathTaken.first = target; -// currentTargetPathTaken.second.push_back(cell); +// if(currentTargetPathTaken.first != target) { +// currentTargetPathTaken.second.clear(); +// } +// currentTargetPathTaken.first = target; +// currentTargetPathTaken.second.push_back(cell); //} -void Unit::setLastPathfindFailedFrameToCurrentFrame() { - lastPathfindFailedFrame = getFrameCount(); -} - -bool Unit::isLastPathfindFailedFrameWithinCurrentFrameTolerance() const { - //static const bool enablePathfinderEnlargeMaxNodes = Config::getInstance().getBool("EnablePathfinderEnlargeMaxNodes","false"); - static const bool enablePathfinderEnlargeMaxNodes = false; - bool result = enablePathfinderEnlargeMaxNodes; - if(enablePathfinderEnlargeMaxNodes) { - const uint32 MIN_FRAME_ELAPSED_RETRY = 960; - result = (getFrameCount() - lastPathfindFailedFrame >= MIN_FRAME_ELAPSED_RETRY); - } - return result; -} - -void Unit::setLastStuckFrameToCurrentFrame() { - lastStuckFrame = getFrameCount(); -} - -bool Unit::isLastStuckFrameWithinCurrentFrameTolerance(bool evalMode) { - //const int MIN_FRAME_ELAPSED_RETRY = 300; - const uint32 MAX_BLOCKED_FRAME_THRESHOLD = 25000; - uint32 MIN_FRAME_ELAPSED_RETRY = 6; - if(lastStuckFrame < MAX_BLOCKED_FRAME_THRESHOLD) { - if(evalMode == true) { - MIN_FRAME_ELAPSED_RETRY = 4; - } - else { - MIN_FRAME_ELAPSED_RETRY = random.randRange(2,6,intToStr(__LINE__)); - } - } - else { - if(evalMode == true) { - MIN_FRAME_ELAPSED_RETRY = 7; - } - else { - MIN_FRAME_ELAPSED_RETRY = random.randRange(6,8,intToStr(__LINE__)); - } - } - bool result (getFrameCount() - lastStuckFrame <= (MIN_FRAME_ELAPSED_RETRY * 100)); - return result; -} - -Vec2i Unit::getPosWithCellMapSet() const { - Vec2i cellMapPos = this->getType()->getFirstOccupiedCellInCellMap(pos); - return cellMapPos; -} - -string Unit::getUniquePickName() const { - string result = intToStr(id) + " - " + type->getName(false) + " : "; - result += pos.getString(); - return result; -} - -Vec2i Unit::getPos() { - Vec2i result; - - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(mutexCommands,mutexOwnerId); - result = this->pos; - safeMutex.ReleaseLock(); - - return result; -} - -void Unit::clearCaches() { - cachedFow.surfPosAlphaList.clear(); - cachedFowPos = Vec2i(0,0); - - cacheExploredCells.exploredCellList.clear(); - cacheExploredCells.visibleCellList.clear(); - cacheExploredCellsKey.first = Vec2i(-1,-1); - cacheExploredCellsKey.second = -1; - - if(unitPath != NULL) { - unitPath->clearCaches(); - } - - lastHarvestedResourcePos = Vec2i(0,0); -} - -bool Unit::showTranslatedTechTree() const { - return (this->game != NULL ? this->game->showTranslatedTechTree() : true); -} - -string Unit::getNetworkCRCDecHpList() const { - string result = ""; - if(networkCRCDecHpList.empty() == false) { - for(unsigned int index = 0; index < networkCRCDecHpList.size(); ++index) { - result += networkCRCDecHpList[index] + " "; - } - } - return result; -} -std::string Unit::toString(bool crcMode) const { - std::string result = ""; - - result += "id = " + intToStr(this->id); - if(this->type != NULL) { - result += " name [" + this->type->getName(false) + "][" + intToStr(this->type->getId()) + "]"; - } - - if(this->faction != NULL) { - result += "\nFactionIndex = " + intToStr(this->faction->getIndex()) + "\n"; - result += "teamIndex = " + intToStr(this->faction->getTeam()) + "\n"; - result += "startLocationIndex = " + intToStr(this->faction->getStartLocationIndex()) + "\n"; - if(crcMode == false) { - result += "thisFaction = " + intToStr(this->faction->getThisFaction()) + "\n"; - result += "control = " + intToStr(this->faction->getControlType()) + "\n"; - } - if(this->faction->getType() != NULL) { - result += "factionName = " + this->faction->getType()->getName(false) + "\n"; - } - } - - result += " hp = " + intToStr(this->hp); - result += " ep = " + intToStr(this->ep); - result += " loadCount = " + intToStr(this->loadCount); - result += " deadCount = " + intToStr(this->deadCount); - result += " progress = " + intToStr(this->progress); - result += "\n"; - result += "networkCRCLogInfo = " + networkCRCLogInfo; - result += "\n"; - if(crcMode == false) { - result += " lastAnimProgress = " + intToStr(this->lastAnimProgress); - result += " animProgress = " + intToStr(this->animProgress); - result += " highlight = " + floatToStr(this->highlight,6); - } - result += " progress2 = " + intToStr(this->progress2); - result += " kills = " + intToStr(this->kills); - result += " enemyKills = " + intToStr(this->enemyKills); - result += "\n"; - - // WARNING!!! Don't access the Unit pointer in this->targetRef in this method or it causes - // a stack overflow - if(this->targetRef.getUnitId() >= 0) { - //result += " targetRef = " + this->targetRef.getUnit()->toString(); - result += " targetRef = " + intToStr(this->targetRef.getUnitId()) + " - factionIndex = " + intToStr(this->targetRef.getUnitFaction()->getIndex()); - } - - result += " currField = " + intToStr(this->currField); - result += " targetField = " + intToStr(this->targetField); - if(level != NULL) { - result += " level = " + level->getName(); - } - result += "\n"; - result += " pos = " + pos.getString(); - result += " lastPos = " + lastPos.getString(); - result += "\n"; - result += " targetPos = " + targetPos.getString(); - result += " targetVec = " + targetVec.getString(); - result += " meetingPos = " + meetingPos.getString(); - result += "\n"; - - if(crcMode == false) { - result += " lastRotation = " + floatToStr(this->lastRotation,6); - result += " targetRotation = " + floatToStr(this->targetRotation,6); - result += " rotation = " + floatToStr(this->rotation,6); - } - - if(loadType != NULL) { - result += " loadType = " + loadType->getName(); + void Unit::setLastPathfindFailedFrameToCurrentFrame () + { + lastPathfindFailedFrame = getFrameCount (); } - if(currSkill != NULL) { - result += " currSkill = " + currSkill->getName(); + bool Unit::isLastPathfindFailedFrameWithinCurrentFrameTolerance () const + { + //static const bool enablePathfinderEnlargeMaxNodes = Config::getInstance().getBool("EnablePathfinderEnlargeMaxNodes","false"); + static const bool enablePathfinderEnlargeMaxNodes = false; + bool result = enablePathfinderEnlargeMaxNodes; + if (enablePathfinderEnlargeMaxNodes) + { + const uint32 MIN_FRAME_ELAPSED_RETRY = 960; + result = + (getFrameCount () - lastPathfindFailedFrame >= + MIN_FRAME_ELAPSED_RETRY); + } + return result; } - result += "\n"; - result += " toBeUndertaken = " + intToStr(this->toBeUndertaken); - result += " alive = " + intToStr(this->alive); - result += " showUnitParticles = " + intToStr(this->showUnitParticles); - - result += " totalUpgrade = " + totalUpgrade.toString(); - result += " " + this->unitPath->toString() + "\n"; - result += "\n"; - - result += "Command count = " + intToStr(commands.size()) + "\n"; - - int cmdIdx = 0; - for(Commands::const_iterator iterList = commands.begin(); iterList != commands.end(); ++iterList) { - result += " index = " + intToStr(cmdIdx) + " "; - const Command *cmd = *iterList; - if(cmd != NULL) { - result += cmd->toString(false) + "\n"; - } - cmdIdx++; + void Unit::setLastStuckFrameToCurrentFrame () + { + lastStuckFrame = getFrameCount (); } - result += "\n"; + + bool Unit::isLastStuckFrameWithinCurrentFrameTolerance (bool evalMode) + { + //const int MIN_FRAME_ELAPSED_RETRY = 300; + const uint32 MAX_BLOCKED_FRAME_THRESHOLD = 25000; + uint32 MIN_FRAME_ELAPSED_RETRY = 6; + if (lastStuckFrame < MAX_BLOCKED_FRAME_THRESHOLD) + { + if (evalMode == true) + { + MIN_FRAME_ELAPSED_RETRY = 4; + } + else + { + MIN_FRAME_ELAPSED_RETRY = + random.randRange (2, 6, intToStr (__LINE__)); + } + } + else + { + if (evalMode == true) + { + MIN_FRAME_ELAPSED_RETRY = 7; + } + else + { + MIN_FRAME_ELAPSED_RETRY = + random.randRange (6, 8, intToStr (__LINE__)); + } + } + bool result (getFrameCount () - lastStuckFrame <= + (MIN_FRAME_ELAPSED_RETRY * 100)); + return result; + } + + Vec2i Unit::getPosWithCellMapSet () const + { + Vec2i cellMapPos = + this->getType ()->getFirstOccupiedCellInCellMap (pos); + return cellMapPos; + } + + string Unit::getUniquePickName () const + { + string result = intToStr (id) + " - " + type->getName (false) + " : "; + result += pos.getString (); + return result; + } + + Vec2i Unit::getPos () + { + Vec2i result; + + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (mutexCommands, mutexOwnerId); + result = this->pos; + safeMutex.ReleaseLock (); + + return result; + } + + void Unit::clearCaches () + { + cachedFow.surfPosAlphaList.clear (); + cachedFowPos = Vec2i (0, 0); + + cacheExploredCells.exploredCellList.clear (); + cacheExploredCells.visibleCellList.clear (); + cacheExploredCellsKey.first = Vec2i (-1, -1); + cacheExploredCellsKey.second = -1; + + if (unitPath != NULL) + { + unitPath->clearCaches (); + } + + lastHarvestedResourcePos = Vec2i (0, 0); + } + + bool Unit::showTranslatedTechTree () const + { + return (this->game != + NULL ? this->game->showTranslatedTechTree () : true); + } + + string Unit::getNetworkCRCDecHpList () const + { + string result = ""; + if (networkCRCDecHpList.empty () == false) + { + for (unsigned int index = 0; index < networkCRCDecHpList.size (); + ++index) + { + result += networkCRCDecHpList[index] + " "; + } + } + return result; + } + std::string Unit::toString (bool crcMode) const + { + std::string result = ""; + + result += "id = " + intToStr (this->id); + if (this->type != NULL) + { + result += + " name [" + this->type->getName (false) + "][" + + intToStr (this->type->getId ()) + "]"; + } + + if (this->faction != NULL) + { + result += + "\nFactionIndex = " + intToStr (this->faction->getIndex ()) + "\n"; + result += + "teamIndex = " + intToStr (this->faction->getTeam ()) + "\n"; + result += + "startLocationIndex = " + + intToStr (this->faction->getStartLocationIndex ()) + "\n"; + if (crcMode == false) + { + result += + "thisFaction = " + intToStr (this->faction->getThisFaction ()) + + "\n"; + result += + "control = " + intToStr (this->faction->getControlType ()) + "\n"; + } + if (this->faction->getType () != NULL) + { + result += + "factionName = " + this->faction->getType ()->getName (false) + + "\n"; + } + } + + result += " hp = " + intToStr (this->hp); + result += " ep = " + intToStr (this->ep); + result += " loadCount = " + intToStr (this->loadCount); + result += " deadCount = " + intToStr (this->deadCount); + result += " progress = " + intToStr (this->progress); + result += "\n"; + result += "networkCRCLogInfo = " + networkCRCLogInfo; + result += "\n"; + if (crcMode == false) + { + result += " lastAnimProgress = " + intToStr (this->lastAnimProgress); + result += " animProgress = " + intToStr (this->animProgress); + result += " highlight = " + floatToStr (this->highlight, 6); + } + result += " progress2 = " + intToStr (this->progress2); + result += " kills = " + intToStr (this->kills); + result += " enemyKills = " + intToStr (this->enemyKills); + result += "\n"; + + // WARNING!!! Don't access the Unit pointer in this->targetRef in this method or it causes + // a stack overflow + if (this->targetRef.getUnitId () >= 0) + { + //result += " targetRef = " + this->targetRef.getUnit()->toString(); + result += + " targetRef = " + intToStr (this->targetRef.getUnitId ()) + + " - factionIndex = " + + intToStr (this->targetRef.getUnitFaction ()->getIndex ()); + } + + result += " currField = " + intToStr (this->currField); + result += " targetField = " + intToStr (this->targetField); + if (level != NULL) + { + result += " level = " + level->getName (); + } + result += "\n"; + result += " pos = " + pos.getString (); + result += " lastPos = " + lastPos.getString (); + result += "\n"; + result += " targetPos = " + targetPos.getString (); + result += " targetVec = " + targetVec.getString (); + result += " meetingPos = " + meetingPos.getString (); + result += "\n"; + + if (crcMode == false) + { + result += " lastRotation = " + floatToStr (this->lastRotation, 6); + result += " targetRotation = " + floatToStr (this->targetRotation, 6); + result += " rotation = " + floatToStr (this->rotation, 6); + } + + if (loadType != NULL) + { + result += " loadType = " + loadType->getName (); + } + + if (currSkill != NULL) + { + result += " currSkill = " + currSkill->getName (); + } + result += "\n"; + + result += " toBeUndertaken = " + intToStr (this->toBeUndertaken); + result += " alive = " + intToStr (this->alive); + result += " showUnitParticles = " + intToStr (this->showUnitParticles); + + result += " totalUpgrade = " + totalUpgrade.toString (); + result += " " + this->unitPath->toString () + "\n"; + result += "\n"; + + result += "Command count = " + intToStr (commands.size ()) + "\n"; + + int cmdIdx = 0; + for (Commands::const_iterator iterList = commands.begin (); + iterList != commands.end (); ++iterList) + { + result += " index = " + intToStr (cmdIdx) + " "; + const Command *cmd = *iterList; + if (cmd != NULL) + { + result += cmd->toString (false) + "\n"; + } + cmdIdx++; + } + result += "\n"; // int obsIdx = 0; // for(Observers::const_iterator iterList = observers.begin(); iterList != observers.end(); ++iterList) { -// const UnitObserver *observer = *iterList; -// if(observer != NULL) { -// } +// const UnitObserver *observer = *iterList; +// if(observer != NULL) { +// } // -// obsIdx++; +// obsIdx++; // } - result += "\n"; + result += "\n"; - result += "modelFacing = " + intToStr(modelFacing.asInt()) + "\n"; + result += "modelFacing = " + intToStr (modelFacing.asInt ()) + "\n"; - result += "retryCurrCommandCount = " + intToStr(retryCurrCommandCount) + "\n"; + result += + "retryCurrCommandCount = " + intToStr (retryCurrCommandCount) + "\n"; - result += "screenPos = " + screenPos.getString() + "\n"; + result += "screenPos = " + screenPos.getString () + "\n"; - result += "currentUnitTitle = " + currentUnitTitle + "\n"; + result += "currentUnitTitle = " + currentUnitTitle + "\n"; - result += "inBailOutAttempt = " + intToStr(inBailOutAttempt) + "\n"; + result += "inBailOutAttempt = " + intToStr (inBailOutAttempt) + "\n"; - result += "random = " + intToStr(random.getLastNumber()) + "\n"; - if(this->random.getLastCaller() != "") { - result += "randomlastCaller = " + random.getLastCaller() + "\n"; + result += "random = " + intToStr (random.getLastNumber ()) + "\n"; + if (this->random.getLastCaller () != "") + { + result += "randomlastCaller = " + random.getLastCaller () + "\n"; + } + result += + "pathFindRefreshCellCount = " + intToStr (pathFindRefreshCellCount) + + "\n"; + + result += + "currentPathFinderDesiredFinalPos = " + + currentPathFinderDesiredFinalPos.getString () + "\n"; + + result += "lastStuckFrame = " + uIntToStr (lastStuckFrame) + "\n"; + result += "lastStuckPos = " + lastStuckPos.getString () + "\n"; + + if (attackParticleSystems.empty () == false) + { + result += + "attackParticleSystems count = " + + intToStr (attackParticleSystems.size ()) + "\n"; + } + if (networkCRCParticleLogInfo != "") + { + result += + "networkCRCParticleLogInfo = " + networkCRCParticleLogInfo + "\n"; + } + if (networkCRCDecHpList.empty () == false) + { + result += + "getNetworkCRCDecHpList() = " + getNetworkCRCDecHpList () + "\n"; + } + + if (getParticleInfo () != "") + { + result += "getParticleInfo() = " + getParticleInfo () + "\n"; + } + for (unsigned int index = 0; index < attackParticleSystems.size (); + ++index) + { + ParticleSystem *ps = attackParticleSystems[index]; + if (ps != NULL && + Renderer::getInstance ().validateParticleSystemStillExists (ps, + rsGame) + == true) + { + + result += + "attackParticleSystems #" + intToStr (index) + " = " + + ps->toString () + "\n"; + } + } + + return result; } - result += "pathFindRefreshCellCount = " + intToStr(pathFindRefreshCellCount) + "\n"; - result += "currentPathFinderDesiredFinalPos = " + currentPathFinderDesiredFinalPos.getString() + "\n"; + void Unit::saveGame (XmlNode * rootNode) + { + std::map < string, string > mapTagReplacements; + XmlNode *unitNode = rootNode->addChild ("Unit"); - result += "lastStuckFrame = " + uIntToStr(lastStuckFrame) + "\n"; - result += "lastStuckPos = " + lastStuckPos.getString() + "\n"; - - if(attackParticleSystems.empty() == false) { - result += "attackParticleSystems count = " + intToStr(attackParticleSystems.size()) + "\n"; - } - if(networkCRCParticleLogInfo != "") { - result += "networkCRCParticleLogInfo = " + networkCRCParticleLogInfo + "\n"; - } - if(networkCRCDecHpList.empty() == false) { - result += "getNetworkCRCDecHpList() = " + getNetworkCRCDecHpList() + "\n"; - } - - if(getParticleInfo() != "") { - result += "getParticleInfo() = " + getParticleInfo() + "\n"; - } - for(unsigned int index = 0; index < attackParticleSystems.size(); ++index) { - ParticleSystem *ps = attackParticleSystems[index]; - if(ps != NULL && - Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - - result += "attackParticleSystems #" + intToStr(index) + " = " + ps->toString() + "\n"; - } - } - - return result; -} - -void Unit::saveGame(XmlNode *rootNode) { - std::map mapTagReplacements; - XmlNode *unitNode = rootNode->addChild("Unit"); - -// const int id; - unitNode->addAttribute("id",intToStr(id), mapTagReplacements); - // For info purposes only - unitNode->addAttribute("name",type->getName(false), mapTagReplacements); +// const int id; + unitNode->addAttribute ("id", intToStr (id), mapTagReplacements); + // For info purposes only + unitNode->addAttribute ("name", type->getName (false), + mapTagReplacements); // int hp; - unitNode->addAttribute("hp",intToStr(hp), mapTagReplacements); + unitNode->addAttribute ("hp", intToStr (hp), mapTagReplacements); // int ep; - unitNode->addAttribute("ep",intToStr(ep), mapTagReplacements); + unitNode->addAttribute ("ep", intToStr (ep), mapTagReplacements); // int loadCount; - unitNode->addAttribute("loadCount",intToStr(loadCount), mapTagReplacements); + unitNode->addAttribute ("loadCount", intToStr (loadCount), + mapTagReplacements); // int deadCount; - unitNode->addAttribute("deadCount",intToStr(deadCount), mapTagReplacements); -// float progress; //between 0 and 1 - unitNode->addAttribute("progress",intToStr(progress), mapTagReplacements); -// float lastAnimProgress; //between 0 and 1 - unitNode->addAttribute("lastAnimProgress",intToStr(lastAnimProgress), mapTagReplacements); -// float animProgress; //between 0 and 1 - unitNode->addAttribute("animProgress",intToStr(animProgress), mapTagReplacements); -// float highlight; - unitNode->addAttribute("highlight",floatToStr(highlight,6), mapTagReplacements); -// int progress2; - unitNode->addAttribute("progress2",intToStr(progress2), mapTagReplacements); -// int kills; - unitNode->addAttribute("kills",intToStr(kills), mapTagReplacements); -// int enemyKills; - unitNode->addAttribute("enemyKills",intToStr(enemyKills), mapTagReplacements); -// UnitReference targetRef; - targetRef.saveGame(unitNode); + unitNode->addAttribute ("deadCount", intToStr (deadCount), + mapTagReplacements); +// float progress; //between 0 and 1 + unitNode->addAttribute ("progress", intToStr (progress), + mapTagReplacements); +// float lastAnimProgress; //between 0 and 1 + unitNode->addAttribute ("lastAnimProgress", intToStr (lastAnimProgress), + mapTagReplacements); +// float animProgress; //between 0 and 1 + unitNode->addAttribute ("animProgress", intToStr (animProgress), + mapTagReplacements); +// float highlight; + unitNode->addAttribute ("highlight", floatToStr (highlight, 6), + mapTagReplacements); +// int progress2; + unitNode->addAttribute ("progress2", intToStr (progress2), + mapTagReplacements); +// int kills; + unitNode->addAttribute ("kills", intToStr (kills), mapTagReplacements); +// int enemyKills; + unitNode->addAttribute ("enemyKills", intToStr (enemyKills), + mapTagReplacements); +// UnitReference targetRef; + targetRef.saveGame (unitNode); // -// Field currField; - unitNode->addAttribute("currField",intToStr(currField), mapTagReplacements); +// Field currField; + unitNode->addAttribute ("currField", intToStr (currField), + mapTagReplacements); // Field targetField; - unitNode->addAttribute("targetField",intToStr(targetField), mapTagReplacements); -// const Level *level; - if(level != NULL) { - level->saveGame(unitNode); - } + unitNode->addAttribute ("targetField", intToStr (targetField), + mapTagReplacements); +// const Level *level; + if (level != NULL) + { + level->saveGame (unitNode); + } // Vec2i pos; - unitNode->addAttribute("pos",pos.getString(), mapTagReplacements); -// Vec2i lastPos; - unitNode->addAttribute("lastPos",lastPos.getString(), mapTagReplacements); -// Vec2i targetPos; //absolute target pos - unitNode->addAttribute("targetPos",targetPos.getString(), mapTagReplacements); -// Vec3f targetVec; - unitNode->addAttribute("targetVec",targetVec.getString(), mapTagReplacements); -// Vec2i meetingPos; - unitNode->addAttribute("meetingPos",meetingPos.getString(), mapTagReplacements); + unitNode->addAttribute ("pos", pos.getString (), mapTagReplacements); +// Vec2i lastPos; + unitNode->addAttribute ("lastPos", lastPos.getString (), + mapTagReplacements); +// Vec2i targetPos; //absolute target pos + unitNode->addAttribute ("targetPos", targetPos.getString (), + mapTagReplacements); +// Vec3f targetVec; + unitNode->addAttribute ("targetVec", targetVec.getString (), + mapTagReplacements); +// Vec2i meetingPos; + unitNode->addAttribute ("meetingPos", meetingPos.getString (), + mapTagReplacements); // -// float lastRotation; //in degrees - unitNode->addAttribute("lastRotation",floatToStr(lastRotation,6), mapTagReplacements); -// float targetRotation; - unitNode->addAttribute("targetRotation",floatToStr(targetRotation,6), mapTagReplacements); -// float rotation; - unitNode->addAttribute("rotation",floatToStr(rotation,6), mapTagReplacements); -// float targetRotationZ; - unitNode->addAttribute("targetRotationZ",floatToStr(targetRotationZ,6), mapTagReplacements); -// float targetRotationX; - unitNode->addAttribute("targetRotationX",floatToStr(targetRotationX,6), mapTagReplacements); -// float rotationZ; - unitNode->addAttribute("rotationZ",floatToStr(rotationZ,6), mapTagReplacements); -// float rotationX; - unitNode->addAttribute("rotationX",floatToStr(rotationX,6), mapTagReplacements); +// float lastRotation; //in degrees + unitNode->addAttribute ("lastRotation", floatToStr (lastRotation, 6), + mapTagReplacements); +// float targetRotation; + unitNode->addAttribute ("targetRotation", + floatToStr (targetRotation, 6), + mapTagReplacements); +// float rotation; + unitNode->addAttribute ("rotation", floatToStr (rotation, 6), + mapTagReplacements); +// float targetRotationZ; + unitNode->addAttribute ("targetRotationZ", + floatToStr (targetRotationZ, 6), + mapTagReplacements); +// float targetRotationX; + unitNode->addAttribute ("targetRotationX", + floatToStr (targetRotationX, 6), + mapTagReplacements); +// float rotationZ; + unitNode->addAttribute ("rotationZ", floatToStr (rotationZ, 6), + mapTagReplacements); +// float rotationX; + unitNode->addAttribute ("rotationX", floatToStr (rotationX, 6), + mapTagReplacements); // const UnitType *type; - unitNode->addAttribute("type",type->getName(false), mapTagReplacements); + unitNode->addAttribute ("type", type->getName (false), + mapTagReplacements); - unitNode->addAttribute("preMorph_type",(preMorph_type != NULL ? preMorph_type->getName(false) : ""), mapTagReplacements); + unitNode->addAttribute ("preMorph_type", + (preMorph_type != + NULL ? preMorph_type->getName (false) : ""), + mapTagReplacements); // const ResourceType *loadType; - if(loadType != NULL) { - unitNode->addAttribute("loadType",loadType->getName(), mapTagReplacements); - } + if (loadType != NULL) + { + unitNode->addAttribute ("loadType", loadType->getName (), + mapTagReplacements); + } // const SkillType *currSkill; - if(currSkill != NULL) { - unitNode->addAttribute("currSkillName",currSkill->getName(), mapTagReplacements); - unitNode->addAttribute("currSkillClass",intToStr(currSkill->getClass()), mapTagReplacements); - } + if (currSkill != NULL) + { + unitNode->addAttribute ("currSkillName", currSkill->getName (), + mapTagReplacements); + unitNode->addAttribute ("currSkillClass", + intToStr (currSkill->getClass ()), + mapTagReplacements); + } // int lastModelIndexForCurrSkillType; - unitNode->addAttribute("lastModelIndexForCurrSkillType",intToStr(lastModelIndexForCurrSkillType), mapTagReplacements); + unitNode->addAttribute ("lastModelIndexForCurrSkillType", + intToStr (lastModelIndexForCurrSkillType), + mapTagReplacements); // int animationRandomCycleCount; - unitNode->addAttribute("animationRandomCycleCount",intToStr(animationRandomCycleCount), mapTagReplacements); + unitNode->addAttribute ("animationRandomCycleCount", + intToStr (animationRandomCycleCount), + mapTagReplacements); // // bool toBeUndertaken; - unitNode->addAttribute("toBeUndertaken",intToStr(toBeUndertaken), mapTagReplacements); -// bool alive; - unitNode->addAttribute("alive",intToStr(alive), mapTagReplacements); -// bool showUnitParticles; - unitNode->addAttribute("showUnitParticles",intToStr(showUnitParticles), mapTagReplacements); + unitNode->addAttribute ("toBeUndertaken", intToStr (toBeUndertaken), + mapTagReplacements); +// bool alive; + unitNode->addAttribute ("alive", intToStr (alive), mapTagReplacements); +// bool showUnitParticles; + unitNode->addAttribute ("showUnitParticles", + intToStr (showUnitParticles), + mapTagReplacements); // Faction *faction; -// ParticleSystem *fire; - int linkFireIndex = -1; - if(this->fire != NULL && Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == true) { - //fire->saveGame(unitNode); - bool fireInSystemList = false; - if(fireParticleSystems.empty() == false) { - for(unsigned int i = 0; i < fireParticleSystems.size(); ++i) { - ParticleSystem *ps= fireParticleSystems[i]; - if(ps == this->fire) { - linkFireIndex = i; - fireInSystemList = true; - break; - } - } - } - if(fireInSystemList == false) { - this->fire->saveGame(unitNode); - } - } -// TotalUpgrade totalUpgrade; - totalUpgrade.saveGame(unitNode); -// Map *map; +// ParticleSystem *fire; + int linkFireIndex = -1; + if (this->fire != NULL + && Renderer::getInstance (). + validateParticleSystemStillExists (this->fire, rsGame) == true) + { + //fire->saveGame(unitNode); + bool fireInSystemList = false; + if (fireParticleSystems.empty () == false) + { + for (unsigned int i = 0; i < fireParticleSystems.size (); ++i) + { + ParticleSystem *ps = fireParticleSystems[i]; + if (ps == this->fire) + { + linkFireIndex = i; + fireInSystemList = true; + break; + } + } + } + if (fireInSystemList == false) + { + this->fire->saveGame (unitNode); + } + } +// TotalUpgrade totalUpgrade; + totalUpgrade.saveGame (unitNode); +// Map *map; // -// UnitPathInterface *unitPath; - unitPath->saveGame(unitNode); -// WaypointPath waypointPath; +// UnitPathInterface *unitPath; + unitPath->saveGame (unitNode); +// WaypointPath waypointPath; // // Commands commands; - for(Commands::iterator it = commands.begin(); it != commands.end(); ++it) { - (*it)->saveGame(unitNode,faction); - } -// Observers observers; - //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { - // (*it)->saveGame(unitNode); - //} + for (Commands::iterator it = commands.begin (); it != commands.end (); + ++it) + { + (*it)->saveGame (unitNode, faction); + } +// Observers observers; + //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { + // (*it)->saveGame(unitNode); + //} -// vector unitParticleSystems; - if(unitParticleSystems.empty() == false) { - XmlNode *unitParticleSystemsNode = unitNode->addChild("unitParticleSystems"); +// vector unitParticleSystems; + if (unitParticleSystems.empty () == false) + { + XmlNode *unitParticleSystemsNode = + unitNode->addChild ("unitParticleSystems"); - for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) { - UnitParticleSystem *ups= unitParticleSystems[i]; - if(ups != NULL && Renderer::getInstance().validateParticleSystemStillExists(ups,rsGame) == true) { - ups->saveGame(unitParticleSystemsNode); - } - } - } -// vector queuedUnitParticleSystemTypes; - if(queuedUnitParticleSystemTypes.empty() == false) { - XmlNode *queuedUnitParticleSystemTypesNode = unitNode->addChild("queuedUnitParticleSystemTypes"); - for(unsigned int i = 0; i < queuedUnitParticleSystemTypes.size(); ++i) { - UnitParticleSystemType *upst= queuedUnitParticleSystemTypes[i]; - if(upst != NULL) { - upst->saveGame(queuedUnitParticleSystemTypesNode); - } - } - } -// UnitParticleSystems damageParticleSystems; - if(damageParticleSystems.empty() == false) { - XmlNode *damageParticleSystemsNode = unitNode->addChild("damageParticleSystems"); - for(unsigned int i = 0; i < damageParticleSystems.size(); ++i) { - UnitParticleSystem *ups= damageParticleSystems[i]; - if(ups != NULL && Renderer::getInstance().validateParticleSystemStillExists(ups,rsGame) == true) { - ups->saveGame(damageParticleSystemsNode); - } - } - } -// std::map damageParticleSystemsInUse; - if(damageParticleSystemsInUse.empty() == false) { - XmlNode *damageParticleSystemsInUseNode = unitNode->addChild("damageParticleSystemsInUse"); + for (unsigned int i = 0; i < unitParticleSystems.size (); ++i) + { + UnitParticleSystem *ups = unitParticleSystems[i]; + if (ups != NULL + && Renderer::getInstance (). + validateParticleSystemStillExists (ups, rsGame) == true) + { + ups->saveGame (unitParticleSystemsNode); + } + } + } +// vector queuedUnitParticleSystemTypes; + if (queuedUnitParticleSystemTypes.empty () == false) + { + XmlNode *queuedUnitParticleSystemTypesNode = + unitNode->addChild ("queuedUnitParticleSystemTypes"); + for (unsigned int i = 0; i < queuedUnitParticleSystemTypes.size (); + ++i) + { + UnitParticleSystemType *upst = queuedUnitParticleSystemTypes[i]; + if (upst != NULL) + { + upst->saveGame (queuedUnitParticleSystemTypesNode); + } + } + } +// UnitParticleSystems damageParticleSystems; + if (damageParticleSystems.empty () == false) + { + XmlNode *damageParticleSystemsNode = + unitNode->addChild ("damageParticleSystems"); + for (unsigned int i = 0; i < damageParticleSystems.size (); ++i) + { + UnitParticleSystem *ups = damageParticleSystems[i]; + if (ups != NULL + && Renderer::getInstance (). + validateParticleSystemStillExists (ups, rsGame) == true) + { + ups->saveGame (damageParticleSystemsNode); + } + } + } +// std::map damageParticleSystemsInUse; + if (damageParticleSystemsInUse.empty () == false) + { + XmlNode *damageParticleSystemsInUseNode = + unitNode->addChild ("damageParticleSystemsInUse"); - for(std::map::const_iterator iterMap = damageParticleSystemsInUse.begin(); - iterMap != damageParticleSystemsInUse.end(); ++iterMap) { - if(iterMap->second != NULL && Renderer::getInstance().validateParticleSystemStillExists(iterMap->second,rsGame) == true) { - XmlNode *damageParticleSystemsInUseNode2 = damageParticleSystemsInUseNode->addChild("damageParticleSystemsInUse"); + for (std::map < int, UnitParticleSystem * >::const_iterator iterMap = + damageParticleSystemsInUse.begin (); + iterMap != damageParticleSystemsInUse.end (); ++iterMap) + { + if (iterMap->second != NULL + && Renderer::getInstance (). + validateParticleSystemStillExists (iterMap->second, + rsGame) == true) + { + XmlNode *damageParticleSystemsInUseNode2 = + damageParticleSystemsInUseNode-> + addChild ("damageParticleSystemsInUse"); - damageParticleSystemsInUseNode2->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); - iterMap->second->saveGame(damageParticleSystemsInUseNode2); - } - } - } + damageParticleSystemsInUseNode2->addAttribute ("key", + intToStr (iterMap-> + first), + mapTagReplacements); + iterMap->second->saveGame (damageParticleSystemsInUseNode2); + } + } + } -// vector fireParticleSystems; - if(fireParticleSystems.empty() == false) { - XmlNode *fireParticleSystemsNode = unitNode->addChild("fireParticleSystems"); +// vector fireParticleSystems; + if (fireParticleSystems.empty () == false) + { + XmlNode *fireParticleSystemsNode = + unitNode->addChild ("fireParticleSystems"); - if(linkFireIndex >= 0) { - fireParticleSystemsNode->addAttribute("fireParticleLink",intToStr(linkFireIndex), mapTagReplacements); - } + if (linkFireIndex >= 0) + { + fireParticleSystemsNode->addAttribute ("fireParticleLink", + intToStr (linkFireIndex), + mapTagReplacements); + } - for(unsigned int i = 0; i < fireParticleSystems.size(); ++i) { - ParticleSystem *ps= fireParticleSystems[i]; - if(ps != NULL && Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - ps->saveGame(fireParticleSystemsNode); - } - } - } + for (unsigned int i = 0; i < fireParticleSystems.size (); ++i) + { + ParticleSystem *ps = fireParticleSystems[i]; + if (ps != NULL + && Renderer::getInstance (). + validateParticleSystemStillExists (ps, rsGame) == true) + { + ps->saveGame (fireParticleSystemsNode); + } + } + } -// vector smokeParticleSystems; - if(smokeParticleSystems.empty() == false) { - XmlNode *smokeParticleSystemsNode = unitNode->addChild("smokeParticleSystems"); - for(unsigned int i = 0; i < smokeParticleSystems.size(); ++i) { - UnitParticleSystem *ups= smokeParticleSystems[i]; - if(ups != NULL && Renderer::getInstance().validateParticleSystemStillExists(ups,rsGame) == true) { - ups->saveGame(smokeParticleSystemsNode); - //printf("Saving smoke particles:\n[%s]\n",ups->toString().c_str()); - } - } - } +// vector smokeParticleSystems; + if (smokeParticleSystems.empty () == false) + { + XmlNode *smokeParticleSystemsNode = + unitNode->addChild ("smokeParticleSystems"); + for (unsigned int i = 0; i < smokeParticleSystems.size (); ++i) + { + UnitParticleSystem *ups = smokeParticleSystems[i]; + if (ups != NULL + && Renderer::getInstance (). + validateParticleSystemStillExists (ups, rsGame) == true) + { + ups->saveGame (smokeParticleSystemsNode); + //printf("Saving smoke particles:\n[%s]\n",ups->toString().c_str()); + } + } + } -// CardinalDir modelFacing; - unitNode->addAttribute("modelFacing",intToStr(modelFacing), mapTagReplacements); +// CardinalDir modelFacing; + unitNode->addAttribute ("modelFacing", intToStr (modelFacing), + mapTagReplacements); -// std::string lastSynchDataString; - unitNode->addAttribute("lastSynchDataString",lastSynchDataString, mapTagReplacements); -// std::string lastFile; - unitNode->addAttribute("lastFile",lastFile, mapTagReplacements); -// int lastLine; - unitNode->addAttribute("lastLine",intToStr(lastLine), mapTagReplacements); -// std::string lastSource; - unitNode->addAttribute("lastSource",lastSource, mapTagReplacements); -// int lastRenderFrame; - unitNode->addAttribute("lastRenderFrame",intToStr(lastRenderFrame), mapTagReplacements); -// bool visible; - unitNode->addAttribute("visible",intToStr(visible), mapTagReplacements); -// int retryCurrCommandCount; - unitNode->addAttribute("retryCurrCommandCount",intToStr(retryCurrCommandCount), mapTagReplacements); -// Vec3f screenPos; - unitNode->addAttribute("screenPos",screenPos.getString(), mapTagReplacements); -// string currentUnitTitle; - unitNode->addAttribute("currentUnitTitle",currentUnitTitle, mapTagReplacements); +// std::string lastSynchDataString; + unitNode->addAttribute ("lastSynchDataString", lastSynchDataString, + mapTagReplacements); +// std::string lastFile; + unitNode->addAttribute ("lastFile", lastFile, mapTagReplacements); +// int lastLine; + unitNode->addAttribute ("lastLine", intToStr (lastLine), + mapTagReplacements); +// std::string lastSource; + unitNode->addAttribute ("lastSource", lastSource, mapTagReplacements); +// int lastRenderFrame; + unitNode->addAttribute ("lastRenderFrame", intToStr (lastRenderFrame), + mapTagReplacements); +// bool visible; + unitNode->addAttribute ("visible", intToStr (visible), + mapTagReplacements); +// int retryCurrCommandCount; + unitNode->addAttribute ("retryCurrCommandCount", + intToStr (retryCurrCommandCount), + mapTagReplacements); +// Vec3f screenPos; + unitNode->addAttribute ("screenPos", screenPos.getString (), + mapTagReplacements); +// string currentUnitTitle; + unitNode->addAttribute ("currentUnitTitle", currentUnitTitle, + mapTagReplacements); // -// bool inBailOutAttempt; - unitNode->addAttribute("inBailOutAttempt",intToStr(inBailOutAttempt), mapTagReplacements); -// //std::vector > badHarvestPosList; -// std::map badHarvestPosList; - for(std::map::const_iterator iterMap = badHarvestPosList.begin(); - iterMap != badHarvestPosList.end(); ++iterMap) { - XmlNode *badHarvestPosListNode = unitNode->addChild("badHarvestPosList"); +// bool inBailOutAttempt; + unitNode->addAttribute ("inBailOutAttempt", intToStr (inBailOutAttempt), + mapTagReplacements); +// //std::vector > badHarvestPosList; +// std::map badHarvestPosList; + for (std::map < Vec2i, int >::const_iterator iterMap = + badHarvestPosList.begin (); iterMap != badHarvestPosList.end (); + ++iterMap) + { + XmlNode *badHarvestPosListNode = + unitNode->addChild ("badHarvestPosList"); - badHarvestPosListNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements); - badHarvestPosListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); - } + badHarvestPosListNode->addAttribute ("key", + iterMap->first.getString (), + mapTagReplacements); + badHarvestPosListNode->addAttribute ("value", + intToStr (iterMap->second), + mapTagReplacements); + } -// //time_t lastBadHarvestListPurge; -// std::pair lastHarvestResourceTarget; - XmlNode *lastHarvestResourceTargetNode = unitNode->addChild("lastHarvestResourceTarget"); - lastHarvestResourceTargetNode->addAttribute("key",lastHarvestResourceTarget.first.getString(), mapTagReplacements); - lastHarvestResourceTargetNode->addAttribute("value",intToStr(lastHarvestResourceTarget.second), mapTagReplacements); +// //time_t lastBadHarvestListPurge; +// std::pair lastHarvestResourceTarget; + XmlNode *lastHarvestResourceTargetNode = + unitNode->addChild ("lastHarvestResourceTarget"); + lastHarvestResourceTargetNode->addAttribute ("key", + lastHarvestResourceTarget. + first.getString (), + mapTagReplacements); + lastHarvestResourceTargetNode->addAttribute ("value", + intToStr + (lastHarvestResourceTarget. + second), + mapTagReplacements); -// //std::pair > currentTargetPathTaken; -// static Game *game; +// //std::pair > currentTargetPathTaken; +// static Game *game; // -// bool ignoreCheckCommand; - unitNode->addAttribute("ignoreCheckCommand",intToStr(ignoreCheckCommand), mapTagReplacements); -// uint32 lastStuckFrame; - unitNode->addAttribute("lastStuckFrame",uIntToStr(lastStuckFrame), mapTagReplacements); -// Vec2i lastStuckPos; - unitNode->addAttribute("lastStuckPos",lastStuckPos.getString(), mapTagReplacements); -// uint32 lastPathfindFailedFrame; - unitNode->addAttribute("lastPathfindFailedFrame",intToStr(lastPathfindFailedFrame), mapTagReplacements); -// Vec2i lastPathfindFailedPos; - unitNode->addAttribute("lastPathfindFailedPos",lastPathfindFailedPos.getString(), mapTagReplacements); -// bool usePathfinderExtendedMaxNodes; - unitNode->addAttribute("usePathfinderExtendedMaxNodes",intToStr(usePathfinderExtendedMaxNodes), mapTagReplacements); -// int maxQueuedCommandDisplayCount; - unitNode->addAttribute("maxQueuedCommandDisplayCount",intToStr(maxQueuedCommandDisplayCount), mapTagReplacements); -// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; - currentAttackBoostOriginatorEffect.saveGame(unitNode); -// std::vector currentAttackBoostEffects; - for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { - UnitAttackBoostEffect *uabe= currentAttackBoostEffects[i]; - if(uabe != NULL) { - uabe->saveGame(unitNode); - } - } +// bool ignoreCheckCommand; + unitNode->addAttribute ("ignoreCheckCommand", + intToStr (ignoreCheckCommand), + mapTagReplacements); +// uint32 lastStuckFrame; + unitNode->addAttribute ("lastStuckFrame", uIntToStr (lastStuckFrame), + mapTagReplacements); +// Vec2i lastStuckPos; + unitNode->addAttribute ("lastStuckPos", lastStuckPos.getString (), + mapTagReplacements); +// uint32 lastPathfindFailedFrame; + unitNode->addAttribute ("lastPathfindFailedFrame", + intToStr (lastPathfindFailedFrame), + mapTagReplacements); +// Vec2i lastPathfindFailedPos; + unitNode->addAttribute ("lastPathfindFailedPos", + lastPathfindFailedPos.getString (), + mapTagReplacements); +// bool usePathfinderExtendedMaxNodes; + unitNode->addAttribute ("usePathfinderExtendedMaxNodes", + intToStr (usePathfinderExtendedMaxNodes), + mapTagReplacements); +// int maxQueuedCommandDisplayCount; + unitNode->addAttribute ("maxQueuedCommandDisplayCount", + intToStr (maxQueuedCommandDisplayCount), + mapTagReplacements); +// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; + currentAttackBoostOriginatorEffect.saveGame (unitNode); +// std::vector currentAttackBoostEffects; + for (unsigned int i = 0; i < currentAttackBoostEffects.size (); ++i) + { + UnitAttackBoostEffect *uabe = currentAttackBoostEffects[i]; + if (uabe != NULL) + { + uabe->saveGame (unitNode); + } + } -// Mutex *mutexCommands; +// Mutex *mutexCommands; // -// //static Mutex mutexDeletedUnits; -// //static std::map deletedUnits; +// //static Mutex mutexDeletedUnits; +// //static std::map deletedUnits; // -// bool changedActiveCommand; - unitNode->addAttribute("changedActiveCommand",intToStr(changedActiveCommand), mapTagReplacements); -// int lastAttackerUnitId; - unitNode->addAttribute("lastAttackerUnitId",intToStr(lastAttackerUnitId), mapTagReplacements); -// int lastAttackedUnitId; - unitNode->addAttribute("lastAttackedUnitId",intToStr(lastAttackedUnitId), mapTagReplacements); -// CauseOfDeathType causeOfDeath; - unitNode->addAttribute("causeOfDeath",intToStr(causeOfDeath), mapTagReplacements); +// bool changedActiveCommand; + unitNode->addAttribute ("changedActiveCommand", + intToStr (changedActiveCommand), + mapTagReplacements); +// int lastAttackerUnitId; + unitNode->addAttribute ("lastAttackerUnitId", + intToStr (lastAttackerUnitId), + mapTagReplacements); +// int lastAttackedUnitId; + unitNode->addAttribute ("lastAttackedUnitId", + intToStr (lastAttackedUnitId), + mapTagReplacements); +// CauseOfDeathType causeOfDeath; + unitNode->addAttribute ("causeOfDeath", intToStr (causeOfDeath), + mapTagReplacements); - //pathfindFailedConsecutiveFrameCount - unitNode->addAttribute("pathfindFailedConsecutiveFrameCount",intToStr(pathfindFailedConsecutiveFrameCount), mapTagReplacements); + //pathfindFailedConsecutiveFrameCount + unitNode->addAttribute ("pathfindFailedConsecutiveFrameCount", + intToStr (pathfindFailedConsecutiveFrameCount), + mapTagReplacements); - unitNode->addAttribute("currentPathFinderDesiredFinalPos",currentPathFinderDesiredFinalPos.getString(), mapTagReplacements); + unitNode->addAttribute ("currentPathFinderDesiredFinalPos", + currentPathFinderDesiredFinalPos.getString (), + mapTagReplacements); - unitNode->addAttribute("random",intToStr(random.getLastNumber()), mapTagReplacements); - unitNode->addAttribute("pathFindRefreshCellCount",intToStr(pathFindRefreshCellCount), mapTagReplacements); -} - -Unit * Unit::loadGame(const XmlNode *rootNode, GameSettings *settings, Faction *faction, World *world) { - const XmlNode *unitNode = rootNode; - - int newUnitId = unitNode->getAttribute("id")->getIntValue(); - Vec2i newUnitPos = Vec2i::strToVec2(unitNode->getAttribute("pos")->getValue()); - string newUnitType = unitNode->getAttribute("type")->getValue(); - const UnitType *ut = faction->getType()->getUnitType(newUnitType); - CardinalDir newModelFacing = static_cast(unitNode->getAttribute("modelFacing")->getIntValue()); - -// Unit *result = new Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, -// const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) : BaseColorPickEntity(), id(id) { - - UnitPathInterface *newpath = NULL; - switch(settings->getPathFinderType()) { - case pfBasic: - newpath = new UnitPathBasic(); - break; - default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); + unitNode->addAttribute ("random", intToStr (random.getLastNumber ()), + mapTagReplacements); + unitNode->addAttribute ("pathFindRefreshCellCount", + intToStr (pathFindRefreshCellCount), + mapTagReplacements); } - newpath->loadGame(unitNode); - //Unit *result = new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH); - //Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); - Unit *result = new Unit(newUnitId, newpath, newUnitPos, ut, faction, world->getMapPtr(), newModelFacing); + Unit *Unit::loadGame (const XmlNode * rootNode, GameSettings * settings, + Faction * faction, World * world) + { + const XmlNode *unitNode = rootNode; - if(unitNode->hasAttribute("preMorph_name") == true) { - string newUnitType_preMorph = unitNode->getAttribute("preMorph_name")->getValue(); - const UnitType *ut_premorph = faction->getType()->getUnitType(newUnitType_preMorph); - result->preMorph_type = ut_premorph; - } + int newUnitId = unitNode->getAttribute ("id")->getIntValue (); + Vec2i newUnitPos = + Vec2i::strToVec2 (unitNode->getAttribute ("pos")->getValue ()); + string newUnitType = unitNode->getAttribute ("type")->getValue (); + const UnitType *ut = faction->getType ()->getUnitType (newUnitType); + CardinalDir newModelFacing = + static_cast < CardinalDir > + (unitNode->getAttribute ("modelFacing")->getIntValue ()); - result->lastRotation = unitNode->getAttribute("lastRotation")->getFloatValue(); - result->targetRotation = unitNode->getAttribute("targetRotation")->getFloatValue(); - result->rotation = unitNode->getAttribute("rotation")->getFloatValue(); +// Unit *result = new Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, +// const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing) : BaseColorPickEntity(), id(id) { - //world->placeUnitAtLocation(newUnitPos, generationArea, unit, true); - //result->setPos(newUnitPos); - //Vec2i meetingPos = newUnitPos-Vec2i(1); - //result->setMeetingPos(meetingPos); - result->pos = newUnitPos; - result->lastPos = Vec2i::strToVec2(unitNode->getAttribute("lastPos")->getValue()); - result->meetingPos = Vec2i::strToVec2(unitNode->getAttribute("meetingPos")->getValue()); - // Attempt to improve performance - //result->exploreCells(); - //result->calculateFogOfWarRadius(); - // -------------------------- + UnitPathInterface *newpath = NULL; + switch (settings->getPathFinderType ()) + { + case pfBasic: + newpath = new UnitPathBasic (); + break; + default: + throw + megaglest_runtime_error ("detected unsupported pathfinder type!"); + } - result->hp = unitNode->getAttribute("hp")->getIntValue(); + newpath->loadGame (unitNode); + //Unit *result = new Unit(getNextUnitId(f), newpath, Vec2i(0), ut, f, &map, CardinalDir::NORTH); + //Unit(int id, UnitPathInterface *path, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing); + Unit *result = + new Unit (newUnitId, newpath, newUnitPos, ut, faction, + world->getMapPtr (), newModelFacing); + + if (unitNode->hasAttribute ("preMorph_name") == true) + { + string newUnitType_preMorph = + unitNode->getAttribute ("preMorph_name")->getValue (); + const UnitType *ut_premorph = + faction->getType ()->getUnitType (newUnitType_preMorph); + result->preMorph_type = ut_premorph; + } + + result->lastRotation = + unitNode->getAttribute ("lastRotation")->getFloatValue (); + result->targetRotation = + unitNode->getAttribute ("targetRotation")->getFloatValue (); + result->rotation = + unitNode->getAttribute ("rotation")->getFloatValue (); + + //world->placeUnitAtLocation(newUnitPos, generationArea, unit, true); + //result->setPos(newUnitPos); + //Vec2i meetingPos = newUnitPos-Vec2i(1); + //result->setMeetingPos(meetingPos); + result->pos = newUnitPos; + result->lastPos = + Vec2i::strToVec2 (unitNode->getAttribute ("lastPos")->getValue ()); + result->meetingPos = + Vec2i::strToVec2 (unitNode->getAttribute ("meetingPos")->getValue ()); + // Attempt to improve performance + //result->exploreCells(); + //result->calculateFogOfWarRadius(); + // -------------------------- + + result->hp = unitNode->getAttribute ("hp")->getIntValue (); // int ep; - result->ep = unitNode->getAttribute("ep")->getIntValue(); + result->ep = unitNode->getAttribute ("ep")->getIntValue (); // int loadCount; - result->loadCount = unitNode->getAttribute("loadCount")->getIntValue(); + result->loadCount = + unitNode->getAttribute ("loadCount")->getIntValue (); // int deadCount; - result->deadCount = unitNode->getAttribute("deadCount")->getIntValue(); -// float progress; //between 0 and 1 - try { - result->progress = unitNode->getAttribute("progress")->getIntValue(); - } + result->deadCount = + unitNode->getAttribute ("deadCount")->getIntValue (); +// float progress; //between 0 and 1 + try + { + result->progress = + unitNode->getAttribute ("progress")->getIntValue (); + } #ifdef WIN32 - catch(const exception &) { + catch (const exception &) + { #else - catch(const exception &ex) { + catch (const exception & ex) + { #endif - result->progress = unitNode->getAttribute("progress")->getFloatValue(); - } -// float lastAnimProgress; //between 0 and 1 - try { - result->lastAnimProgress = unitNode->getAttribute("lastAnimProgress")->getIntValue(); - } + result->progress = + unitNode->getAttribute ("progress")->getFloatValue (); + } +// float lastAnimProgress; //between 0 and 1 + try + { + result->lastAnimProgress = + unitNode->getAttribute ("lastAnimProgress")->getIntValue (); + } #ifdef WIN32 - catch(const exception &) { + catch (const exception &) + { #else - catch(const exception &ex) { + catch (const exception & ex) + { #endif - result->lastAnimProgress = unitNode->getAttribute("lastAnimProgress")->getFloatValue(); - } + result->lastAnimProgress = + unitNode->getAttribute ("lastAnimProgress")->getFloatValue (); + } -// float animProgress; //between 0 and 1 - try { - result->animProgress = unitNode->getAttribute("animProgress")->getIntValue(); - } +// float animProgress; //between 0 and 1 + try + { + result->animProgress = + unitNode->getAttribute ("animProgress")->getIntValue (); + } #ifdef WIN32 - catch(const exception &) { + catch (const exception &) + { #else - catch(const exception &ex) { + catch (const exception & ex) + { #endif - result->animProgress = unitNode->getAttribute("animProgress")->getFloatValue(); - } + result->animProgress = + unitNode->getAttribute ("animProgress")->getFloatValue (); + } -// float highlight; - result->highlight = unitNode->getAttribute("highlight")->getFloatValue(); -// int progress2; - result->progress2 = unitNode->getAttribute("progress2")->getIntValue(); -// int kills; - result->kills = unitNode->getAttribute("kills")->getIntValue(); -// int enemyKills; - result->enemyKills = unitNode->getAttribute("enemyKills")->getIntValue(); -// UnitReference targetRef; -// targetRef.saveGame(unitNode); - result->targetRef.loadGame(unitNode,world); +// float highlight; + result->highlight = + unitNode->getAttribute ("highlight")->getFloatValue (); +// int progress2; + result->progress2 = + unitNode->getAttribute ("progress2")->getIntValue (); +// int kills; + result->kills = unitNode->getAttribute ("kills")->getIntValue (); +// int enemyKills; + result->enemyKills = + unitNode->getAttribute ("enemyKills")->getIntValue (); +// UnitReference targetRef; +// targetRef.saveGame(unitNode); + result->targetRef.loadGame (unitNode, world); // -// Field currField; - result->currField = static_cast(unitNode->getAttribute("currField")->getIntValue()); +// Field currField; + result->currField = + static_cast < Field > + (unitNode->getAttribute ("currField")->getIntValue ()); // Field targetField; - result->targetField = static_cast(unitNode->getAttribute("targetField")->getIntValue()); -// const Level *level; -// if(level != NULL) { -// level->saveGame(unitNode); -// } - result->level = Level::loadGame(unitNode,ut); + result->targetField = + static_cast < Field > + (unitNode->getAttribute ("targetField")->getIntValue ()); +// const Level *level; +// if(level != NULL) { +// level->saveGame(unitNode); +// } + result->level = Level::loadGame (unitNode, ut); // Vec2i pos; - result->pos = Vec2i::strToVec2(unitNode->getAttribute("pos")->getValue()); -// Vec2i lastPos; - result->lastPos = Vec2i::strToVec2(unitNode->getAttribute("lastPos")->getValue()); -// Vec2i targetPos; //absolute target pos - result->targetPos = Vec2i::strToVec2(unitNode->getAttribute("targetPos")->getValue()); -// Vec3f targetVec; - result->targetVec = Vec3f::strToVec3(unitNode->getAttribute("targetVec")->getValue()); -// Vec2i meetingPos; - result->meetingPos = Vec2i::strToVec2(unitNode->getAttribute("meetingPos")->getValue()); + result->pos = + Vec2i::strToVec2 (unitNode->getAttribute ("pos")->getValue ()); +// Vec2i lastPos; + result->lastPos = + Vec2i::strToVec2 (unitNode->getAttribute ("lastPos")->getValue ()); +// Vec2i targetPos; //absolute target pos + result->targetPos = + Vec2i::strToVec2 (unitNode->getAttribute ("targetPos")->getValue ()); +// Vec3f targetVec; + result->targetVec = + Vec3f::strToVec3 (unitNode->getAttribute ("targetVec")->getValue ()); +// Vec2i meetingPos; + result->meetingPos = + Vec2i::strToVec2 (unitNode->getAttribute ("meetingPos")->getValue ()); // -// float lastRotation; //in degrees - result->lastRotation = unitNode->getAttribute("lastRotation")->getFloatValue(); -// float targetRotation; - result->targetRotation = unitNode->getAttribute("targetRotation")->getFloatValue(); -// float rotation; - result->rotation = unitNode->getAttribute("rotation")->getFloatValue(); -// float targetRotationZ; - result->targetRotationZ = unitNode->getAttribute("targetRotationZ")->getFloatValue(); -// float targetRotationX; - result->targetRotationX = unitNode->getAttribute("targetRotationX")->getFloatValue(); -// float rotationZ; - result->rotationZ = unitNode->getAttribute("rotationZ")->getFloatValue(); -// float rotationX; - result->rotationX = unitNode->getAttribute("rotationX")->getFloatValue(); +// float lastRotation; //in degrees + result->lastRotation = + unitNode->getAttribute ("lastRotation")->getFloatValue (); +// float targetRotation; + result->targetRotation = + unitNode->getAttribute ("targetRotation")->getFloatValue (); +// float rotation; + result->rotation = + unitNode->getAttribute ("rotation")->getFloatValue (); +// float targetRotationZ; + result->targetRotationZ = + unitNode->getAttribute ("targetRotationZ")->getFloatValue (); +// float targetRotationX; + result->targetRotationX = + unitNode->getAttribute ("targetRotationX")->getFloatValue (); +// float rotationZ; + result->rotationZ = + unitNode->getAttribute ("rotationZ")->getFloatValue (); +// float rotationX; + result->rotationX = + unitNode->getAttribute ("rotationX")->getFloatValue (); // const UnitType *type; -// unitNode->addAttribute("type",type->getName(), mapTagReplacements); +// unitNode->addAttribute("type",type->getName(), mapTagReplacements); // const ResourceType *loadType; -// if(loadType != NULL) { -// unitNode->addAttribute("loadType",loadType->getName(), mapTagReplacements); -// } - if(unitNode->hasAttribute("loadType") == true) { - string loadTypeName = unitNode->getAttribute("loadType")->getValue(); - result->loadType = world->getTechTree()->getResourceType(loadTypeName); - } +// if(loadType != NULL) { +// unitNode->addAttribute("loadType",loadType->getName(), mapTagReplacements); +// } + if (unitNode->hasAttribute ("loadType") == true) + { + string loadTypeName = + unitNode->getAttribute ("loadType")->getValue (); + result->loadType = + world->getTechTree ()->getResourceType (loadTypeName); + } // const SkillType *currSkill; -// if(currSkill != NULL) { -// unitNode->addAttribute("currSkill",currSkill->getName(), mapTagReplacements); -// } - if(unitNode->hasAttribute("currSkillName") == true) { - string skillTypeName = unitNode->getAttribute("currSkillName")->getValue(); - SkillClass skillClass = static_cast(unitNode->getAttribute("currSkillClass")->getIntValue()); - result->currSkill = ut->getSkillType(skillTypeName,skillClass); - result->setCurrSkill(result->currSkill); - } +// if(currSkill != NULL) { +// unitNode->addAttribute("currSkill",currSkill->getName(), mapTagReplacements); +// } + if (unitNode->hasAttribute ("currSkillName") == true) + { + string skillTypeName = + unitNode->getAttribute ("currSkillName")->getValue (); + SkillClass skillClass = + static_cast < SkillClass > + (unitNode->getAttribute ("currSkillClass")->getIntValue ()); + result->currSkill = ut->getSkillType (skillTypeName, skillClass); + result->setCurrSkill (result->currSkill); + } // int lastModelIndexForCurrSkillType; - result->lastModelIndexForCurrSkillType = unitNode->getAttribute("lastModelIndexForCurrSkillType")->getIntValue(); + result->lastModelIndexForCurrSkillType = + unitNode->getAttribute ("lastModelIndexForCurrSkillType")-> + getIntValue (); // int animationRandomCycleCount; - result->animationRandomCycleCount = unitNode->getAttribute("animationRandomCycleCount")->getIntValue(); + result->animationRandomCycleCount = + unitNode->getAttribute ("animationRandomCycleCount")->getIntValue (); // // bool toBeUndertaken; - result->toBeUndertaken = unitNode->getAttribute("toBeUndertaken")->getIntValue() != 0; -// bool alive; - result->setAlive(unitNode->getAttribute("alive")->getIntValue() != 0); -// bool showUnitParticles; - result->showUnitParticles = unitNode->getAttribute("showUnitParticles")->getIntValue() != 0; + result->toBeUndertaken = + unitNode->getAttribute ("toBeUndertaken")->getIntValue () != 0; +// bool alive; + result->setAlive (unitNode->getAttribute ("alive")->getIntValue () != + 0); +// bool showUnitParticles; + result->showUnitParticles = + unitNode->getAttribute ("showUnitParticles")->getIntValue () != 0; // Faction *faction; -// ParticleSystem *fire; -// if(fire != NULL) { -// fire->saveGame(unitNode); -// } - if(unitNode->hasChild("FireParticleSystem") == true) { - XmlNode *fireNode = unitNode->getChild("FireParticleSystem"); - result->fire = new FireParticleSystem(); - result->fire->setParticleOwner(result); - result->fire->loadGame(fireNode); - //result->fire->setTexture(CoreData::getInstance().getFireTexture()); - result->fireParticleSystems.push_back(result->fire); +// ParticleSystem *fire; +// if(fire != NULL) { +// fire->saveGame(unitNode); +// } + if (unitNode->hasChild ("FireParticleSystem") == true) + { + XmlNode *fireNode = unitNode->getChild ("FireParticleSystem"); + result->fire = new FireParticleSystem (); + result->fire->setParticleOwner (result); + result->fire->loadGame (fireNode); + //result->fire->setTexture(CoreData::getInstance().getFireTexture()); + result->fireParticleSystems.push_back (result->fire); - //printf("Load MAIN fire particle result->fire = %p\n",result->fire); + //printf("Load MAIN fire particle result->fire = %p\n",result->fire); - Renderer::getInstance().addToDeferredParticleSystemList(make_pair(result->fire, rsGame)); - } + Renderer::getInstance (). + addToDeferredParticleSystemList (make_pair (result->fire, rsGame)); + } -// TotalUpgrade totalUpgrade; - result->totalUpgrade.loadGame(unitNode); -// Map *map; +// TotalUpgrade totalUpgrade; + result->totalUpgrade.loadGame (unitNode); +// Map *map; // -// UnitPathInterface *unitPath; -// unitPath->saveGame(unitNode); -// WaypointPath waypointPath; +// UnitPathInterface *unitPath; +// unitPath->saveGame(unitNode); +// WaypointPath waypointPath; // // Commands commands; -// for(Commands::iterator it = commands.begin(); it != commands.end(); ++it) { -// (*it)->saveGame(unitNode); -// } - vector commandNodeList = unitNode->getChildList("Command"); - for(unsigned int i = 0; i < commandNodeList.size(); ++i) { - XmlNode *node = commandNodeList[i]; - Command *command = Command::loadGame(node,ut,world); +// for(Commands::iterator it = commands.begin(); it != commands.end(); ++it) { +// (*it)->saveGame(unitNode); +// } + vector < XmlNode * >commandNodeList = + unitNode->getChildList ("Command"); + for (unsigned int i = 0; i < commandNodeList.size (); ++i) + { + XmlNode *node = commandNodeList[i]; + Command *command = Command::loadGame (node, ut, world); - static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); - MutexSafeWrapper safeMutex(result->mutexCommands,mutexOwnerId); - result->commands.push_back(command); - safeMutex.ReleaseLock(); - } -// Observers observers; - //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { - // (*it)->saveGame(unitNode); - //} + static string mutexOwnerId = + string (__FILE__) + string ("_") + intToStr (__LINE__); + MutexSafeWrapper safeMutex (result->mutexCommands, mutexOwnerId); + result->commands.push_back (command); + safeMutex.ReleaseLock (); + } +// Observers observers; + //for(Observers::iterator it = observers.begin(); it != observers.end(); ++it) { + // (*it)->saveGame(unitNode); + //} -// vector unitParticleSystems; -// for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) { -// UnitParticleSystem *ups= unitParticleSystems[i]; -// ups->saveGame(unitNode); -// } - if(unitNode->hasChild("unitParticleSystems") == true) { - XmlNode *unitParticleSystemsNode = unitNode->getChild("unitParticleSystems"); - vector unitParticleSystemNodeList = unitParticleSystemsNode->getChildList("UnitParticleSystem"); - for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { - XmlNode *node = unitParticleSystemNodeList[i]; +// vector unitParticleSystems; +// for(unsigned int i = 0; i < unitParticleSystems.size(); ++i) { +// UnitParticleSystem *ups= unitParticleSystems[i]; +// ups->saveGame(unitNode); +// } + if (unitNode->hasChild ("unitParticleSystems") == true) + { + XmlNode *unitParticleSystemsNode = + unitNode->getChild ("unitParticleSystems"); + vector < XmlNode * >unitParticleSystemNodeList = + unitParticleSystemsNode->getChildList ("UnitParticleSystem"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) + { + XmlNode *node = unitParticleSystemNodeList[i]; - UnitParticleSystem *ups = new UnitParticleSystem(); - ups->setParticleOwner(result); - ups->loadGame(node); - result->unitParticleSystems.push_back(ups); + UnitParticleSystem *ups = new UnitParticleSystem (); + ups->setParticleOwner (result); + ups->loadGame (node); + result->unitParticleSystems.push_back (ups); - //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); - Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); - } - } + //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); + Renderer::getInstance (). + addToDeferredParticleSystemList (make_pair (ups, rsGame)); + } + } -// vector queuedUnitParticleSystemTypes; -// for(unsigned int i = 0; i < queuedUnitParticleSystemTypes.size(); ++i) { -// UnitParticleSystemType *upst= queuedUnitParticleSystemTypes[i]; -// upst->saveGame(unitNode); -// } +// vector queuedUnitParticleSystemTypes; +// for(unsigned int i = 0; i < queuedUnitParticleSystemTypes.size(); ++i) { +// UnitParticleSystemType *upst= queuedUnitParticleSystemTypes[i]; +// upst->saveGame(unitNode); +// } -// UnitParticleSystems damageParticleSystems; -// for(unsigned int i = 0; i < damageParticleSystems.size(); ++i) { -// UnitParticleSystem *ups= damageParticleSystems[i]; -// ups->saveGame(unitNode); -// } - if(unitNode->hasChild("damageParticleSystems") == true) { - XmlNode *damageParticleSystemsNode = unitNode->getChild("damageParticleSystems"); - vector unitParticleSystemNodeList = damageParticleSystemsNode->getChildList("UnitParticleSystem"); - for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { - XmlNode *node = unitParticleSystemNodeList[i]; +// UnitParticleSystems damageParticleSystems; +// for(unsigned int i = 0; i < damageParticleSystems.size(); ++i) { +// UnitParticleSystem *ups= damageParticleSystems[i]; +// ups->saveGame(unitNode); +// } + if (unitNode->hasChild ("damageParticleSystems") == true) + { + XmlNode *damageParticleSystemsNode = + unitNode->getChild ("damageParticleSystems"); + vector < XmlNode * >unitParticleSystemNodeList = + damageParticleSystemsNode->getChildList ("UnitParticleSystem"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) + { + XmlNode *node = unitParticleSystemNodeList[i]; - UnitParticleSystem *ups = new UnitParticleSystem(); - ups->setParticleOwner(result); - ups->loadGame(node); - result->damageParticleSystems.push_back(ups); - result->damageParticleSystemsInUse[i]=ups; + UnitParticleSystem *ups = new UnitParticleSystem (); + ups->setParticleOwner (result); + ups->loadGame (node); + result->damageParticleSystems.push_back (ups); + result->damageParticleSystemsInUse[i] = ups; - //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); - Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); - } - } + //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); + Renderer::getInstance (). + addToDeferredParticleSystemList (make_pair (ups, rsGame)); + } + } -// std::map damageParticleSystemsInUse; -// for(std::map::const_iterator iterMap = damageParticleSystemsInUse.begin(); -// iterMap != damageParticleSystemsInUse.end(); ++iterMap) { -// XmlNode *damageParticleSystemsInUseNode = unitNode->addChild("damageParticleSystemsInUse"); +// std::map damageParticleSystemsInUse; +// for(std::map::const_iterator iterMap = damageParticleSystemsInUse.begin(); +// iterMap != damageParticleSystemsInUse.end(); ++iterMap) { +// XmlNode *damageParticleSystemsInUseNode = unitNode->addChild("damageParticleSystemsInUse"); // -// damageParticleSystemsInUseNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); -// iterMap->second->saveGame(damageParticleSystemsInUseNode); -// } -// if(unitNode->hasChild("damageParticleSystemsInUse") == true) { -// XmlNode *damageParticleSystemsInUseNode = unitNode->getChild("damageParticleSystemsInUse"); -// vector damageParticleSystemsInUseNode2 = damageParticleSystemsInUseNode->getChildList("damageParticleSystemsInUse"); -// for(unsigned int i = 0; i < damageParticleSystemsInUseNode2.size(); ++i) { -// XmlNode *d2Node = damageParticleSystemsInUseNode2[i]; +// damageParticleSystemsInUseNode->addAttribute("key",intToStr(iterMap->first), mapTagReplacements); +// iterMap->second->saveGame(damageParticleSystemsInUseNode); +// } +// if(unitNode->hasChild("damageParticleSystemsInUse") == true) { +// XmlNode *damageParticleSystemsInUseNode = unitNode->getChild("damageParticleSystemsInUse"); +// vector damageParticleSystemsInUseNode2 = damageParticleSystemsInUseNode->getChildList("damageParticleSystemsInUse"); +// for(unsigned int i = 0; i < damageParticleSystemsInUseNode2.size(); ++i) { +// XmlNode *d2Node = damageParticleSystemsInUseNode2[i]; // -// vector unitParticleSystemNodeList = damageParticleSystemsInUseNode->getChildList("UnitParticleSystem"); -// for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { -// XmlNode *node = unitParticleSystemNodeList[i]; +// vector unitParticleSystemNodeList = damageParticleSystemsInUseNode->getChildList("UnitParticleSystem"); +// for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { +// XmlNode *node = unitParticleSystemNodeList[i]; // -// UnitParticleSystem *ups = new UnitParticleSystem(); -// ups->loadGame(node); -// result->unitParticleSystems.push_back(ups); +// UnitParticleSystem *ups = new UnitParticleSystem(); +// ups->loadGame(node); +// result->unitParticleSystems.push_back(ups); // -// //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); -// Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); -// } +// //Renderer::getInstance().manageParticleSystem(result->fire, rsGame); +// Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); +// } // -// } +// } -// vector fireParticleSystems; -// for(unsigned int i = 0; i < fireParticleSystems.size(); ++i) { -// ParticleSystem *ps= fireParticleSystems[i]; -// ps->saveGame(unitNode); -// } - if(unitNode->hasChild("fireParticleSystems") == true) { - XmlNode *fireParticleSystemsNode = unitNode->getChild("fireParticleSystems"); +// vector fireParticleSystems; +// for(unsigned int i = 0; i < fireParticleSystems.size(); ++i) { +// ParticleSystem *ps= fireParticleSystems[i]; +// ps->saveGame(unitNode); +// } + if (unitNode->hasChild ("fireParticleSystems") == true) + { + XmlNode *fireParticleSystemsNode = + unitNode->getChild ("fireParticleSystems"); - int linkFireIndex = -1; - if(fireParticleSystemsNode->hasAttribute("fireParticleLink") == true) { - linkFireIndex = fireParticleSystemsNode->getAttribute("fireParticleLink")->getIntValue(); - } + int linkFireIndex = -1; + if (fireParticleSystemsNode->hasAttribute ("fireParticleLink") == + true) + { + linkFireIndex = + fireParticleSystemsNode->getAttribute ("fireParticleLink")-> + getIntValue (); + } - vector unitParticleSystemNodeList = fireParticleSystemsNode->getChildList("FireParticleSystem"); - for(int i = 0; i < (int)unitParticleSystemNodeList.size(); ++i) { - XmlNode *node = unitParticleSystemNodeList[i]; + vector < XmlNode * >unitParticleSystemNodeList = + fireParticleSystemsNode->getChildList ("FireParticleSystem"); + for (int i = 0; i < (int) unitParticleSystemNodeList.size (); ++i) + { + XmlNode *node = unitParticleSystemNodeList[i]; - if(result->fire == NULL || linkFireIndex != i) { - FireParticleSystem *ups = new FireParticleSystem(); - ups->setParticleOwner(result); - ups->loadGame(node); - //ups->setTexture(CoreData::getInstance().getFireTexture()); - result->fireParticleSystems.push_back(ups); + if (result->fire == NULL || linkFireIndex != i) + { + FireParticleSystem *ups = new FireParticleSystem (); + ups->setParticleOwner (result); + ups->loadGame (node); + //ups->setTexture(CoreData::getInstance().getFireTexture()); + result->fireParticleSystems.push_back (ups); - //printf("Load fire particle i = %d linkFireIndex = %d result->fire = %p ups = %p\n",i,linkFireIndex,result->fire,ups); + //printf("Load fire particle i = %d linkFireIndex = %d result->fire = %p ups = %p\n",i,linkFireIndex,result->fire,ups); - if(result->fire == NULL && linkFireIndex >= 0 && linkFireIndex == i) { - result->fire = ups; - } - Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); - } - } - } + if (result->fire == NULL && linkFireIndex >= 0 + && linkFireIndex == i) + { + result->fire = ups; + } + Renderer::getInstance (). + addToDeferredParticleSystemList (make_pair (ups, rsGame)); + } + } + } -// vector smokeParticleSystems; -// for(unsigned int i = 0; i < smokeParticleSystems.size(); ++i) { -// UnitParticleSystem *ups= smokeParticleSystems[i]; -// ups->saveGame(unitNode); -// } - if(unitNode->hasChild("smokeParticleSystems") == true) { - XmlNode *smokeParticleSystemsNode = unitNode->getChild("smokeParticleSystems"); - vector unitParticleSystemNodeList = smokeParticleSystemsNode->getChildList("UnitParticleSystem"); - for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { - XmlNode *node = unitParticleSystemNodeList[i]; +// vector smokeParticleSystems; +// for(unsigned int i = 0; i < smokeParticleSystems.size(); ++i) { +// UnitParticleSystem *ups= smokeParticleSystems[i]; +// ups->saveGame(unitNode); +// } + if (unitNode->hasChild ("smokeParticleSystems") == true) + { + XmlNode *smokeParticleSystemsNode = + unitNode->getChild ("smokeParticleSystems"); + vector < XmlNode * >unitParticleSystemNodeList = + smokeParticleSystemsNode->getChildList ("UnitParticleSystem"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) + { + XmlNode *node = unitParticleSystemNodeList[i]; -// printf("Load Smoke particle i = %d\n",i); - UnitParticleSystem *ups = new UnitParticleSystem(); - ups->setParticleOwner(result); - ups->loadGame(node); - //ups->setTexture(CoreData::getInstance().getFireTexture()); - result->smokeParticleSystems.push_back(ups); +// printf("Load Smoke particle i = %d\n",i); + UnitParticleSystem *ups = new UnitParticleSystem (); + ups->setParticleOwner (result); + ups->loadGame (node); + //ups->setTexture(CoreData::getInstance().getFireTexture()); + result->smokeParticleSystems.push_back (ups); - Renderer::getInstance().addToDeferredParticleSystemList(make_pair(ups, rsGame)); + Renderer::getInstance (). + addToDeferredParticleSystemList (make_pair (ups, rsGame)); - //printf("Loading smoke particles:\n[%s]\n",ups->toString().c_str()); - } - } + //printf("Loading smoke particles:\n[%s]\n",ups->toString().c_str()); + } + } -// CardinalDir modelFacing; -// unitNode->addAttribute("modelFacing",intToStr(modelFacing), mapTagReplacements); +// CardinalDir modelFacing; +// unitNode->addAttribute("modelFacing",intToStr(modelFacing), mapTagReplacements); -// std::string lastSynchDataString; -// unitNode->addAttribute("lastSynchDataString",lastSynchDataString, mapTagReplacements); -// std::string lastFile; -// unitNode->addAttribute("lastFile",lastFile, mapTagReplacements); -// int lastLine; -// unitNode->addAttribute("lastLine",intToStr(lastLine), mapTagReplacements); -// std::string lastSource; -// unitNode->addAttribute("lastSource",lastSource, mapTagReplacements); -// int lastRenderFrame; - result->lastRenderFrame = unitNode->getAttribute("lastRenderFrame")->getIntValue(); -// bool visible; - result->visible = unitNode->getAttribute("visible")->getIntValue() != 0; -// int retryCurrCommandCount; - result->retryCurrCommandCount = unitNode->getAttribute("retryCurrCommandCount")->getIntValue(); -// Vec3f screenPos; - result->screenPos = Vec3f::strToVec3(unitNode->getAttribute("screenPos")->getValue()); -// string currentUnitTitle; - result->currentUnitTitle = unitNode->getAttribute("currentUnitTitle")->getValue(); +// std::string lastSynchDataString; +// unitNode->addAttribute("lastSynchDataString",lastSynchDataString, mapTagReplacements); +// std::string lastFile; +// unitNode->addAttribute("lastFile",lastFile, mapTagReplacements); +// int lastLine; +// unitNode->addAttribute("lastLine",intToStr(lastLine), mapTagReplacements); +// std::string lastSource; +// unitNode->addAttribute("lastSource",lastSource, mapTagReplacements); +// int lastRenderFrame; + result->lastRenderFrame = + unitNode->getAttribute ("lastRenderFrame")->getIntValue (); +// bool visible; + result->visible = + unitNode->getAttribute ("visible")->getIntValue () != 0; +// int retryCurrCommandCount; + result->retryCurrCommandCount = + unitNode->getAttribute ("retryCurrCommandCount")->getIntValue (); +// Vec3f screenPos; + result->screenPos = + Vec3f::strToVec3 (unitNode->getAttribute ("screenPos")->getValue ()); +// string currentUnitTitle; + result->currentUnitTitle = + unitNode->getAttribute ("currentUnitTitle")->getValue (); // -// bool inBailOutAttempt; - result->inBailOutAttempt = unitNode->getAttribute("inBailOutAttempt")->getIntValue() != 0; -// //std::vector > badHarvestPosList; -// std::map badHarvestPosList; -// for(std::map::const_iterator iterMap = badHarvestPosList.begin(); -// iterMap != badHarvestPosList.end(); ++iterMap) { -// XmlNode *badHarvestPosListNode = unitNode->addChild("badHarvestPosList"); +// bool inBailOutAttempt; + result->inBailOutAttempt = + unitNode->getAttribute ("inBailOutAttempt")->getIntValue () != 0; +// //std::vector > badHarvestPosList; +// std::map badHarvestPosList; +// for(std::map::const_iterator iterMap = badHarvestPosList.begin(); +// iterMap != badHarvestPosList.end(); ++iterMap) { +// XmlNode *badHarvestPosListNode = unitNode->addChild("badHarvestPosList"); // -// badHarvestPosListNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements); -// badHarvestPosListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); -// } +// badHarvestPosListNode->addAttribute("key",iterMap->first.getString(), mapTagReplacements); +// badHarvestPosListNode->addAttribute("value",intToStr(iterMap->second), mapTagReplacements); +// } -// //time_t lastBadHarvestListPurge; -// std::pair lastHarvestResourceTarget; - const XmlNode *lastHarvestResourceTargetNode = unitNode->getChild("lastHarvestResourceTarget"); -// lastHarvestResourceTargetNode->addAttribute("key",lastHarvestResourceTarget.first.getString(), mapTagReplacements); -// lastHarvestResourceTargetNode->addAttribute("value",intToStr(lastHarvestResourceTarget.second), mapTagReplacements); +// //time_t lastBadHarvestListPurge; +// std::pair lastHarvestResourceTarget; + const XmlNode *lastHarvestResourceTargetNode = + unitNode->getChild ("lastHarvestResourceTarget"); +// lastHarvestResourceTargetNode->addAttribute("key",lastHarvestResourceTarget.first.getString(), mapTagReplacements); +// lastHarvestResourceTargetNode->addAttribute("value",intToStr(lastHarvestResourceTarget.second), mapTagReplacements); - result->lastHarvestResourceTarget = - make_pair(Vec2i::strToVec2(lastHarvestResourceTargetNode->getAttribute("key")->getValue()), - lastHarvestResourceTargetNode->getAttribute("value")->getIntValue()); + result->lastHarvestResourceTarget = + make_pair (Vec2i:: + strToVec2 (lastHarvestResourceTargetNode-> + getAttribute ("key")->getValue ()), + lastHarvestResourceTargetNode->getAttribute ("value")-> + getIntValue ()); -// //std::pair > currentTargetPathTaken; -// static Game *game; +// //std::pair > currentTargetPathTaken; +// static Game *game; // -// bool ignoreCheckCommand; - result->ignoreCheckCommand = unitNode->getAttribute("ignoreCheckCommand")->getIntValue() != 0; -// uint32 lastStuckFrame; - result->lastStuckFrame = unitNode->getAttribute("lastStuckFrame")->getIntValue(); -// Vec2i lastStuckPos; - result->lastStuckPos = Vec2i::strToVec2(unitNode->getAttribute("lastStuckPos")->getValue()); -// uint32 lastPathfindFailedFrame; - result->lastPathfindFailedFrame = unitNode->getAttribute("lastPathfindFailedFrame")->getIntValue(); -// Vec2i lastPathfindFailedPos; - result->lastPathfindFailedPos = Vec2i::strToVec2(unitNode->getAttribute("lastPathfindFailedPos")->getValue()); -// bool usePathfinderExtendedMaxNodes; - result->usePathfinderExtendedMaxNodes = unitNode->getAttribute("usePathfinderExtendedMaxNodes")->getIntValue() != 0; -// int maxQueuedCommandDisplayCount; - result->maxQueuedCommandDisplayCount = unitNode->getAttribute("maxQueuedCommandDisplayCount")->getIntValue(); -// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; +// bool ignoreCheckCommand; + result->ignoreCheckCommand = + unitNode->getAttribute ("ignoreCheckCommand")->getIntValue () != 0; +// uint32 lastStuckFrame; + result->lastStuckFrame = + unitNode->getAttribute ("lastStuckFrame")->getIntValue (); +// Vec2i lastStuckPos; + result->lastStuckPos = + Vec2i::strToVec2 (unitNode->getAttribute ("lastStuckPos")-> + getValue ()); +// uint32 lastPathfindFailedFrame; + result->lastPathfindFailedFrame = + unitNode->getAttribute ("lastPathfindFailedFrame")->getIntValue (); +// Vec2i lastPathfindFailedPos; + result->lastPathfindFailedPos = + Vec2i::strToVec2 (unitNode->getAttribute ("lastPathfindFailedPos")-> + getValue ()); +// bool usePathfinderExtendedMaxNodes; + result->usePathfinderExtendedMaxNodes = + unitNode->getAttribute ("usePathfinderExtendedMaxNodes")-> + getIntValue () != 0; +// int maxQueuedCommandDisplayCount; + result->maxQueuedCommandDisplayCount = + unitNode->getAttribute ("maxQueuedCommandDisplayCount")-> + getIntValue (); +// UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; - // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet - result->currentAttackBoostOriginatorEffect.loadGame(unitNode,result, world); + // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet + result->currentAttackBoostOriginatorEffect.loadGame (unitNode, result, + world); -// std::vector currentAttackBoostEffects; -// for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { -// UnitAttackBoostEffect *uabe= currentAttackBoostEffects[i]; -// uabe->saveGame(unitNode); -// } +// std::vector currentAttackBoostEffects; +// for(unsigned int i = 0; i < currentAttackBoostEffects.size(); ++i) { +// UnitAttackBoostEffect *uabe= currentAttackBoostEffects[i]; +// uabe->saveGame(unitNode); +// } - // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet - if(unitNode->hasChild("UnitAttackBoostEffect") == true) { - vector unitParticleSystemNodeList = unitNode->getChildList("UnitAttackBoostEffect"); - for(unsigned int i = 0; i < unitParticleSystemNodeList.size(); ++i) { - XmlNode *node = unitParticleSystemNodeList[i]; + // !!! TODO: Softcoder - in progress work to load attack boosts, not working properly yet + if (unitNode->hasChild ("UnitAttackBoostEffect") == true) + { + vector < XmlNode * >unitParticleSystemNodeList = + unitNode->getChildList ("UnitAttackBoostEffect"); + for (unsigned int i = 0; i < unitParticleSystemNodeList.size (); ++i) + { + XmlNode *node = unitParticleSystemNodeList[i]; - UnitAttackBoostEffect *attackBoostEffect = new UnitAttackBoostEffect(); - attackBoostEffect->loadGame(node,result,world,false); + UnitAttackBoostEffect *attackBoostEffect = + new UnitAttackBoostEffect (); + attackBoostEffect->loadGame (node, result, world, false); - result->currentAttackBoostEffects.push_back(attackBoostEffect); - } - } - //printf("Unit [%d - %s] has currentAttackBoostEffects count: %d\n",result->getId(),result->getType()->getName(false).c_str(),(int)result->currentAttackBoostEffects.size()); + result->currentAttackBoostEffects.push_back (attackBoostEffect); + } + } + //printf("Unit [%d - %s] has currentAttackBoostEffects count: %d\n",result->getId(),result->getType()->getName(false).c_str(),(int)result->currentAttackBoostEffects.size()); -// Mutex *mutexCommands; +// Mutex *mutexCommands; // -// //static Mutex mutexDeletedUnits; -// //static std::map deletedUnits; +// //static Mutex mutexDeletedUnits; +// //static std::map deletedUnits; // -// bool changedActiveCommand; - result->changedActiveCommand = unitNode->getAttribute("changedActiveCommand")->getIntValue() != 0; -// int lastAttackerUnitId; - result->lastAttackerUnitId = unitNode->getAttribute("lastAttackerUnitId")->getIntValue(); -// int lastAttackedUnitId; - result->lastAttackedUnitId = unitNode->getAttribute("lastAttackedUnitId")->getIntValue(); -// CauseOfDeathType causeOfDeath; - result->causeOfDeath = static_cast(unitNode->getAttribute("causeOfDeath")->getIntValue()); +// bool changedActiveCommand; + result->changedActiveCommand = + unitNode->getAttribute ("changedActiveCommand")->getIntValue () != 0; +// int lastAttackerUnitId; + result->lastAttackerUnitId = + unitNode->getAttribute ("lastAttackerUnitId")->getIntValue (); +// int lastAttackedUnitId; + result->lastAttackedUnitId = + unitNode->getAttribute ("lastAttackedUnitId")->getIntValue (); +// CauseOfDeathType causeOfDeath; + result->causeOfDeath = + static_cast < CauseOfDeathType > + (unitNode->getAttribute ("causeOfDeath")->getIntValue ()); + + result->pathfindFailedConsecutiveFrameCount = + unitNode->getAttribute ("pathfindFailedConsecutiveFrameCount")-> + getIntValue (); + + if (result->alive) + { + world->getMapPtr ()->putUnitCells (result, newUnitPos); + //result->born(); + } + + result->pos = newUnitPos; + result->lastPos = + Vec2i::strToVec2 (unitNode->getAttribute ("lastPos")->getValue ()); + result->meetingPos = + Vec2i::strToVec2 (unitNode->getAttribute ("meetingPos")->getValue ()); + + if (unitNode->hasAttribute ("currentPathFinderDesiredFinalPos")) + { + result->currentPathFinderDesiredFinalPos = + Vec2i::strToVec2 (unitNode-> + getAttribute + ("currentPathFinderDesiredFinalPos")-> + getValue ()); + } + + if (unitNode->hasAttribute ("random")) + { + result->random.setLastNumber (unitNode->getAttribute ("random")-> + getIntValue ()); + } + if (unitNode->hasAttribute ("pathFindRefreshCellCount")) + { + result->pathFindRefreshCellCount = + unitNode->getAttribute ("pathFindRefreshCellCount")->getIntValue (); + } + + //result->exploreCells(); + //result->calculateFogOfWarRadius(); + + return result; + } + + Checksum Unit::getCRC () + { + const bool consoleDebug = false; + + Checksum crcForUnit; + + crcForUnit.addInt (id); + crcForUnit.addInt (hp); + crcForUnit.addInt (ep); + crcForUnit.addInt (loadCount); + crcForUnit.addInt (deadCount); + + if (consoleDebug) + printf ("#1 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + crcForUnit.addInt64 (progress); + crcForUnit.addInt64 (lastAnimProgress); + crcForUnit.addInt64 (animProgress); + + if (consoleDebug) + printf ("#2 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + //float highlight; + crcForUnit.addInt (progress2); + crcForUnit.addInt (kills); + crcForUnit.addInt (enemyKills); + crcForUnit.addInt (morphFieldsBlocked); + + if (consoleDebug) + printf ("#3 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + //UnitReference targetRef; + + crcForUnit.addInt (currField); + crcForUnit.addInt (targetField); + + if (consoleDebug) + printf ("#4 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + //const Level *level; + if (level != NULL) + { + crcForUnit.addString (level->getName (false)); + } + + if (consoleDebug) + printf ("#5 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + crcForUnit.addInt (pos.x); + crcForUnit.addInt (pos.y); + crcForUnit.addInt (lastPos.x); + crcForUnit.addInt (lastPos.y); + crcForUnit.addInt (targetPos.x); + crcForUnit.addInt (targetPos.y); + + if (consoleDebug) + printf ("#6 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + //Vec3f targetVec; + + crcForUnit.addInt (meetingPos.x); + crcForUnit.addInt (meetingPos.y); + + if (consoleDebug) + printf ("#7 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + //float lastRotation; + //float targetRotation; + //float rotation; + //float targetRotationZ; + //float targetRotationX; + //float rotationZ; + //float rotationX; + + //const UnitType *preMorph_type; + if (preMorph_type != NULL) + { + crcForUnit.addString (preMorph_type->getName (false)); + } + + if (consoleDebug) + printf ("#8 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + //const UnitType *type; + if (type != NULL) + { + crcForUnit.addString (type->getName (false)); + } + + //const ResourceType *loadType; + if (loadType != NULL) + { + crcForUnit.addString (loadType->getName (false)); + } + + //const SkillType *currSkill; + if (currSkill != NULL) + { + crcForUnit.addString (currSkill->getName ()); + } + + //printf("#9 Unit: %d CRC: %u lastModelIndexForCurrSkillType: %d\n",id,crcForUnit.getSum(),lastModelIndexForCurrSkillType); + //printf("#9a Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + //crcForUnit.addInt(lastModelIndexForCurrSkillType); - result->pathfindFailedConsecutiveFrameCount = unitNode->getAttribute("pathfindFailedConsecutiveFrameCount")->getIntValue(); + if (consoleDebug) + printf ("#9 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - if(result->alive) { - world->getMapPtr()->putUnitCells(result, newUnitPos); - //result->born(); - } + //crcForUnit.addInt(animationRandomCycleCount); + //printf("#9b Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - result->pos = newUnitPos; - result->lastPos = Vec2i::strToVec2(unitNode->getAttribute("lastPos")->getValue()); - result->meetingPos = Vec2i::strToVec2(unitNode->getAttribute("meetingPos")->getValue()); + crcForUnit.addInt (toBeUndertaken); - if(unitNode->hasAttribute("currentPathFinderDesiredFinalPos")) { - result->currentPathFinderDesiredFinalPos = Vec2i::strToVec2(unitNode->getAttribute("currentPathFinderDesiredFinalPos")->getValue()); - } + if (consoleDebug) + printf ("#9c Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + crcForUnit.addInt (alive); + //bool showUnitParticles; - if(unitNode->hasAttribute("random")) { - result->random.setLastNumber(unitNode->getAttribute("random")->getIntValue()); - } - if(unitNode->hasAttribute("pathFindRefreshCellCount")) { - result->pathFindRefreshCellCount = unitNode->getAttribute("pathFindRefreshCellCount")->getIntValue(); - } + if (consoleDebug) + printf ("#10 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - //result->exploreCells(); - //result->calculateFogOfWarRadius(); + //Faction *faction; + //ParticleSystem *fire; + if (fire != NULL) + { + crcForUnit.addInt (fire->getActive ()); + } - return result; -} + //TotalUpgrade totalUpgrade; + uint32 crc = totalUpgrade.getCRC ().getSum (); + crcForUnit.addBytes (&crc, sizeof (uint32)); -Checksum Unit::getCRC() { - const bool consoleDebug = false; + //Map *map; + //UnitPathInterface *unitPath; + if (unitPath != NULL) + { + uint32 crc = unitPath->getCRC ().getSum (); + crcForUnit.addBytes (&crc, sizeof (uint32)); + } + //WaypointPath waypointPath; - Checksum crcForUnit; + if (consoleDebug) + printf ("#11 Unit: %d CRC: %u commands.size(): " MG_SIZE_T_SPECIFIER + "\n", id, crcForUnit.getSum (), commands.size ()); - crcForUnit.addInt(id); - crcForUnit.addInt(hp); - crcForUnit.addInt(ep); - crcForUnit.addInt(loadCount); - crcForUnit.addInt(deadCount); + //Commands commands; + if (commands.empty () == false) + { + crcForUnit.addInt ((int) commands.size ()); + for (Commands::const_iterator it = commands.begin (); + it != commands.end (); ++it) + { + uint32 crc = (*it)->getCRC ().getSum (); + crcForUnit.addBytes (&crc, sizeof (uint32)); + } + } - if(consoleDebug) printf("#1 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + //printf("#11 Unit: %d CRC: %u observers.size(): %ld\n",id,crcForUnit.getSum(),observers.size()); - crcForUnit.addInt64(progress); - crcForUnit.addInt64(lastAnimProgress); - crcForUnit.addInt64(animProgress); + //Observers observers; + //crcForUnit.addInt64((int64)observers.size()); - if(consoleDebug) printf("#2 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + if (consoleDebug) + printf ("#11 Unit: %d CRC: %u damageParticleSystems.size(): " + MG_SIZE_T_SPECIFIER "\n", id, crcForUnit.getSum (), + damageParticleSystems.size ()); - //float highlight; - crcForUnit.addInt(progress2); - crcForUnit.addInt(kills); - crcForUnit.addInt(enemyKills); - crcForUnit.addInt(morphFieldsBlocked); + //vector unitParticleSystems; + //vector queuedUnitParticleSystemTypes; - if(consoleDebug) printf("#3 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + //UnitParticleSystems damageParticleSystems; + crcForUnit.addInt ((int) damageParticleSystems.size ()); - //UnitReference targetRef; + if (consoleDebug) + printf ("#12 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - crcForUnit.addInt(currField); - crcForUnit.addInt(targetField); + //std::map damageParticleSystemsInUse; - if(consoleDebug) printf("#4 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + //vector fireParticleSystems; + //vector smokeParticleSystems; + + //CardinalDir modelFacing; + crcForUnit.addInt (modelFacing); + + //std::string lastSynchDataString; + //std::string lastFile; + //int lastLine; + //std::string lastSource; + //int lastRenderFrame; + //bool visible; + + //int retryCurrCommandCount; - //const Level *level; - if(level != NULL) { - crcForUnit.addString(level->getName(false)); - } + //Vec3f screenPos; + //string currentUnitTitle; + + if (consoleDebug) + printf ("#13 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - if(consoleDebug) printf("#5 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + crcForUnit.addInt (inBailOutAttempt); - crcForUnit.addInt(pos.x); - crcForUnit.addInt(pos.y); - crcForUnit.addInt(lastPos.x); - crcForUnit.addInt(lastPos.y); - crcForUnit.addInt(targetPos.x); - crcForUnit.addInt(targetPos.y); + crcForUnit.addInt ((int) badHarvestPosList.size ()); + //crcForUnit.addInt(lastHarvestResourceTarget.first()); - if(consoleDebug) printf("#6 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + if (consoleDebug) + printf ("#14 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - //Vec3f targetVec; + //static Game *game; + //bool ignoreCheckCommand; - crcForUnit.addInt(meetingPos.x); - crcForUnit.addInt(meetingPos.y); + //uint32 lastStuckFrame; + crcForUnit.addUInt (lastStuckFrame); + //Vec2i lastStuckPos; + crcForUnit.addInt (lastStuckPos.x); + crcForUnit.addInt (lastStuckPos.y); + + //uint32 lastPathfindFailedFrame; + //Vec2i lastPathfindFailedPos; + //bool usePathfinderExtendedMaxNodes; + //int maxQueuedCommandDisplayCount; + + //UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; + crcForUnit.addInt ((int) currentAttackBoostOriginatorEffect. + currentAttackBoostUnits.size ()); + + if (consoleDebug) + printf ("#15 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); + + //std::vector currentAttackBoostEffects; + + //Mutex *mutexCommands; + + //bool changedActiveCommand; + + //int lastAttackerUnitId; + //int lastAttackedUnitId; + //CauseOfDeathType causeOfDeath; - if(consoleDebug) printf("#7 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + //uint32 pathfindFailedConsecutiveFrameCount; + crcForUnit.addString (this->currentPathFinderDesiredFinalPos. + getString ()); - //float lastRotation; - //float targetRotation; - //float rotation; - //float targetRotationZ; - //float targetRotationX; - //float rotationZ; - //float rotationX; + crcForUnit.addInt (random.getLastNumber ()); + if (this->random.getLastCaller () != "") + { + crcForUnit.addString (this->random.getLastCaller ()); + } - //const UnitType *preMorph_type; - if(preMorph_type != NULL) { - crcForUnit.addString(preMorph_type->getName(false)); - } + if (consoleDebug) + printf ("#16 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - if(consoleDebug) printf("#8 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + //int pathFindRefreshCellCount; - //const UnitType *type; - if(type != NULL) { - crcForUnit.addString(type->getName(false)); - } + //FowAlphaCellsLookupItem cachedFow; + //Vec2i cachedFowPos; - //const ResourceType *loadType; - if(loadType != NULL) { - crcForUnit.addString(loadType->getName(false)); - } + crcForUnit.addInt (lastHarvestedResourcePos.x); + crcForUnit.addInt (lastHarvestedResourcePos.y); - //const SkillType *currSkill; - if(currSkill != NULL) { - crcForUnit.addString(currSkill->getName()); - } + if (consoleDebug) + printf ("#17 Unit: %d CRC: %u\n", id, crcForUnit.getSum ()); - //printf("#9 Unit: %d CRC: %u lastModelIndexForCurrSkillType: %d\n",id,crcForUnit.getSum(),lastModelIndexForCurrSkillType); - //printf("#9a Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - //crcForUnit.addInt(lastModelIndexForCurrSkillType); + if (this->getParticleInfo () != "") + { + crcForUnit.addString (this->getParticleInfo ()); + } - if(consoleDebug) printf("#9 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + crcForUnit.addInt ((int) attackParticleSystems.size ()); + if (isNetworkCRCEnabled () == true) + { + for (unsigned int index = 0; index < attackParticleSystems.size (); + ++index) + { + ParticleSystem *ps = attackParticleSystems[index]; + if (ps != NULL && + Renderer::getInstance ().validateParticleSystemStillExists (ps, + rsGame) + == true) + { + uint32 crc = ps->getCRC ().getSum (); + crcForUnit.addBytes (&crc, sizeof (uint32)); + } + } + } - //crcForUnit.addInt(animationRandomCycleCount); - //printf("#9b Unit: %d CRC: %u\n",id,crcForUnit.getSum()); + if (this->networkCRCParticleLogInfo != "") + { + crcForUnit.addString (this->networkCRCParticleLogInfo); + } - crcForUnit.addInt(toBeUndertaken); + return crcForUnit; + } - if(consoleDebug) printf("#9c Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - crcForUnit.addInt(alive); - //bool showUnitParticles; - - if(consoleDebug) printf("#10 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - //Faction *faction; - //ParticleSystem *fire; - if(fire != NULL) { - crcForUnit.addInt(fire->getActive()); - } - - //TotalUpgrade totalUpgrade; - uint32 crc = totalUpgrade.getCRC().getSum(); - crcForUnit.addBytes(&crc,sizeof(uint32)); - - //Map *map; - //UnitPathInterface *unitPath; - if(unitPath != NULL) { - uint32 crc = unitPath->getCRC().getSum(); - crcForUnit.addBytes(&crc,sizeof(uint32)); - } - //WaypointPath waypointPath; - - if(consoleDebug) printf("#11 Unit: %d CRC: %u commands.size(): " MG_SIZE_T_SPECIFIER "\n",id,crcForUnit.getSum(),commands.size()); - - //Commands commands; - if(commands.empty() == false) { - crcForUnit.addInt((int)commands.size()); - for(Commands::const_iterator it= commands.begin(); it != commands.end(); ++it) { - uint32 crc = (*it)->getCRC().getSum(); - crcForUnit.addBytes(&crc,sizeof(uint32)); - } - } - - //printf("#11 Unit: %d CRC: %u observers.size(): %ld\n",id,crcForUnit.getSum(),observers.size()); - - //Observers observers; - //crcForUnit.addInt64((int64)observers.size()); - - if(consoleDebug) printf("#11 Unit: %d CRC: %u damageParticleSystems.size(): " MG_SIZE_T_SPECIFIER "\n",id,crcForUnit.getSum(),damageParticleSystems.size()); - - //vector unitParticleSystems; - //vector queuedUnitParticleSystemTypes; - - //UnitParticleSystems damageParticleSystems; - crcForUnit.addInt((int)damageParticleSystems.size()); - - if(consoleDebug) printf("#12 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - //std::map damageParticleSystemsInUse; - - //vector fireParticleSystems; - //vector smokeParticleSystems; - - //CardinalDir modelFacing; - crcForUnit.addInt(modelFacing); - - //std::string lastSynchDataString; - //std::string lastFile; - //int lastLine; - //std::string lastSource; - //int lastRenderFrame; - //bool visible; - - //int retryCurrCommandCount; - - //Vec3f screenPos; - //string currentUnitTitle; - - if(consoleDebug) printf("#13 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - crcForUnit.addInt(inBailOutAttempt); - - crcForUnit.addInt((int)badHarvestPosList.size()); - //crcForUnit.addInt(lastHarvestResourceTarget.first()); - - if(consoleDebug) printf("#14 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - //static Game *game; - //bool ignoreCheckCommand; - - //uint32 lastStuckFrame; - crcForUnit.addUInt(lastStuckFrame); - //Vec2i lastStuckPos; - crcForUnit.addInt(lastStuckPos.x); - crcForUnit.addInt(lastStuckPos.y); - - //uint32 lastPathfindFailedFrame; - //Vec2i lastPathfindFailedPos; - //bool usePathfinderExtendedMaxNodes; - //int maxQueuedCommandDisplayCount; - - //UnitAttackBoostEffectOriginator currentAttackBoostOriginatorEffect; - crcForUnit.addInt((int)currentAttackBoostOriginatorEffect.currentAttackBoostUnits.size()); - - if(consoleDebug) printf("#15 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - //std::vector currentAttackBoostEffects; - - //Mutex *mutexCommands; - - //bool changedActiveCommand; - - //int lastAttackerUnitId; - //int lastAttackedUnitId; - //CauseOfDeathType causeOfDeath; - - //uint32 pathfindFailedConsecutiveFrameCount; - crcForUnit.addString(this->currentPathFinderDesiredFinalPos.getString()); - - crcForUnit.addInt(random.getLastNumber()); - if(this->random.getLastCaller() != "") { - crcForUnit.addString(this->random.getLastCaller()); - } - - if(consoleDebug) printf("#16 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - //int pathFindRefreshCellCount; - - //FowAlphaCellsLookupItem cachedFow; - //Vec2i cachedFowPos; - - crcForUnit.addInt(lastHarvestedResourcePos.x); - crcForUnit.addInt(lastHarvestedResourcePos.y); - - if(consoleDebug) printf("#17 Unit: %d CRC: %u\n",id,crcForUnit.getSum()); - - if(this->getParticleInfo() != "") { - crcForUnit.addString(this->getParticleInfo()); - } - - crcForUnit.addInt((int)attackParticleSystems.size()); - if(isNetworkCRCEnabled() == true) { - for(unsigned int index = 0; index < attackParticleSystems.size(); ++index) { - ParticleSystem *ps = attackParticleSystems[index]; - if(ps != NULL && - Renderer::getInstance().validateParticleSystemStillExists(ps,rsGame) == true) { - uint32 crc = ps->getCRC().getSum(); - crcForUnit.addBytes(&crc,sizeof(uint32)); - } - } - } - - if(this->networkCRCParticleLogInfo != "") { - crcForUnit.addString(this->networkCRCParticleLogInfo); - } - - return crcForUnit; -} - -}}//end namespace + } +} //end namespace diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index eec94a95e..0e5840cad 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -1,854 +1,1264 @@ -// This file is part of Glest (www.glest.org) +// This file is part of Glest (www.glest.org) // -// Copyright (C) 2001-2008 Martiño Figueroa +// 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 +// 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_ +# define _GLEST_GAME_UNIT_H_ -#ifdef WIN32 - #include - #include -#endif +# 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" +# 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 { +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; + 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 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; + 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 CommandResult + { + crSuccess, + crFailRes, + crFailReqs, + crFailUnitCount, + crFailUndefined, + crSomeFailed + }; -enum InterestingUnitType { - iutIdleHarvester, - iutBuiltBuilding, - iutProducer, - iutDamaged, - iutStore -}; + enum InterestingUnitType + { + iutIdleHarvester, + iutBuiltBuilding, + iutProducer, + iutDamaged, + iutStore + }; -enum CauseOfDeathType { - ucodNone, - ucodAttacked, - ucodAttackBoost, - ucodStarvedResource, - ucodStarvedRegeneration -}; + 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 UnitBuildInfo + { + public: + UnitBuildInfo () + { + unit = NULL; + //pos; + buildUnit = NULL; + } + const Unit *unit; + CardinalDir facing; + Vec2i pos; + const UnitType *buildUnit; + }; // ===================================================== -// class UnitObserver +// class UnitObserver // ===================================================== -class UnitObserver { -public: - enum Event{ - eKill - }; + class UnitObserver + { + public: + enum Event + { + eKill + }; -public: - virtual ~UnitObserver() {} - virtual void unitEvent(Event event, const Unit *unit)=0; + public: + virtual ~ UnitObserver () + { + } + virtual void unitEvent (Event event, const Unit * unit) = 0; - virtual void saveGame(XmlNode *rootNode) const = 0; -}; + virtual void saveGame (XmlNode * rootNode) const = 0; + }; // ===================================================== -// class UnitReference +// class UnitReference // ===================================================== -class UnitReference { -private: - int id; - Faction *faction; + class UnitReference + { + private: + int id; + Faction *faction; -public: - UnitReference(); + public: + UnitReference (); - UnitReference & operator=(const Unit *unit); - Unit *getUnit() const; + UnitReference & operator= (const Unit * unit); + Unit *getUnit () const; - int getUnitId() const { return id; } - Faction *getUnitFaction() const { return faction; } + int getUnitId () const + { + return id; + } + Faction *getUnitFaction () const + { + return faction; + } - void saveGame(XmlNode *rootNode); - void loadGame(const XmlNode *rootNode,World *world); -}; + void saveGame (XmlNode * rootNode); + void loadGame (const XmlNode * rootNode, World * world); + }; -class UnitPathInterface { + class UnitPathInterface + { -public: - UnitPathInterface() {} - virtual ~UnitPathInterface() {} + public: + UnitPathInterface () + { + } + virtual ~ UnitPathInterface () + { + } - virtual bool isBlocked() const = 0; - virtual bool isEmpty() const = 0; - virtual bool isStuck() const = 0; + 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 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 vector < Vec2i > getQueue () const = 0; - virtual std::string toString() const = 0; + virtual std::string toString () const = 0; - virtual void setMap(Map *value) = 0; - virtual Map * getMap() = 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 saveGame (XmlNode * rootNode) = 0; + virtual void loadGame (const XmlNode * rootNode) = 0; - virtual void clearCaches() = 0; + virtual void clearCaches () = 0; - virtual Checksum getCRC() = 0; -}; + virtual Checksum getCRC () = 0; + }; -class UnitPathBasic : public UnitPathInterface { -private: - static const int maxBlockCount; - Map *map; + class UnitPathBasic:public UnitPathInterface + { + private: + static const int maxBlockCount; + Map *map; -#ifdef LEAK_CHECK_UNITS - static std::map mapMemoryList; -#endif +# ifdef LEAK_CHECK_UNITS + static std::map < UnitPathBasic *, bool > mapMemoryList; +# endif -private: - int blockCount; - vector pathQueue; + private: + int blockCount; + vector < Vec2i > pathQueue; -public: - UnitPathBasic(); - virtual ~UnitPathBasic(); + public: + UnitPathBasic (); + virtual ~ UnitPathBasic (); -#ifdef LEAK_CHECK_UNITS - static void dumpMemoryList(); -#endif +# ifdef LEAK_CHECK_UNITS + static void dumpMemoryList (); +# endif - virtual bool isBlocked() const; - virtual bool isEmpty() const; - virtual bool isStuck() const; + 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 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 vector < Vec2i > getQueue () const + { + return pathQueue; + } - virtual void setMap(Map *value) { map = value; } - virtual Map * getMap() { return map; } + virtual void setMap (Map * value) + { + map = value; + } + virtual Map *getMap () + { + return map; + } - virtual std::string toString() const; + virtual std::string toString () const; - virtual void saveGame(XmlNode *rootNode); - virtual void loadGame(const XmlNode *rootNode); - virtual void clearCaches(); + virtual void saveGame (XmlNode * rootNode); + virtual void loadGame (const XmlNode * rootNode); + virtual void clearCaches (); - virtual Checksum getCRC(); -}; + virtual Checksum getCRC (); + }; // ===================================================== -// class UnitPath +// 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 */ + class UnitPath:public list < Vec2i >, 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; + private: + int blockCount; /**< number of command updates this path has been blocked */ + Map *map; -public: - UnitPath() : UnitPathInterface(), blockCount(0), map(NULL) {} /**< Construct path object */ + 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; } + virtual bool isBlocked () const + { + return blockCount >= maxBlockCount; + } /**< is this path blocked */ + virtual bool isEmpty () const + { + return list < Vec2i >::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 */ + int size () const + { + return (int) list < Vec2i >::size (); + } /**< size of path */ + virtual void clear () + { + list < Vec2i >::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 < Vec2i >::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(); } +# 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 vector < Vec2i > getQueue () const + { + vector < Vec2i > result; + for (list < Vec2i >::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 void setMap (Map * value) + { + map = value; + } + virtual Map *getMap () + { + return map; + } - virtual std::string toString() const; + virtual std::string toString () const; - virtual void saveGame(XmlNode *rootNode) {}; - virtual void loadGame(const XmlNode *rootNode) {}; - virtual void clearCaches() {}; + virtual void saveGame (XmlNode * rootNode) + { + }; + virtual void loadGame (const XmlNode * rootNode) + { + }; + virtual void clearCaches () + { + }; - virtual Checksum getCRC() { return Checksum(); }; -}; + 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 WaypointPath:public list < Vec2i > + { + public: + WaypointPath () + { + } + void push (const Vec2i & pos) + { + push_front (pos); + } + Vec2i peek () const + { + return front (); + } + void pop () + { + erase (begin ()); + } + //void condense(); + }; // =============================== -// class Unit +// class Unit // -/// A game unit or building +/// 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; - // Progress2 keeps track of update/ upgrade progress of a unit. - int32 progress2; - int32 kills; - int32 enemyKills; - bool morphFieldsBlocked; - int oldTotalSight; - - 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(bool forceRefresh=false); - - //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;} - // resetProgress2 resets produce and upgrade progress. - inline void resetProgress2() {this->progress2 = 0;} - void setPos(const Vec2i &pos,bool clearPathFinder=false, bool threaded=false); - void refreshPos(bool forceRefresh=false); - void setTargetPos(const Vec2i &targetPos, bool threaded=false); - 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 getCurrMidHeightVector() const; - Vec3f getCurrVectorForParticlesystems() const; - Vec3f getCurrVectorAsTarget() const; - Vec3f getCurrBurnVector() 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(bool threadAccessAllowed=false); - - 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, int frameIndex); - 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(bool forceRefresh=false); - - 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(); - void setMeshPosInParticleSystem(UnitParticleSystem *ups); - - 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 AnimCycleStarts(); - 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(const UnitParticleSystemTypes &unitParticleSystemTypesList, - bool applySkillChangeParticles); - void queueTimedParticles(const UnitParticleSystemTypes &unitParticleSystemTypesList); - - 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 + 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 < int >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 < Command * >Commands; + typedef list < UnitObserver * >Observers; + typedef vector < UnitParticleSystem * >UnitParticleSystems; + +# ifdef LEAK_CHECK_UNITS + static std::map < Unit *, bool > 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 < UnitPathInterface *, int >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; + // Progress2 keeps track of update/ upgrade progress of a unit. + int32 progress2; + int32 kills; + int32 enemyKills; + bool morphFieldsBlocked; + int oldTotalSight; + + 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 < UnitParticleSystem * >unitParticleSystems; + vector < UnitParticleSystemType * >queuedUnitParticleSystemTypes; + + UnitParticleSystems damageParticleSystems; + std::map < int, UnitParticleSystem * >damageParticleSystemsInUse; + + vector < ParticleSystem * >fireParticleSystems; + vector < UnitParticleSystem * >smokeParticleSystems; + vector < ParticleSystem * >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 < Vec2i, int >badHarvestPosList; + //time_t lastBadHarvestListPurge; + std::pair < Vec2i, int >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 < UnitAttackBoostEffect * >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 < Vec2i, int >cacheExploredCellsKey; + + Vec2i lastHarvestedResourcePos; + + string networkCRCLogInfo; + string networkCRCParticleLogInfo; + vector < string > networkCRCDecHpList; + vector < string > 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 (bool forceRefresh = false); + + //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 < + float >(lastAnimProgress) / ANIMATION_SPEED_MULTIPLIER; + } + inline float getAnimProgressAsFloat () const + { + return static_cast < + float >(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; + } + // resetProgress2 resets produce and upgrade progress. + inline void resetProgress2 () + { + this->progress2 = 0; + } + void setPos (const Vec2i & pos, bool clearPathFinder = + false, bool threaded = false); + void refreshPos (bool forceRefresh = false); + void setTargetPos (const Vec2i & targetPos, bool threaded = false); + 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 getCurrMidHeightVector () const; + Vec3f getCurrVectorForParticlesystems () const; + Vec3f getCurrVectorAsTarget () const; + Vec3f getCurrBurnVector () 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 < CommandResult, string > 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 (bool threadAccessAllowed = false); + + 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, int frameIndex); + std::pair < CommandResult, + string > 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 (bool forceRefresh = false); + + 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 < Vec2i, int >::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 < Vec2i, int >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 (); + void setMeshPosInParticleSystem (UnitParticleSystem * ups); + + 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 AnimCycleStarts (); + 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 (const + UnitParticleSystemTypes & + unitParticleSystemTypesList, + bool + applySkillChangeParticles); + void queueTimedParticles (const UnitParticleSystemTypes & + unitParticleSystemTypesList); + + 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