2019-12-12 20:26 CET

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000202Spring engineGeneralpublic2006-09-22 12:28
ReporterILMTitan 
Assigned Totvo 
PrioritynormalSeverityfeatureReproducibilityN/A
StatusresolvedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000202: [patch] Changes to patrol. Addition of Fight.
Description*Added CMD_FIGHT = 16, which acts similar to patrol except that it does not repeat without the repeat command. Patrol now calls CMD_FIGHT internally and moves itself onto the end of the queue.

Changes to Patrol:
*Patrol commands now draw correctly onscreen.
*Lacking air targets, fighters now will attack land tragets at move state 1, down from 2.
*Commands queued after a patrol route will now be executed.
*Units are better at staying on the patrol route.
*Construction units now don't reclaim for resources already at maximum capacity while on patrol.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • patch file icon 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);
    
    patch file icon Patrol-Fight.patch (30,078 bytes) 2006-06-16 03:00 +

-Relationships
+Relationships

-Notes

~0000367

tvo (reporter)

added [patch] in front of topic

~0000385

tvo (reporter)

has been committed a while ago
+Notes

-Issue History
Date Modified Username Field Change
2006-06-16 03:00 ILMTitan New Issue
2006-06-16 03:00 ILMTitan File Added: Patrol-Fight.patch
2006-09-19 21:46 tvo Note Added: 0000367
2006-09-19 21:46 tvo Summary Changes to patrol. Addition of Fight. => [patch] Changes to patrol. Addition of Fight.
2006-09-22 12:28 tvo Status new => assigned
2006-09-22 12:28 tvo Assigned To => tvo
2006-09-22 12:28 tvo Status assigned => resolved
2006-09-22 12:28 tvo Resolution open => fixed
2006-09-22 12:28 tvo Note Added: 0000385
+Issue History