From 8b681e1cb99fe8550ed6a3dc29649212480e3fd9 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 2 Sep 2010 05:38:49 +0000 Subject: [PATCH] - more bugfixes for multi-build. Added extra check for repairer / builder swap so that old builder who became a repairer will not try to start building when another unit already took over. --- source/glest_game/world/map.cpp | 15 ++-- source/glest_game/world/unit_updater.cpp | 107 ++++++++++++++++++----- source/glest_game/world/unit_updater.h | 4 + 3 files changed, 97 insertions(+), 29 deletions(-) diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 869e94c5..33f45160 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -285,12 +285,12 @@ bool Map::isResourceNear(const Vec2i &pos, int size, const ResourceType *rt, Vec // ==================== free cells ==================== -bool Map::isFreeCell(const Vec2i &pos, Field field) const{ +bool Map::isFreeCell(const Vec2i &pos, Field field) const { return isInside(pos) && getCell(pos)->isFree(field) && (field==fAir || getSurfaceCell(toSurfCoords(pos))->isFree()) && - (field!=fLand || !getDeepSubmerged(getCell(pos))); + (field!=fLand || getDeepSubmerged(getCell(pos)) == false); } bool Map::isFreeCellOrHasUnit(const Vec2i &pos, Field field, const Unit *unit) const{ @@ -324,10 +324,13 @@ bool Map::isAproxFreeCell(const Vec2i &pos, Field field, int teamIndex) const{ return false; } -bool Map::isFreeCells(const Vec2i & pos, int size, Field field) const{ - for(int i=pos.x; iisFree(field) = %d, getSurfaceCell(toSurfCoords(testPos))->isFree() = %d, getDeepSubmerged(getCell(testPos)) = %d\n",__FILE__,__FUNCTION__,__LINE__,testPos.getString().c_str(),field,getCell(testPos)->isFree(field),getSurfaceCell(toSurfCoords(testPos))->isFree(),getDeepSubmerged(getCell(testPos))); + return false; } } diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 72a919bf..4e341842 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -439,6 +439,7 @@ void UnitUpdater::updateBuild(Unit *unit) { bool canOccupyCell = false; switch(this->game->getGameSettings()->getPathFinderType()) { case pfBasic: + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] tsArrived about to call map->isFreeCells() for command->getPos() = %s, ut->getSize() = %d\n",__FILE__,__FUNCTION__,__LINE__,command->getPos().getString().c_str(),ut->getSize()); canOccupyCell = map->isFreeCells(command->getPos(), ut->getSize(), fLand); break; case pfRoutePlanner: @@ -498,7 +499,7 @@ void UnitUpdater::updateBuild(Unit *unit) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unit created for unit [%s]\n",__FILE__,__FUNCTION__,__LINE__,builtUnit->toString().c_str()); } - else{ + else { //if there are no free cells unit->cancelCommand(); unit->setCurrSkill(scStop); @@ -506,14 +507,17 @@ void UnitUpdater::updateBuild(Unit *unit) { if(unit->getFactionIndex()==world->getThisFactionIndex()){ console->addStdMessage("BuildingNoPlace"); } + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] got BuildingNoPlace\n",__FILE__,__FUNCTION__,__LINE__); } } break; case tsBlocked: - if(unit->getPath()->isBlocked()){ + if(unit->getPath()->isBlocked()) { unit->cancelCommand(); + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] got tsBlocked\n",__FILE__,__FUNCTION__,__LINE__); } break; } @@ -522,26 +526,30 @@ void UnitUpdater::updateBuild(Unit *unit) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] tsArrived:\n",__FILE__,__FUNCTION__,__LINE__); //if building - Unit *builtUnit= map->getCell(unit->getTargetPos())->getUnit(fLand); + Unit *builtUnit = map->getCell(unit->getTargetPos())->getUnit(fLand); //if u is killed while building then u==NULL; - if(builtUnit!=NULL && builtUnit!=command->getUnit()){ + if(builtUnit != NULL && builtUnit != command->getUnit()) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); unit->setCurrSkill(scStop); - } - else if(builtUnit==NULL || builtUnit->isBuilt()){ + else if(builtUnit == NULL || builtUnit->isBuilt()) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + unit->finishCommand(); unit->setCurrSkill(scStop); } - else if(builtUnit->repair()){ + else if(builtUnit->repair()) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //building finished unit->finishCommand(); unit->setCurrSkill(scStop); builtUnit->born(); scriptManager->onUnitCreated(builtUnit); - if(unit->getFactionIndex()==world->getThisFactionIndex()){ + if(unit->getFactionIndex() == world->getThisFactionIndex()) { SoundRenderer::getInstance().playFx( bct->getBuiltSound(), unit->getCurrVector(), @@ -756,6 +764,44 @@ void UnitUpdater::SwapActiveCommand(Unit *unitSrc, Unit *unitDest) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } +void UnitUpdater::SwapActiveCommandState(Unit *unit, CommandStateType commandStateType, + const CommandType *commandType, + int originalValue,int newValue) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + if(commandStateType == cst_linkedUnit) { + if(dynamic_cast(commandType) != NULL) { + + for(int i = 0; i < unit->getFaction()->getUnitCount(); ++i) { + Unit *peerUnit = unit->getFaction()->getUnit(i); + if(peerUnit != NULL) { + if(peerUnit->getCommandSize() > 0 ) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + Command *peerCommand = peerUnit->getCurrCommand(); + //const BuildCommandType *bct = dynamic_cast(peerCommand->getCommandType()); + //if(bct != NULL) { + if(peerCommand != NULL) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + //if(command->getPos() == peerCommand->getPos()) { + if( peerCommand->getStateType() == commandStateType && + peerCommand->getStateValue() == originalValue) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + peerCommand->setStateValue(newValue); + } + } + } + } + } + + } + } + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); +} + Unit * UnitUpdater::findPeerUnitBuilder(Unit *unit) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -819,24 +865,39 @@ void UnitUpdater::updateRepair(Unit *unit) { if(peerUnitBuilder != NULL) { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] peerUnitBuilder = %p\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder); - Vec2i buildPos = map->findBestBuildApproach(unit->getPos(), command->getPos(), peerUnitBuilder->getCurrCommand()->getUnitType()); + if(peerUnitBuilder->getCurrCommand()->getUnit() != NULL) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] peerbuilder's unitid = %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder->getCurrCommand()->getUnit()->getId()); - //nextToRepaired= (unit->getPos() == (command->getPos()-Vec2i(1))); - nextToRepaired = (unit->getPos() == buildPos); - - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] peerUnitBuilder = %p, nextToRepaired = %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder,nextToRepaired); - - if(nextToRepaired == true) { + repaired = peerUnitBuilder->getCurrCommand()->getUnit(); + nextToRepaired = repaired != NULL && map->isNextTo(unit->getPos(), repaired); + } + else { SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - SwapActiveCommand(unit,peerUnitBuilder); - // Give the swapped unit a fresh chance to help build in case they - // were or are about to be blocked - peerUnitBuilder->getPath()->clear(); - peerUnitBuilder->setRetryCurrCommandCount(1); - updateUnitCommand(unit); - //updateUnitCommand(peerUnitBuilder); - return; + Vec2i buildPos = map->findBestBuildApproach(unit->getPos(), command->getPos(), peerUnitBuilder->getCurrCommand()->getUnitType()); + + //nextToRepaired= (unit->getPos() == (command->getPos()-Vec2i(1))); + nextToRepaired = (unit->getPos() == buildPos); + + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] peerUnitBuilder = %p, nextToRepaired = %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder,nextToRepaired); + + if(nextToRepaired == true) { + SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + + CommandStateType commandStateType = unit->getCurrCommand()->getStateType(); + SwapActiveCommand(unit,peerUnitBuilder); + int oldPeerUnitId = peerUnitBuilder->getId(); + int newPeerUnitId = unit->getId(); + SwapActiveCommandState(unit,commandStateType,unit->getCurrCommand()->getCommandType(),oldPeerUnitId,newPeerUnitId); + + // Give the swapped unit a fresh chance to help build in case they + // were or are about to be blocked + peerUnitBuilder->getPath()->clear(); + peerUnitBuilder->setRetryCurrCommandCount(1); + updateUnitCommand(unit); + //updateUnitCommand(peerUnitBuilder); + return; + } } } } diff --git a/source/glest_game/world/unit_updater.h b/source/glest_game/world/unit_updater.h index 2db8c4e3..363bf6e6 100644 --- a/source/glest_game/world/unit_updater.h +++ b/source/glest_game/world/unit_updater.h @@ -15,6 +15,7 @@ #include "gui.h" #include "particle.h" #include "randomgen.h" +#include "command.h" using Shared::Graphics::ParticleObserver; using Shared::Util::RandomGen; @@ -118,6 +119,9 @@ private: Unit * findPeerUnitBuilder(Unit *unit); void SwapActiveCommand(Unit *unitSrc, Unit *unitDest); + void SwapActiveCommandState(Unit *unit, CommandStateType commandStateType, + const CommandType *commandType, + int originalValue,int newValue); };