Four-directional building placement.
Moderator: Moderators
-
- Posts: 578
- Joined: 19 Aug 2004, 17:38
Four-directional building placement.
As some of you might know, I have been charged with the task of implementing into Spring the long sought-after function that would allow the rotation of buildings prior to ordering their placement. A lot fewer people, up until this moment at least, know that the making of this task has ended with an astonishing success:
Note that buildings correctly display their orientation in build que, and the building's ghost following the cursor displays the current setting for building rotation. Factories have been tested and appear to be working fine, so do turrets and misc. structures. Rejoice!!! :D
Now somebody tell me what to do with the .diff...
Note that buildings correctly display their orientation in build que, and the building's ghost following the cursor displays the current setting for building rotation. Factories have been tested and appear to be working fine, so do turrets and misc. structures. Rejoice!!! :D
Now somebody tell me what to do with the .diff...
- Tim Blokdijk
- Posts: 1242
- Joined: 29 May 2005, 11:18
Mail it to the mailinglist and ask if someone could review it for inclusion.
But maybe you could release a test version to see if there are things that still need to be improved?
But maybe you could release a test version to see if there are things that still need to be improved?
-
- Posts: 578
- Joined: 19 Aug 2004, 17:38
-
- Posts: 578
- Joined: 19 Aug 2004, 17:38
Here ya go:
There's probably a lot of useless and inefficient stuff there, but I guess it's my way of coding.
And you might be able to get the exe from http://edf.tauniverse.com/spring.exe, but only when the server no longer thinks it's exceeding the limit.
Comp1337: I might let buildAngle actually have an effect.
Code: Select all
Index: C:/Springproject/rts/ExternalAI/AICallback.cpp
===================================================================
--- C:/Springproject/rts/ExternalAI/AICallback.cpp (revision 1511)
+++ C:/Springproject/rts/ExternalAI/AICallback.cpp (working copy)
@@ -604,7 +604,7 @@
{
CFeature* f;
pos=helper->Pos2BuildPos (pos, unitDef);
- return !!uh->TestUnitBuildSquare(pos,unitDef->name,f);
+ return !!uh->TestUnitBuildSquare(pos,unitDef->name,f,0);
}
@@ -656,7 +656,7 @@
float z = pos.z+ofs[so].dy*SQUARE_SIZE*2;
float3 p(x,0,z);
p = helper->Pos2BuildPos (p, unitdef);
- if(uh->TestUnitBuildSquare(p,unitdef,feature) && (!feature || feature->allyteam!=allyteam))
+ if(uh->TestUnitBuildSquare(p,unitdef,feature,0) && (!feature || feature->allyteam!=allyteam))
{
int xs=(int)(x/SQUARE_SIZE);
int zs=(int)(z/SQUARE_SIZE);
Index: C:/Springproject/rts/Game/Game.cpp
===================================================================
--- C:/Springproject/rts/Game/Game.cpp (revision 1511)
+++ C:/Springproject/rts/Game/Game.cpp (working copy)
@@ -590,6 +590,12 @@
if (s=="updatefov")
gd->updateFov=!gd->updateFov;
+ if (s=="spinbuilddir"){
+ guihandler->buildFacing++;
+ if(guihandler->buildFacing>3)
+ guihandler->buildFacing=0;
+ }
+
if (s=="drawtrees")
treeDrawer->drawTrees=!treeDrawer->drawTrees;
@@ -877,6 +883,18 @@
inMapDrawer->keyPressed=false;
}
+ if(s=="buildfaceup"){
+ }
+
+ if(s=="buildfaceright"){
+ }
+
+ if(s=="buildfacedown"){
+ }
+
+ if(s=="buildfaceleft"){
+ }
+
if (s=="moveforward")
camMove[0]=false;
Index: C:/Springproject/rts/Game/UI/GUI/GUIgame.cpp
===================================================================
--- C:/Springproject/rts/Game/UI/GUI/GUIgame.cpp (revision 1511)
+++ C:/Springproject/rts/Game/UI/GUI/GUIgame.cpp (working copy)
@@ -407,7 +407,7 @@
int size=positions.size();
for(int i=0; i<size; i++)
{
- if(uh->ShowUnitBuildSquare(positions[i],unitdef))
+ if(uh->ShowUnitBuildSquare(positions[i],unitdef, guihandler->buildFacing))
glColor4f(0.7,1,1,0.4);
else
glColor4f(1,0.5,0.5,0.4);
@@ -439,7 +439,7 @@
}
else
{
- if(uh->ShowUnitBuildSquare(pos,unitdef))
+ if(uh->ShowUnitBuildSquare(pos,unitdef,guihandler->buildFacing))
glColor4f(0.7,1,1,0.4);
else
glColor4f(1,0.5,0.5,0.4);
Index: C:/Springproject/rts/Game/UI/GuiHandler.cpp
===================================================================
--- C:/Springproject/rts/Game/UI/GuiHandler.cpp (revision 1511)
+++ C:/Springproject/rts/Game/UI/GuiHandler.cpp (working copy)
@@ -96,7 +96,8 @@
activePage(0),
maxPages(0),
showingMetal(false),
- buildSpacing(0)
+ buildSpacing(0),
+ buildFacing(0)
{
// LoadCMDBitmap(CMD_STOP, "bitmaps\\ocean.bmp");
LoadCMDBitmap(CMD_STOCKPILE, "bitmaps/armsilo1.bmp");
@@ -735,7 +736,7 @@
}
}
}
- if(uh->ShowUnitBuildSquare(pos,unitdef,cv))
+ if(uh->ShowUnitBuildSquare(pos,unitdef,cv,buildFacing))
glColor4f(0.7,1,1,0.4);
else
glColor4f(1,0.5,0.5,0.4);
@@ -740,7 +741,7 @@
else
glColor4f(1,0.5,0.5,0.4);
- unitDrawer->DrawBuildingSample(unitdef, gu->myTeam, pos);
+ unitDrawer->DrawBuildingSample(unitdef, gu->myTeam, pos, buildFacing);
if(unitdef->weapons.size()>0){ //draw range
glDisable(GL_TEXTURE_2D);
glColor4f(1,0.3,0.3,0.7);
@@ -1152,6 +1153,33 @@
if(!unitdef){
return defaultRet;
}
+ switch (buildFacing)
+ {
+ case 0:
+ unitdef->xsize=unitdef->rxsize;
+ unitdef->ysize=unitdef->rysize;
+ unitdef->yardmap=unitdef->yardmap1;
+ break;
+ case 1:
+ unitdef->xsize=unitdef->rysize;
+ unitdef->ysize=unitdef->rxsize;
+ unitdef->yardmap=unitdef->yardmap2;
+ break;
+ case 2:
+ unitdef->xsize=unitdef->rxsize;
+ unitdef->ysize=unitdef->rysize;
+ unitdef->yardmap=unitdef->yardmap3;
+ break;
+ case 3:
+ unitdef->xsize=unitdef->rysize;
+ unitdef->ysize=unitdef->rxsize;
+ unitdef->yardmap=unitdef->yardmap4;
+ break;
+ default:
+ unitdef->xsize=unitdef->rxsize;
+ unitdef->ysize=unitdef->rysize;
+ unitdef->yardmap=unitdef->yardmap1;
+ }
float3 pos=camera->pos+mouse->dir*dist;
std::vector<float3> buildPos;
if(keys[SDLK_LSHIFT] && button==SDL_BUTTON_LEFT){
@@ -1175,6 +1203,7 @@
c.params.push_back(pos.x);
c.params.push_back(pos.y);
c.params.push_back(pos.z);
+ c.params.push_back(buildFacing);
CreateOptions(c,(button==SDL_BUTTON_LEFT?0:1));
if(!preview)
selectedUnits.GiveCommand(c);
@@ -1185,6 +1214,7 @@
c.params.push_back(pos.x);
c.params.push_back(pos.y);
c.params.push_back(pos.z);
+ c.params.push_back(buildFacing);
CreateOptions(c,(button==SDL_BUTTON_LEFT?0:1));
return c;}
Index: C:/Springproject/rts/Game/UI/GuiHandler.h
===================================================================
--- C:/Springproject/rts/Game/UI/GuiHandler.h (revision 1511)
+++ C:/Springproject/rts/Game/UI/GuiHandler.h (working copy)
@@ -46,6 +46,7 @@
int defaultCmdMemory;
CglList* list;
int buildSpacing;
+ int buildFacing; // which side the built buildings should face?
void CreateOptions(Command& c,bool rmb);
int GetDefaultCommand(int x,int y);
Index: C:/Springproject/rts/Map/BaseGroundDrawer.cpp
===================================================================
--- C:/Springproject/rts/Map/BaseGroundDrawer.cpp (revision 1511)
+++ C:/Springproject/rts/Map/BaseGroundDrawer.cpp (working copy)
@@ -172,7 +172,7 @@
UnitDef *unitdef = unitDefHandler->GetUnitByID(-guihandler->commands[guihandler->inCommand].id);
CFeature* f;
- if(uh->TestUnitBuildSquare(float3(x*16+8,0,y*16+8),unitdef,f))
+ if(uh->TestUnitBuildSquare(float3(x*16+8,0,y*16+8),unitdef,f,guihandler->buildFacing))
m=1;
else
m=0;
Index: C:/Springproject/rts/Rendering/UnitModels/UnitDrawer.cpp
===================================================================
--- C:/Springproject/rts/Rendering/UnitModels/UnitDrawer.cpp (revision 1511)
+++ C:/Springproject/rts/Rendering/UnitModels/UnitDrawer.cpp (working copy)
@@ -438,6 +438,7 @@
if(camera->InView((*gbi)->pos,(*gbi)->model->radius*2)){
glPushMatrix();
glTranslatef3((*gbi)->pos);
+ glRotatef((*gbi)->facing*1024*16*(180.0/32768.0),0,1,0);
(*gbi)->model->DrawStatic();
glPopMatrix();
}
@@ -981,7 +982,7 @@
if (unit->model->textureType == 0){
/* 3DO */
SetupForUnitDrawing();
- unit->Draw();
+ unit->Draw();
CleanUpUnitDrawing();
} else {
/* S3O */
@@ -1003,7 +1004,7 @@
* Note: does all the GL state setting for that one unit, so you might want
* something else for drawing many translucent units.
*/
-void CUnitDrawer::DrawBuildingSample(UnitDef* unitdef, int side, float3 pos)
+void CUnitDrawer::DrawBuildingSample(UnitDef* unitdef, int side, float3 pos, int facing)
{
S3DOModel* model=modelParser->Load3DO(unitdef->model.modelpath.c_str(), 1, side);
@@ -1012,6 +1013,7 @@
SetupForGhostDrawing();
glPushMatrix();
glTranslatef3(pos);
+ glRotatef((facing*1024*16)*(180.0/32768.0),0,1,0);
model->DrawStatic();
CleanUpGhostDrawing();
glPopMatrix();
@@ -1050,6 +1052,7 @@
/* Push out the polygons. */
glPushMatrix();
glTranslatef3(pos);
+
model->DrawStatic();
glPopMatrix();
Index: C:/Springproject/rts/Rendering/UnitModels/UnitDrawer.h
===================================================================
--- C:/Springproject/rts/Rendering/UnitModels/UnitDrawer.h (revision 1511)
+++ C:/Springproject/rts/Rendering/UnitModels/UnitDrawer.h (working copy)
@@ -72,6 +72,7 @@
BuildingGroundDecal* decal;
float3 pos;
S3DOModel* model;
+ int facing;
};
std::list<GhostBuilding*> ghostBuildings; //these are buildings that where in LOS_PREVLOS when they died and havent been in los since then
@@ -92,7 +93,7 @@
std::set<int> usedS3OTextures;
void SetS3OTeamColour(int team);
- void DrawBuildingSample(UnitDef* unitdef, int side, float3 pos);
+ void DrawBuildingSample(UnitDef* unitdef, int side, float3 pos, int facing=0);
/* CUnit::Draw */
void UnitDrawingTexturesOff(S3DOModel *model);
Index: C:/Springproject/rts/Sim/Objects/SolidObject.cpp
===================================================================
--- C:/Springproject/rts/Sim/Objects/SolidObject.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Objects/SolidObject.cpp (working copy)
@@ -151,7 +151,7 @@
void CSolidObject::Block() {
if(isMarkedOnBlockingMap)
UnBlock();
-
+
if(blocking && (physicalState == OnGround || physicalState == Floating || physicalState == Hovering || physicalState == Submarine)){
//Using yardmap if available.
if(yardMap) {
Index: C:/Springproject/rts/Sim/Objects/SolidObject.h
===================================================================
--- C:/Springproject/rts/Sim/Objects/SolidObject.h (revision 1511)
+++ C:/Springproject/rts/Sim/Objects/SolidObject.h (working copy)
@@ -46,7 +46,7 @@
int ysize; //The z-size of this object, according to it's footprint. NOTE: This one should have been called zsize!
float height; //The height of this object.
short heading; //Contains the same information as frontdir, but in a short signed integer.
-
+
//Positional properties.
PhysicalState physicalState; //The current state of the object within the gameworld. I.e Flying or OnGround.
float3 midPos; //This is the calculated center position of the model (pos is usually at the very bottom of the model). Used as mass center.
@@ -65,6 +65,7 @@
//Map
int2 mapPos; //Current position on GroundBlockingMap.
unsigned char* yardMap; //Current active yardmap of this object. 0 means no active yardmap => all blocked.
+ int buildFacing;
bool isMarkedOnBlockingMap; //Tells if this object are marked on the GroundBlockingMap.
//Old stuff. Used for back-compability. NOTE: Don't use whose!
Index: C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.cpp (working copy)
@@ -135,6 +135,9 @@
buildPos.x=c.params[0];
buildPos.y=c.params[1];
buildPos.z=c.params[2];
+ if(c.params[3])
+ buildFacing=c.params[3];
+ else buildFacing=0;
if(buildPos.distance2D(fac->pos)<fac->buildDistance*0.6+radius){
StopMove();
if(uh->maxUnits>(int)gs->Team(owner->team)->units.size()){
@@ -140,7 +143,7 @@
if(uh->maxUnits>(int)gs->Team(owner->team)->units.size()){
buildRetries++;
owner->moveType->KeepPointingTo(buildPos, fac->buildDistance*0.7+radius, false);
- if(fac->StartBuild(boi->second,buildPos) || buildRetries>20){
+ if(fac->StartBuild(boi->second,buildPos,buildFacing) || buildRetries>20){
building=true;
} else {
ENTER_MIXED;
@@ -169,7 +172,8 @@
pos.z=floor(c.params[2]/SQUARE_SIZE+0.5)*SQUARE_SIZE;
pos.y=c.params[1];
CFeature* f=0;
- uh->TestUnitBuildSquare(pos,boi->second,f);
+ buildFacing=c.params[3];
+ uh->TestUnitBuildSquare(pos,boi->second,f,buildFacing);
if(f){
Command c2;
c2.id=CMD_RECLAIM;
@@ -673,6 +677,7 @@
map<int,string>::iterator boi;
if((boi=buildOptions.find(ci->id))!=buildOptions.end()){
pos=float3(ci->params[0],ci->params[1],ci->params[2]);
+ int facing=ci->params[3];
UnitDef *unitdef = unitDefHandler->GetUnitByName(boi->second);
glColor4f(1,1,1,0.4);
@@ -695,7 +700,7 @@
}
glColor4f(1,1,1,0.3);
- unitDrawer->DrawBuildingSample(unitdef, owner->team, pos);
+ unitDrawer->DrawBuildingSample(unitdef, owner->team, pos, facing);
glColor4f(1,1,1,0.4);
glBegin(GL_LINE_STRIP);
@@ -727,10 +732,11 @@
if(c.params.size()<3)
return;
float3 pos(c.params[0],c.params[1],c.params[2]);
+ buildFacing=c.params[3];
UnitDef *unitdef = unitDefHandler->GetUnitByName(boi->second);
pos=helper->Pos2BuildPos(pos,unitdef);
CFeature* feature;
- if(!uh->TestUnitBuildSquare(pos,unitdef,feature)){
+ if(!uh->TestUnitBuildSquare(pos,unitdef,feature,buildFacing)){
return;
}
}
@@ -745,9 +751,38 @@
map<int,string>::iterator boi;
if((boi=buildOptions.find(ci->id))!=buildOptions.end()){
float3 pos=float3(ci->params[0],ci->params[1]+3,ci->params[2]);
+ int facing=ci->params[3];
UnitDef *unitdef = unitDefHandler->GetUnitByName(boi->second);
pos=helper->Pos2BuildPos(pos,unitdef);
+
+ switch (facing)
+ {
+ case 0:
+ unitdef->xsize=unitdef->rxsize;
+ unitdef->ysize=unitdef->rysize;
+ unitdef->yardmap=unitdef->yardmap1;
+ break;
+ case 1:
+ unitdef->xsize=unitdef->rysize;
+ unitdef->ysize=unitdef->rxsize;
+ unitdef->yardmap=unitdef->yardmap2;
+ break;
+ case 2:
+ unitdef->xsize=unitdef->rxsize;
+ unitdef->ysize=unitdef->rysize;
+ unitdef->yardmap=unitdef->yardmap3;
+ break;
+ case 3:
+ unitdef->xsize=unitdef->rysize;
+ unitdef->ysize=unitdef->rxsize;
+ unitdef->yardmap=unitdef->yardmap4;
+ break;
+ default:
+ unitdef->xsize=unitdef->rxsize;
+ unitdef->ysize=unitdef->rysize;
+ unitdef->yardmap=unitdef->yardmap1;
+ }
float xsize=unitdef->xsize*4;
float ysize=unitdef->ysize*4;
Index: C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.h
===================================================================
--- C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.h (revision 1511)
+++ C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.h (working copy)
@@ -27,6 +27,7 @@
map<int,string> buildOptions;
bool building;
float3 buildPos;
+ int buildFacing;
float cachedRadius;
int cachedRadiusId;
Index: C:/Springproject/rts/Sim/Units/Unit.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/Unit.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/Unit.cpp (working copy)
@@ -367,6 +367,7 @@
if(beingBuilt){
if(lastNanoAdd<gs->frameNum-200){
+// heading=16*1024*buildFacing;
health-=maxHealth/(buildTime*0.03);
buildProgress-=1/(buildTime*0.03);
AddMetal(metalCost/(buildTime*0.03));
@@ -459,6 +460,7 @@
isCloaked=false;
}
+
if(uh->waterDamage && (physicalState==CSolidObject::Floating || (physicalState==CSolidObject::OnGround && pos.y<=-3 && readmap->halfHeightmap[int((pos.z/(SQUARE_SIZE*2))*gs->hmapx+(pos.x/(SQUARE_SIZE*2)))]<-1))){
DoDamage(DamageArray()*uh->waterDamage,0,ZeroVector);
}
@@ -618,7 +620,7 @@
{
glPushMatrix();
float3 interPos=pos+speed*gu->timeOffset;
-
+
if (physicalState == Flying && unitDef->canmove) {
//aircraft or skidding ground unit
CMatrix44f transMatrix(interPos,-rightdir,updir,frontdir);
@@ -956,7 +958,6 @@
void CUnit::Init(void)
{
relMidPos=model->relMidPos;
-
midPos=pos+frontdir*relMidPos.z + updir*relMidPos.y + rightdir*relMidPos.x;
losHeight=relMidPos.y+radius*0.5;
height = model->height; //TODO: This one would be much better to have either in Constructor or UnitLoader!//why this is always called in unitloader
Index: C:/Springproject/rts/Sim/Units/UnitDef.h
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitDef.h (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitDef.h (working copy)
@@ -162,9 +162,15 @@
MoveData* movedata;
// unsigned char* yardmapLevels[6];
unsigned char* yardmap; //Used for open ground blocking maps.
-
+ unsigned char* yardmap1; //Iterations of the Ymap for building rotation
+ unsigned char* yardmap2;
+ unsigned char* yardmap3;
+ unsigned char* yardmap4;
+
int xsize; //each size is 8 units
int ysize; //each size is 8 units
+ int rxsize; //real sizes of the unit for building rotation thing
+ int rysize;
float loadingRadius; //for transports
int transportCapacity;
Index: C:/Springproject/rts/Sim/Units/UnitDefHandler.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitDefHandler.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitDefHandler.cpp (working copy)
@@ -73,6 +73,12 @@
unitDefs[i].filename = tafiles[a];
unitDefs[i].id = i;
unitDefs[i].yardmap = 0;
+ unitDefs[i].yardmap1 = 0;
+ unitDefs[i].yardmap2 = 0;
+ unitDefs[i].yardmap3 = 0;
+ unitDefs[i].yardmap4 = 0;
+ unitDefs[i].rxsize = 1;
+ unitDefs[i].rysize = 1;
unitDefs[i].name = unitname;
unitDefs[i].unitimage = 0;
unitID[unitname] = i;
@@ -466,6 +472,9 @@
ud.xsize=atoi(tdfparser.SGetValueDef("1", "UNITINFO\\FootprintX").c_str())*2;//ta has only half our res so multiply size with 2
ud.ysize=atoi(tdfparser.SGetValueDef("1", "UNITINFO\\FootprintZ").c_str())*2;
+ ud.rxsize=ud.xsize;
+ ud.rysize=ud.ysize;
+
ud.needGeo=false;
if(ud.type=="Building" || ud.type=="Factory"){
CreateYardMap(&ud, tdfparser.SGetValueDef("c", "UNITINFO\\YardMap"));
@@ -587,6 +596,14 @@
//Creates the map.
def->yardmap = new unsigned char[def->xsize * def->ysize];
memset(def->yardmap, 1, def->xsize * def->ysize); //Q: Needed?
+ def->yardmap1 = new unsigned char[def->xsize * def->ysize];
+ memset(def->yardmap1, 1, def->xsize * def->ysize); //Q: Needed?
+ def->yardmap2 = new unsigned char[def->xsize * def->ysize];
+ memset(def->yardmap2, 1, def->xsize * def->ysize); //Q: Needed?
+ def->yardmap3 = new unsigned char[def->xsize * def->ysize];
+ memset(def->yardmap3, 1, def->xsize * def->ysize); //Q: Needed?
+ def->yardmap4 = new unsigned char[def->xsize * def->ysize];
+ memset(def->yardmap4, 1, def->xsize * def->ysize); //Q: Needed?
unsigned char *originalMap = new unsigned char[def->xsize * def->ysize / 4]; //TAS resolution is double of TA resolution.
memset(originalMap, 1, def->xsize * def->ysize / 4);
@@ -611,9 +628,13 @@
}
}
for(int y = 0; y < def->ysize; y++)
- for(int x = 0; x < def->xsize; x++)
+ for(int x = 0; x < def->xsize; x++){
def->yardmap[x + y*def->xsize] = originalMap[x/2 + y/2*def->xsize/2];
-
+ def->yardmap1[x + y*def->xsize] = originalMap[x/2 + y/2*def->xsize/2];
+ def->yardmap4[def->ysize*(x+1)-(y+1)] = originalMap[x/2 + y/2*def->xsize/2];
+ def->yardmap3[(def->ysize*def->xsize)-(x + y*def->xsize+1)] = originalMap[x/2 + y/2*def->xsize/2];
+ def->yardmap2[(def->ysize*def->xsize)-(def->ysize*(x+1)-(y+1)+1)] = originalMap[x/2 + y/2*def->xsize/2];
+ }
delete[] originalMap;
}
Index: C:/Springproject/rts/Sim/Units/UnitHandler.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitHandler.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitHandler.cpp (working copy)
@@ -224,11 +224,14 @@
int numBorder=0;
float borderh=0;
+ int xsize=1;
+ int ysize=1;
+
float maxDif=unitdef->maxHeightDif;
- int x1 = (int)max(0.f,(pos.x-(unitdef->xsize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
- int x2 = min(gs->mapx,x1+unitdef->xsize);
- int z1 = (int)max(0.f,(pos.z-(unitdef->ysize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
- int z2 = min(gs->mapy,z1+unitdef->ysize);
+ int x1 = (int)max(0.f,(pos.x-(xsize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
+ int x2 = min(gs->mapx,x1+xsize);
+ int z1 = (int)max(0.f,(pos.z-(ysize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
+ int z2 = min(gs->mapy,z1+ysize);
if (x1 > gs->mapx) x1 = gs->mapx;
if (x2 < 0) x2 = 0;
@@ -259,20 +262,43 @@
return h;
}
-int CUnitHandler::TestUnitBuildSquare(const float3& pos, std::string unit,CFeature *&feature)
+int CUnitHandler::TestUnitBuildSquare(const float3& pos, std::string unit,CFeature *&feature, int facing)
{
UnitDef *unitdef = unitDefHandler->GetUnitByName(unit);
- return TestUnitBuildSquare(pos, unitdef,feature);
+ return TestUnitBuildSquare(pos, unitdef,feature, facing);
}
-int CUnitHandler::TestUnitBuildSquare(const float3& pos, const UnitDef *unitdef,CFeature *&feature)
+int CUnitHandler::TestUnitBuildSquare(const float3& pos, const UnitDef *unitdef, CFeature *&feature, int facing)
{
feature=0;
+ int xsize=1;
+ int ysize=1;
+ switch(facing){
+ case 0:
+ xsize=unitdef->rxsize;
+ ysize=unitdef->rysize;
+ break;
+ case 1:
+ xsize=unitdef->rysize;
+ ysize=unitdef->rxsize;
+ break;
+ case 2:
+ xsize=unitdef->rxsize;
+ ysize=unitdef->rysize;
+ break;
+ case 3:
+ ysize=unitdef->rxsize;
+ xsize=unitdef->rysize;
+ break;
+ default:
+ xsize=unitdef->rxsize;
+ ysize=unitdef->rysize;
+ break;}
- int x1 = (int) (pos.x-(unitdef->xsize*0.5f*SQUARE_SIZE));
- int x2 = x1+unitdef->xsize*SQUARE_SIZE;
- int z1 = (int) (pos.z-(unitdef->ysize*0.5f*SQUARE_SIZE));
- int z2 = z1+unitdef->ysize*SQUARE_SIZE;
+ int x1 = (int) (pos.x-(xsize*0.5f*SQUARE_SIZE));
+ int x2 = x1+xsize*SQUARE_SIZE;
+ int z1 = (int) (pos.z-(ysize*0.5f*SQUARE_SIZE));
+ int z2 = z1+ysize*SQUARE_SIZE;
float h=GetBuildHeight(pos,unitdef);
int canBuild=2;
@@ -279,10 +305,10 @@
if(unitdef->needGeo){
canBuild=0;
- std::vector<CFeature*> features=qf->GetFeaturesExact(pos,max(unitdef->xsize,unitdef->ysize)*6);
+ std::vector<CFeature*> features=qf->GetFeaturesExact(pos,max(xsize,ysize)*6);
for(std::vector<CFeature*>::iterator fi=features.begin();fi!=features.end();++fi){
- if((*fi)->def->geoThermal && fabs((*fi)->pos.x-pos.x)<unitdef->xsize*4-4 && fabs((*fi)->pos.z-pos.z)<unitdef->ysize*4-4){
+ if((*fi)->def->geoThermal && fabs((*fi)->pos.x-pos.x)<xsize*4-4 && fabs((*fi)->pos.z-pos.z)<ysize*4-4){
canBuild=2;
break;
}
@@ -345,12 +371,12 @@
return ret;
}
-int CUnitHandler::ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef)
+int CUnitHandler::ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef, int facing)
{
- return ShowUnitBuildSquare(pos, unitdef, std::vector<Command>());
+ return ShowUnitBuildSquare(pos, unitdef, std::vector<Command>(),facing);
}
-int CUnitHandler::ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef, const std::vector<Command> &cv)
+int CUnitHandler::ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef, const std::vector<Command> &cv, int facing)
{
glDisable(GL_DEPTH_TEST );
glEnable(GL_BLEND);
@@ -358,11 +384,35 @@
glDisable(GL_TEXTURE_2D);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_QUADS);
+ int xsize=1;
+ int ysize=1;
- int x1 = (int) (pos.x-(unitdef->xsize*0.5f*SQUARE_SIZE));
- int x2 = x1+unitdef->xsize*SQUARE_SIZE;
- int z1 = (int) (pos.z-(unitdef->ysize*0.5f*SQUARE_SIZE));
- int z2 = z1+unitdef->ysize*SQUARE_SIZE;
+ switch(facing){
+ case 0:
+ xsize=unitdef->rxsize;
+ ysize=unitdef->rysize;
+ break;
+ case 1:
+ xsize=unitdef->rysize;
+ ysize=unitdef->rxsize;
+ break;
+ case 2:
+ xsize=unitdef->rxsize;
+ ysize=unitdef->rysize;
+ break;
+ case 3:
+ ysize=unitdef->rxsize;
+ xsize=unitdef->rysize;
+ break;
+ default:
+ xsize=unitdef->rxsize;
+ ysize=unitdef->rysize;
+ break;}
+
+ int x1 = (int) (pos.x-(xsize*0.5f*SQUARE_SIZE));
+ int x2 = x1+xsize*SQUARE_SIZE;
+ int z1 = (int) (pos.z-(ysize*0.5f*SQUARE_SIZE));
+ int z2 = z1+ysize*SQUARE_SIZE;
float h=GetBuildHeight(pos,unitdef);
int canbuild=2;
@@ -369,10 +419,10 @@
if(unitdef->needGeo){
canbuild=0;
- std::vector<CFeature*> features=qf->GetFeaturesExact(pos,max(unitdef->xsize,unitdef->ysize)*6);
+ std::vector<CFeature*> features=qf->GetFeaturesExact(pos,max(xsize,ysize)*6);
for(std::vector<CFeature*>::iterator fi=features.begin();fi!=features.end();++fi){
- if((*fi)->def->geoThermal && fabs((*fi)->pos.x-pos.x)<unitdef->xsize*4-4 && fabs((*fi)->pos.z-pos.z)<unitdef->ysize*4-4){
+ if((*fi)->def->geoThermal && fabs((*fi)->pos.x-pos.x)<xsize*4-4 && fabs((*fi)->pos.z-pos.z)<ysize*4-4){
canbuild=2;
break;
}
Index: C:/Springproject/rts/Sim/Units/UnitHandler.h
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitHandler.h (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitHandler.h (working copy)
@@ -49,10 +49,10 @@
//0 blocked
//1 mobile unit in the way
//2 free (or if feature is != 0 then with a blocking feature that can be reclaimed)
- 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 TestUnitBuildSquare(const float3& pos, const UnitDef *unitdef,CFeature *&feature, int facing=0); //test if a unit can be built at specified position
+ int TestUnitBuildSquare(const float3& pos, std::string unit,CFeature *&feature, int facing=0); //test if a unit can be built at specified position
+ int ShowUnitBuildSquare(const float3& pos, const UnitDef *unitdef, int facing=0); //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 facing=0);
int TestBuildSquare(const float3& pos, const UnitDef *unitdef,CFeature *&feature); //test a singel mapsquare for build possibility
void AddBuilderCAI(CBuilderCAI*);
Index: C:/Springproject/rts/Sim/Units/UnitLoader.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitLoader.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitLoader.cpp (working copy)
@@ -62,7 +62,7 @@
{
}
-CUnit* CUnitLoader::LoadUnit(const string& name, float3 pos, int side, bool build)
+CUnit* CUnitLoader::LoadUnit(const string& name, float3 pos, int side, bool build, int facing)
{
CUnit* unit;
START_TIME_PROFILE;
@@ -112,6 +112,34 @@
unit->UnitInit (ud, side, pos);
unit->beingBuilt=build;
+
+ switch(facing){
+ case 0:
+ unit->yardMap=ud->yardmap1;
+ unit->xsize=ud->rxsize;
+ unit->ysize=ud->rysize;
+ break;
+ case 1:
+ unit->yardMap=ud->yardmap2;
+ unit->xsize=ud->rysize;
+ unit->ysize=ud->rxsize;
+ break;
+ case 2:
+ unit->yardMap=ud->yardmap3;
+ unit->xsize=ud->rxsize;
+ unit->ysize=ud->rysize;
+ break;
+ case 3:
+ unit->yardMap=ud->yardmap4;
+ unit->xsize=ud->rysize;
+ unit->ysize=ud->rxsize;
+ break;
+ default:
+ unit->yardMap=ud->yardmap1;
+ unit->xsize=ud->rxsize;
+ unit->ysize=ud->rysize;
+ }
+ unit->buildFacing=facing;
unit->power=ud->power;
unit->maxHealth=ud->health;
unit->health=ud->health;
@@ -129,8 +157,6 @@
unit->realLosRadius=(int) (ud->losRadius/(SQUARE_SIZE*2));
unit->realAirLosRadius=(int) (ud->airLosRadius/(SQUARE_SIZE*4));
unit->upright=ud->upright;
- unit->xsize=ud->xsize;
- unit->ysize=ud->ysize;
unit->radarRadius=ud->radarRadius/(SQUARE_SIZE*8);
unit->sonarRadius=ud->sonarRadius/(SQUARE_SIZE*8);
unit->jammerRadius=ud->jammerRadius/(SQUARE_SIZE*8);
@@ -298,7 +324,8 @@
unit->cob->Call("SetMaxReloadTime", relMax);
unit->Init();
-
+ if(facing)
+ unit->heading=facing*16*1024;
if(!build)
unit->FinishedBuilding();
Index: C:/Springproject/rts/Sim/Units/UnitLoader.h
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitLoader.h (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitLoader.h (working copy)
@@ -16,7 +16,7 @@
class CUnitLoader
{
public:
- CUnit* LoadUnit(const string& name,float3 pos, int side, bool build=true);
+ CUnit* LoadUnit(const string& name,float3 pos, int side, bool build=true, int facing=0);
CUnitLoader();
virtual ~CUnitLoader();
Index: C:/Springproject/rts/Sim/Units/UnitTypes/Builder.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitTypes/Builder.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitTypes/Builder.cpp (working copy)
@@ -200,7 +200,7 @@
}
if(curResurrect->resurrectProgress>1){ //resurrect finished
curResurrect->UnBlock();
- CUnit* u=unitLoader.LoadUnit(curResurrect->createdFromUnit,curResurrect->pos,team,false);
+ CUnit* u=unitLoader.LoadUnit(curResurrect->createdFromUnit,curResurrect->pos,team,false,0);
u->health*=0.05;
lastResurrected=u->id;
curResurrect->resurrectProgress=0;
@@ -345,7 +345,7 @@
// info->AddLine("stop build");
}
-bool CBuilder::StartBuild(const string &type, float3 &buildPos)
+bool CBuilder::StartBuild(const string &type, float3 &buildPos, int facing)
{
StopBuild(false);
// info->AddLine("start build");
@@ -354,7 +354,7 @@
buildPos=helper->Pos2BuildPos(buildPos,unitdef);
CFeature* feature;
- int canBuild=uh->TestUnitBuildSquare(buildPos,unitdef,feature);
+ int canBuild=uh->TestUnitBuildSquare(buildPos,unitdef,feature, facing);
if(canBuild<2){
CUnit* u=helper->GetClosestFriendlyUnit(buildPos,5,allyteam);
if(u && u->unitDef==unitdef){
@@ -373,7 +373,7 @@
terraformLeft=0;
}
else {
- CalculateBuildTerraformCost(buildPos, unitdef);
+ CalculateBuildTerraformCost(buildPos, unitdef, facing);
terraforming=true;
terraformType=Terraform_Building;
@@ -386,7 +386,7 @@
nextBuildType=type;
nextBuildPos=buildPos;
- CUnit* b=unitLoader.LoadUnit(nextBuildType,nextBuildPos,team,true);
+ CUnit* b=unitLoader.LoadUnit(nextBuildType,nextBuildPos,team,true, facing);
AddDeathDependence(b);
curBuild=b;
if (mapDamage->disabled && !(curBuild->floatOnWater)) {
@@ -413,8 +413,10 @@
return true;
}
-void CBuilder::CalculateBuildTerraformCost(float3 buildPos, UnitDef * unitdef)
+void CBuilder::CalculateBuildTerraformCost(float3 buildPos, UnitDef * unitdef, int facing)
{
+
+
tx1 = (int)max((float)0,(buildPos.x-(unitdef->xsize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
tx2 = min(gs->mapx,tx1+unitdef->xsize);
tz1 = (int)max((float)0,(buildPos.z-(unitdef->ysize*0.5f*SQUARE_SIZE))/SQUARE_SIZE);
Index: C:/Springproject/rts/Sim/Units/UnitTypes/Builder.h
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitTypes/Builder.h (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitTypes/Builder.h (working copy)
@@ -23,8 +23,8 @@
void SlowUpdate(void);
void DependentDied(CObject* o);
- bool StartBuild(const string& type,float3& pos);
- void CalculateBuildTerraformCost(float3 buildPos, UnitDef * unitdef);
+ bool StartBuild(const string& type,float3& pos, int facing);
+ void CalculateBuildTerraformCost(float3 buildPos, UnitDef * unitdef, int facing);
void StopBuild(bool callScript=true);
void SetRepairTarget(CUnit* target);
void SetReclaimTarget(CSolidObject* object);
Index: C:/Springproject/rts/Sim/Units/UnitTypes/Building.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitTypes/Building.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitTypes/Building.cpp (working copy)
@@ -37,6 +37,7 @@
gb->pos=pos;
gb->model=model;
gb->decal=buildingDecal;
+ gb->facing=buildFacing;
unitDrawer->ghostBuildings.push_back(gb);
mygb=gb;
}
Index: C:/Springproject/rts/Sim/Units/UnitTypes/Factory.cpp
===================================================================
--- C:/Springproject/rts/Sim/Units/UnitTypes/Factory.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/UnitTypes/Factory.cpp (working copy)
@@ -79,7 +79,7 @@
}
if(canBuild){
quedBuild=false;
- CUnit* b=unitLoader.LoadUnit(nextBuild,buildPos+float3(0.01,0.01,0.01),team,true);
+ CUnit* b=unitLoader.LoadUnit(nextBuild,buildPos+float3(0.01,0.01,0.01),team,true,0);
AddDeathDependence(b);
curBuild=b;
@@ -174,7 +174,7 @@
if(!opening){
cob->Call(COBFN_Activate);
- readmap->OpenBlockingYard(this, unitDef->yardmap);
+ readmap->OpenBlockingYard(this, this->yardMap);
opening=true;
}
}
Index: C:/Springproject/rts/build/vstudio7/rts.vcproj
===================================================================
--- C:/Springproject/rts/build/vstudio7/rts.vcproj (revision 1511)
+++ C:/Springproject/rts/build/vstudio7/rts.vcproj (working copy)
@@ -2246,6 +2246,12 @@
RelativePath="..\..\System\FileSystem\ArchiveBuffered.h">
</File>
<File
+ RelativePath="..\..\System\FileSystem\ArchiveDir.cpp">
+ </File>
+ <File
+ RelativePath="..\..\System\FileSystem\ArchiveDir.h">
+ </File>
+ <File
RelativePath="..\..\System\FileSystem\ArchiveFactory.cpp">
</File>
<File
And you might be able to get the exe from http://edf.tauniverse.com/spring.exe, but only when the server no longer thinks it's exceeding the limit.
Comp1337: I might let buildAngle actually have an effect.
- Guessmyname
- Posts: 3301
- Joined: 28 Apr 2005, 21:07
Ok a couple of remarks:
- It seems you kindof hacked it in by modifying UnitDef::xsize and UnitDef::ysize when they are needed. This is not a clean solution. The unitdef shouldn't contain any temporary data. Better add things in a clean way directly. A proper solution for this is more work, but since you've already got a working version it shouldn't be that far away.
- As a more general idea, I think what spring needs is the concept of build information that is not part of the UnitDef itself. Right now this would only be buildFacing, but it might be more in the future. So you could solve it by passing around some BuildInfo structure that has xsize, ysize and buildFacing, instead of passing around the buildFacing setting.
Doesn't have to be exactly like this, as long as the idea is supported.
- Do rotated features work too? (For the destroyed rotated buildings)
- In builderCAI.cpp,
should probably be
The extra parameters for passing buildfacing must be optional, otherwise you'll break the AIs.
Other than that the code looks ok.
Also about the patch itself:
- The patch should have relative filenames, not absolute ones
- Be sure to upload the final patch it to a text file somewhere because the forum breaks lines.
- It seems you kindof hacked it in by modifying UnitDef::xsize and UnitDef::ysize when they are needed. This is not a clean solution. The unitdef shouldn't contain any temporary data. Better add things in a clean way directly. A proper solution for this is more work, but since you've already got a working version it shouldn't be that far away.
- As a more general idea, I think what spring needs is the concept of build information that is not part of the UnitDef itself. Right now this would only be buildFacing, but it might be more in the future. So you could solve it by passing around some BuildInfo structure that has xsize, ysize and buildFacing, instead of passing around the buildFacing setting.
Code: Select all
struct BuildInfo {
UnitDef* def;
int xsize, ysize, buildFacing;
};
- Do rotated features work too? (For the destroyed rotated buildings)
- In builderCAI.cpp,
Code: Select all
if(c.params[3])
buildFacing=c.params[3];
Code: Select all
if(c.params.size()==4)
buildFacing=c.params[3];
Other than that the code looks ok.
Also about the patch itself:
- The patch should have relative filenames, not absolute ones
- Be sure to upload the final patch it to a text file somewhere because the forum breaks lines.
Last edited by jcnossen on 25 Jun 2006, 23:41, edited 2 times in total.
good job man
also, could you add a "default orientatio" ?
for those who plan on N vs S maps, they may not want to bother rotating buildings every time they place one
tho, i havent try it so maybe you did it already .. or keep last orientation is ram
btw, if you wanna play with others, won't that cause unsync if everybody isn't using same exe ?
also, could you add a "default orientatio" ?
for those who plan on N vs S maps, they may not want to bother rotating buildings every time they place one
tho, i havent try it so maybe you did it already .. or keep last orientation is ram
btw, if you wanna play with others, won't that cause unsync if everybody isn't using same exe ?
Very nice!
I know that minor features like this aren't as ultra-sexy as some of the things we have in Spring from the lead devs, but between you and ColorBlind, maybe we can get the "little stuff" done now that really seperates Spring from a truely polished gaming experience. Between the nice new explosions (I'm having waaaay too much fun with, btw) and everything else that's coming down the pipe, I am happy as a clam these days- now, if only I could get the latest version of NanoBlobs polished up enough to release...
I know that minor features like this aren't as ultra-sexy as some of the things we have in Spring from the lead devs, but between you and ColorBlind, maybe we can get the "little stuff" done now that really seperates Spring from a truely polished gaming experience. Between the nice new explosions (I'm having waaaay too much fun with, btw) and everything else that's coming down the pipe, I am happy as a clam these days- now, if only I could get the latest version of NanoBlobs polished up enough to release...
Some more comments on your patch:
Shouldn't the upper line be changed to if (c.params.size() < 4)? Or implement a separate check before assigning buildFacing (the fixed way as JC pointed out). Now it seems a bit inconsistent throughout the patch that sometimes you just assume c.params[3] is available, sometimes you check it is and default to 0, and other times you forget to check at all. (I could be a bit misguided because diffs only have 6 lines context per change tho, but check it )
Also you can eliminate/merge the switches by doing what JC says.
For the rest it looks good. Good work!
Code: Select all
--- C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.cpp (revision 1511)
+++ C:/Springproject/rts/Sim/Units/CommandAI/BuilderCAI.cpp (working copy)
@@ -727,10 +732,11 @@
if(c.params.size()<3)
return;
float3 pos(c.params[0],c.params[1],c.params[2]);
+ buildFacing=c.params[3];
UnitDef *unitdef = unitDefHandler->GetUnitByName(boi->second);
pos=helper->Pos2BuildPos(pos,unitdef);
CFeature* feature;
- if(!uh->TestUnitBuildSquare(pos,unitdef,feature)){
+ if(!uh->TestUnitBuildSquare(pos,unitdef,feature,buildFacing)){
return;
}
}
Also you can eliminate/merge the switches by doing what JC says.
For the rest it looks good. Good work!
-
- Posts: 578
- Joined: 19 Aug 2004, 17:38
I don't know, but I think I made it that way because AIs can't currently send build orders with 4 parameters, and checking for 4 will break them. Or maybe I just forgot.. Speaking of which, still haven't tested it with an AI...
And just to clarify, JC, what was that you wanted me to do with buildFacing? Replace it with a buildInfo struct read from the same unitDef? Or what?
And just to clarify, JC, what was that you wanted me to do with buildFacing? Replace it with a buildInfo struct read from the same unitDef? Or what?