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.GetZSize() + tbi.GetZSize()); const float maxSizeX = SQUARE_SIZE * std::max(cbi.GetXSize(), tbi.GetXSize()); const float maxSizeZ = SQUARE_SIZE * std::max(cbi.GetZSize(), tbi.GetZSize()); 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; }
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.GetZSize() & 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; }
float3 CGameHelper::Pos2BuildPos(const BuildInfo& buildInfo, bool synced) { float3 pos; if (buildInfo.GetXSize() & 2) pos.x = math::floor((buildInfo.pos.x ) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2 + SQUARE_SIZE; else pos.x = math::floor((buildInfo.pos.x + SQUARE_SIZE) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2; if (buildInfo.GetZSize() & 2) pos.z = math::floor((buildInfo.pos.z ) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2 + SQUARE_SIZE; else pos.z = math::floor((buildInfo.pos.z + SQUARE_SIZE) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2; const UnitDef* ud = buildInfo.def; pos.y = CGameHelper::GetBuildHeight(pos, ud, synced); return pos; }
int CUnitHandler::TestUnitBuildSquare(const BuildInfo& buildInfo, CFeature *&feature, int allyteam) { feature = NULL; int xsize = buildInfo.GetXSize(); int zsize = buildInfo.GetZSize(); 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 - (zsize * 0.5f * SQUARE_SIZE)); int z2 = z1 + zsize * 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,zsize)*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) < (zsize * 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; }
void LSCompiler::generateRootDependenciesRecursive(const utString& ref) { // We're either going to be compiling against an existing loom assembly // or compiling from a build file char cref[2048]; snprintf(cref, 2048, "%s", ref.c_str()); if (strstr(cref, ".loomlib")) { *(strstr(cref, ".loomlib")) = 0; } for (UTsize i = 0; i < rootBuildDependencies.size(); i++) { BuildInfo *buildInfo = rootBuildDependencies.at(i); if (buildInfo->getAssemblyName() == cref) { return; } } // first look in the src folders for an existing build file BuildInfo *buildInfo = loadBuildFile(cref); if (buildInfo) { utString assemblyLib = buildInfo->getOutputDir() + platform_getFolderDelimiter() + buildInfo->getAssemblyName() + ".loomlib"; // If the assembly is not built yet, build it if (!platform_mapFileExists(assemblyLib.c_str())) { for (UTsize i = 0; i < buildInfo->getNumReferences(); i++) { utString rref = buildInfo->getReference(i); generateRootDependenciesRecursive(rref); } rootBuildDependencies.push_back(buildInfo); } else { rootLibDependencies.push_back(ref); } } if (rootDependencies.find(ref) == UT_NPOS) { if (!buildInfo) { // we're compiling against a .loomlib and won't be rebuilding it rootLibDependencies.push_back(ref); } rootDependencies.push_back(ref); } }
float3 CGameHelper::Pos2BuildPos(const BuildInfo& buildInfo, bool synced) { float3 pos; if (buildInfo.GetXSize() & 2) pos.x = floor((buildInfo.pos.x ) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2 + SQUARE_SIZE; else pos.x = floor((buildInfo.pos.x + SQUARE_SIZE) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2; if (buildInfo.GetZSize() & 2) pos.z = floor((buildInfo.pos.z ) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2 + SQUARE_SIZE; else pos.z = floor((buildInfo.pos.z + SQUARE_SIZE) / (SQUARE_SIZE * 2)) * SQUARE_SIZE * 2; const UnitDef* ud = buildInfo.def; const float bh = uh->GetBuildHeight(pos, ud, synced); pos.y = bh; if (ud->floatOnWater && bh < 0.0f) pos.y = -ud->waterline; return pos; }
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.params.size() != c.params.size()) continue; if (t.GetID() == c.GetID() || (c.GetID() < 0 && t.GetID() < 0)) { 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 c and t are positional commands // NOTE: uses a BuildInfo structure, but <t> can be ANY command BuildInfo tbi; if (tbi.Parse(t)) { const float dist2X = 2.0f * math::fabs(cbi.pos.x - tbi.pos.x); const float dist2Z = 2.0f * math::fabs(cbi.pos.z - tbi.pos.z); const float addSizeX = SQUARE_SIZE * (cbi.GetXSize() + tbi.GetXSize()); const float addSizeZ = SQUARE_SIZE * (cbi.GetZSize() + tbi.GetZSize()); const float maxSizeX = SQUARE_SIZE * std::max(cbi.GetXSize(), tbi.GetXSize()); const float maxSizeZ = SQUARE_SIZE * std::max(cbi.GetZSize(), tbi.GetZSize()); if (cbi.def == NULL) continue; if (tbi.def == NULL) continue; if (((dist2X > maxSizeX) || (dist2Z > maxSizeZ)) && ((dist2X < addSizeX) && (dist2Z < addSizeZ))) { v.push_back(t); } } else { if ((cbi.pos - tbi.pos).SqLength2D() >= (COMMAND_CANCEL_DIST * COMMAND_CANCEL_DIST)) continue; if ((c.options & SHIFT_KEY) != 0 && (c.options & INTERNAL_ORDER) != 0) continue; 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; }
CGameHelper::BuildSquareStatus CGameHelper::TestUnitBuildSquare( const BuildInfo& buildInfo, CFeature*& feature, int allyteam, bool synced, std::vector<float3>* canbuildpos, std::vector<float3>* featurepos, std::vector<float3>* nobuildpos, const std::vector<Command>* commands) { feature = NULL; const int xsize = buildInfo.GetXSize(); const int zsize = buildInfo.GetZSize(); const float3 pos = buildInfo.pos; const int x1 = (pos.x - (xsize * 0.5f * SQUARE_SIZE)); const int z1 = (pos.z - (zsize * 0.5f * SQUARE_SIZE)); const int z2 = z1 + zsize * SQUARE_SIZE; const int x2 = x1 + xsize * SQUARE_SIZE; const float bh = GetBuildHeight(pos, buildInfo.def, synced); const MoveDef* moveDef = (buildInfo.def->pathType != -1U) ? moveDefHandler->GetMoveDefByPathType(buildInfo.def->pathType) : NULL; const S3DModel* model = buildInfo.def->LoadModel(); const float buildHeight = (model != NULL) ? math::fabs(model->height) : 10.0f; BuildSquareStatus canBuild = BUILDSQUARE_OPEN; if (buildInfo.def->needGeo) { canBuild = BUILDSQUARE_BLOCKED; const std::vector<CFeature*>& features = quadField->GetFeaturesExact(pos, std::max(xsize, zsize) * 6); // look for a nearby geothermal feature if we need one for (std::vector<CFeature*>::const_iterator fi = features.begin(); fi != features.end(); ++fi) { if ((*fi)->def->geoThermal && math::fabs((*fi)->pos.x - pos.x) < (xsize * 4 - 4) && math::fabs((*fi)->pos.z - pos.z) < (zsize * 4 - 4)) { canBuild = BUILDSQUARE_OPEN; break; } } } if (commands != NULL) { // this is only called in unsynced context (ShowUnitBuildSquare) assert(!synced); for (int x = x1; x < x2; x += SQUARE_SIZE) { for (int z = z1; z < z2; z += SQUARE_SIZE) { BuildSquareStatus tbs = TestBuildSquare(float3(x, bh, z), buildHeight, buildInfo.def, moveDef, feature, gu->myAllyTeam, synced); if (tbs != BUILDSQUARE_BLOCKED) { //??? what does this do? for (std::vector<Command>::const_iterator ci = commands->begin(); ci != commands->end(); ++ci) { BuildInfo bc(*ci); if (std::max(bc.pos.x - x - SQUARE_SIZE, x - bc.pos.x) * 2 < bc.GetXSize() * SQUARE_SIZE && std::max(bc.pos.z - z - SQUARE_SIZE, z - bc.pos.z) * 2 < bc.GetZSize() * SQUARE_SIZE) { tbs = BUILDSQUARE_BLOCKED; break; } } } switch (tbs) { case BUILDSQUARE_OPEN: canbuildpos->push_back(float3(x, bh, z)); break; case BUILDSQUARE_RECLAIMABLE: case BUILDSQUARE_OCCUPIED: featurepos->push_back(float3(x, bh, z)); break; case BUILDSQUARE_BLOCKED: nobuildpos->push_back(float3(x, bh, z)); break; } canBuild = std::min(canBuild, tbs); } } } else { // this can be called in either context for (int x = x1; x < x2; x += SQUARE_SIZE) { for (int z = z1; z < z2; z += SQUARE_SIZE) { canBuild = std::min(canBuild, TestBuildSquare(float3(x, bh, z), buildHeight, buildInfo.def, moveDef, feature, allyteam, synced)); if (canBuild == BUILDSQUARE_BLOCKED) { return BUILDSQUARE_BLOCKED; } } } } 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 zsize=buildInfo.GetZSize(); 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-(zsize*0.5f*SQUARE_SIZE)); int z2 = z1+zsize*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,zsize)*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)<zsize*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.GetZSize()*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; }
void LSCompiler::linkRootAssembly(const utString& sjson) { json_error_t jerror; json_t *json = json_loadb((const char *)sjson.c_str(), sjson.length(), 0, &jerror); lmAssert(json, "Error linking assembly"); json_t *ref_array = json_object_get(json, "references"); lmAssert(json, "Error linking assembly, can't get executable references"); for (UTsize i = 0; i < rootBuildDependencies.size(); i++) { BuildInfo *buildInfo = rootBuildDependencies.at(i); utString assemblySource = buildInfo->getOutputDir() + platform_getFolderDelimiter() + buildInfo->getAssemblyName() + ".loomlib"; utArray<unsigned char> rarray; lmAssert(utFileStream::tryReadToArray(assemblySource, rarray), "Unable to load library assembly %s", assemblySource.c_str()); utBase64 base64 = utBase64::encode64(rarray); for (size_t j = 0; j < json_array_size(ref_array); j++) { json_t *jref = json_array_get(ref_array, j); utString jname = json_string_value(json_object_get(jref, "name")); if (buildInfo->getAssemblyName() == jname) { logVerbose("Linking: %s", jname.c_str()); json_object_set(jref, "binary", json_string(base64.getBase64().c_str())); json_object_set(jref, "uid", json_string(readAssemblyUID(rarray))); break; } } } // filter the reference array by the import assemblies utStack<int> filter; for (size_t j = 0; j < json_array_size(ref_array); j++) { json_t *jref = json_array_get(ref_array, j); utString jname = json_string_value(json_object_get(jref, "name")); bool found = false; // always find the System assembly, so we don't have to explicitly import from it if (jname == "System") { found = true; } for (UTsize k = 0; k < importedAssemblies.size() && !found; k++) { if (importedAssemblies.at(k)->getName() == jname) { found = true; break; } } if (!found) { filter.push((int)j); } } while (filter.size()) { json_array_remove(ref_array, filter.pop()); } for (UTsize i = 0; i < rootLibDependencies.size(); i++) { utString libName = rootLibDependencies.at(i); for (size_t j = 0; j < json_array_size(ref_array); j++) { json_t *jref = json_array_get(ref_array, j); utString jname = json_string_value(json_object_get(jref, "name")); if (libName != jname) { continue; } log("Linking: %s", libName.c_str()); utString delim = platform_getFolderDelimiter(); utString libPath = sdkPath + delim + "libs" + delim + libName + ".loomlib"; utArray<unsigned char> rarray; if (libName == "System" && embeddedSystemAssembly) { size_t embeddedSystemAssemblyLength = strlen(embeddedSystemAssembly); rarray.resize((int)(embeddedSystemAssemblyLength + 1)); memcpy(&rarray[0], embeddedSystemAssembly, embeddedSystemAssemblyLength + 1); } else { lmAssert(utFileStream::tryReadToArray(libPath, rarray), "Unable to load library assembly %s at %s", libName.c_str(), libPath.c_str()); } utBase64 base64 = utBase64::encode64(rarray); json_object_set(jref, "binary", json_string(base64.getBase64().c_str())); json_object_set(jref, "uid", json_string(readAssemblyUID(rarray))); break; } } json_object_set(json, "executable", json_true()); utString execSource = rootBuildInfo->getOutputDir() + utString(platform_getFolderDelimiter()) + rootBuildInfo->getAssemblyName() + ".loom"; // generate binary assembly for executable BinWriter::writeExecutable(execSource.c_str(), json); log("Compile Successful: %s\n", execSource.c_str()); }
int CUnitHandler::TestUnitBuildSquare( const BuildInfo& buildInfo, CFeature*& feature, int allyteam, std::vector<float3>* canbuildpos, std::vector<float3>* featurepos, std::vector<float3>* nobuildpos, const std::vector<Command>* commands) { feature = NULL; const int xsize = buildInfo.GetXSize(); const int zsize = buildInfo.GetZSize(); const float3 pos = buildInfo.pos; const int x1 = (int) (pos.x - (xsize * 0.5f * SQUARE_SIZE)); const int x2 = x1 + xsize * SQUARE_SIZE; const int z1 = (int) (pos.z - (zsize * 0.5f * SQUARE_SIZE)); const int z2 = z1 + zsize * SQUARE_SIZE; const float h = GetBuildHeight(pos, buildInfo.def); int canBuild = 2; if (buildInfo.def->needGeo) { canBuild = 0; const std::vector<CFeature*> &features = qf->GetFeaturesExact(pos, max(xsize, zsize) * 6); for (std::vector<CFeature*>::const_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) < (zsize * 4 - 4)) { canBuild = 2; break; } } } if (commands != NULL) { //! unsynced code for (int x = x1; x < x2; x += SQUARE_SIZE) { for (int z = z1; z < z2; z += SQUARE_SIZE) { int tbs = TestBuildSquare(float3(x, pos.y, z), buildInfo.def, feature, gu->myAllyTeam); if (tbs) { std::vector<Command>::const_iterator ci = commands->begin(); for (; ci != commands->end() && tbs; ++ci) { BuildInfo bc(*ci); if (std::max(bc.pos.x - x - SQUARE_SIZE, x - bc.pos.x) * 2 < bc.GetXSize() * SQUARE_SIZE && std::max(bc.pos.z - z - SQUARE_SIZE, z - bc.pos.z) * 2 < bc.GetZSize() * 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)); canBuild = 0; } } } } else { for (int x = x1; x < x2; x += SQUARE_SIZE) { for (int z = z1; z < z2; z += SQUARE_SIZE) { canBuild = min(canBuild, TestBuildSquare(float3(x, h, z), buildInfo.def, feature, allyteam)); 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){ int square=ground->GetSquare(float3(x,pos.y,z)); CFeature* feature=0; int tbs=TestBuildSquare(float3(x,pos.y,z),buildInfo.def,feature,gu->myAllyTeam); if(tbs){ 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)); 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(); glEnable(GL_DEPTH_TEST ); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); //glDisable(GL_BLEND); return canbuild; }