diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index a9f10b75..326f3db9 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -120,9 +120,11 @@ std::pair Commander::tryGiveCommand(const Selection *selec } if(useCommandtype != NULL) { + auto mct= unit->getCurrMorphCt(); + int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1; NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, - useCommandtype->getId(), usePos, unitType->getId(), - (targetUnit != NULL ? targetUnit->getId() : -1), + useCommandtype->getId(), usePos, unitType->getId(), nextUnitTypeId, + (targetUnit != NULL ? targetUnit->getId() : -1), facing, tryQueue, commandStateType,commandStateValue, unitCommandGroupId); @@ -162,8 +164,10 @@ std::pair Commander::tryGiveCommand(const Unit* unit, cons std::pair result(crFailUndefined,""); bool canSubmitCommand=canSubmitCommandType(unit, commandType); if(canSubmitCommand == true) { + auto mct= unit->getCurrMorphCt(); + int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1; NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), - commandType->getId(), pos, unitType->getId(), + commandType->getId(), pos, unitType->getId(), nextUnitTypeId, (targetUnit != NULL ? targetUnit->getId() : -1), facing, tryQueue,cst_None,-1,unitGroupCommandId); @@ -210,8 +214,10 @@ std::pair Commander::tryGiveCommand(const Selection *selec int unitId= selection->getUnit(i)->getId(); Vec2i currPos= world->getMap()->computeDestPos(refPos, selection->getUnit(i)->getPosNotThreadSafe(), pos); + auto mct= unit->getCurrMorphCt(); + int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1; NetworkCommand networkCommand(this->world,nctGiveCommand, - unitId, ct->getId(), currPos, -1, targetId, -1, + unitId, ct->getId(), currPos, -1, nextUnitTypeId, targetId, -1, tryQueue,cst_None,-1,unitCommandGroupId); //every unit is ordered to a different pos @@ -263,8 +269,11 @@ std::pair Commander::tryGiveCommand(const Selection *selec int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId(); int unitId= unit->getId(); Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); + auto mct= unit->getCurrMorphCt(); + int nextUnitTypeId= mct? mct->getMorphUnit()->getId(): -1; + NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, - commandType->getId(), currPos, -1, targetId, -1, tryQueue, + commandType->getId(), currPos, -1, nextUnitTypeId, targetId, -1, tryQueue, cst_None, -1, unitCommandGroupId); //every unit is ordered to a different position @@ -310,19 +319,22 @@ std::pair Commander::tryGiveCommand(const Selection *selec currPos= world->getMap()->computeDestPos(refPos, unit->getPosNotThreadSafe(), pos); //get command type - const CommandType *commandType= unit->computeCommandType(pos, targetUnit); + auto mct= unit->getCurrMorphCt(); + auto nextUnitType= mct? mct->getMorphUnit(): NULL; + const CommandType *commandType= unit->computeCommandType(pos, targetUnit, nextUnitType); //give commands if(commandType != NULL) { int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId(); int unitId= unit->getId(); + int nextUnitTypeId= nextUnitType? nextUnitType->getId(): -1; std::pair resultCur(crFailUndefined,""); bool canSubmitCommand=canSubmitCommandType(unit, commandType); if(canSubmitCommand == true) { NetworkCommand networkCommand(this->world,nctGiveCommand, - unitId, commandType->getId(), currPos, -1, targetId, + unitId, commandType->getId(), currPos, -1, nextUnitTypeId, targetId, -1, tryQueue, cst_None, -1, unitCommandGroupId); resultCur= pushNetworkCommand(&networkCommand); } @@ -330,7 +342,7 @@ std::pair Commander::tryGiveCommand(const Selection *selec } else if(unit->isMeetingPointSettable() == true) { NetworkCommand command(this->world,nctSetMeetingPoint, - unit->getId(), -1, currPos,-1,-1,-1,false, + unit->getId(), -1, currPos,-1,-1,-1,-1,false, cst_None,-1,unitCommandGroupId); std::pair resultCur= pushNetworkCommand(&command); @@ -358,7 +370,7 @@ CommandResult Commander::tryCancelCommand(const Selection *selection) const { for(int i = 0; i < selection->getCount(); ++i) { NetworkCommand command(this->world,nctCancelCommand, - selection->getUnit(i)->getId(),-1,Vec2i(0),-1,-1,-1,false, + selection->getUnit(i)->getId(),-1,Vec2i(0),-1,-1,-1,-1,false, cst_None,-1,unitCommandGroupId); pushNetworkCommand(&command); } @@ -950,7 +962,7 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const { throw megaglest_runtime_error(szBuf); } - ct = unit->getType()->findCommandTypeById(networkCommand->getCommandTypeId()); + ct = unit->getType()->findCommandTypeById(networkCommand->getCommandTypeId()); if(unit->getFaction()->getIndex() != networkCommand->getUnitFactionIndex()) { @@ -984,7 +996,13 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const { throw megaglest_runtime_error(sError); } - const UnitType* unitType= world->findUnitTypeById(unit->getFaction()->getType(), networkCommand->getUnitTypeId()); + const UnitType* unitType= world->findUnitTypeById(unit->getFaction()->getType(), networkCommand->getUnitTypeId()); + + if(networkCommand->getNextUnitTypeId() > -1 && networkCommand->getWantQueue()) { //Morph Queue + auto nextUnitType= world->findUnitTypeById(unit->getFaction()->getType(), networkCommand->getNextUnitTypeId()); + auto mct = nextUnitType->findCommandTypeById(networkCommand->getCommandTypeId()); + if(mct) ct = mct; + } // debug test! //throw megaglest_runtime_error("Test missing command type!"); diff --git a/source/glest_game/game/game.cpp b/source/glest_game/game/game.cpp index 178f68b4..1768476d 100644 --- a/source/glest_game/game/game.cpp +++ b/source/glest_game/game/game.cpp @@ -5005,7 +5005,10 @@ void Game::keyUp(SDL_KeyboardEvent key) { gameCamera.setMoveX(0); camRightButtonDown= false; calcCameraMoveX(); + } else { + gui.hotKeyReleased(key); } + } } catch(const exception &ex) { diff --git a/source/glest_game/gui/gui.cpp b/source/glest_game/gui/gui.cpp index 9d25798d..33d3375d 100644 --- a/source/glest_game/gui/gui.cpp +++ b/source/glest_game/gui/gui.cpp @@ -460,6 +460,16 @@ void Gui::hotKey(SDL_KeyboardEvent key) { break; } } + + if(isKeyDown(queueCommandKey)) { + computeDisplay(); + } +} + +void Gui::hotKeyReleased(SDL_KeyboardEvent key) { + if(!isKeyDown(queueCommandKey)) { + computeDisplay(); + } } void Gui::switchToNextDisplayColor(){ @@ -567,7 +577,7 @@ void Gui::giveTwoClickOrders(int x, int y , bool prepared) { else { result= commander->tryGiveCommand(&selection, activeCommandClass, targetPos, targetUnit,queueKeyDown); - } + } } else { //selecting building @@ -697,6 +707,8 @@ void Gui::mouseDownDisplayUnitSkills(int posDisplay) { if (activeCommandClass == ccAttack) { ct = selection.getUnitFromCC(ccAttack)->getType()->getFirstCtOfClass(activeCommandClass); } + auto mct= unit->getCurrMorphCt(); + if(mct && isKeyDown(queueCommandKey)) ct= mct->getMorphUnit()->getFirstCtOfClass(activeCommandClass); if(activeCommandType!=NULL && activeCommandType->getClass()==ccBuild){ assert(selection.isUniform()); @@ -969,6 +981,10 @@ void Gui::computeDisplay(){ //uniform selection if(u->isBuilt()){ //printf("u->isBuilt()\n"); + auto mct = u->getCurrMorphCt(); + if(mct && isKeyDown(queueCommandKey)) {//Morph Queue + ut=mct->getMorphUnit(); + }//TODO on queueCommandKey presed disable stop cmd int morphPos= CommandHelper::getRowPos(crMorphs); for(int i= 0; i < ut->getCommandTypeSortedCount(); ++i){ @@ -993,7 +1009,7 @@ void Gui::computeDisplay(){ display.setCommandType(displayPos, ct); display.setCommandClass(displayPos, ct->getClass()); bool reqOk=u->getFaction()->reqsOk(ct); - display.setDownLighted(displayPos,reqOk); + display.setDownLighted(displayPos, reqOk && !(!ct->isQueueAppendable() && isKeyDown(queueCommandKey))); if (reqOk && produced != NULL) { if (possibleAmount == 0) { diff --git a/source/glest_game/gui/gui.h b/source/glest_game/gui/gui.h index d44831b1..0cccc666 100644 --- a/source/glest_game/gui/gui.h +++ b/source/glest_game/gui/gui.h @@ -197,6 +197,7 @@ public: void mouseDoubleClickLeftGraphics(int x, int y); void groupKey(int groupIndex); void hotKey(SDL_KeyboardEvent key); + void hotKeyReleased(SDL_KeyboardEvent key); //misc void switchToNextDisplayColor(); diff --git a/source/glest_game/network/network_types.cpp b/source/glest_game/network/network_types.cpp index 62b73425..b88c6c87 100644 --- a/source/glest_game/network/network_types.cpp +++ b/source/glest_game/network/network_types.cpp @@ -28,12 +28,13 @@ namespace Glest{ namespace Game{ NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId, int commandTypeId, const Vec2i &pos, int unitTypeId, - int targetId, int facing, bool wantQueue, + int nextUnitTypeId, int targetId, int facing, bool wantQueue, CommandStateType commandStateType, int commandStateValue, int unitCommandGroupId) : networkCommandType(networkCommandType) , unitId(unitId) , unitTypeId(unitTypeId) + , nextUnitTypeId(nextUnitTypeId) , commandTypeId(commandTypeId) , positionX(pos.x) , positionY(pos.y) @@ -48,43 +49,44 @@ NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId, this->targetId = targetId >= 0 ? targetId : facing; this->fromFactionIndex = world->getThisFactionIndex(); - if(this->networkCommandType == nctGiveCommand) { - const Unit *unit= world->findUnitById(this->unitId); + if(this->networkCommandType == nctGiveCommand) { + const Unit *unit= world->findUnitById(this->unitId); - //validate unit - if(unit != NULL) { - this->unitFactionIndex = unit->getFaction()->getIndex(); - this->unitFactionUnitCount = unit->getFaction()->getUnitCount(); + //validate unit + if(unit != NULL) { + this->unitFactionIndex = unit->getFaction()->getIndex(); + this->unitFactionUnitCount = unit->getFaction()->getUnitCount(); - //const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), this->unitTypeId); - const CommandType *ct = unit->getType()->findCommandTypeById(this->commandTypeId); - if(ct != NULL && ct->getClass() == ccBuild) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); - CardinalDir::assertDirValid(facing); - assert(targetId == -1); - } - } - } + const CommandType *ct= unit->getType()->findCommandTypeById(this->commandTypeId); + + if(ct != NULL && ct->getClass() == ccBuild) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); + CardinalDir::assertDirValid(facing); + assert(targetId == -1); + } + } + } - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Created NetworkCommand as follows:\n%s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Created NetworkCommand as follows:\n%s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); } void NetworkCommand::preprocessNetworkCommand(World *world) { - if(networkCommandType == nctGiveCommand) { - const Unit *unit= world->findUnitById(unitId); + if(networkCommandType == nctGiveCommand) { + const Unit *unit= world->findUnitById(unitId); - //validate unit - if(unit != NULL) { - //const UnitType *unitType= world->findUnitTypeById(unit->getFaction()->getType(), unitTypeId); - const CommandType *ct = unit->getType()->findCommandTypeById(commandTypeId); - if(ct != NULL && ct->getClass() == ccBuild && targetId >= 0) { + //validate unit + if(unit != NULL) { + + const CommandType *ct= unit->getType()->findCommandTypeById(commandTypeId); + + if(ct != NULL && ct->getClass() == ccBuild && targetId >= 0) { CardinalDir::assertDirValid(targetId); - } - } - else { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] (unit == NULL) %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); - } - } + } + } + else { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] (unit == NULL) %s\n",__FILE__,__FUNCTION__,__LINE__,toString().c_str()); + } + } } diff --git a/source/glest_game/network/network_types.h b/source/glest_game/network/network_types.h index 22493582..16435ca4 100644 --- a/source/glest_game/network/network_types.h +++ b/source/glest_game/network/network_types.h @@ -94,6 +94,7 @@ public: networkCommandType=0; unitId=0; unitTypeId=0; + nextUnitTypeId=0; commandTypeId=0; positionX=0; positionY=0; @@ -114,6 +115,7 @@ public: int commandTypeId= -1, const Vec2i &pos= Vec2i(0), int unitTypeId= -1, + int nextUnitTypeId= -1, int targetId= -1, int facing= -1, bool wantQueue = false, @@ -124,6 +126,7 @@ public: int16 networkCommandType; int32 unitId; int16 unitTypeId; + int16 nextUnitTypeId; int16 commandTypeId; int16 positionX; int16 positionY; @@ -141,6 +144,7 @@ public: int getCommandTypeId() const {return commandTypeId;} Vec2i getPosition() const {return Vec2i(positionX, positionY);} int getUnitTypeId() const {return unitTypeId;} + int getNextUnitTypeId() const {return nextUnitTypeId;} int getTargetId() const {return targetId;} int getWantQueue() const {return wantQueue;} int getFromFactionIndex() const {return fromFactionIndex;} diff --git a/source/glest_game/type_instances/command.cpp b/source/glest_game/type_instances/command.cpp index 56f45b50..c35af60a 100644 --- a/source/glest_game/type_instances/command.cpp +++ b/source/glest_game/type_instances/command.cpp @@ -76,12 +76,6 @@ Command::Command(const CommandType *ct, const Vec2i &pos, const UnitType *unitTy //} } -int Command::getPriority(){ - if(this->commandType->commandTypeClass==ccAttack && getUnit()==NULL){ - return 5; // attacks to the ground have low priority - } - return this->commandType->getTypePriority(); -} // =============== set =============== void Command::setCommandType(const CommandType *commandType) { diff --git a/source/glest_game/type_instances/command.h b/source/glest_game/type_instances/command.h index 8c04fea4..922ec9fc 100644 --- a/source/glest_game/type_instances/command.h +++ b/source/glest_game/type_instances/command.h @@ -71,9 +71,6 @@ public: inline const UnitType* getUnitType() const {return unitType;} inline CardinalDir getFacing() const {return facing;} - //Priority: commands of higher priority will cancel commands of lower priority - virtual int getPriority(); - //set void setCommandType(const CommandType *commandType); void setPos(const Vec2i &pos); diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index dc81399c..a4d5e12a 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -745,6 +745,15 @@ void Unit::cleanupAllParticlesystems() { } +const MorphCommandType* Unit::getCurrMorphCt() const { + auto result = std::find_if(commands.rbegin(), commands.rend(),[](Command *i) + { return i->getCommandType()->getClass() == ccMorph; });//TODO set CurrMorphCt on push comands instead of looping + if(result != commands.rend()) { + return static_cast((*result)->getCommandType()); + } + else return NULL; +} + ParticleSystem * Unit::getFire() const { if(this->fire != NULL && Renderer::getInstance().validateParticleSystemStillExists(this->fire,rsGame) == false) { @@ -1828,8 +1837,6 @@ std::pair Unit::giveCommand(Command *command, bool tryQueu 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)); @@ -1839,32 +1846,6 @@ std::pair Unit::giveCommand(Command *command, bool tryQueu 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 @@ -2183,8 +2164,9 @@ void Unit::resetHighlight(){ highlight= 1.f; } -const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *targetUnit) const{ +const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *targetUnit, const UnitType* unitType) const{ const CommandType *commandType= NULL; + unitType= unitType? unitType: type; if(map->isInside(pos) == false || map->isInsideSurface(map->toSurfCoords(pos)) == false) { throw megaglest_runtime_error("#6 Invalid path position = " + pos.getString()); @@ -2192,22 +2174,21 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target SurfaceCell *sc= map->getSurfaceCell(Map::toSurfCoords(pos)); - if(type == NULL) { + if(unitType == 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()); + snprintf(szBuf,8096,"In [%s::%s Line: %d] ERROR: unitType == 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()); + commandType= unitType->getFirstAttackCommand(targetUnit->getCurrField()); } //repair allies else { if(targetUnit->isBuilt() == false || targetUnit->isDamaged() == true) { - commandType= type->getFirstRepairCommand(targetUnit->getType()); + commandType= unitType->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); @@ -2223,7 +2204,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target targetUnit->getType() != NULL && targetUnit->getType()->getStore(this->getLoadType()) > 0) { - commandType = type->getFirstHarvestEmergencyReturnCommand(); + commandType = unitType->getFirstHarvestEmergencyReturnCommand(); } } } @@ -2232,7 +2213,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target //check harvest command Resource *resource= sc->getResource(); if(resource != NULL) { - commandType= type->getFirstHarvestCommand(resource->getType(),this->getFaction()); + commandType= unitType->getFirstHarvestCommand(resource->getType(),this->getFaction()); } } @@ -2247,7 +2228,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target (targetUnit->isBuilt() == false || targetUnit->isDamaged() == true)) { const RepairCommandType *rct= this->getType()->getFirstRepairCommand(targetUnit->getType()); if(rct != NULL) { - commandType= type->getFirstRepairCommand(targetUnit->getType()); + commandType= unitType->getFirstRepairCommand(targetUnit->getType()); //printf("************ Unit will repair building built = %d, repair = %d\n",targetUnit->isBuilt(),targetUnit->isDamaged()); } } @@ -2257,7 +2238,7 @@ const CommandType *Unit::computeCommandType(const Vec2i &pos, const Unit *target //default command is move command if(commandType == NULL) { - commandType= type->getFirstCtOfClass(ccMove); + commandType= unitType->getFirstCtOfClass(ccMove); } return commandType; @@ -3848,12 +3829,16 @@ std::pair Unit::checkCommand(Command *command) const { (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())); + auto mct = getCurrMorphCt(); // 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 if(mct && mct->getMorphUnit()->hasCommandType(command->getCommandType())) { + // Allow Current Morph Commands + } else { //printf("In [%s::%s Line: %d] command = %p\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,command); diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 1760f17e..ccadf227 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -653,6 +653,7 @@ public: } return NULL; } + const MorphCommandType* getCurrMorphCt() const; void replaceCurrCommand(Command *cmd); int getCountOfProducedUnitsPreExistence(const UnitType *ut) const; unsigned int getCommandSize() const; @@ -673,7 +674,7 @@ public: //other void resetHighlight(); - const CommandType *computeCommandType(const Vec2i &pos, const Unit *targetUnit= NULL) const; + const CommandType *computeCommandType(const Vec2i &pos, const Unit *targetUnit= NULL, const UnitType* unitType= NULL) const; string getDesc(bool translatedValue) const; string getDescExtension(bool translatedValue) const; bool computeEp(); diff --git a/source/glest_game/types/command_type.h b/source/glest_game/types/command_type.h index 84b84beb..2364f679 100644 --- a/source/glest_game/types/command_type.h +++ b/source/glest_game/types/command_type.h @@ -125,8 +125,6 @@ public: Queueability q = isQueuable(); return (q != qNever) && (q != qOnlyLast); } - //Priority: commands of higher priority will cancel commands of lower priority - virtual int getTypePriority() const {return 10;} virtual bool usesPathfinder() const= 0; //get @@ -156,7 +154,6 @@ public: virtual string getDesc(const TotalUpgrade *totalUpgrade, bool translatedValue) const; virtual string toString(bool translatedValue) const; virtual Queueability isQueuable() const {return qNever;} - virtual int getTypePriority() const {return 100000;} //get const StopSkillType *getStopSkillType() const {return stopSkillType;}; @@ -230,6 +227,7 @@ public: const TechTree *tt, const FactionType *ft, const UnitType &ut, std::map > > &loadedFileList, string parentLoader); virtual string getDesc(const TotalUpgrade *totalUpgrade, bool translatedValue) const; + virtual Queueability isQueuable() const {return qOnlyLast;} virtual string toString(bool translatedValue) const; //get @@ -386,7 +384,6 @@ public: virtual string toString(bool translatedValue) const; virtual const ProducibleType *getProduced() const; virtual Queueability isQueuable() const {return qAlways;} - virtual int getTypePriority() const {return 15;} //get const ProduceSkillType *getProduceSkillType() const {return produceSkillType;} @@ -416,7 +413,6 @@ public: virtual string getReqDesc(bool translatedValue) const; virtual const ProducibleType *getProduced() const; virtual Queueability isQueuable() const {return qAlways;} - virtual int getTypePriority() const {return 15;} //get const UpgradeSkillType *getUpgradeSkillType() const {return upgradeSkillType;} @@ -446,7 +442,7 @@ public: virtual string toString(bool translatedValue) const; virtual string getReqDesc(bool translatedValue) const; virtual const ProducibleType *getProduced() const; - Queueability isQueuable() const {return qOnlyLast;} //After morph anything can happen + Queueability isQueuable() const {return qAlways;} //After morph anything can happen //get const MorphSkillType *getMorphSkillType() const {return morphSkillType;} diff --git a/source/glest_game/world/unit_updater.cpp b/source/glest_game/world/unit_updater.cpp index 88fa1dd3..5a2bf0a9 100644 --- a/source/glest_game/world/unit_updater.cpp +++ b/source/glest_game/world/unit_updater.cpp @@ -720,167 +720,137 @@ void UnitUpdater::updateAttack(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()); - if( (command->getUnit() == NULL || !(command->getUnit()->isAlive()) ) && unit->getCommandSize() > 1) { - + + if(attackableOnRange(unit, &target, act->getAttackSkillType(),(frameIndex >= 0))) { if(frameIndex < 0) { - unit->finishCommand(); // all queued "ground attacks" are skipped if somthing else is queued after them. - + if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) { + unit->setCurrSkill(act->getAttackSkillType()); + unit->setTarget(target); + } + else { + unit->setCurrSkill(scStop); + } if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { char szBuf[8096]=""; snprintf(szBuf,8096,"[updateAttack]"); unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); } } - return; + 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()); } - - //if found - //if(frameIndex < 0) { - { - if(attackableOnRange(unit, &target, act->getAttackSkillType(),(frameIndex >= 0))) { - if(frameIndex < 0) { - if(unit->getEp() >= act->getAttackSkillType()->getEpCost()) { - unit->setCurrSkill(act->getAttackSkillType()); - unit->setTarget(target); - } - else { - unit->setCurrSkill(scStop); - } - + else { + //compute target pos + Vec2i pos; + if(command->getUnit() != NULL) { + pos= command->getUnit()->getCenteredPos(); + } + else if(attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) { + pos= target->getPos(); + } + else { + pos= command->getPos(); + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"[updateAttack] pos [%s] unit->getPos() [%s]",pos.getString().c_str(),unit->getPos().getString().c_str()); + unit->logSynchData(__FILE__,__LINE__,szBuf); + } + 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 tsValue = tsImpossible; + //if(frameIndex < 0) { + { + //printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); + //fflush(stdout); + switch(this->game->getGameSettings()->getPathFinderType()) { + case pfBasic: + tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex); + break; + default: + throw megaglest_runtime_error("detected unsupported pathfinder type!"); + } + //printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); + //fflush(stdout); + } + 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()); + if(frameIndex < 0) { + if(command->getUnit() != NULL && !command->getUnit()->isAlive() && unit->getCommandSize() > 1) { + // don't run over to dead body if there is still something to do in the queue + unit->finishCommand(); if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { char szBuf[8096]=""; snprintf(szBuf,8096,"[updateAttack]"); unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); } - } - 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()); - } - else { - //compute target pos - Vec2i pos; - if(command->getUnit() != NULL) { - pos= command->getUnit()->getCenteredPos(); - } - else if(attackableOnSight(unit, &target, act->getAttackSkillType(), (frameIndex >= 0))) { - pos= target->getPos(); } else { - pos= command->getPos(); - } - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack] pos [%s] unit->getPos() [%s]",pos.getString().c_str(),unit->getPos().getString().c_str()); - unit->logSynchData(__FILE__,__LINE__,szBuf); - } - - 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 tsValue = tsImpossible; - //if(frameIndex < 0) { - { - //printf("In [%s::%s Line: %d] START pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); - //fflush(stdout); - switch(this->game->getGameSettings()->getPathFinderType()) { - case pfBasic: - tsValue = pathFinder->findPath(unit, pos, NULL, frameIndex); + //if unit arrives destPos order has ended + if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"#1 [updateAttack] tsValue = %d",tsValue); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + } + switch (tsValue) { + case tsMoving: + unit->setCurrSkill(act->getMoveSkillType()); + break; + case tsBlocked: + if(unit->getPath()->isBlocked()) { + unit->finishCommand(); + } break; default: - throw megaglest_runtime_error("detected unsupported pathfinder type!"); - } - //printf("In [%s::%s Line: %d] END pathfind for attacker [%d - %s]\n",__FILE__,__FUNCTION__,__LINE__,unit->getId(), unit->getType()->getName().c_str()); - //fflush(stdout); - } - - 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()); - - if(frameIndex < 0) { - if(command->getUnit() != NULL && !command->getUnit()->isAlive() && unit->getCommandSize() > 1) { - // don't run over to dead body if there is still something to do in the queue - unit->finishCommand(); - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"[updateAttack]"); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); + unit->finishCommand(); + break; } - } - else { - //if unit arrives destPos order has ended - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"#1 [updateAttack] tsValue = %d",tsValue); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - - switch (tsValue) { - case tsMoving: - unit->setCurrSkill(act->getMoveSkillType()); - break; - case tsBlocked: - if(unit->getPath()->isBlocked()) { - unit->finishCommand(); - } - break; - default: - unit->finishCommand(); - break; - } /* - case tsMoving: - unit->setCurrSkill(act->getMoveSkillType()); - - { - std::pair beingAttacked = unitBeingAttacked(unit); - if(beingAttacked.first == true) { - Unit *enemy = beingAttacked.second; - const AttackCommandType *act_forenemy = unit->getType()->getFirstAttackCommand(enemy->getCurrField()); - if(act_forenemy != NULL) { - if(unit->getEp() >= act_forenemy->getAttackSkillType()->getEpCost()) { - unit->setCurrSkill(act_forenemy->getAttackSkillType()); - unit->setTarget(enemy); - } - //aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos()); + case tsMoving: + unit->setCurrSkill(act->getMoveSkillType()); + { + std::pair beingAttacked = unitBeingAttacked(unit); + if(beingAttacked.first == true) { + Unit *enemy = beingAttacked.second; + const AttackCommandType *act_forenemy = unit->getType()->getFirstAttackCommand(enemy->getCurrField()); + if(act_forenemy != NULL) { + if(unit->getEp() >= act_forenemy->getAttackSkillType()->getEpCost()) { + unit->setCurrSkill(act_forenemy->getAttackSkillType()); + unit->setTarget(enemy); } - else { - const AttackStoppedCommandType *asct_forenemy = unit->getType()->getFirstAttackStoppedCommand(enemy->getCurrField()); - if(asct_forenemy != NULL) { - //aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos()); - if(unit->getEp() >= asct_forenemy->getAttackSkillType()->getEpCost()) { - unit->setCurrSkill(asct_forenemy->getAttackSkillType()); - unit->setTarget(enemy); - } + //aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos()); + } + else { + const AttackStoppedCommandType *asct_forenemy = unit->getType()->getFirstAttackStoppedCommand(enemy->getCurrField()); + if(asct_forenemy != NULL) { + //aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos()); + if(unit->getEp() >= asct_forenemy->getAttackSkillType()->getEpCost()) { + unit->setCurrSkill(asct_forenemy->getAttackSkillType()); + unit->setTarget(enemy); } } } } - - break; - - case tsBlocked: - if(unit->getPath()->isBlocked()){ - unit->finishCommand(); - } - break; - default: + } + break; + case tsBlocked: + if(unit->getPath()->isBlocked()){ unit->finishCommand(); - } + } + break; + default: + unit->finishCommand(); + } */ - - if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && - SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { - char szBuf[8096]=""; - snprintf(szBuf,8096,"#2 [updateAttack] tsValue = %d",tsValue); - unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); - } - + if(SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynch).enabled == true && frameIndex < 0 && + SystemFlags::getSystemSettingType(SystemFlags::debugWorldSynchMax).enabled == true) { + char szBuf[8096]=""; + snprintf(szBuf,8096,"#2 [updateAttack] tsValue = %d",tsValue); + unit->logSynchData(extractFileFromDirectoryPath(__FILE__).c_str(),__LINE__,szBuf); } } - - 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()); } - } + 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()); + } + if(SystemFlags::getSystemSettingType(SystemFlags::debugPerformance).enabled && chrono.getMillis() > 0) SystemFlags::OutputDebug(SystemFlags::debugPerformance,"In [%s::%s] Line: %d took msecs: %lld --------------------------- [END OF METHOD] ---------------------------\n",__FILE__,__FUNCTION__,__LINE__,chrono.getMillis()); @@ -1350,7 +1320,7 @@ void UnitUpdater::updateHarvestEmergencyReturn(Unit *unit, int frameIndex) { if(previousHarvestCmd != NULL) { //printf("\n\n#1a return harvested resources\n\n"); NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), previousHarvestCmd->getId(), unit->getLastHarvestedResourcePos(), - -1, Unit::invalidId, -1, false, cst_None, -1, -1); + -1, -1, Unit::invalidId, -1, false, cst_None, -1, -1); if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -2088,7 +2058,7 @@ void UnitUpdater::updateRepair(Unit *unit, int frameIndex) { const CommandType *ctbuild = unit->getType()->getFirstCtOfClass(ccBuild); NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), ctbuild->getId(), command->getPos(), - command->getUnitType()->getId(), -1, CardinalDir(CardinalDir::NORTH), true, command->getStateType(), + command->getUnitType()->getId(), -1, -1, CardinalDir(CardinalDir::NORTH), true, command->getStateType(), command->getStateValue()); if(SystemFlags::getSystemSettingType(SystemFlags::debugUnitCommands).enabled) SystemFlags::OutputDebug(SystemFlags::debugUnitCommands,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); @@ -2918,97 +2888,86 @@ void UnitUpdater::findEnemiesForCell(const Vec2i pos, int size, int sightRange, //if the unit has any enemy on range bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr, - const AttackSkillType *ast,bool evalMode) { + const AttackSkillType *ast,bool evalMode) { bool result=false; try { - vector enemies; - enemies.reserve(100); + vector enemies; + enemies.reserve(100); - //we check command target - const Unit *commandTarget = NULL; - if(unit->anyCommand() && unit->getCurrCommand() != NULL) { - commandTarget = static_cast(unit->getCurrCommand()->getUnit()); - } - if(commandTarget != NULL && commandTarget->isDead()) { - commandTarget = NULL; - } - //aux vars - int size = unit->getType()->getSize(); - Vec2i center = unit->getPos(); - Vec2f floatCenter = unit->getFloatCenteredPos(); + //we check command target + const Unit *commandTarget = NULL; + if(unit->anyCommand() && unit->getCurrCommand() != NULL) { + commandTarget = static_cast(unit->getCurrCommand()->getUnit()); + } + if(commandTarget != NULL && commandTarget->isDead()) { + commandTarget = NULL; + } + //aux vars + int size = unit->getType()->getSize(); + Vec2i center = unit->getPos(); + Vec2f floatCenter = unit->getFloatCenteredPos(); - //bool foundInCache = true; - if(findCachedCellsEnemies(center,range,size,enemies,ast, - unit,commandTarget) == false) { + //bool foundInCache = true; + if(findCachedCellsEnemies(center,range,size,enemies,ast, + unit,commandTarget) == false) { - //foundInCache = false; - //nearby cells - UnitRangeCellsLookupItem cacheItem; - for(int i = center.x - range; i < center.x + range + size; ++i) { - for(int j = center.y - range; j < center.y + range + size; ++j) { - //cells inside map and in range + //foundInCache = false; + //nearby cells + UnitRangeCellsLookupItem cacheItem; + for(int i = center.x - range; i < center.x + range + size; ++i) { + for(int j = center.y - range; j < center.y + range + size; ++j) { + //cells inside map and in range #ifdef USE_STREFLOP - if(map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float)i, (float)j)))) <= (range+1)){ + if(map->isInside(i, j) && streflop::floor(static_cast(floatCenter.dist(Vec2f((float)i, (float)j)))) <= (range+1)) #else - if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)){ + if(map->isInside(i, j) && floor(floatCenter.dist(Vec2f((float)i, (float)j))) <= (range+1)) #endif - Cell *cell = map->getCell(i,j); - findEnemiesForCell(ast,cell,unit,commandTarget,enemies); + { + Cell *cell = map->getCell(i,j); + findEnemiesForCell(ast,cell,unit,commandTarget,enemies); - cacheItem.rangeCellList.push_back(cell); + cacheItem.rangeCellList.push_back(cell); + } } } + + + // Ok update our caches with the latest info + if(cacheItem.rangeCellList.empty() == false) { + MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__)); + + UnitRangeCellsLookupItemCache[center][size][range] = cacheItem; + } } - - // Ok update our caches with the latest info - if(cacheItem.rangeCellList.empty() == false) { - MutexSafeWrapper safeMutex(mutexUnitRangeCellsLookupItemCache,string(__FILE__) + "_" + intToStr(__LINE__)); - - UnitRangeCellsLookupItemCache[center][size][range] = cacheItem; - } - } - - //attack enemies that can attack first - float distToUnit= -1; - Unit* enemySeen= NULL; - std::vector fightingEnemiesInRange; - std::vector damagedFightingEnemiesInRange; - Unit* myFightingEnemyInRange= NULL; - - float distToStandingUnit= -1; - Unit* attackingEnemySeen= NULL; - ControlType controlType= unit->getFaction()->getControlType(); - bool isUltra= controlType == ctCpuUltra || controlType == ctNetworkCpuUltra; - bool isMega= controlType == ctCpuMega || controlType == ctNetworkCpuMega; - - - string randomInfoData = "enemies.size() = " + intToStr(enemies.size()); - - //printf("unit %d has control:%d\n",unit->getId(),controlType); - for(int i = 0; i< (int)enemies.size(); ++i) { - Unit *enemy = enemies[i]; - - - if(enemy != NULL && enemy->isAlive() == true) { - - // Here we default to first enemy if no attackers found - if(enemySeen == NULL) { - *rangedPtr = enemy; - enemySeen = enemy; - result = true; - } - - //randomInfoData += " i = " + intToStr(i) + " alive = true result = " + intToStr(result); - - // Attackers get first priority - if(enemy->getType()->hasSkillClass(scAttack) == true) { - - float currentDist = unit->getCenteredPos().dist(enemy->getCenteredPos()); - - //randomInfoData += " currentDist = " + floatToStr(currentDist); - + //attack enemies that can attack first + float distToUnit= -1; + Unit* enemySeen= NULL; + std::vector fightingEnemiesInRange; + std::vector damagedFightingEnemiesInRange; + Unit* myFightingEnemyInRange= NULL; + float distToStandingUnit= -1; + Unit* attackingEnemySeen= NULL; + ControlType controlType= unit->getFaction()->getControlType(); + bool isUltra= controlType == ctCpuUltra || controlType == ctNetworkCpuUltra; + bool isMega= controlType == ctCpuMega || controlType == ctNetworkCpuMega; + string randomInfoData = "enemies.size() = " + intToStr(enemies.size()); + //printf("unit %d has control:%d\n",unit->getId(),controlType); + for(int i = 0; i< (int)enemies.size(); ++i) { + Unit *enemy = enemies[i]; + if(enemy != NULL && enemy->isAlive() == true) { + // Here we default to first enemy if no attackers found + if(enemySeen == NULL) { + *rangedPtr = enemy; + enemySeen = enemy; + result = true; + } + //randomInfoData += " i = " + intToStr(i) + " alive = true result = " + intToStr(result); + // Attackers get first priority + if(enemy->getType()->hasSkillClass(scAttack) == true) { + float currentDist = unit->getCenteredPos().dist(enemy->getCenteredPos()); + //randomInfoData += " currentDist = " + floatToStr(currentDist); // Select closest attacking unit if (distToUnit < 0 || currentDist < distToUnit) { distToUnit = currentDist; @@ -3041,10 +3000,9 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr, } } } - - } - } - } + } + } + } if (evalMode == false) { bool doUltra = false; if (isMega) { @@ -3062,7 +3020,6 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr, unitList = &damagedFightingEnemiesInRange; else unitList = &fightingEnemiesInRange; - //printf("Choosing new one\n"); int myChoice = unit->getRandom()->randRange(1, unitList->size(), extractFileFromDirectoryPath(__FILE__) + intToStr(__LINE__)); //printf("myChoice=%d\n", myChoice); @@ -3085,95 +3042,90 @@ bool UnitUpdater::unitOnRange(Unit *unit, int range, Unit **rangedPtr, } - if(result == true) { + if(result == true) { - //const Unit* teamUnit = NULL; - const Unit* enemyUnit = NULL; - bool onlyEnemyUnits = true; + //const Unit* teamUnit = NULL; + const Unit* enemyUnit = NULL; + bool onlyEnemyUnits = true; - if(unit->getTeam() == world->getThisTeamIndex()) { - //teamUnit = unit; - enemyUnit = enemySeen; - onlyEnemyUnits = false; - } - else if(enemySeen->getTeam() == world->getThisTeamIndex()) { - //teamUnit = enemySeen; - enemyUnit = unit; - onlyEnemyUnits = false; - } + if(unit->getTeam() == world->getThisTeamIndex()) { + //teamUnit = unit; + enemyUnit = enemySeen; + onlyEnemyUnits = false; + } + else if(enemySeen->getTeam() == world->getThisTeamIndex()) { + //teamUnit = enemySeen; + enemyUnit = unit; + onlyEnemyUnits = false; + } - if(evalMode == false && onlyEnemyUnits == false && - enemyUnit->getTeam() != world->getThisTeamIndex()) { - - Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos(); - // find nearest Attack and cleanup old dates - AttackWarningData *nearest = NULL; - float currentDistance = 0.f; - float nearestDistance = 0.f; + if(evalMode == false && onlyEnemyUnits == false && + enemyUnit->getTeam() != world->getThisTeamIndex()) { + + Vec2f enemyFloatCenter = enemyUnit->getFloatCenteredPos(); + // find nearest Attack and cleanup old dates + AttackWarningData *nearest = NULL; + float currentDistance = 0.f; + float nearestDistance = 0.f; - MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__)); - for(int i = (int)attackWarnings.size() - 1; i >= 0; --i) { - if(world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again - AttackWarningData *toDelete =attackWarnings[i]; - attackWarnings.erase(attackWarnings.begin()+i); - delete toDelete; // old one - } - else { -#ifdef USE_STREFLOP - currentDistance = streflop::floor(static_cast(enemyFloatCenter.dist(attackWarnings[i]->attackPosition))); // no need for streflops here! -#else - currentDistance = floor(enemyFloatCenter.dist(attackWarnings[i]->attackPosition)); // no need for streflops here! -#endif - - if(nearest == NULL) { - nearest = attackWarnings[i]; - nearestDistance = currentDistance; + MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__)); + for(int i = (int)attackWarnings.size() - 1; i >= 0; --i) { + if(world->getFrameCount() - attackWarnings[i]->lastFrameCount > 200) { //after 200 frames attack break we warn again + AttackWarningData *toDelete =attackWarnings[i]; + attackWarnings.erase(attackWarnings.begin()+i); + delete toDelete; // old one } else { - if(currentDistance < nearestDistance) { +#ifdef USE_STREFLOP + currentDistance = streflop::floor(static_cast(enemyFloatCenter.dist(attackWarnings[i]->attackPosition))); // no need for streflops here! +#else + currentDistance = floor(enemyFloatCenter.dist(attackWarnings[i]->attackPosition)); // no need for streflops here! +#endif + + if(nearest == NULL) { nearest = attackWarnings[i]; nearestDistance = currentDistance; } + else { + if(currentDistance < nearestDistance) { + nearest = attackWarnings[i]; + nearestDistance = currentDistance; + } + } } } - } + if(nearest != NULL) { + // does it fit? + if(nearestDistance < attackWarnRange) { + // update entry with current values + nearest->lastFrameCount=world->getFrameCount(); + nearest->attackPosition.x=enemyFloatCenter.x; + nearest->attackPosition.y=enemyFloatCenter.y; + } + else { + //Must be a different Attack! + nearest=NULL; //set to null to force a new entry in next step + } + } + // add new attack + if(nearest == NULL) { + // no else! + AttackWarningData* awd= new AttackWarningData(); + awd->lastFrameCount=world->getFrameCount(); + awd->attackPosition.x=enemyFloatCenter.x; + awd->attackPosition.y=enemyFloatCenter.y; + MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__)); + attackWarnings.push_back(awd); - if(nearest != NULL) { - - // does it fit? - if(nearestDistance < attackWarnRange) { - // update entry with current values - nearest->lastFrameCount=world->getFrameCount(); - nearest->attackPosition.x=enemyFloatCenter.x; - nearest->attackPosition.y=enemyFloatCenter.y; - } - else { - //Must be a different Attack! - nearest=NULL; //set to null to force a new entry in next step - } - } - // add new attack - if(nearest == NULL) { - // no else! - AttackWarningData* awd= new AttackWarningData(); - awd->lastFrameCount=world->getFrameCount(); - awd->attackPosition.x=enemyFloatCenter.x; - awd->attackPosition.y=enemyFloatCenter.y; - - MutexSafeWrapper safeMutex(mutexAttackWarnings,string(__FILE__) + "_" + intToStr(__LINE__)); - attackWarnings.push_back(awd); - - if(world->getAttackWarningsEnabled() == true) { - - SoundRenderer::getInstance().playFx(CoreData::getInstance().getAttentionSound(),true); - world->addAttackEffects(enemyUnit); - } - } + if(world->getAttackWarningsEnabled() == true) { + SoundRenderer::getInstance().playFx(CoreData::getInstance().getAttentionSound(),true); + world->addAttackEffects(enemyUnit); + } + } + } } } - - } catch(const exception &ex) { //setRunningStatus(false);