void CBuilder::CalculateBuildTerraformCost(BuildInfo& buildInfo) { float3& buildPos=buildInfo.pos; const UnitDef *unitdef=buildInfo.def; tx1 = (int)max((float)0,(buildPos.x-(buildInfo.GetXSize()*0.5f*SQUARE_SIZE))/SQUARE_SIZE); tx2 = min(gs->mapx,tx1+buildInfo.GetXSize()); tz1 = (int)max((float)0,(buildPos.z-(buildInfo.GetYSize()*0.5f*SQUARE_SIZE))/SQUARE_SIZE); tz2 = min(gs->mapy,tz1+buildInfo.GetYSize()); float tcost=0; float* heightmap = readmap->GetHeightmap(); for(int z=tz1; z<=tz2; z++){ for(int x=tx1; x<=tx2; x++){ float delta=buildPos.y-heightmap[z*(gs->mapx+1)+x]; float cost; if(delta>0){ cost=max(3.f,heightmap[z*(gs->mapx+1)+x]-readmap->orgheightmap[z*(gs->mapx+1)+x]+delta*0.5f); } else { cost=max(3.f,readmap->orgheightmap[z*(gs->mapx+1)+x]-heightmap[z*(gs->mapx+1)+x]-delta*0.5f); } tcost+=fabs(delta)*cost; } } terraformLeft=tcost; }
std::vector<Command> CCommandAI::GetOverlapQueued(const Command &c, CCommandQueue& q) { CCommandQueue::iterator ci = q.end(); std::vector<Command> v; BuildInfo cbi(c); if (ci != q.begin()){ do { ci--; //iterate from the end and dont check the current order const Command& t = *ci; if (((t.id == c.id) || ((c.id < 0) && (t.id < 0))) && (t.params.size() == c.params.size())){ if (c.params.size()==1) { // assume the param is a unit or feature id if (t.params[0] == c.params[0]) { v.push_back(t); } } else if (c.params.size() >= 3) { // assume this means that the first 3 makes a position BuildInfo tbi; if (tbi.Parse(t)) { const float dist2X = 2.0f * fabs(cbi.pos.x - tbi.pos.x); const float dist2Z = 2.0f * fabs(cbi.pos.z - tbi.pos.z); const float addSizeX = SQUARE_SIZE * (cbi.GetXSize() + tbi.GetXSize()); const float addSizeZ = SQUARE_SIZE * (cbi.GetYSize() + tbi.GetYSize()); const float maxSizeX = SQUARE_SIZE * max(cbi.GetXSize(), tbi.GetXSize()); const float maxSizeZ = SQUARE_SIZE * max(cbi.GetYSize(), tbi.GetYSize()); if (cbi.def && tbi.def && ((dist2X > maxSizeX) || (dist2Z > maxSizeZ)) && ((dist2X < addSizeX) && (dist2Z < addSizeZ))) { v.push_back(t); } } else { if ((cbi.pos - tbi.pos).SqLength2D() < (17.0f * 17.0f)) { v.push_back(t); } } } } } while (ci != q.begin()); } return v; }
/** * @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; BuildInfo buildInfo(c); 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 or 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 { BuildInfo other; if(other.Parse(*ci)){ if(buildInfo.def && other.def && (fabs(buildInfo.pos.x-other.pos.x)*2 > max(buildInfo.GetXSize(), other.GetXSize())*SQUARE_SIZE || fabs(buildInfo.pos.z-other.pos.z)*2 > max(buildInfo.GetYSize(), other.GetYSize())*SQUARE_SIZE) && fabs(buildInfo.pos.x-other.pos.x)*2 < (buildInfo.GetXSize() + other.GetXSize())*SQUARE_SIZE && fabs(buildInfo.pos.z-other.pos.z)*2 < (buildInfo.GetYSize() + other.GetYSize())*SQUARE_SIZE) { v.push_back(*ci); } } else { if((buildInfo.pos-other.pos).SqLength2D()<17*17) v.push_back(*ci); } } } }while(ci!=commandQue.begin()); } return v; }
float3 CGameHelper::Pos2BuildPos(const BuildInfo& buildInfo) { float3 pos; if(buildInfo.GetXSize()&2) pos.x=floor((buildInfo.pos.x)/(SQUARE_SIZE*2))*SQUARE_SIZE*2+8; else pos.x=floor((buildInfo.pos.x+8)/(SQUARE_SIZE*2))*SQUARE_SIZE*2; if(buildInfo.GetYSize()&2) pos.z=floor((buildInfo.pos.z)/(SQUARE_SIZE*2))*SQUARE_SIZE*2+8; else pos.z=floor((buildInfo.pos.z+8)/(SQUARE_SIZE*2))*SQUARE_SIZE*2; pos.y=uh->GetBuildHeight(pos,buildInfo.def); if(buildInfo.def->floater && pos.y<0) pos.y = -buildInfo.def->waterline; return pos; }
int CUnitHandler::TestUnitBuildSquare(const BuildInfo& buildInfo, CFeature *&feature, int allyteam) { feature = NULL; int xsize = buildInfo.GetXSize(); int ysize = buildInfo.GetYSize(); float3 pos = buildInfo.pos; 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,buildInfo.def); int canBuild = 2; if (buildInfo.def->needGeo) { canBuild = 0; 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) < (xsize * 4 - 4) && fabs((*fi)->pos.z - pos.z) < (ysize * 4 - 4)){ canBuild = 2; break; } } } for (int x = x1; x < x2; x += SQUARE_SIZE) { for (int z = z1; z < z2; z += SQUARE_SIZE) { int tbs = TestBuildSquare(float3(x, h, z), buildInfo.def, feature, allyteam); canBuild = min(canBuild, tbs); if (canBuild == 0) { return 0; } } } return canBuild; }
int CUnitHandler::ShowUnitBuildSquare(const BuildInfo& buildInfo, const std::vector<Command> &cv) { glDisable(GL_DEPTH_TEST ); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); glDisable(GL_TEXTURE_2D); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glBegin(GL_QUADS); int xsize=buildInfo.GetXSize(); int ysize=buildInfo.GetYSize(); const float3& pos = buildInfo.pos; 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,buildInfo.def); int canbuild=2; if(buildInfo.def->needGeo) { canbuild=0; 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)<xsize*4-4 && fabs((*fi)->pos.z-pos.z)<ysize*4-4){ canbuild=2; break; } } } std::vector<float3> canbuildpos; std::vector<float3> featurepos; std::vector<float3> nobuildpos; for(int x=x1; x<x2; x+=SQUARE_SIZE){ for(int z=z1; z<z2; z+=SQUARE_SIZE){ CFeature* feature=0; int tbs=TestBuildSquare(float3(x,pos.y,z),buildInfo.def,feature,gu->myAllyTeam); if(tbs){ std::vector<Command>::const_iterator ci = cv.begin(); for(;ci != cv.end() && tbs; ci++){ BuildInfo bc(*ci); if(max(bc.pos.x-x-SQUARE_SIZE,x-bc.pos.x)*2 < bc.GetXSize()*SQUARE_SIZE && max(bc.pos.z-z-SQUARE_SIZE,z-bc.pos.z)*2 < bc.GetYSize()*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)); canbuild=min(canbuild,tbs); } else { nobuildpos.push_back(float3(x,h,z)); //glColor4f(0.8f,0.0f,0,0.4f); canbuild = 0; } } } if(canbuild) glColor4f(0,0.8f,0,1.0f); else glColor4f(0.5f,0.5f,0,1.0f); for(unsigned int i=0; i<canbuildpos.size(); i++) { glVertexf3(canbuildpos[i]); glVertexf3(canbuildpos[i]+float3(SQUARE_SIZE,0,0)); glVertexf3(canbuildpos[i]+float3(SQUARE_SIZE,0,SQUARE_SIZE)); glVertexf3(canbuildpos[i]+float3(0,0,SQUARE_SIZE)); } glColor4f(0.5f,0.5f,0,1.0f); for(unsigned int i=0; i<featurepos.size(); i++) { glVertexf3(featurepos[i]); glVertexf3(featurepos[i]+float3(SQUARE_SIZE,0,0)); glVertexf3(featurepos[i]+float3(SQUARE_SIZE,0,SQUARE_SIZE)); glVertexf3(featurepos[i]+float3(0,0,SQUARE_SIZE)); } glColor4f(0.8f,0.0f,0,1.0f); for(unsigned int i=0; i<nobuildpos.size(); i++) { glVertexf3(nobuildpos[i]); glVertexf3(nobuildpos[i]+float3(SQUARE_SIZE,0,0)); glVertexf3(nobuildpos[i]+float3(SQUARE_SIZE,0,SQUARE_SIZE)); glVertexf3(nobuildpos[i]+float3(0,0,SQUARE_SIZE)); } glEnd(); if (h < 0.0f) { const float s[4] = { 0.0f, 0.0f, 1.0f, 0.5f }; // start color const float e[4] = { 0.0f, 0.5f, 1.0f, 1.0f }; // end color glBegin(GL_LINES); glColor4fv(s); glVertex3f(x1, h, z1); glColor4fv(e); glVertex3f(x1, 0.0f, z1); glColor4fv(s); glVertex3f(x2, h, z1); glColor4fv(e); glVertex3f(x2, 0.0f, z1); glColor4fv(s); glVertex3f(x1, h, z2); glColor4fv(e); glVertex3f(x1, 0.0f, z2); glColor4fv(s); glVertex3f(x2, h, z2); glColor4fv(e); glVertex3f(x2, 0.0f, z2); glEnd(); // using the last end color glBegin(GL_LINE_LOOP); glVertex3f(x1, 0.0f, z1); glVertex3f(x1, 0.0f, z2); glVertex3f(x2, 0.0f, z2); glVertex3f(x2, 0.0f, z1); glEnd(); } glEnable(GL_DEPTH_TEST ); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //glDisable(GL_BLEND); return canbuild; }