From 2c80543889454afa06680376414efec6e3f860bc Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Tue, 5 Jul 2011 04:37:35 +0000 Subject: [PATCH] - attempt to group command execution so units given the same command at the same time will work more smartly (closer units go first and so on) --- source/glest_game/ai/ai.cpp | 34 ++++++-- source/glest_game/ai/ai_interface.cpp | 15 ++-- source/glest_game/ai/ai_interface.h | 4 +- source/glest_game/ai/ai_rule.cpp | 10 ++- source/glest_game/game/commander.cpp | 74 ++++++++++++---- source/glest_game/game/commander.h | 4 +- source/glest_game/gui/gui.cpp | 6 +- source/glest_game/network/network_types.cpp | 10 ++- source/glest_game/network/network_types.h | 6 +- source/glest_game/type_instances/command.cpp | 6 ++ source/glest_game/type_instances/command.h | 5 ++ source/glest_game/type_instances/faction.cpp | 89 +++++++++++++++++--- source/glest_game/type_instances/faction.h | 13 ++- source/glest_game/world/world.cpp | 46 ++++++++-- source/glest_game/world/world.h | 3 + 15 files changed, 264 insertions(+), 61 deletions(-) diff --git a/source/glest_game/ai/ai.cpp b/source/glest_game/ai/ai.cpp index b57ad85d..f91aa5f6 100644 --- a/source/glest_game/ai/ai.cpp +++ b/source/glest_game/ai/ai.cpp @@ -494,6 +494,7 @@ void Ai::massiveAttack(const Vec2i &pos, Field field, bool ultraAttack){ int producerWarriorCount=0; int maxProducerWarriors=random.randRange(1,11); int unitCount = aiInterface->getMyUnitCount(); + int unitGroupCommandId = -1; int attackerWorkersHarvestingCount = 0; for(int i = 0; i < unitCount; ++i) { @@ -553,8 +554,12 @@ void Ai::massiveAttack(const Vec2i &pos, Field field, bool ultraAttack){ attackerWorkersHarvestingCount++; } } - if(shouldAttack){ - aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos()); + if(shouldAttack) { + if(unitGroupCommandId == -1) { + unitGroupCommandId = aiInterface->getWorld()->getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, act_forenemy, beingAttacked.second->getPos(), unitGroupCommandId); unitSignalledToAttack= true; } } @@ -573,7 +578,12 @@ void Ai::massiveAttack(const Vec2i &pos, Field field, bool ultraAttack){ if(shouldAttack){ // printf("~~~~~~~~ Unit [%s - %d] WILL AttackStoppedCommand [%s - %d]\n", unit->getFullName().c_str(), // unit->getId(), enemy->getFullName().c_str(), enemy->getId()); - aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos()); + + if(unitGroupCommandId == -1) { + unitGroupCommandId = aiInterface->getWorld()->getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, asct_forenemy, beingAttacked.second->getCenteredPos(), unitGroupCommandId); unitSignalledToAttack= true; } } @@ -599,8 +609,12 @@ void Ai::massiveAttack(const Vec2i &pos, Field field, bool ultraAttack){ } } } - if(shouldAttack){ - aiInterface->giveCommand(i, act, pos); + if(shouldAttack) { + if(unitGroupCommandId == -1) { + unitGroupCommandId = aiInterface->getWorld()->getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, act, pos, unitGroupCommandId); } } } @@ -647,7 +661,7 @@ void Ai::harvest(int unitIndex) { Vec2i resPos; if(hct != NULL && aiInterface->getNearestSightedResource(rt, aiInterface->getHomeLocation(), resPos, false)) { resPos= resPos+Vec2i(random.randRange(-2, 2), random.randRange(-2, 2)); - aiInterface->giveCommand(unitIndex, hct, resPos); + aiInterface->giveCommand(unitIndex, hct, resPos, -1); //aiInterface->printLog(4, "Order harvest pos:" + intToStr(resPos.x)+", "+intToStr(resPos.y)+": "+rrToStr(r)+"\n"); } } @@ -793,6 +807,8 @@ void Ai::unblockUnits() { if(signalAdjacentUnits.size() > 0) { //printf("#2 AI units ARE BLOCKED about to unblock\n"); + int unitGroupCommandId = -1; + for(std::map >::reverse_iterator iterMap = signalAdjacentUnits.rbegin(); iterMap != signalAdjacentUnits.rend(); iterMap++) { @@ -812,7 +828,11 @@ void Ai::unblockUnits() { if(canUnitMoveToCell == true) { if(ct != NULL) { - CommandResult r = aiInterface->giveCommand(adjacentUnit,ct, pos); + if(unitGroupCommandId == -1) { + unitGroupCommandId = aiInterface->getWorld()->getNextCommandGroupId(); + } + + CommandResult r = aiInterface->giveCommand(adjacentUnit,ct, pos, unitGroupCommandId); } } } diff --git a/source/glest_game/ai/ai_interface.cpp b/source/glest_game/ai/ai_interface.cpp index 106e9f02..8d5e2024 100644 --- a/source/glest_game/ai/ai_interface.cpp +++ b/source/glest_game/ai/ai_interface.cpp @@ -137,7 +137,7 @@ CommandResult AiInterface::giveCommand(int unitIndex, CommandClass commandClass, } } -CommandResult AiInterface::giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos) { +CommandResult AiInterface::giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId) { assert(this->gameSettings != NULL); if(unit == NULL) { @@ -172,7 +172,8 @@ CommandResult AiInterface::giveCommand(const Unit *unit, const CommandType *comm } if(executeCommandOverNetwork() == true) { - CommandResult result = commander->tryGiveCommand(unit, commandType, pos, unit->getType(),CardinalDir::NORTH); + CommandResult result = commander->tryGiveCommand(unit, commandType, pos, + unit->getType(),CardinalDir::NORTH, false, NULL,unitGroupCommandId); return result; } else { @@ -180,14 +181,16 @@ CommandResult AiInterface::giveCommand(const Unit *unit, const CommandType *comm Faction *faction = world->getFaction(unit->getFactionIndex()); Unit *unitToCommand = faction->findUnit(unit->getId()); - CommandResult result = unitToCommand->giveCommand(new Command(commandType, pos)); + Command *cmd = new Command(commandType, pos); + cmd->setUnitCommandGroupId(unitGroupCommandId); + CommandResult result = unitToCommand->giveCommand(cmd); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); return result; } } -CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos){ +CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId) { assert(this->gameSettings != NULL); const Unit *unit = getMyUnit(unitIndex); @@ -225,7 +228,9 @@ CommandResult AiInterface::giveCommand(int unitIndex, const CommandType *command else { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); - CommandResult result = world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(new Command(commandType, pos)); + Command *cmd = new Command(commandType, pos); + cmd->setUnitCommandGroupId(unitGroupCommandId); + CommandResult result = world->getFaction(factionIndex)->getUnit(unitIndex)->giveCommand(cmd); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); return result; diff --git a/source/glest_game/ai/ai_interface.h b/source/glest_game/ai/ai_interface.h index bb1e000b..b3607616 100644 --- a/source/glest_game/ai/ai_interface.h +++ b/source/glest_game/ai/ai_interface.h @@ -66,9 +66,9 @@ public: //interact CommandResult giveCommand(int unitIndex, CommandClass commandClass, const Vec2i &pos=Vec2i(0)); CommandResult giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType); - CommandResult giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos); + CommandResult giveCommand(int unitIndex, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId); CommandResult giveCommand(int unitIndex, const CommandType *commandType, Unit *u= NULL); - CommandResult giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos); + CommandResult giveCommand(const Unit *unit, const CommandType *commandType, const Vec2i &pos, int unitGroupCommandId); //get data const ControlType getControlType(); diff --git a/source/glest_game/ai/ai_rule.cpp b/source/glest_game/ai/ai_rule.cpp index 998f7126..ccf0a76d 100644 --- a/source/glest_game/ai/ai_rule.cpp +++ b/source/glest_game/ai/ai_rule.cpp @@ -273,6 +273,9 @@ void AiRuleRepair::execute() { if(unitCountAlreadyRepairingDamagedUnit >= minUnitsRepairingCastle){ return; } + + int unitGroupCommandId = -1; + //find a repairer and issue command for(int i = 0; i < aiInterface->getMyUnitCount(); ++i) { const Unit *u= aiInterface->getMyUnit(i); @@ -304,7 +307,12 @@ void AiRuleRepair::execute() { //aiInterface->giveCommand(i, rct, damagedUnit->getPos()); if(unitCountAlreadyRepairingDamagedUnit < minUnitsRepairingCastle) { - aiInterface->giveCommand(i, rct, damagedUnit->getPosWithCellMapSet()); + + if(unitGroupCommandId == -1) { + unitGroupCommandId = aiInterface->getWorld()->getNextCommandGroupId(); + } + + aiInterface->giveCommand(i, rct, damagedUnit->getPosWithCellMapSet(),unitGroupCommandId); aiInterface->printLog(3, "Repairing order issued"); unitCountAlreadyRepairingDamagedUnit++; // printf( diff --git a/source/glest_game/game/commander.cpp b/source/glest_game/game/commander.cpp index 0f9855bd..4da12db0 100644 --- a/source/glest_game/game/commander.cpp +++ b/source/glest_game/game/commander.cpp @@ -190,6 +190,11 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Comman CommandStateType commandStateType = cst_None; int commandStateValue = -1; + int unitCommandGroupId = -1; + if(selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + //bool unitSignalledToBuild = false; //give orders to all selected units for(int i = 0; i < selection->getCount(); ++i) { @@ -228,7 +233,8 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Comman NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, useCommandtype->getId(), usePos, unitType->getId(), (targetUnit != NULL ? targetUnit->getId() : -1), - facing, tryQueue, commandStateType,commandStateValue); + facing, tryQueue, commandStateType,commandStateValue, + unitCommandGroupId); //every unit is ordered to a the position result= pushNetworkCommand(&networkCommand); @@ -247,7 +253,8 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Comman CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, - CardinalDir facing, bool tryQueue,Unit *targetUnit) const { + CardinalDir facing, bool tryQueue,Unit *targetUnit, + int unitGroupCommandId) const { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); Chrono chrono; @@ -266,7 +273,7 @@ CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *com NetworkCommand networkCommand(this->world,nctGiveCommand, unit->getId(), commandType->getId(), pos, unitType->getId(), (targetUnit != NULL ? targetUnit->getId() : -1), - facing, tryQueue); + facing, tryQueue,cst_None,-1,unitGroupCommandId); 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()); @@ -278,7 +285,8 @@ CommandResult Commander::tryGiveCommand(const Unit* unit, const CommandType *com return result; } -CommandResult Commander::tryGiveCommand(const Selection *selection, CommandClass commandClass, const Vec2i &pos, const Unit *targetUnit, bool tryQueue) const{ +CommandResult Commander::tryGiveCommand(const Selection *selection, CommandClass commandClass, + const Vec2i &pos, const Unit *targetUnit, bool tryQueue) const{ if(selection->isEmpty() == false) { Vec2i refPos, currPos; @@ -286,6 +294,11 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, CommandClass refPos= world->getMap()->computeRefPos(selection); + int unitCommandGroupId = -1; + if(selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + //give orders to all selected units for(int i = 0; i < selection->getCount(); ++i) { const Unit *unit= selection->getUnit(i); @@ -297,8 +310,11 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, CommandClass int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId(); int unitId= selection->getUnit(i)->getId(); - Vec2i currPos= world->getMap()->computeDestPos(refPos, selection->getUnit(i)->getPos(), pos); - NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, ct->getId(), currPos, -1, targetId, -1, tryQueue); + Vec2i currPos= world->getMap()->computeDestPos(refPos, + selection->getUnit(i)->getPos(), pos); + NetworkCommand networkCommand(this->world,nctGiveCommand, + unitId, ct->getId(), currPos, -1, targetId, -1, + tryQueue,cst_None,-1,unitCommandGroupId); //every unit is ordered to a different pos result= pushNetworkCommand(&networkCommand); @@ -318,15 +334,20 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, CommandClass CommandResult Commander::tryGiveCommand(const Selection *selection, const CommandType *commandType, const Vec2i &pos, - const Unit *targetUnit, bool tryQueue) const{ + const Unit *targetUnit, bool tryQueue) const { if(!selection->isEmpty() && commandType!=NULL){ Vec2i refPos; CommandResultContainer results; refPos= world->getMap()->computeRefPos(selection); + int unitCommandGroupId = -1; + if(selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + //give orders to all selected units - for(int i=0; igetCount(); ++i){ + for(int i = 0; i < selection->getCount(); ++i) { const Unit *unit = selection->getUnit(i); assert(unit != NULL); @@ -336,7 +357,9 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, int targetId= targetUnit==NULL? Unit::invalidId: targetUnit->getId(); int unitId= unit->getId(); Vec2i currPos= world->getMap()->computeDestPos(refPos, unit->getPos(), pos); - NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, commandType->getId(), currPos, -1, targetId, -1, tryQueue); + NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, + commandType->getId(), currPos, -1, targetId, -1, tryQueue, + cst_None, -1, unitCommandGroupId); //every unit is ordered to a different position result= pushNetworkCommand(&networkCommand); @@ -352,7 +375,8 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, } //auto command -CommandResult Commander::tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit, bool tryQueue) const { +CommandResult Commander::tryGiveCommand(const Selection *selection, const Vec2i &pos, + const Unit *targetUnit, bool tryQueue, int unitCommandGroupId) const { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); CommandResult result = crFailUndefined; @@ -361,9 +385,13 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Vec2i Vec2i refPos, currPos; CommandResultContainer results; + if(unitCommandGroupId == -1 && selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + //give orders to all selected units refPos= world->getMap()->computeRefPos(selection); - for(int i=0; igetCount(); ++i) { + for(int i=0; i < selection->getCount(); ++i) { //every unit is ordered to a different pos const Unit *unit = selection->getUnit(i); assert(unit != NULL); @@ -381,13 +409,17 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Vec2i CommandResult result = crFailUndefined; bool canSubmitCommand=canSubmitCommandType(unit, commandType); if(canSubmitCommand == true) { - NetworkCommand networkCommand(this->world,nctGiveCommand, unitId, commandType->getId(), currPos, -1, targetId, -1, tryQueue); + NetworkCommand networkCommand(this->world,nctGiveCommand, + unitId, commandType->getId(), currPos, -1, targetId, + -1, tryQueue, cst_None, -1, unitCommandGroupId); result= pushNetworkCommand(&networkCommand); } results.push_back(result); } else if(unit->isMeetingPointSettable() == true) { - NetworkCommand command(this->world,nctSetMeetingPoint, unit->getId(), -1, currPos); + NetworkCommand command(this->world,nctSetMeetingPoint, + unit->getId(), -1, currPos,-1,-1,-1,false, + cst_None,-1,unitCommandGroupId); CommandResult result= pushNetworkCommand(&command); results.push_back(result); @@ -404,17 +436,24 @@ CommandResult Commander::tryGiveCommand(const Selection *selection, const Vec2i return result; } -CommandResult Commander::tryCancelCommand(const Selection *selection) const{ +CommandResult Commander::tryCancelCommand(const Selection *selection) const { - for(int i=0; igetCount(); ++i){ - NetworkCommand command(this->world,nctCancelCommand, selection->getUnit(i)->getId()); + int unitCommandGroupId = -1; + if(selection->getCount() > 1) { + unitCommandGroupId = world->getNextCommandGroupId(); + } + + for(int i = 0; i < selection->getCount(); ++i) { + NetworkCommand command(this->world,nctCancelCommand, + selection->getUnit(i)->getId(),-1,Vec2i(0),-1,-1,-1,false, + cst_None,-1,unitCommandGroupId); pushNetworkCommand(&command); } return crSuccess; } -void Commander::trySetMeetingPoint(const Unit* unit, const Vec2i &pos)const{ +void Commander::trySetMeetingPoint(const Unit* unit, const Vec2i &pos) const { NetworkCommand command(this->world,nctSetMeetingPoint, unit->getId(), -1, pos); pushNetworkCommand(&command); } @@ -776,6 +815,7 @@ Command* Commander::buildCommand(const NetworkCommand* networkCommand) const { command->setStateType(commandStateType); command->setStateValue(commandStateValue); + command->setUnitCommandGroupId(networkCommand->getUnitCommandGroupId()); if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); diff --git a/source/glest_game/game/commander.h b/source/glest_game/game/commander.h index c0ee453d..8691a55c 100644 --- a/source/glest_game/game/commander.h +++ b/source/glest_game/game/commander.h @@ -92,10 +92,10 @@ public: const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue,Unit *targetUnit=NULL) const; - CommandResult tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue = false,Unit *targetUnit=NULL) const; + CommandResult tryGiveCommand(const Unit* unit, const CommandType *commandType, const Vec2i &pos, const UnitType* unitType, CardinalDir facing, bool tryQueue = false,Unit *targetUnit=NULL,int unitGroupCommandId=-1) const; CommandResult tryGiveCommand(const Selection *selection, CommandClass commandClass, const Vec2i &pos= Vec2i(0), const Unit *targetUnit= NULL, bool tryQueue = false) const; CommandResult tryGiveCommand(const Selection *selection, const CommandType *commandType, const Vec2i &pos= Vec2i(0), const Unit *targetUnit= NULL, bool tryQueue = false) const; - CommandResult tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit= NULL, bool tryQueue = false) const; + CommandResult tryGiveCommand(const Selection *selection, const Vec2i &pos, const Unit *targetUnit= NULL, bool tryQueue = false, int unitCommandGroupId = -1) const; CommandResult tryCancelCommand(const Selection *selection) const; void trySetMeetingPoint(const Unit* unit, const Vec2i &pos) const; CommandResult pushNetworkCommand(const NetworkCommand* networkCommand) const; diff --git a/source/glest_game/gui/gui.cpp b/source/glest_game/gui/gui.cpp index f8fed9f9..b3f61299 100644 --- a/source/glest_game/gui/gui.cpp +++ b/source/glest_game/gui/gui.cpp @@ -388,6 +388,8 @@ void Gui::onSelectionChanged(){ // ================= PRIVATE ================= void Gui::giveOneClickOrders(){ + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); + CommandResult result; bool queueKeyDown = isKeyDown(queueCommandKey); if(selection.isUniform()){ @@ -414,10 +416,12 @@ void Gui::giveDefaultOrders(int x, int y) { } void Gui::givePreparedDefaultOrders(int x, int y){ + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); giveDefaultOrders(x, y, NULL,false); } void Gui::giveDefaultOrders(int x, int y,const Unit *targetUnit, bool paintMouse3d) { + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); bool queueKeyDown = isKeyDown(queueCommandKey); Vec2i targetPos=Vec2i(x, y); //give order @@ -442,7 +446,7 @@ void Gui::giveDefaultOrders(int x, int y,const Unit *targetUnit, bool paintMouse } void Gui::giveTwoClickOrders(int x, int y , bool prepared) { - + //printf("In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); CommandResult result; //compute target diff --git a/source/glest_game/network/network_types.cpp b/source/glest_game/network/network_types.cpp index e0b1e779..a593155c 100644 --- a/source/glest_game/network/network_types.cpp +++ b/source/glest_game/network/network_types.cpp @@ -31,7 +31,7 @@ NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId, int commandTypeId, const Vec2i &pos, int unitTypeId, int targetId, int facing, bool wantQueue, CommandStateType commandStateType, - int commandStateValue) + int commandStateValue, int unitCommandGroupId) : networkCommandType(networkCommandType) , unitId(unitId) , commandTypeId(commandTypeId) @@ -40,7 +40,8 @@ NetworkCommand::NetworkCommand(World *world, int networkCommandType, int unitId, , unitTypeId(unitTypeId) , wantQueue(wantQueue) , commandStateType(commandStateType) - , commandStateValue(commandStateValue) { + , commandStateValue(commandStateValue) + , unitCommandGroupId(unitCommandGroupId) { assert(targetId == -1 || facing == -1); this->targetId = targetId >= 0 ? targetId : facing; @@ -88,9 +89,10 @@ void NetworkCommand::preprocessNetworkCommand(World *world) { string NetworkCommand::toString() const { char szBuf[1024]=""; - sprintf(szBuf,"networkCommandType = %d\nunitId = %d\ncommandTypeId = %d\npositionX = %d\npositionY = %d\nunitTypeId = %d\ntargetId = %d\nwantQueue= %d\nfromFactionIndex = %d\nunitFactionUnitCount = %d\nunitFactionIndex = %d, commandStateType = %d, commandStateValue = %d", + sprintf(szBuf,"networkCommandType = %d\nunitId = %d\ncommandTypeId = %d\npositionX = %d\npositionY = %d\nunitTypeId = %d\ntargetId = %d\nwantQueue= %d\nfromFactionIndex = %d\nunitFactionUnitCount = %d\nunitFactionIndex = %d, commandStateType = %d, commandStateValue = %d, unitCommandGroupId = %d", networkCommandType,unitId,commandTypeId,positionX,positionY,unitTypeId,targetId,wantQueue, - fromFactionIndex,unitFactionUnitCount,unitFactionIndex,commandStateType,commandStateValue); + fromFactionIndex,unitFactionUnitCount,unitFactionIndex,commandStateType,commandStateValue, + unitCommandGroupId); string result = szBuf; return result; diff --git a/source/glest_game/network/network_types.h b/source/glest_game/network/network_types.h index 3cc28560..64e81b91 100644 --- a/source/glest_game/network/network_types.h +++ b/source/glest_game/network/network_types.h @@ -87,6 +87,7 @@ private: int8 unitFactionIndex; int8 commandStateType; int32 commandStateValue; + int32 unitCommandGroupId; public: NetworkCommand(){}; @@ -101,7 +102,8 @@ public: int facing= -1, bool wantQueue = false, CommandStateType commandStateType = cst_None, - int commandTypeStateValue = -1); + int commandTypeStateValue = -1, + int unitCommandGroupId = -1); NetworkCommandType getNetworkCommandType() const {return static_cast(networkCommandType);} int getUnitId() const {return unitId;} @@ -117,6 +119,8 @@ public: CommandStateType getCommandStateType() const {return static_cast(commandStateType);} int getCommandStateValue() const {return commandStateValue;} + int getUnitCommandGroupId() const { return unitCommandGroupId; } + void preprocessNetworkCommand(World *world); string toString() const; }; diff --git a/source/glest_game/type_instances/command.cpp b/source/glest_game/type_instances/command.cpp index 7f38e12e..15c1f7d6 100644 --- a/source/glest_game/type_instances/command.cpp +++ b/source/glest_game/type_instances/command.cpp @@ -35,6 +35,7 @@ Command::Command(const CommandType *ct, const Vec2i &pos){ unitType= NULL; stateType = cst_None; stateValue = -1; + unitCommandGroupId = -1; } Command::Command(const CommandType *ct, Unit* unit) { @@ -49,6 +50,7 @@ Command::Command(const CommandType *ct, Unit* unit) { } stateType = cst_None; stateValue = -1; + unitCommandGroupId = -1; } Command::Command(const CommandType *ct, const Vec2i &pos, const UnitType *unitType, CardinalDir facing) { @@ -60,6 +62,7 @@ Command::Command(const CommandType *ct, const Vec2i &pos, const UnitType *unitTy this->facing = facing; stateType = cst_None; stateValue = -1; + unitCommandGroupId = -1; //if(this->unitType != NULL) { // SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] unitType = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->unitType->toString().c_str()); @@ -131,6 +134,9 @@ std::string Command::toString() const { result += ", stateType = " + intToStr(stateType) + ", stateValue = " + intToStr(stateValue); + + result += ", unitCommandGroupId = " + intToStr(unitCommandGroupId); + return result; } diff --git a/source/glest_game/type_instances/command.h b/source/glest_game/type_instances/command.h index 3fd18597..d58e9eb4 100644 --- a/source/glest_game/type_instances/command.h +++ b/source/glest_game/type_instances/command.h @@ -48,6 +48,8 @@ private: CommandStateType stateType; int stateValue; + int unitCommandGroupId; + public: //constructor Command(const CommandType *ct, const Vec2i &pos=Vec2i(0)); @@ -80,6 +82,9 @@ public: int getStateValue() const { return stateValue; } + void setUnitCommandGroupId(int value) { unitCommandGroupId = value; } + int getUnitCommandGroupId() const { return unitCommandGroupId; } + std::string toString() const; }; diff --git a/source/glest_game/type_instances/faction.cpp b/source/glest_game/type_instances/faction.cpp index 3a1e6cec..04f756b2 100644 --- a/source/glest_game/type_instances/faction.cpp +++ b/source/glest_game/type_instances/faction.cpp @@ -30,6 +30,45 @@ using Shared::Util::RandomGen; namespace Glest { namespace Game { +CommandGroupSorter::CommandGroupSorter(Unit *unit) { + this->unit = unit; +} + +bool CommandGroupSorter::operator< (const CommandGroupSorter &j) const { + + Command *command= this->unit->getCurrCommand(); + if( command != NULL && + (command->getCommandType()->getClass() == ccMove || + command->getCommandType()->getClass() == ccAttack) && + command->getUnitCommandGroupId() > 0) { + int curCommandGroupId = command->getUnitCommandGroupId(); + + Command *commandPeer = j.unit->getCurrCommand(); + if(commandPeer == NULL) { + return true; + } + else if(commandPeer->getCommandType()->getClass() != + command->getCommandType()->getClass()) { + return true; + } + else if(commandPeer->getUnitCommandGroupId() < 0) { + return true; + } + else if(curCommandGroupId > commandPeer->getUnitCommandGroupId()) { + return false; + } + else { + float unitDist = this->unit->getCenteredPos().dist(command->getPos()); + float unitDistPeer = j.unit->getCenteredPos().dist(commandPeer->getPos()); + + + return unitDist < unitDistPeer; + } + } + + return false; +} + // ===================================================== // class FactionThread // ===================================================== @@ -43,18 +82,20 @@ void FactionThread::setQuitStatus(bool value) { BaseThread::setQuitStatus(value); if(value == true) { - signalPathfinder(-1); + signalPathfinder(-1,NULL); } if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } -void FactionThread::signalPathfinder(int frameIndex) { +void FactionThread::signalPathfinder(int frameIndex, std::vector *unitsInFactionsSorted) { if(frameIndex >= 0) { static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__); MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); this->frameIndex.first = frameIndex; this->frameIndex.second = false; + + this->unitsInFactionsSorted = unitsInFactionsSorted; safeMutex.ReleaseLock(); } semTaskSignalled.signal(); @@ -66,6 +107,7 @@ void FactionThread::setTaskCompleted(int frameIndex) { MutexSafeWrapper safeMutex(&triggerIdMutex,mutexOwnerId); if(this->frameIndex.first == frameIndex) { this->frameIndex.second = true; + this->unitsInFactionsSorted = NULL; } safeMutex.ReleaseLock(); } @@ -129,17 +171,36 @@ void FactionThread::execute() { ExecutingTaskSafeWrapper safeExecutingTaskMutex(this); World *world = faction->getWorld(); - int unitCount = faction->getUnitCount(); - for(int j = 0; j < unitCount; ++j) { - Unit *unit = faction->getUnit(j); - if(unit == NULL) { - throw runtime_error("unit == NULL"); - } - bool update = unit->needToUpdate(); - //update = true; - if(update == true) { - world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first); + if(this->unitsInFactionsSorted != NULL) { + //std::vector *unitsInFactionsSorted + int unitCount = unitsInFactionsSorted->size(); + for(int j = 0; j < unitCount; ++j) { + Unit *unit = (*unitsInFactionsSorted)[j].unit; + if(unit == NULL) { + throw runtime_error("unit == NULL"); + } + + bool update = unit->needToUpdate(); + //update = true; + if(update == true) { + world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first); + } + } + } + else { + int unitCount = faction->getUnitCount(); + for(int j = 0; j < unitCount; ++j) { + Unit *unit = faction->getUnit(j); + if(unit == NULL) { + throw runtime_error("unit == NULL"); + } + + bool update = unit->needToUpdate(); + //update = true; + if(update == true) { + world->getUnitUpdater()->updateUnitCommand(unit,frameIndex.first); + } } } @@ -203,9 +264,9 @@ Faction::~Faction() { if(SystemFlags::getSystemSettingType(SystemFlags::debugSystem).enabled) SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } -void Faction::signalWorkerThread(int frameIndex) { +void Faction::signalWorkerThread(int frameIndex, std::vector *unitsInFactionsSorted) { if(workerThread != NULL) { - workerThread->signalPathfinder(frameIndex); + workerThread->signalPathfinder(frameIndex,unitsInFactionsSorted); } } diff --git a/source/glest_game/type_instances/faction.h b/source/glest_game/type_instances/faction.h index 0d6122a0..4d530aaa 100644 --- a/source/glest_game/type_instances/faction.h +++ b/source/glest_game/type_instances/faction.h @@ -49,6 +49,14 @@ class Faction; /// Each of the game players // ===================================================== +class CommandGroupSorter { +public: + Unit *unit; + + CommandGroupSorter(Unit *unit); + bool operator< (const CommandGroupSorter &j) const; +}; + class FactionThread : public BaseThread { protected: @@ -56,6 +64,7 @@ protected: Semaphore semTaskSignalled; Mutex triggerIdMutex; std::pair frameIndex; + std::vector *unitsInFactionsSorted; virtual void setQuitStatus(bool value); virtual void setTaskCompleted(int frameIndex); @@ -64,7 +73,7 @@ protected: public: FactionThread(Faction *faction); virtual void execute(); - void signalPathfinder(int frameIndex); + void signalPathfinder(int frameIndex,std::vector *unitsInFactionsSorted); bool isSignalPathfinderCompleted(int frameIndex); }; @@ -193,7 +202,7 @@ public: World * getWorld() { return world; } int getFrameCount(); - void signalWorkerThread(int frameIndex); + void signalWorkerThread(int frameIndex,std::vector *unitsInFactionsSorted); bool isWorkerThreadSignalCompleted(int frameIndex); void limitResourcesToStore(); diff --git a/source/glest_game/world/world.cpp b/source/glest_game/world/world.cpp index 718fe4cc..e0b09591 100644 --- a/source/glest_game/world/world.cpp +++ b/source/glest_game/world/world.cpp @@ -57,6 +57,7 @@ World::World(){ ExploredCellsLookupItemCacheTimerCount = 0; FowAlphaCellsLookupItemCache.clear(); + nextCommandGroupId = 0; techTree = NULL; fogOfWarOverride = false; @@ -272,14 +273,35 @@ Checksum World::loadScenario(const string &path, Checksum *checksum) { void World::updateAllFactionUnits() { scriptManager->onTimerTriggerEvent(); - // Signal the faction threads to do any pre-processing + // Prioritize grouped command units so closest units to target go first + // units int factionCount = getFactionCount(); + std::map > unitsInFactionsSorted; for(int i = 0; i < factionCount; ++i) { Faction *faction = getFaction(i); if(faction == NULL) { throw runtime_error("faction == NULL"); } - faction->signalWorkerThread(frameCount); + + int unitCount = faction->getUnitCount(); + for(int j = 0; j < unitCount; ++j) { + Unit *unit = faction->getUnit(j); + if(unit == NULL) { + throw runtime_error("unit == NULL"); + } + + unitsInFactionsSorted[faction->getIndex()].push_back(CommandGroupSorter(unit)); + } + std::sort(unitsInFactionsSorted[faction->getIndex()].begin(),unitsInFactionsSorted[faction->getIndex()].end()); + } + + // Signal the faction threads to do any pre-processing + for(int i = 0; i < factionCount; ++i) { + Faction *faction = getFaction(i); + if(faction == NULL) { + throw runtime_error("faction == NULL"); + } + faction->signalWorkerThread(frameCount,&unitsInFactionsSorted[faction->getIndex()]); } bool workThreadsFinished = false; @@ -316,16 +338,25 @@ void World::updateAllFactionUnits() { throw runtime_error("faction == NULL"); } - int unitCount = faction->getUnitCount(); - + int unitCount = unitsInFactionsSorted[faction->getIndex()].size(); for(int j = 0; j < unitCount; ++j) { - Unit *unit = faction->getUnit(j); + Unit *unit = unitsInFactionsSorted[faction->getIndex()][j].unit; if(unit == NULL) { throw runtime_error("unit == NULL"); } unitUpdater.updateUnit(unit); } + +// int unitCount = faction->getUnitCount(); +// for(int j = 0; j < unitCount; ++j) { +// Unit *unit = faction->getUnit(j); +// if(unit == NULL) { +// throw runtime_error("unit == NULL"); +// } +// +// unitUpdater.updateUnit(unit); +// } } if(SystemFlags::VERBOSE_MODE_ENABLED && chrono.getMillis() >= 20) printf("In [%s::%s Line: %d] *** Faction MAIN thread processing took [%lld] msecs for %d factions for frameCount = %d.\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis(),factionCount,frameCount); @@ -1644,6 +1675,11 @@ int World::getNextUnitId(Faction *faction) { return mapFactionNextUnitId[faction->getIndex()]++; } +// Get a unique commandid when sending commands to a group of units +int World::getNextCommandGroupId() { + return ++nextCommandGroupId; +} + std::string World::DumpWorldToLog(bool consoleBasicInfoOnly) const { string debugWorldLogFile = Config::getInstance().getString("DebugWorldLogFile","debugWorld.log"); diff --git a/source/glest_game/world/world.h b/source/glest_game/world/world.h index 9ee6ce78..08763d4e 100644 --- a/source/glest_game/world/world.h +++ b/source/glest_game/world/world.h @@ -140,6 +140,8 @@ private: std::map staticSoundList; std::map streamSoundList; + uint32 nextCommandGroupId; + public: World(); ~World(); @@ -169,6 +171,7 @@ public: const WaterEffects *getWaterEffects() const {return &waterEffects;} const WaterEffects *getAttackEffects() const {return &attackEffects;} int getNextUnitId(Faction *faction); + int getNextCommandGroupId(); int getFrameCount() const {return frameCount;} //init & load