- 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
This commit is contained in:
Mark Vejvoda 2011-10-28 05:22:41 +00:00
parent 64eeba93cb
commit 9ffad02f8f
4 changed files with 94 additions and 51 deletions

View File

@ -565,12 +565,15 @@ void RepairCommandType::load(int id, const XmlNode *n, const string &dir,
std::map<string,vector<pair<string, string> > > &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<const MoveSkillType*>(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<const MoveSkillType*>(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<const RepairSkillType*>(ut.getSkillType(skillName, scRepair));
//repaired units

View File

@ -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 {

View File

@ -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);

View File

@ -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());