Patrol-Fight.patch (30,078 bytes)
2006-06-16 03:00
Index: rts/Game/command.h
===================================================================
--- rts/Game/command.h (revision 1478)
+++ rts/Game/command.h (working copy)
@@ -15,6 +15,7 @@
#define CMD_WAIT 5
#define CMD_MOVE 10
#define CMD_PATROL 15
+#define CMD_FIGHT 16
#define CMD_ATTACK 20
#define CMD_AREA_ATTACK 21
#define CMD_GUARD 25
Index: rts/Sim/Units/CommandAI/AirCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/AirCAI.cpp (revision 1478)
+++ rts/Sim/Units/CommandAI/AirCAI.cpp (working copy)
@@ -12,7 +12,7 @@
#include "mmgr.h"
CAirCAI::CAirCAI(CUnit* owner)
-: CCommandAI(owner)
+: CCommandAI(owner), lastPC1(-1), lastPC2(-1)
{
CommandDescription c;
c.id=CMD_MOVE;
@@ -254,63 +254,99 @@
}
break;}
case CMD_PATROL:{
+ float3 curPos=owner->pos;
+ if(c.params.size()<3){ //this shouldnt happen but anyway ...
+ info->AddLine("Error: got patrol cmd with less than 3 params on %s in aircai",
+ owner->unitDef->humanName.c_str());
+ return;
+ }
+ Command temp;
+ temp.id = CMD_FIGHT;
+ temp.params.push_back(c.params[0]);
+ temp.params.push_back(c.params[1]);
+ temp.params.push_back(c.params[2]);
+ temp.options = c.options|INTERNAL_ORDER;
+ commandQue.push_back(c);
+ commandQue.pop_front();
+ commandQue.push_front(temp);
+ if(owner->group){
+ owner->group->CommandFinished(owner->id,CMD_PATROL);
+ }
+ SlowUpdate();
+ break;}
+ case CMD_FIGHT:{
if(tempOrder){
tempOrder=false;
inCommand=true;
}
+ goalPos=float3(c.params[0],c.params[1],c.params[2]);
if(!inCommand){
- float3 pos(c.params[0],c.params[1],c.params[2]);
+ commandPos2=goalPos;
inCommand=true;
- Command co;
- co.id=CMD_PATROL;
- co.params.push_back(curPos.x);
- co.params.push_back(curPos.y);
- co.params.push_back(curPos.z);
- commandQue.push_front(co);
- commandPos1=curPos;
- activeCommand=1;
- patrolTime=3;
}
- Command& c=commandQue[activeCommand];
- if(c.params.size()<3){
- info->AddLine("Patrol command with insufficient parameters ?");
+ commandPos1=curPos;
+ if(c.params.size()<3){ //this shouldnt happen but anyway ...
+ info->AddLine("Error: got fight cmd with less than 3 params on %s in aircai",
+ owner->unitDef->humanName.c_str());
return;
}
- goalPos=float3(c.params[0],c.params[1],c.params[2]);
- commandPos2=goalPos;
- patrolTime++;
+ float testRad=1000*owner->moveState;
+ CUnit* enemy = helper->GetClosestEnemyAircraft(owner->pos+owner->speed*10,testRad,owner->allyteam);
if(owner->fireState==2 && owner->moveState!=0 && owner->maxRange>0){
- if(myPlane->isFighter){
- float testRad=1000*owner->moveState;
- CUnit* enemy=helper->GetClosestEnemyAircraft(owner->pos+owner->speed*10,testRad,owner->allyteam);
- if(enemy && !enemy->crashing){
- if(owner->moveState!=1 || LinePointDist(commandPos1,commandPos2,enemy->pos) < 1000){
- Command nc;
- nc.id=CMD_ATTACK;
- nc.params.push_back(enemy->id);
- nc.options=c.options;
- commandQue.push_front(nc);
- tempOrder=true;
- inCommand=false;
- SlowUpdate();
- return;
- }
+ if(myPlane->isFighter
+ && enemy && !enemy->crashing
+ && (owner->moveState!=1 || LinePointDist(commandPos1,commandPos2,enemy->pos) < 1000))
+ {
+ Command nc,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ float3 dir = goalPos-curPos;
+ dir.Normalize();
+ dir*=sqrtf(1024+owner->xsize*owner->xsize+owner->ysize*owner->ysize);
+ dir+=curPos;
+ c3.params.push_back(dir.x);
+ c3.params.push_back(dir.y);
+ c3.params.push_back(dir.z);
+ c3.options = c.options|INTERNAL_ORDER;
+ nc.id=CMD_ATTACK;
+ nc.params.push_back(enemy->id);
+ nc.options=c.options|INTERNAL_ORDER;
+ commandQue.push_front(nc);
+ tempOrder=true;
+ inCommand=false;
+ if(lastPC1!=gs->frameNum){ //avoid infinite loops
+ lastPC1=gs->frameNum;
+ SlowUpdate();
}
- }
- if((!myPlane->isFighter || owner->moveState==2) && owner->maxRange>0){
+ return;
+ } else if(owner->maxRange>0){
float testRad=500*owner->moveState;
- CUnit* enemy=helper->GetClosestEnemyUnit(owner->pos+owner->speed*20,testRad,owner->allyteam);
- if(enemy && (owner->hasUWWeapons || !enemy->isUnderWater) && !enemy->crashing && (myPlane->isFighter || !enemy->unitDef->canfly)){
+ enemy=helper->GetClosestEnemyUnit(owner->pos+owner->speed*20,testRad,owner->allyteam);
+ if(enemy && (owner->hasUWWeapons || !enemy->isUnderWater) && !enemy->crashing
+ && (myPlane->isFighter || !enemy->unitDef->canfly))
+ {
if(owner->moveState!=1 || LinePointDist(commandPos1,commandPos2,enemy->pos) < 1000){
- Command nc;
+ Command nc,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ float3 dir = goalPos-curPos;
+ dir.Normalize();
+ dir*=sqrtf(1024+owner->xsize*owner->xsize+owner->ysize*owner->ysize);
+ dir+=curPos;
+ c3.params.push_back(dir.x);
+ c3.params.push_back(dir.y);
+ c3.params.push_back(dir.z);
+ c3.options = c.options|INTERNAL_ORDER;
nc.id=CMD_ATTACK;
nc.params.push_back(enemy->id);
- nc.options=c.options;
+ nc.options=c.options|INTERNAL_ORDER;
+ commandQue.push_front(c3);
commandQue.push_front(nc);
tempOrder=true;
inCommand=false;
- SlowUpdate();
+ if(lastPC2!=gs->frameNum){ //avoid infinite loops
+ lastPC2=gs->frameNum;
+ SlowUpdate();
+ }
return;
}
}
@@ -319,18 +355,7 @@
myPlane->goalPos=goalPos;
if((owner->pos-goalPos).SqLength2D()<16000 || (owner->pos+owner->speed*8-goalPos).SqLength2D()<16000){
- if(owner->group)
- owner->group->CommandFinished(owner->id,CMD_PATROL);
-
- commandPos1=commandPos2;
- if((int)commandQue.size()<=activeCommand+1)
- activeCommand=0;
- else {
- if(commandQue[activeCommand+1].id!=CMD_PATROL)
- activeCommand=0;
- else
- activeCommand++;
- }
+ FinishCommand();
}
return;}
case CMD_ATTACK:
@@ -481,6 +506,7 @@
glColor4f(0.5,1,0.5,0.4);
glVertexf3(pos);
break;
+ case CMD_FIGHT:
case CMD_PATROL:
pos=float3(ci->params[0],ci->params[1]+curHeight,ci->params[2]);
glColor4f(0.5,0.5,1,0.4);
Index: rts/Sim/Units/CommandAI/AirCAI.h
===================================================================
--- rts/Sim/Units/CommandAI/AirCAI.h (revision 1478)
+++ rts/Sim/Units/CommandAI/AirCAI.h (working copy)
@@ -31,8 +31,11 @@
int activeCommand;
int targetAge;
- unsigned int patrolTime;
+// unsigned int patrolTime;
+ int lastPC1;
+ int lastPC2;
+
float3 commandPos1; //used to limit how far away stuff can fly from path
float3 commandPos2;
};
Index: rts/Sim/Units/CommandAI/BuilderCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/BuilderCAI.cpp (revision 1478)
+++ rts/Sim/Units/CommandAI/BuilderCAI.cpp (working copy)
@@ -26,11 +26,12 @@
CBuilderCAI::CBuilderCAI(CUnit* owner)
: CMobileCAI(owner),
building(false),
- commandFromPatrol(false),
buildPos(0,0,0),
cachedRadius(0),
cachedRadiusId(0),
- buildRetries(0)
+ buildRetries(0),
+ lastPC1(-1),
+ lastPC2(-1)
{
CommandDescription c;
c.id=CMD_REPAIR;
@@ -107,6 +108,7 @@
Command& c=commandQue.front();
CBuilder* fac=(CBuilder*)owner;
+ float3 curPos=owner->pos;
map<int,string>::iterator boi;
if((boi=buildOptions.find(c.id))!=buildOptions.end()){
@@ -114,7 +116,8 @@
if(cachedRadiusId==c.id){
radius=cachedRadius;
} else {
- radius=modelParser->Load3DO(unitDefHandler->GetUnitByName(boi->second)->model.modelpath,1,owner->team)->radius;
+ radius=modelParser->Load3DO(
+ unitDefHandler->GetUnitByName(boi->second)->model.modelpath,1,owner->team)->radius;
cachedRadiusId=c.id;
cachedRadius=radius;
}
@@ -192,7 +195,7 @@
case CMD_REPAIR:{
if(c.params.size()==1){ //repair unit
CUnit* unit=uh->units[(int)c.params[0]];
- if(commandFromPatrol && owner->moveState==1){ //limit how far away we go
+ if(tempOrder && owner->moveState==1){ //limit how far away we go
if(unit && LinePointDist(commandPos1,commandPos2,unit->pos) > 500){
StopMove();
FinishCommand();
@@ -360,7 +363,7 @@
} else if(c.params.size()==4){//area reclaim
float3 pos(c.params[0],c.params[1],c.params[2]);
float radius=c.params[3];
- if(FindReclaimableFeatureAndReclaim(pos,radius,c.options)){
+ if(FindReclaimableFeatureAndReclaim(pos,radius,c.options,true)){
inCommand=false;
SlowUpdate();
return;
@@ -426,75 +429,74 @@
return;}
case CMD_PATROL:{
float3 curPos=owner->pos;
- if(commandFromPatrol){
- commandFromPatrol=false;
- inCommand=true;
- --patrolTime; //prevent searching reclaimtargets etc directly if one of those call returned directly (infinite loop)
+ if(c.params.size()<3){ //this shouldnt happen but anyway ...
+ info->AddLine("Error: got patrol cmd with less than 3 params on %s in buildercai",
+ owner->unitDef->humanName.c_str());
+ return;
}
- if(!inCommand){
- float3 pos(c.params[0],c.params[1],c.params[2]);
+ Command temp;
+ temp.id = CMD_FIGHT;
+ temp.params.push_back(c.params[0]);
+ temp.params.push_back(c.params[1]);
+ temp.params.push_back(c.params[2]);
+ temp.options = c.options|INTERNAL_ORDER;
+ commandQue.push_back(c);
+ commandQue.pop_front();
+ commandQue.push_front(temp);
+ if(owner->group){
+ owner->group->CommandFinished(owner->id,CMD_PATROL);
+ }
+ SlowUpdate();
+ return;}
+ case CMD_FIGHT:{
+ if(tempOrder){
+ tempOrder=false;
inCommand=true;
- Command co;
- co.id=CMD_PATROL;
- co.params.push_back(curPos.x);
- co.params.push_back(curPos.y);
- co.params.push_back(curPos.z);
- commandQue.push_front(co);
- activeCommand=1;
- commandPos1=curPos;
- patrolTime=0;
}
- Command& c=commandQue[activeCommand];
-
if(c.params.size()<3){ //this shouldnt happen but anyway ...
info->AddLine("Error: got patrol cmd with less than 3 params on %s in BuilderCAI",owner->unitDef->humanName.c_str());
return;
}
patrolGoal=float3(c.params[0],c.params[1],c.params[2]);
- commandPos2=patrolGoal;
-
- if(!(patrolTime&3) && owner->fireState==2){
- if(FindRepairTargetAndRepair(owner->pos,300*owner->moveState,c.options,true)){
- CUnit* target=uh->units[(int)commandQue.front().params[0]];
- if(owner->moveState!=1 || LinePointDist(commandPos1,commandPos2,target->pos) < 300){
- commandFromPatrol=true;
- inCommand=false;
+ if(!inCommand){
+ inCommand = true;
+ commandPos2=patrolGoal;
+ }
+ commandPos1 = curPos;
+ if(!(patrolGoal==goalPos)){
+ SetGoal(patrolGoal,curPos);
+ }
+ if(FindRepairTargetAndRepair(curPos,300*owner->moveState,c.options,true)){
+ CUnit* target=uh->units[(int)commandQue.front().params[0]];
+ if(owner->moveState!=1 || LinePointDist(commandPos1,commandPos2,target->pos) < 300){
+ tempOrder=true;
+ inCommand=false;
+ if(lastPC1!=gs->frameNum){ //avoid infinite loops
+ lastPC1=gs->frameNum;
SlowUpdate();
- return;
- } else {
- commandQue.pop_front();
}
+ return;
+ } else {
+ commandQue.pop_front();
}
- if(FindReclaimableFeatureAndReclaim(owner->pos,300*owner->moveState,c.options)){
- commandFromPatrol=true;
- inCommand=false;
+ } else if(FindReclaimableFeatureAndReclaim(owner->pos,300*owner->moveState,c.options,false)){
+ tempOrder=true;
+ inCommand=false;
+ if(lastPC2!=gs->frameNum){ //avoid infinite loops
+ lastPC2=gs->frameNum;
SlowUpdate();
- return;
}
+ return;
}
- patrolTime++;
- if(!(patrolGoal==goalPos)){
- SetGoal(patrolGoal,curPos);
- }
if((curPos-patrolGoal).SqLength2D()<4096){
- if(owner->group)
- owner->group->CommandFinished(owner->id,CMD_PATROL);
-
- if((int)commandQue.size()<=activeCommand+1)
- activeCommand=0;
- else {
- if(commandQue[activeCommand+1].id!=CMD_PATROL)
- activeCommand=0;
- else
- activeCommand++;
- }
- commandPos1=commandPos2;
+ FinishCommand();
+ return;
}
- if(owner->haveTarget && owner->moveType->progressState!=CMoveType::Done)
+ if(owner->haveTarget && owner->moveType->progressState!=CMoveType::Done){
StopMove();
- else if(owner->moveType->progressState!=CMoveType::Active)
+ } else if(owner->moveType->progressState!=CMoveType::Active){
owner->moveType->StartMoving(goalPos, 8);
-
+ }
return;}
case CMD_RESTORE:{
if(inCommand){
@@ -605,6 +607,7 @@
}
draw=true;
break;
+ case CMD_FIGHT:
case CMD_PATROL:
pos=float3(ci->params[0],ci->params[1],ci->params[2]);
glColor4f(0.5,0.5,1,0.4);
@@ -763,7 +766,7 @@
}
}
-bool CBuilderCAI::FindReclaimableFeatureAndReclaim(float3 pos, float radius,unsigned char options)
+bool CBuilderCAI::FindReclaimableFeatureAndReclaim(float3 pos, float radius,unsigned char options, bool recAny)
{
CFeature* best=0;
float bestDist=10000000;
@@ -771,14 +774,31 @@
for(std::vector<CFeature*>::iterator fi=features.begin();fi!=features.end();++fi){
if((*fi)->def->destructable && (*fi)->allyteam!=owner->allyteam){
float dist=(*fi)->pos.distance2D(owner->pos);
- if(dist<bestDist){
+ if(dist<bestDist && (recAny
+ ||((*fi)->def->energy > 0 && gs->Team(owner->team)->energy < gs->Team(owner->team)->energyStorage)
+ ||((*fi)->def->metal > 0 && gs->Team(owner->team)->metal < gs->Team(owner->team)->metalStorage)))
+ {
bestDist=dist;
best=*fi;
}
}
}
if(best){
- Command c2;
+ Command c2,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ float3 cmdPos(commandQue.front().params[0],commandQue.front().params[1],commandQue.front().params[2]);
+ float3 dir = cmdPos-pos;
+ dir.Normalize();
+ dir*=sqrtf(1024+owner->xsize*owner->xsize+owner->ysize*owner->ysize);
+ dir+=pos;
+ c3.params.push_back(dir.x);
+ c3.params.push_back(dir.y);
+ c3.params.push_back(dir.z);/*
+ c3.params.push_back(owner->pos.x);
+ c3.params.push_back(owner->pos.y);
+ c3.params.push_back(owner->pos.z);*/
+ c3.options = options|INTERNAL_ORDER;
+ commandQue.push_front(c3);
c2.options=options | INTERNAL_ORDER;
c2.id=CMD_RECLAIM;
c2.params.push_back(MAX_UNITS+best->id);
@@ -796,14 +816,21 @@
for(std::vector<CFeature*>::iterator fi=features.begin();fi!=features.end();++fi){
if((*fi)->def->destructable && (*fi)->createdFromUnit!=""){
float dist=(*fi)->pos.distance2D(owner->pos);
- if(dist<bestDist){
+ if(dist<bestDist)
+ {
bestDist=dist;
best=*fi;
}
}
}
if(best){
- Command c2;
+ Command c2,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ c3.params.push_back(owner->pos.x);
+ c3.params.push_back(owner->pos.y);
+ c3.params.push_back(owner->pos.z);
+ c3.options = options|INTERNAL_ORDER;
+ commandQue.push_front(c3);
c2.options=options | INTERNAL_ORDER;
c2.id=CMD_RESURRECT;
c2.params.push_back(MAX_UNITS+best->id);
@@ -820,7 +847,7 @@
CMobileCAI::FinishCommand();
}
-bool CBuilderCAI::FindRepairTargetAndRepair(float3 pos, float radius,unsigned char options,bool attackEnemy)
+bool CBuilderCAI::FindRepairTargetAndRepair(float3 pos, float radius,unsigned char options, bool attackEnemy)
{
std::vector<CUnit*> cu=qf->GetUnits(pos,radius);
int myAllyteam=owner->allyteam;
@@ -828,14 +855,42 @@
if(gs->Ally(owner->allyteam,(*ui)->allyteam) && (*ui)->health<(*ui)->maxHealth && (*ui)!=owner){
if((*ui)->mobility && (*ui)->beingBuilt && owner->moveState<2) //dont help factories produce units unless set on roam
continue;
- Command nc;
+ Command nc,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ float3 cmdPos(commandQue.front().params[0],commandQue.front().params[1],commandQue.front().params[2]);
+ float3 dir = cmdPos-pos;
+ dir.Normalize();
+ dir*=sqrtf(1024+owner->xsize*owner->xsize+owner->ysize*owner->ysize);
+ dir+=pos;
+ c3.params.push_back(dir.x);
+ c3.params.push_back(dir.y);
+ c3.params.push_back(dir.z);/*
+ c3.params.push_back(owner->pos.x);
+ c3.params.push_back(owner->pos.y);
+ c3.params.push_back(owner->pos.z);*/
+ c3.options = options|INTERNAL_ORDER;
+ commandQue.push_front(c3);
nc.id=CMD_REPAIR;
nc.options=options | INTERNAL_ORDER;
nc.params.push_back((*ui)->id);
commandQue.push_front(nc);
return true;
} else if(attackEnemy && owner->maxRange>0 && !gs->Ally(owner->allyteam,(*ui)->allyteam)){
- Command nc;
+ Command nc,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ float3 cmdPos(commandQue.front().params[0],commandQue.front().params[1],commandQue.front().params[2]);
+ float3 dir = cmdPos-pos;
+ dir.Normalize();
+ dir*=1024+owner->xsize*owner->xsize+owner->ysize*owner->ysize;
+ dir+=pos;
+ c3.params.push_back(dir.x);
+ c3.params.push_back(dir.y);
+ c3.params.push_back(dir.z);/*
+ c3.params.push_back(owner->pos.x);
+ c3.params.push_back(owner->pos.y);
+ c3.params.push_back(owner->pos.z);*/
+ c3.options = options|INTERNAL_ORDER;
+ commandQue.push_front(c3);
nc.id=CMD_ATTACK;
nc.options=options | INTERNAL_ORDER;
nc.params.push_back((*ui)->id);
@@ -852,7 +907,13 @@
int myAllyteam=owner->allyteam;
for(std::vector<CUnit*>::iterator ui=cu.begin();ui!=cu.end();++ui){
if(!gs->Ally(myAllyteam,(*ui)->allyteam) && (*ui)!=owner && !(*ui)->beingBuilt){
- Command nc;
+ Command nc,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ c3.params.push_back(owner->pos.x);
+ c3.params.push_back(owner->pos.y);
+ c3.params.push_back(owner->pos.z);
+ c3.options = options|INTERNAL_ORDER;
+ commandQue.push_front(c3);
nc.id=CMD_CAPTURE;
nc.options=options | INTERNAL_ORDER;
nc.params.push_back((*ui)->id);
Index: rts/Sim/Units/CommandAI/BuilderCAI.h
===================================================================
--- rts/Sim/Units/CommandAI/BuilderCAI.h (revision 1478)
+++ rts/Sim/Units/CommandAI/BuilderCAI.h (working copy)
@@ -17,13 +17,12 @@
void GiveCommand(Command& c);
void DrawQuedBuildingSquares(void);
- bool FindReclaimableFeatureAndReclaim(float3 pos, float radius,unsigned char options);
+ bool FindReclaimableFeatureAndReclaim(float3 pos, float radius,unsigned char options, bool recAny);
bool FindResurrectableFeatureAndResurrect(float3 pos, float radius,unsigned char options);
void FinishCommand(void);
bool FindRepairTargetAndRepair(float3 pos, float radius,unsigned char options,bool attackEnemy);
bool FindCaptureTargetAndCapture(float3 pos, float radius,unsigned char options);
- bool commandFromPatrol;
map<int,string> buildOptions;
bool building;
float3 buildPos;
@@ -32,6 +31,9 @@
int cachedRadiusId;
int buildRetries;
+
+ int lastPC1; //helps avoid infinite loops
+ int lastPC2;
};
#endif // __BUILDER_CAI_H__
Index: rts/Sim/Units/CommandAI/CommandAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/CommandAI.cpp (revision 1478)
+++ rts/Sim/Units/CommandAI/CommandAI.cpp (working copy)
@@ -295,18 +295,20 @@
stockpileWeapon->numStockpileQued=0;
UpdateStockpileIcon();
return; }
- case CMD_SELFD:
+ case CMD_SELFD:{
if(owner->selfDCountdown){
owner->selfDCountdown=0;
} else {
owner->selfDCountdown = owner->unitDef->selfDCountdown*2+1;
}
- return;
+ return;}
}
-
+
if(!(c.options & SHIFT_KEY)){
if(!commandQue.empty()){
- if(commandQue.front().id==CMD_ATTACK || commandQue.front().id==CMD_AREA_ATTACK || commandQue.front().id==CMD_DGUN){
+ if(commandQue.front().id==CMD_ATTACK || commandQue.front().id==CMD_AREA_ATTACK
+ || commandQue.front().id==CMD_DGUN)
+ {
owner->AttackUnit(0,true);
}
@@ -321,30 +323,65 @@
orderTarget=0;
}
}
+ if(c.id == CMD_PATROL){
+ std::deque<Command>::iterator ci = commandQue.begin();
+ for(; ci != commandQue.end() && ci->id!=CMD_PATROL; ci++);
+ if(ci==commandQue.end()){
+ if(commandQue.empty()){
+ Command c2;
+ c2.id = CMD_PATROL;
+ c2.params.push_back(owner->pos.x);
+ c2.params.push_back(owner->pos.y);
+ c2.params.push_back(owner->pos.z);
+ c2.options = c.options;
+ commandQue.push_back(c2);
+ } else {
+ do{
+ ci--;
+ if(ci->params.size() >=3){
+ Command c2;
+ c2.id = CMD_PATROL;
+ c2.params = ci->params;
+ c2.options = c.options;
+ commandQue.push_back(c2);
+ ci=commandQue.begin();
+ } else if(ci==commandQue.begin()){
+ Command c2;
+ c2.id = CMD_PATROL;
+ c2.params.push_back(owner->pos.x);
+ c2.params.push_back(owner->pos.y);
+ c2.params.push_back(owner->pos.z);
+ c2.options = c.options;
+ commandQue.push_back(c2);
+ }
+ }while(ci!=commandQue.begin());
+ }
+ }
+ }
std::deque<Command>::iterator ci = CCommandAI::GetCancelQueued(c);
- if(c.id<0 && ci != this->commandQue.end()){
+ if(c.id<0 && ci != commandQue.end()){
do{
- if(ci == this->commandQue.begin()){
- this->commandQue.erase(ci);
+ if(ci == commandQue.begin()){
+ commandQue.erase(ci);
Command c2;
c2.id = CMD_STOP;
- this->commandQue.push_front(c2);
- this->SlowUpdate();
+ commandQue.push_front(c2);
+ SlowUpdate();
} else {
- this->commandQue.erase(ci);
+ commandQue.erase(ci);
}
ci = CCommandAI::GetCancelQueued(c);
- }while(ci != this->commandQue.end());
+ }while(ci != commandQue.end());
return;
- } else if(ci != this->commandQue.end()){
- if(ci == this->commandQue.begin()){
- this->commandQue.erase(ci);
+ } else if(ci != commandQue.end()){
+ if(ci == commandQue.begin()){
+ commandQue.erase(ci);
Command c2;
c2.id = CMD_STOP;
- this->commandQue.push_front(c2);
- this->SlowUpdate();
+ commandQue.push_front(c2);
+ SlowUpdate();
} else {
- this->commandQue.erase(ci);
+ commandQue.erase(ci);
}
ci = CCommandAI::GetCancelQueued(c);
return;
@@ -547,7 +584,7 @@
void CCommandAI::FinishCommand(void)
{
int type=commandQue.front().id;
- if(repeatOrders && type!=CMD_STOP && !(commandQue.front().options & INTERNAL_ORDER))
+ if(repeatOrders && type!=CMD_STOP && type != CMD_PATROL && !(commandQue.front().options & INTERNAL_ORDER))
commandQue.push_back(commandQue.front());
commandQue.pop_front();
inCommand=false;
@@ -589,7 +626,8 @@
for(pci=possibleCommands.begin();pci!=possibleCommands.end();++pci){
if(pci->id==CMD_STOCKPILE){
char name[50];
- sprintf(name,"%i/%i",stockpileWeapon->numStockpiled,stockpileWeapon->numStockpiled+stockpileWeapon->numStockpileQued);
+ sprintf(name,"%i/%i",stockpileWeapon->numStockpiled,
+ stockpileWeapon->numStockpiled+stockpileWeapon->numStockpileQued);
pci->name=name;
selectedUnits.PossibleCommandChange(owner);
}
@@ -598,7 +636,9 @@
void CCommandAI::WeaponFired(CWeapon* weapon)
{
- if(weapon->weaponDef->manualfire && !weapon->weaponDef->dropped && !commandQue.empty() && (commandQue.front().id==CMD_ATTACK || commandQue.front().id==CMD_DGUN) && inCommand){
+ if(weapon->weaponDef->manualfire && !weapon->weaponDef->dropped && !commandQue.empty()
+ && (commandQue.front().id==CMD_ATTACK || commandQue.front().id==CMD_DGUN) && inCommand)
+ {
owner->AttackUnit(0,true);
FinishCommand();
}
Index: rts/Sim/Units/CommandAI/MobileCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/MobileCAI.cpp (revision 1478)
+++ rts/Sim/Units/CommandAI/MobileCAI.cpp (working copy)
@@ -17,8 +17,7 @@
CMobileCAI::CMobileCAI(CUnit* owner)
: CCommandAI(owner),
- activeCommand(0),
- patrolTime(0),
+// patrolTime(0),
goalPos(-1,-1,-1),
tempOrder(false),
patrolGoal(1,1,1),
@@ -28,7 +27,8 @@
maxWantedSpeed(0),
lastIdleCheck(0),
commandPos1(ZeroVector),
- commandPos2(ZeroVector)
+ commandPos2(ZeroVector),
+ lastPC(-1)
{
lastUserGoal=owner->pos;
@@ -114,7 +114,6 @@
}
if(!(c.options & SHIFT_KEY) && nonQueingCommands.find(c.id)==nonQueingCommands.end()){
- activeCommand=0;
tempOrder=false;
}
CCommandAI::GiveCommand(c);
@@ -154,69 +153,83 @@
}
break;}
case CMD_PATROL:{
+ if(c.params.size()<3){ //this shouldnt happen but anyway ...
+ info->AddLine("Error: got patrol cmd with less than 3 params on %s in mobilecai",
+ owner->unitDef->humanName.c_str());
+ return;
+ }
+ Command temp;
+ temp.id = CMD_FIGHT;
+ temp.params.push_back(c.params[0]);
+ temp.params.push_back(c.params[1]);
+ temp.params.push_back(c.params[2]);
+ temp.options = c.options|INTERNAL_ORDER;
+ commandQue.push_back(c);
+ commandQue.pop_front();
+ commandQue.push_front(temp);
+ if(owner->group){
+ owner->group->CommandFinished(owner->id,CMD_PATROL);
+ }
+ SlowUpdate();
+ return;}
+ case CMD_FIGHT:{
if(tempOrder){
- tempOrder=false;
- inCommand=true;
- patrolTime=1;
+ inCommand = true;
+ tempOrder = false;
}
- if(!inCommand){
- float3 pos(c.params[0],c.params[1],c.params[2]);
- inCommand=true;
- Command co;
- co.id=CMD_PATROL;
- co.params.push_back(curPos.x);
- co.params.push_back(curPos.y);
- co.params.push_back(curPos.z);
- commandQue.push_front(co);
- activeCommand=1;
- commandPos1=curPos;
- patrolTime=1;
- }
- Command& c=commandQue[activeCommand];
if(c.params.size()<3){ //this shouldnt happen but anyway ...
- info->AddLine("Error: got patrol cmd with less than 3 params on %s in mobilecai",owner->unitDef->humanName.c_str());
+ info->AddLine("Error: got fight cmd with less than 3 params on %s in mobilecai",
+ owner->unitDef->humanName.c_str());
return;
}
- patrolGoal=float3(c.params[0],c.params[1],c.params[2]);
- commandPos2=patrolGoal;
- patrolTime++;
+ float3 pos(c.params[0],c.params[1],c.params[2]);
+ if(!inCommand){
+ inCommand = true;
+ commandPos2 = pos;
+ }
+ commandPos1 = curPos;
+ if(pos!=goalPos){
+ SetGoal(pos,curPos);
+ }
- if(!(patrolTime&1) && owner->fireState==2){
- CUnit* enemy=helper->GetClosestEnemyUnit(curPos,owner->maxRange+100*owner->moveState*owner->moveState,owner->allyteam);
- if(enemy && (owner->hasUWWeapons || !enemy->isUnderWater) && !(owner->unitDef->noChaseCategory & enemy->category) && !owner->weapons.empty()){ //todo: make sure they dont stray to far from path
- if(owner->moveState!=1 || LinePointDist(commandPos1,commandPos2,enemy->pos) < 300+owner->maxRange){
- Command c2;
+ if(owner->fireState==2){
+ CUnit* enemy=helper->GetClosestEnemyUnit(
+ curPos, owner->maxRange+100*owner->moveState*owner->moveState, owner->allyteam);
+ if(enemy && (owner->hasUWWeapons || !enemy->isUnderWater)
+ && !(owner->unitDef->noChaseCategory & enemy->category) && !owner->weapons.empty()) //todo: make sure they dont stray to far from path
+ {
+ if(owner->moveState!=1
+ || LinePointDist(commandPos1,commandPos2,enemy->pos)
+ < 300+max(owner->maxRange, (float)owner->losRadius))
+ {
+ Command c2,c3;
+ c3.id = CMD_MOVE; //keep it from being pulled too far off the path
+ float3 dir = pos-curPos;
+ dir.Normalize();
+ dir*=sqrtf(1024+owner->xsize*owner->xsize+owner->ysize*owner->ysize);
+ dir+=curPos;
+ c3.params.push_back(dir.x);
+ c3.params.push_back(dir.y);
+ c3.params.push_back(dir.z);
+ c3.options = c.options|INTERNAL_ORDER;
c2.id=CMD_ATTACK;
- c2.options=c.options;
+ c2.options=c.options|INTERNAL_ORDER;
c2.params.push_back(enemy->id);
+ commandQue.push_front(c3);
commandQue.push_front(c2);
inCommand=false;
tempOrder=true;
- SlowUpdate(); //if attack can finish immidiatly this could lead to an infinite loop so make sure it doesnt
+ if(lastPC!=gs->frameNum){ //avoid infinite loops
+ lastPC=gs->frameNum;
+ SlowUpdate();
+ }
return;
}
}
}
- if((curPos-patrolGoal).SqLength2D()<4096 || owner->moveType->progressState==CMoveType::Failed){
- if(owner->group)
- owner->group->CommandFinished(owner->id,CMD_PATROL);
-
- if((int)commandQue.size()<=activeCommand+1)
- activeCommand=0;
- else {
- if(commandQue[activeCommand+1].id!=CMD_PATROL)
- activeCommand=0;
- else
- activeCommand++;
- }
- Command& c=commandQue[activeCommand];
- patrolGoal=float3(c.params[0],c.params[1],c.params[2]);
- commandPos1=commandPos2;
- commandPos2=patrolGoal;
+ if((curPos-goalPos).SqLength2D()<4096 || owner->moveType->progressState==CMoveType::Failed){
+ FinishCommand();
}
- if((patrolGoal!=goalPos)){
- SetGoal(patrolGoal,curPos);
- }
return;}
case CMD_DGUN:
if(uh->limitDgun && owner->unitDef->isCommander && owner->pos.distance(gs->Team(owner->team)->startPos)>uh->dgunRadius){
@@ -357,6 +370,7 @@
draw=true;
break;
case CMD_PATROL:
+ case CMD_FIGHT:
pos=float3(ci->params[0],ci->params[1],ci->params[2]);
glColor4f(0.5,0.5,1,0.4);
draw=true;
@@ -424,7 +438,6 @@
lastUserGoal=owner->pos;
// info->AddLine("Reseting user goal");
}
-
CCommandAI::FinishCommand();
}
Index: rts/Sim/Units/CommandAI/MobileCAI.h
===================================================================
--- rts/Sim/Units/CommandAI/MobileCAI.h (revision 1478)
+++ rts/Sim/Units/CommandAI/MobileCAI.h (working copy)
@@ -25,12 +25,13 @@
float3 patrolGoal;
float3 lastUserGoal;
- int activeCommand;
int lastIdleCheck;
bool tempOrder;
- unsigned int patrolTime;
+ int lastPC; //helps avoid infinate loops
+// unsigned int patrolTime;
+
float maxWantedSpeed;
int lastBuggerOffTime;
Index: rts/Sim/Units/CommandAI/TransportCAI.cpp
===================================================================
--- rts/Sim/Units/CommandAI/TransportCAI.cpp (revision 1478)
+++ rts/Sim/Units/CommandAI/TransportCAI.cpp (working copy)
@@ -334,6 +334,7 @@
glColor4f(0.5,1,0.5,0.4);
draw=true;
break;
+ case CMD_FIGHT:
case CMD_PATROL:
pos=float3(ci->params[0],ci->params[1],ci->params[2]);
glColor4f(0.5,0.5,1,0.4);