string CUBuild::GetGUNSHIP(){ NLOG("CUBuild::GetGUNSHIP"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; float best_score = 0; string best = ""; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(G->Pl->feasable(p,utd)==false) continue; if(p->IsGunship()){ float temp = G->efficiency->GetEfficiency(p->GetName()); temp /= (p->GetUnitDef()->energyCost+(p->GetUnitDef()->metalCost*45)); temp = temp - G->mrand()%max(int(temp/4),1); if(temp > best_score){ best_score = temp; best = p->GetName(); } } } } return best; }
string CUBuild::GetFACTORY(){ NLOG("CUBuild::GetFACTORY"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; float best_score = 0; string best = ""; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p = G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(p->IsFactory()){ if(!G->Pl->feasable(p,utd)) continue; if(p->IsUWStructure()!=(water||G->info->spacemod)) continue; float temp = G->efficiency->GetEfficiency(p->GetName()); temp /= (p->GetUnitDef()->energyCost+(p->GetUnitDef()->metalCost*45)); int r = G->mrand()%max(int(temp/4),1)+1; temp += (float)abs(r); if(temp > best_score){ best_score = temp; best = p->GetName(); } } } } return best; }
string CUBuild::GetGEO(){ NLOG("CUBuild::GetGEO"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(G->Pl->feasable(p,utd)==false) continue; if(p->GetUnitDef()->needGeo&&(p->GetUnitDef()->builder == false)) possibles.push_back(p->GetName()); } } if(possibles.empty() == false){ return possibles.front(); } return string(""); }
string CUBuild::GetDEFENCE(){ NLOG("CUBuild::GetDEFENCE"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; int defnum = 0; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ // retrieve the unit type information CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); const UnitDef* pd = p->GetUnitDef(); if(Useless(p)) continue; if((p->GetUnitDef()->weapons.empty() == false)&&(!p->GetUnitDef()->isFeature)&&(!p->IsMobile())){ if((G->info->spacemod == true)||(water == true)){ if(G->Pl->feasable(p,utd)==false) continue; possibles.push_back(p->GetName()); defnum++; } else if (pd->floater == false){ if(G->Pl->feasable(p,utd)==false) continue; possibles.push_back(p->GetName()); defnum++; } } } } if(possibles.empty() == false){ defnum = G->mrand()%defnum; int j = 0; for(list<string>::iterator k = possibles.begin(); k != possibles.end(); ++k){ if(j == defnum){ return *k; }else{ j++; } } return possibles.front(); } return string(""); }
string CUBuild::GetPOWER(){ NLOG("CUBuild::GetPOWER"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; // Find all energy generators this unit can build and add them to a list. list<const UnitDef*> possibles_u; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p = G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(p->IsEnergy()) possibles_u.push_back(p->GetUnitDef()); } } string best_energy = ""; if(possibles_u.empty() == false){ float bestpoint = 0; for(list<const UnitDef*>::iterator pd = possibles_u.begin();pd != possibles_u.end(); ++pd){ float temp_energy = 0; if((*pd)->energyUpkeep <0) temp_energy += -(*pd)->energyUpkeep; if((*pd)->windGenerator>1) temp_energy += (G->cb->GetMaxWind()+G->cb->GetMinWind())/2; if((*pd)->energyMake > 1) temp_energy += (*pd)->energyMake; if((*pd)->tidalGenerator >0) temp_energy += G->cb->GetTidalStrength(); temp_energy /= ((*pd)->energyCost+((*pd)->metalCost*45)); if(temp_energy/(((*pd)->metalCost+(*pd)->energyCost)/2) > bestpoint){ bestpoint = temp_energy; best_energy = (*pd)->name; } } } return best_energy; //return string(""); }
string CUBuild::GetBUILDER(){ NLOG("CUBuild::GetBUILDER"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; float best_score = 0; string best = ""; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(p->GetUnitDef()->builder&&((p->GetUnitDef()->movedata !=0)||p->GetUnitDef()->canfly)){ if(G->Pl->feasable(p,utd)==false) continue; if(p->GetUnitDef()->floater){ if(G->info->spacemod||water){ float temp = G->efficiency->GetEfficiency(p->GetUnitDef()->name); if(!p->GetUnitDef()->buildOptions.empty()){ for(map<int,std::string>::const_iterator i = p->GetUnitDef()->buildOptions.begin(); i != p->GetUnitDef()->buildOptions.end(); ++i){ temp += G->efficiency->GetEfficiency(i->second); } } temp*=p->GetUnitDef()->buildSpeed; temp /= (p->GetUnitDef()->energyCost+(p->GetUnitDef()->metalCost*45)); temp = temp - G->mrand()%max(int(temp/4),1); if(temp > best_score){ best_score = temp; best = p->GetName(); } } } } } } return best; }
string CUBuild::GetSCOUT(){ NLOG("CUBuild::GetSCOUT"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); //if(Useless(ud)) continue; if((p->GetUnitDef()->speed > G->info->scout_speed)&&(p->GetUnitDef()->movedata != 0)&&(p->GetUnitDef()->canfly == false)&&(p->GetUnitDef()->transportCapacity == 0)&&(p->GetUnitDef()->isCommander == false)&&(p->GetUnitDef()->builder == false)) possibles.push_back(p->GetName()); if((p->GetUnitDef()->weapons.empty() == true)&&(p->GetUnitDef()->canfly == true)&&(p->GetUnitDef()->transportCapacity == 0)&&(p->GetUnitDef()->isCommander == false)&&(p->GetUnitDef()->builder == false)) possibles.push_back(p->GetName()); if((p->GetUnitDef()->weapons.empty()==true)&&(p->GetUnitDef()->canResurrect == false)&&(p->GetUnitDef()->canCapture == false)&&(p->GetUnitDef()->builder == false)&& ((p->GetUnitDef()->canfly==true)||(p->GetUnitDef()->movedata != 0)) &&((p->GetUnitDef()->radarRadius > 10)||(p->GetUnitDef()->sonarRadius > 10))) possibles.push_back(p->GetName()); } } if(possibles.empty() == false) return possibles.front(); return string(""); }
string CUBuild::GetMSTORE(){ NLOG("CUBuild::GetMSTORE"); list<string> possibles; const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); int randnum = 0; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ // retrieve the unit type information CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); const UnitDef* pd = p->GetUnitDef(); if(pd->metalStorage >100){ if(G->Pl->feasable(p,utd)==false) continue; if(pd->floater){ if(G->info->spacemod||water){ possibles.push_back(pd->name); randnum++; } } else { possibles.push_back(pd->name); randnum++; } } } } if(possibles.empty() == false){ randnum = G->mrand()%randnum; int j = 0; for(list<string>::iterator k = possibles.begin(); k != possibles.end(); ++k){ if(j == randnum){ return *k; }else{ j++; } } return possibles.front(); } return string(""); }
string CUBuild::GetMISSILE_UNIT(){ NLOG("CUBuild::GetMISSILE_UNIT"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; float best_score = 0; string best = ""; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(p->GetUnitDef()->metalCost+p->GetUnitDef()->energyCost > (G->cb->GetEnergyStorage()+G->cb->GetMetalStorage())*atof(G->Get_mod_tdf()->SGetValueDef("2.1", "AI\\cheap_multiplier").c_str())) continue; bool good = true; if(p->GetUnitDef()->canfly == false) good = false; if(p->GetUnitDef()->weapons.empty() == true) good = false; if(p->GetUnitDef()->builder == true) good = false; if(p->GetUnitDef()->transportCapacity > 0) good = false; bool found = false; for(vector<UnitDef::UnitDefWeapon>::const_iterator i = p->GetUnitDef()->weapons.begin(); i != p->GetUnitDef()->weapons.end(); ++i){ if(i->def->interceptor > 0){ continue; } if(i->def->type == string("StarburstLauncher")){ found = true; break; } } if(found == false) good = false; if(good == true){ float temp = G->efficiency->GetEfficiency(p->GetName()); temp /= (p->GetUnitDef()->energyCost+(p->GetUnitDef()->metalCost*45)); temp = temp - G->mrand()%min((int)(temp/3),1); if(temp > best_score){ best_score = temp; best = p->GetName(); } } } } return best; }
string CUBuild::GetANTIMISSILE(){ NLOG("CUBuild::GetANTIMISSILE"); list<string> possibles; const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); int randnum = 0; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ // retrieve the unit type information CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); const UnitDef* pd = p->GetUnitDef(); if(pd->weapons.empty() != true){ if(G->Pl->feasable(pd->name,uid)==false) continue; for(vector<UnitDef::UnitDefWeapon>::const_iterator i = pd->weapons.begin(); i != pd->weapons.end(); ++i){ // if(i->def->interceptor == 1){ possibles.push_back(pd->name); randnum++; break; } } } } } if(possibles.empty() == false){ randnum = G->mrand()%randnum; int j = 0; for(list<string>::iterator k = possibles.begin(); k != possibles.end(); ++k){ if(j == randnum){ return *k; }else{ j++; } } return possibles.front(); } return string(""); }
string CUBuild::GetRADAR(){ NLOG("CUBuild::GetRADAR"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; int randnum = 0; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ // retrieve the unit type information CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); const UnitDef* pd = p->GetUnitDef(); if(pd == 0) continue; if(Useless(p)) continue; if((pd->radarRadius >10)&&(pd->floater == false)&&(pd->builder == false)){ possibles.push_back(pd->name); randnum++; }else if((pd->radarRadius >10)&&(pd->floater == false)&&(pd->builder == false)&&(pd->floater == true)&&((G->info->spacemod == true)||(water == true))){ possibles.push_back(pd->name); randnum++; } } } if(possibles.empty() == false){ randnum = G->mrand()%randnum; int j = 0; for(list<string>::iterator k = possibles.begin(); k != possibles.end(); ++k){ if(j == randnum){ return *k; }else{ j++; } } return possibles.front(); } return string(""); }
string CUBuild::GetFORTIFICATION(){ NLOG("CUBuild::GetFORTIFICATION"); if(G->DTHandler->DTNeeded() == false) return string(""); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ // retrieve the unit type information CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); const UnitDef* pd = p->GetUnitDef(); if(G->DTHandler->IsDragonsTeeth(pd)){ possibles.push_back(pd->name); } } } if(possibles.empty() == false){ int randnum = G->mrand()%possibles.size(); int j = 0; for(list<string>::iterator k = possibles.begin(); k != possibles.end(); ++k){ if(j == randnum){ return *k; }else{ j++; } } return possibles.front(); } return string(""); }
string CUBuild::GetMETAL_MAKER(){ NLOG("CUBuild::GetMETAL_MAKER"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ // retrieve the unit type information CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); const UnitDef* pd = p->GetUnitDef(); if((pd->isMetalMaker == true)&&(pd->floater == false)){ possibles.push_back(pd->name); } if((pd->isMetalMaker == true)&&(pd->floater == true)&&((G->info->spacemod == true)||(water == true))){ possibles.push_back(pd->name); } } } if(possibles.empty() == false){ int randnum = G->mrand()%possibles.size(); for(list<string>::iterator k = possibles.begin(); k != possibles.end(); ++k){ if(0 == randnum){ return *k; }else{ randnum--; } } return possibles.front(); } return string(""); }
string CUBuild::GetSHIELD(){ NLOG("CUBuild::GetSHIELD"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; float best_score = 0; string best = ""; for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(G->Pl->feasable(p,utd)) continue; if(p->GetUnitDef()->metalCost+p->GetUnitDef()->energyCost > (G->cb->GetEnergyStorage()+G->cb->GetMetalStorage())*atof(G->Get_mod_tdf()->SGetValueDef("2.1", "AI\\cheap_multiplier").c_str())) continue; bool found = false; if(p->GetUnitDef()->weapons.empty() == false){ for(vector<UnitDef::UnitDefWeapon>::const_iterator i = p->GetUnitDef()->weapons.begin(); i != p->GetUnitDef()->weapons.end(); ++i){ if(i->def->isShield){ found = true; break; } } } if(found == true){ float temp = G->efficiency->GetEfficiency(p->GetName()); temp /= (p->GetUnitDef()->energyCost+(p->GetUnitDef()->metalCost*45)); temp = temp - G->mrand()%max(int(temp/4),1); if(temp > best_score){ best_score = temp; best = p->GetName(); } } } } return best; }
bool CActions::RepairNearbyUnfinishedMobileUnits(int uid, float radius){ NLOG("CActions::RepairNearbyUnfinishedMobileUnits"); const UnitDef* udi = G->cb->GetUnitDef(uid); if(udi == 0) return false; float3 pos = G->GetUnitPos(uid); int* hn = new int[10000]; int h = G->cb->GetFriendlyUnits(hn, pos, radius); if( h>0){ for( int i = 0; i<h; i++){ if(G->cb->UnitBeingBuilt(hn[i]) == true){ CUnitTypeData* btd = G->UnitDefLoader->GetUnitTypeDataByUnitId(hn[i]); if(!btd->IsMobile()){ continue; } float Remainder = 1.0f - G->cb->GetUnitHealth(hn[i]) / G->cb->GetUnitMaxHealth(hn[i]); float RemainingTime = btd->GetUnitDef()->buildTime / udi->buildSpeed * Remainder; if (RemainingTime < 30.0f){ continue; } float EPerS = btd->GetUnitDef()->energyCost / (btd->GetUnitDef()->buildTime / udi->buildSpeed); float MPerS = btd->GetUnitDef()->metalCost / (btd->GetUnitDef()->buildTime / udi->buildSpeed); if (G->cb->GetMetal() + (G->Pl->GetMetalIncome() - MPerS) * RemainingTime > 0 && G->cb->GetEnergy() + (G->Pl->GetEnergyIncome() - EPerS) * RemainingTime > 0){ if (RemainingTime > 120.0f || btd->GetUnitDef()->buildSpeed > 0){ int target = hn[i]; delete [] hn; return Repair(uid, target); } } } } }else{ h = G->cb->GetFriendlyUnits(hn); if(h <1){ return false; } for( int i = 0; i<h; i++){ if((G->cb->UnitBeingBuilt(hn[i])||(G->cb->GetUnitMaxHealth(hn[i])*0.6f > G->cb->GetUnitHealth(hn[i])))&&(G->cb->GetUnitTeam(hn[i]) == G->Cached->team)){ CUnitTypeData* btd = G->UnitDefLoader->GetUnitTypeDataByUnitId(hn[i]); float Remainder = 1.0f - G->cb->GetUnitHealth(hn[i]) / G->cb->GetUnitMaxHealth(hn[i]); float RemainingTime = btd->GetUnitDef()->buildTime / udi->buildSpeed * Remainder; if (RemainingTime < 30.0f){ continue; } float EPerS = btd->GetUnitDef()->energyCost / (btd->GetUnitDef()->buildTime / udi->buildSpeed); float MPerS = btd->GetUnitDef()->metalCost / (btd->GetUnitDef()->buildTime / udi->buildSpeed); if (G->cb->GetMetal() + (G->Pl->GetMetalIncome() - MPerS) * RemainingTime > 0 && G->cb->GetEnergy() + (G->Pl->GetEnergyIncome() - EPerS) * RemainingTime > 0 ){ if (RemainingTime > 120.0f || btd->GetUnitDef()->buildSpeed > 0) { int target = hn[i]; delete [] hn; return Repair(uid, target); } } } } } delete [] hn; return false; }
bool CActions::DGunNearby(int uid){ NLOG("CActions::DGunNearby"); CUnitTypeData* utd = G->UnitDefLoader->GetUnitTypeDataByUnitId(uid); if(utd == 0 ){ G->L.print("Dgunning failed, utd == 0"); return false; } if(!utd->CanDGun()){ return false; } float3 compos = G->GetUnitPos(uid); if(G->Map->CheckFloat3(compos)==false){ return false; } int* en = new int[10000]; int e = G->GetEnemyUnits(en, compos, G->cb->GetUnitMaxRange(uid)*1.3f); // get all enemy units within weapons range atm if(e>0){ for(int i = 0; i < e; i++){ if(ValidUnitID(en[i])==false){ continue; } CUnitTypeData* edt = G->UnitDefLoader->GetUnitTypeDataByUnitId(en[i]); //if(endi->isCommander == true) continue; // no dgunning enemy commanders! // no dgunning enemy commanders is commented out because now if the enemy is a commander the CMD_DGUN is // changed to CMD_RECLAIM, allowing the enemy commander to be eliminated without causing a wild goose chase of // building dgunned building dgunned, commander in the way of building dgunned, BANG, both commanders bye bye // that and the line needs fiddling anyway due to the CUnitTypeData refactor if(edt->IsAirCraft()&&(edt->GetUnitDef()->speed<3)){ continue;// attempting to dgun an aircraft without predictive dgunning leads to a goose chase } int k = en[i]; delete [] en; if(edt->GetUnitDef()->canDGun){ int r = (int)G->Pl->ReclaimTime(utd->GetUnitDef(), edt->GetUnitDef(), G->chcb->GetUnitHealth(k)); int c = (int)G->Pl->CaptureTime(utd->GetUnitDef(), edt->GetUnitDef(), G->chcb->GetUnitHealth(k)); if (r<(4 SECONDS) && r < c){ return Reclaim(uid, k); } else { if (c<(4 SECONDS)){ return Capture(uid, k); } else { NLOG("CActions::IfNobodyNearMoveToNearest :: WipePlansForBuilder"); return MoveToStrike(uid, G->Map->nbasepos(compos), false); } } } else { if (utd->GetDGunCost()<G->cb->GetEnergy()){ return DGun(uid, k); } else { int r = (int)G->Pl->ReclaimTime(utd->GetUnitDef(), edt->GetUnitDef(), G->chcb->GetUnitHealth(k)); int c = (int)G->Pl->CaptureTime(utd->GetUnitDef(), edt->GetUnitDef(), G->chcb->GetUnitHealth(k)); if(r<(4 SECONDS) && r < c){ return Reclaim(uid, k); } else { if (c<(4 SECONDS)){ return Capture(uid, k); } else { return MoveToStrike(uid, G->Map->nbasepos(compos), false); } } } } } }else{ // we aint got enemies within immediate range, however this doesnt mean we're safe. // check fi there are nearby enemy groups // check the surrounding units and repair them if necessary. // if none need repairing then retreat, this may be an enemy base or an incoming army e = G->GetEnemyUnits(en, compos, G->cb->GetUnitMaxRange(uid)*2.5f); // get all enemy units within weapons range atm if(e > 0){ float total_enemy_power = 0; float total_allied_power = 0; for(int i = 0; i < e; i++){ if(!ValidUnitID(en[i])){ continue; } const UnitDef* endi = G->GetUnitDef(en[i]); if(endi){ total_enemy_power += endi->power; } } e = G->cb->GetFriendlyUnits(en, compos, G->cb->GetUnitMaxRange(uid)*2.5f); for(int i = 0; i < e; i++){ if(!ValidUnitID(en[i])){ continue; // filter out bad unit id's } const UnitDef* endi = G->GetUnitDef(en[i]); if(endi){ total_allied_power += endi->power; } } float ratio = total_allied_power/total_enemy_power; if((ratio<0.9f)&&(ratio > 0.4f)){ // repair nearby units int r_uid = -1; float best_r = 0; e = G->cb->GetFriendlyUnits(en, compos, G->cb->GetUnitMaxRange(uid)*2.5f); for(int i = 0; i < e; i++){ if(!ValidUnitID(en[i])){ continue; // filter out bad unit id's } if(en[i] == uid){ continue; // we cant repair ourself!! } const UnitDef* endi = G->GetUnitDef(en[i]); if(endi){ float ratio = G->cb->GetUnitHealth(en[i])/G->cb->GetUnitMaxHealth(en[i]); ratio = endi->power*ratio; if( ratio > best_r){ best_r = ratio; r_uid = en[i]; } } } delete[] en; if(ValidUnitID(r_uid)){ return Repair(uid, r_uid); } }else{ delete[] en; // runaway!!!!!!!!!!!!!!!!!! return MoveToStrike(uid, G->Map->nbasepos(compos), true); } } } delete [] en; return false; }
bool CConfigTaskManager::LoadTaskList(){ NLOG("CConfigTaskManager::LoadTaskList"); CUnit* u = G->unit_array[unit]; CUnitTypeData* utd = u->GetUnitDataType(); vector<string> vl; string sl; if(G->Cached->cheating){ sl= G->Get_mod_tdf()->SGetValueMSG(string("TASKLISTS\\CHEAT\\")+utd->GetName()); }else{ sl = G->Get_mod_tdf()->SGetValueMSG(string("TASKLISTS\\NORMAL\\")+utd->GetName()); } tolowercase(sl); trim(sl); string us = utd->GetName(); if(sl != string("")){ CTokenizer<CIsComma>::Tokenize(vl, sl, CIsComma()); if(vl.empty() == false){ int randnum = G->mrand()%vl.size(); us = vl.at(min(randnum,max(int(vl.size()-1),1))); } } string s = G->Get_mod_tdf()->SGetValueMSG(string("TASKLISTS\\LISTS\\")+us); if(s.empty()){ G->L.print(" error loading tasklist for unit :: \"" + us + "\" :: buffer empty, most likely because of an empty list"); nolist=true; return false; } tolowercase(s); trim(s); vector<string> v; CTokenizer<CIsComma>::Tokenize(v, s, CIsComma()); if(v.empty() == false){ G->L.print("loading contents of tasklist :: " + us + " :: filling tasklist with #" + to_string(v.size()) + " items"); bool polate=false; bool polation = G->info->rule_extreme_interpolate; btype bt = G->Manufacturer->GetTaskType(G->Get_mod_tdf()->SGetValueDef("b_na","AI\\interpolate_tag")); if(utd->IsFactory()){ polation = false; } if(bt == B_NA){ polation = false; } // TASKS LOADING for(std::vector<string>::iterator vi = v.begin(); vi != v.end(); ++vi){ if(polation){ if(polate){ boost::shared_ptr<IModule> t(new CKeywordConstructionTask(G,u->GetID(),bt)); tasks.push_back(t); } polate = !polate; } std::string q = *vi; trim(q); tolowercase(q); CUnitTypeData* b = G->UnitDefLoader->GetUnitTypeDataByName(q); if(b != 0){ boost::shared_ptr<IModule> t(new CUnitConstructionTask(G,u->GetID(),utd,b)); tasks.push_back(t); }else if(q == string("")){ continue; }else if(q == string("b_na")){ continue; } else if(q == string("no_rule_interpolation")){ polation=false; } else if(q == string("rule_interpolate")){ polation=true; }else if(q == string("base_pos")){ G->Map->base_positions.push_back(G->GetUnitPos(u->GetID())); } else if(q == string("gaia")){ G->info->gaia = true; } else if(q == string("not_gaia")){ G->info->gaia = false; } else if(q == string("switch_gaia")){ G->info->gaia = !G->info->gaia; } else if(q == string("b_factory")){ boost::shared_ptr<IModule> t(new CKeywordConstructionTask(G,u->GetID(),B_FACTORY)); tasks.push_back(t); } else if(q == string("b_power")){ boost::shared_ptr<IModule> t(new CKeywordConstructionTask(G,u->GetID(),B_POWER)); tasks.push_back(t); } else if(q == string("b_defence")){ boost::shared_ptr<IModule> t(new CKeywordConstructionTask(G,u->GetID(),B_DEFENCE)); tasks.push_back(t); } else if(q == string("b_mex")){ boost::shared_ptr<IModule> t(new CKeywordConstructionTask(G,u->GetID(),B_MEX)); tasks.push_back(t); } else{ btype x = G->Manufacturer->GetTaskType(q); if( x != B_NA){ boost::shared_ptr<IModule> t(new CKeywordConstructionTask(G,u->GetID(),x)); tasks.push_back(t); }else{ G->L.print("error :: a value :: " + *vi +" :: was parsed in :: "+us + " :: this does not have a valid UnitDef according to the engine, and is not a Task keyword such as repair or b_mex"); } } } if(utd->GetUnitDef()->isCommander){ G->Map->basepos = G->GetUnitPos(u->GetID()); } G->L.print("loaded contents of tasklist :: " + us + " :: loaded tasklist at " + to_string(tasks.size()) + " items"); return !tasks.empty(); } else{ G->L.print(" error loading contents of tasklist :: " + us + " :: buffer empty, most likely because of an empty tasklist"); return false; } }
string CUBuild::GetMEX(){ NLOG("CUBuild::GetMEX"); // Find all metal extractors this unit can build and add them to a list. float highscore= 0; string highest=""; for(map<int,string>::const_iterator is = utd->GetUnitDef()->buildOptions.begin(); is != utd->GetUnitDef()->buildOptions.end();++is){ CUnitTypeData* p = G->UnitDefLoader->GetUnitTypeDataByName(is->second); if(p->IsMex()){ if(Useless(p)){ continue; } float score = (p->GetUnitDef()->extractsMetal+1)*1000; if(p->GetUnitDef()->weapons.empty()==false){ score *= 1.2f; } if(p->GetUnitDef()->canCloak==true){ score *= 1.2f; } score /= (p->GetUnitDef()->energyCost+(p->GetUnitDef()->metalCost*45)); if(score > highscore){ highscore = score; highest = p->GetUnitDef()->name; } continue; } if((p->GetUnitDef()->metalMake > 5)&&(p->GetUnitDef()->builder == false)&&(p->GetUnitDef()->movedata == 0 )&&(p->GetUnitDef()->canfly == false)){ float score = p->GetUnitDef()->metalMake; if(p->GetUnitDef()->weapons.empty()==false){ score *= 1.2f; } if(p->GetUnitDef()->canCloak==true){ score *= 1.2f; } score /= (p->GetUnitDef()->energyCost+(p->GetUnitDef()->metalCost*45)); if(score > highscore){ highscore = score; highest = p->GetUnitDef()->name; } continue; } } return highest; }
string CUBuild::GetRANDOM(){ NLOG("CUBuild::GetRANDOM"); const vector<CommandDescription>* di = G->cb->GetUnitCommands(uid); if(di == 0) return string(""); list<string> possibles; int randnum = 0; // for each possible build command the unit could do for(vector<CommandDescription>::const_iterator is = di->begin(); is != di->end();++is){ if(is->id<0){ // retrieve the unit type information CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); // no mine fields if(p->GetUnitDef()->canKamikaze &&((!p->GetUnitDef()->canfly)&&(p->GetUnitDef()->movedata == 0))){ // IT'S AN EXPLOSIVE MINE!!!! // We dont want nonblocking mines built ontop of eachother next to the factory!!!!!!!!!!! continue; } // no radar towers!!!! if((p->GetUnitDef() ->radarRadius > 10)&&((!p->GetUnitDef()->builder)||p->GetUnitDef()->isAirBase)){ continue; } // no resource storage!!!!!!!! if((p->GetUnitDef()->energyStorage > 100)||(p->GetUnitDef()->metalStorage > 100)){ continue; } // no metal makers if(p->GetUnitDef()->isMetalMaker){ continue; } // remove 'useless' or 'irrelevant' items if(Useless(p)){ continue; } if((p->GetUnitDef()->metalCost+p->GetUnitDef()->energyCost < (G->cb->GetEnergy()+G->cb->GetMetal())*0.9)&&(((!p->GetUnitDef()->floater)&&(!water)&&(!G->info->spacemod))||(G->info->spacemod||water))){ // check the antistall algorithm if it's ok if(!G->Pl->feasable(p,utd)){ continue; } possibles.push_back(p->GetName()); randnum++; } } } // if potential items where found if(!possibles.empty()){ // randomly pick one of the randnum = G->mrand()%randnum; // remove entries from the beginning of the list of potential items // so that the randnum'th entry is at the begining of the list while(randnum > 0){ possibles.pop_front(); } // now that we've removed all those entries our random selection // is at the front of the list, so lets return it return possibles.front(); } return string(""); }