2025-07-21 17:05 CEST

View Issue Details Jump to Notes ]
IDProjectCategoryView StatusLast Update
0000199Spring engineGeneralpublic2006-06-12 23:37
ReporterILMTitan 
Assigned To 
PrioritynormalSeverityfeatureReproducibilityN/A
StatusclosedResolutionfixed 
Product Version 
Target VersionFixed in Version 
Summary0000199: Patch to change/improve canceling of commands
DescriptionWith this patch:
*Attempting to place buildings in the queue will cancel queued buildings when one of the centers is within or on the edge of the other building and shift.
*Building orders will not be given when they are to be placed on the queue and they overlap a prexesting queued building but won't cancel it. Visually it has the same effect as attempting to place over a prexsisting building.
*Currently active orders can now be canceled by repitition.
*The queues factories give to new units can now be canceled by repition.

*Previous improvements to the ctr-shift surround command are included in this patch.
TagsNo tags attached.
Checked infolog.txt for Errors
Attached Files
  • patch file icon cancelCommandChanges.patch (18,365 bytes) 2006-06-12 18:41 -
    Index: rts/Game/UI/GuiHandler.cpp
    ===================================================================
    --- rts/Game/UI/GuiHandler.cpp	(revision 1459)
    +++ rts/Game/UI/GuiHandler.cpp	(working copy)
    @@ -32,6 +32,7 @@
     #include "SDL_keysym.h"
     #include "SDL_mouse.h"
     #include "mmgr.h"
    +#include "Sim/Units/CommandAI/CommandAI.h"
     
     //////////////////////////////////////////////////////////////////////
     // Construction/Destruction
    @@ -717,7 +718,24 @@
     
     				for(std::vector<float3>::iterator bpi=buildPos.begin();bpi!=buildPos.end();++bpi){
     					float3 pos=*bpi;
    -					if(uh->ShowUnitBuildSquare(pos,unitdef))
    +					std::vector<Command> cv;
    +					if(keys[SDLK_LSHIFT]){
    +						Command c;
    +						c.id = -unitdef->id;
    +						c.params.push_back(pos.x);
    +						c.params.push_back(pos.y);
    +						c.params.push_back(pos.z);
    +						std::vector<Command> temp;
    +						std::set<CUnit*>::iterator ui = selectedUnits.selectedUnits.begin();
    +						for(; ui != selectedUnits.selectedUnits.end(); ui++){
    +							temp = (*ui)->commandAI->GetOverlapQueued(c);
    +							std::vector<Command>::iterator ti = temp.begin();
    +							for(; ti != temp.end(); ti++){
    +								cv.insert(cv.end(),*ti);
    +							}
    +						}
    +					}
    +					if(uh->ShowUnitBuildSquare(pos,unitdef,cv))
     						glColor4f(0.7,1,1,0.4);
     					else
     						glColor4f(1,0.5,0.5,0.4);
    @@ -1300,13 +1318,32 @@
     	start=helper->Pos2BuildPos(start,unitdef);
     	end=helper->Pos2BuildPos(end,unitdef);
     
    -	
    -	CUnit* unit=0;
    -	float dist2=helper->GuiTraceRay(camera->pos,mouse->dir,gu->viewRange*1.4,unit,20,true);
    +	float3 buildPos;
    +	UnitDef* unitdef2=0;
    +	if(keys[SDLK_LSHIFT] && keys[SDLK_LCTRL]){
    +		CUnit* unit=0;
    +		float dist2=helper->GuiTraceRay(camera->pos,mouse->dir,gu->viewRange*1.4,unit,20,true);
    +		if(unit){
    +			unitdef2=unit->unitDef;
    +			buildPos = unit->pos;
    +		} else {
    +			Command c = uh->GetBuildCommand(camera->pos,mouse->dir);
    +			if(c.id < 0){
    +				unitdef2=unitDefHandler->GetUnitByID(-c.id);
    +				buildPos.x = c.params[0];
    +				buildPos.y = c.params[1];
    +				buildPos.z = c.params[2];
    +			}
    +		}
    +	}
    +	if(unitdef2 && keys[SDLK_LSHIFT] && keys[SDLK_LCTRL]){		//circle build around building
    +		Command c;
    +		c.id = -unitdef->id;
    +		c.params.push_back(0);
    +		c.params.push_back(0);
    +		c.params.push_back(0);
     
    -	if(unit && keys[SDLK_LSHIFT] && keys[SDLK_LCTRL]){		//circle build around building
    -		UnitDef* unitdef2=unit->unitDef;
    -		float3 pos2=unit->pos;
    +		float3 pos2 = buildPos;
     		pos2=helper->Pos2BuildPos(pos2,unitdef2);
     		start=pos2;
     		end=pos2;
    @@ -1321,7 +1358,19 @@
     			p2.x+=(unitdef->xsize/2)*SQUARE_SIZE;
     			p2.z-=(unitdef->ysize/2)*SQUARE_SIZE;
     			p2=helper->Pos2BuildPos(p2,unitdef);
    -			ret.push_back(p2);
    +			c.params[0] = p2.x;
    +			c.params[1] = p2.y;
    +			c.params[2] = p2.z;
    +			bool cancel = false;
    +			std::set<CUnit*>::iterator ui = selectedUnits.selectedUnits.begin();
    +			for(;ui != selectedUnits.selectedUnits.end() && !cancel; ++ui){
    +				if((*ui)->commandAI->WillCancelQueued(c)){
    +					cancel = true;
    +				}
    +			}
    +			if(!cancel){
    +				ret.push_back(p2);
    +			}
     		}
     		pos=start;
     		pos.x=end.x;
    @@ -1330,7 +1379,19 @@
     			p2.x+=(unitdef->xsize/2)*SQUARE_SIZE;
     			p2.z+=(unitdef->ysize/2)*SQUARE_SIZE;
     			p2=helper->Pos2BuildPos(p2,unitdef);
    -			ret.push_back(p2);
    +			c.params[0] = p2.x;
    +			c.params[1] = p2.y;
    +			c.params[2] = p2.z;
    +			bool cancel = false;
    +			std::set<CUnit*>::iterator ui = selectedUnits.selectedUnits.begin();
    +			for(;ui != selectedUnits.selectedUnits.end() && !cancel; ++ui){
    +				if((*ui)->commandAI->WillCancelQueued(c)){
    +					cancel = true;
    +				}
    +			}
    +			if(!cancel){
    +				ret.push_back(p2);
    +			}
     		}
     		pos=end;
     		for(;pos.x>=start.x;pos.x-=unitdef->xsize*SQUARE_SIZE){
    @@ -1338,7 +1399,19 @@
     			p2.x-=(unitdef->xsize/2)*SQUARE_SIZE;
     			p2.z+=(unitdef->ysize/2)*SQUARE_SIZE;
     			p2=helper->Pos2BuildPos(p2,unitdef);
    -			ret.push_back(p2);
    +			c.params[0] = p2.x;
    +			c.params[1] = p2.y;
    +			c.params[2] = p2.z;
    +			bool cancel = false;
    +			std::set<CUnit*>::iterator ui = selectedUnits.selectedUnits.begin();
    +			for(;ui != selectedUnits.selectedUnits.end() && !cancel; ++ui){
    +				if((*ui)->commandAI->WillCancelQueued(c)){
    +					cancel = true;
    +				}
    +			}
    +			if(!cancel){
    +				ret.push_back(p2);
    +			}
     		}
     		pos=end;
     		pos.x=start.x;
    @@ -1347,7 +1420,19 @@
     			p2.x-=(unitdef->xsize/2)*SQUARE_SIZE;
     			p2.z-=(unitdef->ysize/2)*SQUARE_SIZE;
     			p2=helper->Pos2BuildPos(p2,unitdef);
    -			ret.push_back(p2);
    +			c.params[0] = p2.x;
    +			c.params[1] = p2.y;
    +			c.params[2] = p2.z;
    +			bool cancel = false;
    +			std::set<CUnit*>::iterator ui = selectedUnits.selectedUnits.begin();
    +			for(;ui != selectedUnits.selectedUnits.end() && !cancel; ++ui){
    +				if((*ui)->commandAI->WillCancelQueued(c)){
    +					cancel = true;
    +				}
    +			}
    +			if(!cancel){
    +				ret.push_back(p2);
    +			}
     		}
     	} else if(keys[SDLK_LALT]){			//build a rectangle
     		float xsize=unitdef->xsize*8+buildSpacing*16;
    Index: rts/Sim/Units/CommandAI/BuilderCAI.cpp
    ===================================================================
    --- rts/Sim/Units/CommandAI/BuilderCAI.cpp	(revision 1459)
    +++ rts/Sim/Units/CommandAI/BuilderCAI.cpp	(working copy)
    @@ -447,7 +447,7 @@
     		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",owner->unitDef->humanName.c_str());
    +			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]);
    Index: rts/Sim/Units/CommandAI/CommandAI.cpp
    ===================================================================
    --- rts/Sim/Units/CommandAI/CommandAI.cpp	(revision 1459)
    +++ rts/Sim/Units/CommandAI/CommandAI.cpp	(working copy)
    @@ -2,6 +2,7 @@
     #include "CommandAI.h"
     #include "Sim/Units/UnitHandler.h"
     #include "Sim/Units/Unit.h"
    +#include "Sim/Units/UnitDefHandler.h"
     #include "Sim/Weapons/Weapon.h"
     #include "ExternalAI/Group.h"
     #include "Rendering/GL/myGL.h"
    @@ -320,33 +321,131 @@
     			orderTarget=0;
     		}
     	}
    +	std::deque<Command>::iterator ci = CCommandAI::GetCancelQueued(c);
    +	if(c.id<0 && ci != this->commandQue.end()){
    +		do{
    +			if(ci == this->commandQue.begin()){
    +				this->commandQue.erase(ci);
    +				Command c2;
    +				c2.id = CMD_STOP;
    +				this->commandQue.push_front(c2);
    +				this->SlowUpdate();
    +			} else {
    +				this->commandQue.erase(ci);
    +			}
    +			ci = CCommandAI::GetCancelQueued(c);
    +		}while(ci != this->commandQue.end());
    +		return;
    +	} else if(ci != this->commandQue.end()){
    +		if(ci == this->commandQue.begin()){
    +			this->commandQue.erase(ci);
    +			Command c2;
    +			c2.id = CMD_STOP;
    +			this->commandQue.push_front(c2);
    +			this->SlowUpdate();
    +		} else {
    +			this->commandQue.erase(ci);
    +		}
    +		ci = CCommandAI::GetCancelQueued(c);
    +		return;
    +	}
    +	if(!this->GetOverlapQueued(c).empty()){
    +		return;
    +	}
    +	if(c.id==CMD_ATTACK && owner->weapons.empty() && owner->unitDef->canKamikaze==false)		//avoid weaponless units moving to 0 distance when given attack order
    +		c.id=CMD_STOP;
    +
    +	commandQue.push_back(c);
    +	if(commandQue.size()==1 && !owner->beingBuilt)
    +		SlowUpdate();
    +}
    +
    +/**
    +* @brief Determins if c will cancel a queued command
    +* @return true if c will cancel a queued command
    +**/
    +bool CCommandAI::WillCancelQueued(Command &c)
    +{
    +	return this->GetCancelQueued(c) != this->commandQue.end();
    +}
    +
    +/**
    +* @brief Finds the queued command that would be canceled by the Command c
    +* @return An iterator located at the command, or commandQue.end() if no such queued command exsists
    +**/
    +std::deque<Command>::iterator CCommandAI::GetCancelQueued(Command &c){
     	if(!commandQue.empty()){
     		std::deque<Command>::iterator ci=commandQue.end();
    -		for(--ci;ci!=commandQue.begin();--ci){							//iterate from the end and dont check the current order
    +		do{
    +			--ci;			//iterate from the end and dont check the current order
     			if((ci->id==c.id || (c.id<0 && ci->id<0)) && ci->params.size()==c.params.size()){
     				if(c.params.size()==1){			//we assume the param is a unit of feature id
     					if(ci->params[0]==c.params[0]){
    -						commandQue.erase(ci);
    -						return;
    +						return ci;
     					}
     				} else if(c.params.size()>=3){		//we assume this means that the first 3 makes a position
     					float3 cpos(c.params[0],c.params[1],c.params[2]);
     					float3 cipos(ci->params[0],ci->params[1],ci->params[2]);
    +					if(c.id < 0){
    +						UnitDef* u1 = unitDefHandler->GetUnitByID(-c.id);
    +						UnitDef* u2 = unitDefHandler->GetUnitByID(-ci->id);
    +						if(u1 && u2
    +							&& abs(cpos.x-cipos.x)*2 <= max(u1->xsize, u2->xsize)*SQUARE_SIZE
    +							&& abs(cpos.z-cipos.z)*2 <= max(u1->ysize, u2->ysize)*SQUARE_SIZE)
    +						{
    +							return ci;
    +						}
    +					} else {
    +                        if((cpos-cipos).SqLength2D()<17*17){
    +							return ci;				
    +						}
    +					}
    +				}
    +			}
    +		}while(ci!=commandQue.begin());
    +	}
    +	return commandQue.end();
    +}
     
    -					if((cpos-cipos).SqLength2D()<17*17){
    -						commandQue.erase(ci);
    -						return;				
    +/**
    +* @brief Returns commands that overlap c, but will not be canceled by c
    +* @return a vector containing commands that overlap c
    +*/
    +std::vector<Command> CCommandAI::GetOverlapQueued(Command &c){
    +	std::deque<Command>::iterator ci = commandQue.end();
    +	std::vector<Command> v;
    +	if(ci != commandQue.begin()){
    +		do{
    +			--ci;			//iterate from the end and dont check the current order
    +			if((ci->id==c.id || (c.id<0 && ci->id<0)) && ci->params.size()==c.params.size()){
    +				if(c.params.size()==1){			//we assume the param is a unit of feature id
    +					if(ci->params[0]==c.params[0]){
    +						v.push_back(*ci);
     					}
    +				} else if(c.params.size()>=3){		//we assume this means that the first 3 makes a position
    +					float3 cpos(c.params[0],c.params[1],c.params[2]);
    +					float3 cipos(ci->params[0],ci->params[1],ci->params[2]);
    +					if(c.id < 0){
    +						UnitDef* u1 = unitDefHandler->GetUnitByID(-c.id);
    +						UnitDef* u2 = unitDefHandler->GetUnitByID(-ci->id);
    +						if(u1 && u2
    +							&& (abs(cpos.x-cipos.x)*2 > max(u1->xsize, u2->xsize)*SQUARE_SIZE
    +							|| abs(cpos.z-cipos.z)*2 > max(u1->ysize, u2->ysize)*SQUARE_SIZE)
    +							&& abs(cpos.x-cipos.x)*2 < (u1->xsize + u2->xsize)*SQUARE_SIZE
    +							&& abs(cpos.z-cipos.z)*2 < (u1->ysize + u2->ysize)*SQUARE_SIZE)
    +						{
    +							v.push_back(*ci);
    +						}
    +					} else {
    +						if((cpos-cipos).SqLength2D()<17*17){
    +							v.push_back(*ci);
    +						}
    +					}
     				}
     			}
    -		}
    +		}while(ci!=commandQue.begin());
     	}
    -	if(c.id==CMD_ATTACK && owner->weapons.empty() && owner->unitDef->canKamikaze==false)		//avoid weaponless units moving to 0 distance when given attack order
    -		c.id=CMD_STOP;
    -
    -	commandQue.push_back(c);
    -	if(commandQue.size()==1 && !owner->beingBuilt)
    -		SlowUpdate();
    +	return v;
     }
     
     void CCommandAI::SlowUpdate()
    Index: rts/Sim/Units/CommandAI/CommandAI.h
    ===================================================================
    --- rts/Sim/Units/CommandAI/CommandAI.h	(revision 1459)
    +++ rts/Sim/Units/CommandAI/CommandAI.h	(working copy)
    @@ -29,6 +29,9 @@
     	virtual void WeaponFired(CWeapon* weapon);
     	virtual void BuggerOff(float3 pos, float radius);
     	virtual void LoadSave(CLoadSaveInterface* file, bool loading);
    +	virtual bool WillCancelQueued(Command &c);
    +	std::deque<Command>::iterator GetCancelQueued(Command &c);
    +	std::vector<Command> GetOverlapQueued(Command &c);
     
     	void AddStockpileWeapon(CWeapon* weapon);
     	void StockpileChanged(CWeapon* weapon);
    Index: rts/Sim/Units/CommandAI/FactoryCAI.cpp
    ===================================================================
    --- rts/Sim/Units/CommandAI/FactoryCAI.cpp	(revision 1459)
    +++ rts/Sim/Units/CommandAI/FactoryCAI.cpp	(working copy)
    @@ -75,9 +75,14 @@
     		if(!(c.options & SHIFT_KEY)){
     			newUnitCommands.clear();
     		}
    -		if(c.id!=CMD_STOP)
    -			newUnitCommands.push_back(c);
    -
    +		if(c.id!=CMD_STOP){
    +			std::deque<Command>::iterator ci = GetCancelQueued(c);
    +			if(ci == this->newUnitCommands.end()){
    +				newUnitCommands.push_back(c);
    +			} else {
    +				this->newUnitCommands.erase(ci);
    +			}
    +		}
     		return;
     	}
     	BuildOption &bo=boi->second;
    @@ -243,3 +248,31 @@
     	}
     	glEnd();
     }
    +
    +/**
    +* @brief Finds the queued command that would be canceled by the Command c
    +* @return An iterator located at the command, or commandQue.end() if no such queued command exsists
    +**/
    +std::deque<Command>::iterator CFactoryCAI::GetCancelQueued(Command &c){
    +	if(!newUnitCommands.empty()){
    +		std::deque<Command>::iterator ci=newUnitCommands.end();
    +		do{
    +			--ci;			//iterate from the end and dont check the current order
    +			if((ci->id==c.id || (c.id<0 && ci->id<0)) && ci->params.size()==c.params.size()){
    +				if(c.params.size()==1){			//we assume the param is a unit of feature id
    +					if(ci->params[0]==c.params[0]){
    +						return ci;
    +					}
    +				} else if(c.params.size()>=3){		//we assume this means that the first 3 makes a position
    +					float3 cpos(c.params[0],c.params[1],c.params[2]);
    +					float3 cipos(ci->params[0],ci->params[1],ci->params[2]);
    +
    +					if((cpos-cipos).SqLength2D()<17*17){
    +						return ci;
    +					}
    +				}
    +			}
    +		}while(ci!=newUnitCommands.begin());
    +	}
    +	return newUnitCommands.end();
    +}
    \ No newline at end of file
    Index: rts/Sim/Units/CommandAI/FactoryCAI.h
    ===================================================================
    --- rts/Sim/Units/CommandAI/FactoryCAI.h	(revision 1459)
    +++ rts/Sim/Units/CommandAI/FactoryCAI.h	(working copy)
    @@ -24,6 +24,7 @@
     	void GiveCommand(Command& c);
     	void DrawCommands(void);
     	void UpdateIconName(int id,BuildOption& bo);
    +	std::deque<Command>::iterator GetCancelQueued(Command &c);
     
     	std::deque<Command> newUnitCommands;
     
    Index: rts/Sim/Units/UnitHandler.cpp
    ===================================================================
    --- rts/Sim/Units/UnitHandler.cpp	(revision 1459)
    +++ rts/Sim/Units/UnitHandler.cpp	(working copy)
    @@ -19,12 +19,15 @@
     #include "Game/SelectedUnits.h"
     #include "FileSystem/FileHandler.h"
     #include "Game/UI/InfoConsole.h"
    +#include "Game/SelectedUnits.h"
     #include "Sim/Misc/Feature.h"
     #include "Sim/Misc/FeatureHandler.h"
    +#include "Sim/Units/Unit.h"
     #include "LoadSaveInterface.h"
     #include "UnitLoader.h"
     #include "SyncTracer.h"
     #include "Game/GameSetup.h"
    +#include "Game/Command.h"
     #include "Sim/Misc/AirBaseHandler.h"
     #include "mmgr.h"
     
    @@ -333,12 +336,22 @@
     		return 0;
     	if(groundheight>-unitdef->minWaterDepth)
     		return 0;
    +	std::set<CUnit*>::iterator ui = selectedUnits.selectedUnits.begin();
    +	std::vector<Command> cv;
    +	for(;ui != selectedUnits.selectedUnits.end(); ui++){
    +	
    +	}
     
     	return ret;
     }
     
     int CUnitHandler::ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef)
     {
    +	return ShowUnitBuildSquare(pos, unitdef, std::vector<Command>());
    +}
    +
    +int CUnitHandler::ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef, const std::vector<Command> &cv)
    +{
     	glDisable(GL_DEPTH_TEST );
     	glEnable(GL_BLEND);
     	glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
    @@ -376,7 +389,22 @@
     			CFeature* feature=0;
     			int tbs=TestBuildSquare(float3(x,pos.y,z),unitdef,feature);
     			if(tbs){
    -				if(feature || tbs==1)
    +				UnitDef* ud;
    +				float3 cPos;
    +				std::vector<Command>::const_iterator ci = cv.begin();
    +				for(;ci != cv.end() && tbs; ci++){
    +					ud = unitDefHandler->GetUnitByID(-ci->id);
    +					cPos.x = ci->params[0];
    +					cPos.z = ci->params[2];
    +					if(max(cPos.x-x-SQUARE_SIZE,x-cPos.x)*2 < ud->xsize*SQUARE_SIZE
    +						&& max(cPos.z-z-SQUARE_SIZE,z-cPos.z)*2 < ud->ysize*SQUARE_SIZE){
    +						tbs=0;
    +					}
    +				}
    +				if(!tbs){
    +					nobuildpos.push_back(float3(x,h,z));
    +					canbuild = 0;
    +				} else if(feature || tbs==1)
     					featurepos.push_back(float3(x,h,z));
     				else
     					canbuildpos.push_back(float3(x,h,z));
    @@ -495,3 +523,36 @@
     	}
     	return true;
     }
    +
    +/**
    +* returns a build Command that intersects the ray described by pos and dir from the command queues of the
    +* units units on team number team
    +* @breif returns a build Command that intersects the ray described by pos and dir
    +* @return the build Command, or 0 if one is not found
    +*/
    +
    +Command CUnitHandler::GetBuildCommand(float3 pos, float3 dir){
    +	float3 tempF1 = pos;
    +	std::list<CUnit*>::iterator ui = this->activeUnits.begin();
    +	std::deque<Command>::iterator ci;
    +	for(; ui != this->activeUnits.end(); ui++){
    +		if((*ui)->team == gu->myTeam){
    +			ci = (*ui)->commandAI->commandQue.begin();
    +			for(; ci != (*ui)->commandAI->commandQue.end(); ci++){
    +				if((*ci).id < 0 && (*ci).params.size() >= 3){
    +					tempF1.x = (*ci).params[0];
    +					tempF1.y = (*ci).params[1];
    +					tempF1.z = (*ci).params[2];
    +					tempF1 = pos + dir*((tempF1.y - pos.y)/dir.y) - tempF1;
    +					UnitDef* ud = unitDefHandler->GetUnitByID(-(*ci).id);
    +					if(ud && ud->xsize/2*SQUARE_SIZE > abs(tempF1.x) && ud->ysize/2*SQUARE_SIZE > abs(tempF1.z)){
    +						return (*ci);
    +					}
    +				}
    +			}
    +		}
    +	}
    +	Command c;
    +	c.id = 0;
    +	return c;
    +}
    Index: rts/Sim/Units/UnitHandler.h
    ===================================================================
    --- rts/Sim/Units/UnitHandler.h	(revision 1459)
    +++ rts/Sim/Units/UnitHandler.h	(working copy)
    @@ -14,6 +14,7 @@
     #include <string>
     
     #include "UnitDef.h"
    +#include "Game\Command.h"
     
     class CBuilderCAI;
     class CFeature;
    @@ -51,6 +52,7 @@
     	int  TestUnitBuildSquare(const float3& pos, const UnitDef *unitdef,CFeature *&feature);	//test if a unit can be built at specified position
     	int  TestUnitBuildSquare(const float3& pos, std::string unit,CFeature *&feature);	//test if a unit can be built at specified position
     	int  ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef);	//test if a unit can be built at specified position and show on the ground where it's to rough
    +	int  ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef, const std::vector<Command> &cv);
     	int  TestBuildSquare(const float3& pos, const UnitDef *unitdef,CFeature *&feature);	//test a singel mapsquare for build possibility
     
     	void AddBuilderCAI(CBuilderCAI*);
    @@ -58,6 +60,7 @@
     	float GetBuildHeight(float3 pos, const UnitDef* unitdef);
     
     	void LoadSaveUnits(CLoadSaveInterface* file, bool loading);
    +	Command GetBuildCommand(float3 pos, float3 dir);
     
     	std::list<CUnit*> activeUnits;				//used to get all active units
     	std::deque<int> freeIDs;
    
    patch file icon cancelCommandChanges.patch (18,365 bytes) 2006-06-12 18:41 +

-Relationships
+Relationships

-Notes

~0000229

jcnossen (reporter)

thanks, patch applied
+Notes

-Issue History
Date Modified Username Field Change
2006-06-12 18:41 ILMTitan New Issue
2006-06-12 18:41 ILMTitan File Added: cancelCommandChanges.patch
2006-06-12 23:37 jcnossen Status new => closed
2006-06-12 23:37 jcnossen Note Added: 0000229
2006-06-12 23:37 jcnossen Resolution open => fixed
+Issue History