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

This commit is contained in:
Mark Vejvoda 2011-07-05 04:37:35 +00:00
parent ece9755dfd
commit 2c80543889
15 changed files with 264 additions and 61 deletions

View File

@ -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<float, std::map<int, const Unit *> >::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);
}
}
}

View File

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

View File

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

View File

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

View File

@ -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; i<selection->getCount(); ++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; i<selection->getCount(); ++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; i<selection->getCount(); ++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__);

View File

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

View File

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

View File

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

View File

@ -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>(networkCommandType);}
int getUnitId() const {return unitId;}
@ -117,6 +119,8 @@ public:
CommandStateType getCommandStateType() const {return static_cast<CommandStateType>(commandStateType);}
int getCommandStateValue() const {return commandStateValue;}
int getUnitCommandGroupId() const { return unitCommandGroupId; }
void preprocessNetworkCommand(World *world);
string toString() const;
};

View File

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

View File

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

View File

@ -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<CommandGroupSorter> *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<CommandGroupSorter> *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<CommandGroupSorter> *unitsInFactionsSorted) {
if(workerThread != NULL) {
workerThread->signalPathfinder(frameIndex);
workerThread->signalPathfinder(frameIndex,unitsInFactionsSorted);
}
}

View File

@ -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<int,bool> frameIndex;
std::vector<CommandGroupSorter> *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<CommandGroupSorter> *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<CommandGroupSorter> *unitsInFactionsSorted);
bool isWorkerThreadSignalCompleted(int frameIndex);
void limitResourcesToStore();

View File

@ -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<int, std::vector<CommandGroupSorter> > 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");

View File

@ -140,6 +140,8 @@ private:
std::map<string,StaticSound *> staticSoundList;
std::map<string,StrSound *> 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