From 9ffad02f8f66ff1a6a387fd965d77d0dabb006a1 Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Fri, 28 Oct 2011 05:22:41 +0000 Subject: [PATCH] - bugfix for detecting if one unit is next to another - now repair command does NOT require a move skill. If a move skill is not defined then the repairer must be beside the unit he will repair or they get an invalid position console message --- source/glest_game/types/command_type.cpp | 11 ++- source/glest_game/world/map.cpp | 21 +++++ source/glest_game/world/map.h | 1 + source/glest_game/world/unit_updater.cpp | 112 +++++++++++++---------- 4 files changed, 94 insertions(+), 51 deletions(-) diff --git a/source/glest_game/types/command_type.cpp b/source/glest_game/types/command_type.cpp index bdecf6be..b31958c7 100644 --- a/source/glest_game/types/command_type.cpp +++ b/source/glest_game/types/command_type.cpp @@ -565,12 +565,15 @@ void RepairCommandType::load(int id, const XmlNode *n, const string &dir, std::map > > &loadedFileList, string parentLoader) { CommandType::load(id, n, dir, tt, ft, ut, loadedFileList, parentLoader); - //move - string skillName= n->getChild("move-skill")->getAttribute("value")->getRestrictedValue(); - moveSkillType= static_cast(ut.getSkillType(skillName, scMove)); + // move skill (no longer required by means unit must already be beside unit to repair) + // for example a hospital + if(n->hasChild("move-skill") == true) { + string skillName= n->getChild("move-skill")->getAttribute("value")->getRestrictedValue(); + moveSkillType= static_cast(ut.getSkillType(skillName, scMove)); + } //repair - skillName= n->getChild("repair-skill")->getAttribute("value")->getRestrictedValue(); + string skillName= n->getChild("repair-skill")->getAttribute("value")->getRestrictedValue(); repairSkillType= static_cast(ut.getSkillType(skillName, scRepair)); //repaired units diff --git a/source/glest_game/world/map.cpp b/source/glest_game/world/map.cpp index 9ed0df70..1c2b8417 100644 --- a/source/glest_game/world/map.cpp +++ b/source/glest_game/world/map.cpp @@ -1381,6 +1381,27 @@ bool Map::isNextTo(const Vec2i &pos, const Unit *unit) const { return false; } +//return if unit is next to pos +bool Map::isNextTo(const Unit *unit1, const Unit *unit2) const { + Vec2i pos = unit1->getPos(); + const UnitType *ut = unit1->getType(); + for (int y=-1; y < ut->getSize()+1; ++y) { + for (int x=-1; x < ut->getSize()+1; ++x) { + Vec2i cellPos = pos + Vec2i(x, y); + if(isInside(cellPos) && isInsideSurface(toSurfCoords(cellPos))) { + if(getCell(cellPos)->getUnit(fLand) == unit2) { + return true; + } + else if(getCell(cellPos)->getUnitWithEmptyCellMap(fLand) == unit2) { + return true; + } + } + } + } + + return false; +} + //return if unit is next to pos bool Map::isNextTo(const Vec2i &pos, const Vec2i &nextToPos) const { diff --git a/source/glest_game/world/map.h b/source/glest_game/world/map.h index ada80ea2..816a3885 100644 --- a/source/glest_game/world/map.h +++ b/source/glest_game/world/map.h @@ -246,6 +246,7 @@ public: //misc bool isNextTo(const Vec2i &pos, const Unit *unit) const; bool isNextTo(const Vec2i &pos, const Vec2i &nextToPos) const; + bool isNextTo(const Unit *unit1, const Unit *unit2) const; void clampPos(Vec2i &pos) const; void prepareTerrain(const Unit *unit); diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 704c3b75..f4ea2a0d 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -1188,7 +1188,7 @@ void UnitUpdater::updateHarvest(Unit *unit, int frameIndex) { } //world->changePosCells(unit,unit->getPos()+unit->getDest()); - if(map->isNextTo(unit->getPos(), store)) { + if(map->isNextTo(unit, store)) { //update resources int resourceAmount= unit->getLoadCount(); @@ -1484,7 +1484,7 @@ void UnitUpdater::updateRepair(Unit *unit, int frameIndex) { } } - bool nextToRepaired = repaired != NULL && map->isNextTo(unit->getPos(), repaired); + bool nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -1498,7 +1498,7 @@ void UnitUpdater::updateRepair(Unit *unit, int frameIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] peerbuilder's unitid = %d\n",__FILE__,__FUNCTION__,__LINE__,peerUnitBuilder->getCurrCommand()->getUnit()->getId()); repaired = peerUnitBuilder->getCurrCommand()->getUnit(); - nextToRepaired = repaired != NULL && map->isNextTo(unit->getPos(), repaired); + nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); } else { if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -1617,62 +1617,80 @@ void UnitUpdater::updateRepair(Unit *unit, int frameIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); - TravelState ts; - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + // If the repair command has no move skill and we are not next to + // the unit we cannot repair it + if(rct->getMoveSkillType() == NULL) { + //printf("CANCEL REPAIR NOT NEXT TO REPAIR UNIT\n"); - ts = pathFinder->findPath(unit, repairPos, NULL, frameIndex); - break; - case pfRoutePlanner: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + //Vec2i repairPos = command->getPos(); + //bool startRepairing = (repaired != NULL && rct->isRepairableUnitType(repaired->getType()) && repaired->isDamaged()); + //bool nextToRepaired = repaired != NULL && map->isNextTo(unit, repaired); - if (repaired && !repaired->getType()->isMobile()) { - ts = routePlanner->findPathToBuildSite(unit, repaired->getType(), repaired->getPos(), repaired->getModelFacing()); - } - else { - ts = routePlanner->findPath(unit, repairPos); - } - break; - default: - throw runtime_error("detected unsupported pathfinder type!"); - } + //printf("repairPos [%s] startRepairing = %d nextToRepaired = %d unit->getPos() [%s] repaired->getPos() [%s]\n",repairPos.getString().c_str(),startRepairing,nextToRepaired,unit->getPos().getString().c_str(),repaired->getPos().getString().c_str()); - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] ts = %d\n",__FILE__,__FUNCTION__,__LINE__,ts); + console->addStdMessage("InvalidPosition"); + unit->setCurrSkill(scStop); + unit->finishCommand(); + } + else { + TravelState ts; + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + ts = pathFinder->findPath(unit, repairPos, NULL, frameIndex); + break; + case pfRoutePlanner: + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - switch(ts) { - case tsMoving: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsMoving\n",__FILE__,__FUNCTION__,__LINE__); - unit->setCurrSkill(rct->getMoveSkillType()); - break; - case tsBlocked: - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsBlocked\n",__FILE__,__FUNCTION__,__LINE__); - - if(unit->getPath()->isBlocked()) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to call [scStop]\n",__FILE__,__FUNCTION__,__LINE__); - - if(unit->getRetryCurrCommandCount() > 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] will retry command, unit->getRetryCurrCommandCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getRetryCurrCommandCount()); - - unit->setRetryCurrCommandCount(0); - unit->getPath()->clear(); - updateUnitCommand(unit,-1); - } - else { - unit->finishCommand(); - } + if (repaired && !repaired->getType()->isMobile()) { + ts = routePlanner->findPathToBuildSite(unit, repaired->getType(), repaired->getPos(), repaired->getModelFacing()); + } + else { + ts = routePlanner->findPath(unit, repairPos); + } + break; + default: + throw runtime_error("detected unsupported pathfinder type!"); + } + + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] ts = %d\n",__FILE__,__FUNCTION__,__LINE__,ts); + + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); + + switch(ts) { + case tsMoving: + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsMoving\n",__FILE__,__FUNCTION__,__LINE__); + unit->setCurrSkill(rct->getMoveSkillType()); + break; + case tsBlocked: + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] tsBlocked\n",__FILE__,__FUNCTION__,__LINE__); + + if(unit->getPath()->isBlocked()) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to call [scStop]\n",__FILE__,__FUNCTION__,__LINE__); + + if(unit->getRetryCurrCommandCount() > 0) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] will retry command, unit->getRetryCurrCommandCount() = %d\n",__FILE__,__FUNCTION__,__LINE__,unit->getRetryCurrCommandCount()); + + unit->setRetryCurrCommandCount(0); + unit->getPath()->clear(); + updateUnitCommand(unit,-1); + } + else { + unit->finishCommand(); + } + } + break; + default: + break; } - break; - default: - break; } } } else { if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d] about to call [scStop]\n",__FILE__,__FUNCTION__,__LINE__); + console->addStdMessage("InvalidPosition"); unit->setCurrSkill(scStop); unit->finishCommand(); if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis());