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::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::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::GetRAND_ASSAULT(){ NLOG("CUBuild::GetRAND_ASSAULT"); 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){ CUnitTypeData* p =G->UnitDefLoader->GetUnitTypeDataByName(is->name); if(G->Pl->feasable(p,utd)==false) continue; if(p->IsAttacker()){ 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(); }else{ 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::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; }
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; }
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::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(""); }
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::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(""); }
bool CUBuild::OkBuildSelection(string name){ CUnitTypeData* u =G->UnitDefLoader->GetUnitTypeDataByName(name); float emax=1000000000; string key = "Resource\\MaxEnergy\\"; key += u->GetName(); G->Get_mod_tdf()->GetDef(emax,"3000000",key);// +300k energy per tick by default/**/ if(G->Pl->GetEnergyIncome() > emax){ //G->L.print("Factor::CBuild emax " + name); return false; } //NLOG("CManufacturer::CBuild Resource\\MinEnergy\\"); float emin=1; key = "Resource\\MinEnergy\\"; key += u->GetName(); G->Get_mod_tdf()->GetDef(emin,"0",key);// +0k energy per tick by default/**/ if(G->Pl->GetEnergyIncome() < emin){ //G->L.print("Factor::CBuild emin " + name); return false; } // Now sort out stuff that can only be built one at a time if(u->GetSoloBuild()){ if(u->GetSoloBuildActive()){ // One is already being built! We're not supposed to build more than one at any one time. return false; } deque<CBPlan* >* b = G->Manufacturer->BPlans; if(b->empty() == false){ // for(deque<CBPlan* >::iterator i = b->begin(); i != b->end(); ++i){ string s = (*i)->utd->GetName(); if(s == u->GetName()){ return false; } } } } // Now sort out if it's one of those things that can only be built once if(u->GetSingleBuild()){ if(u->GetSingleBuildActive()){ return false; } deque<CBPlan* >* b = G->Manufacturer->BPlans; if(b->empty() == false){ // for(deque<CBPlan* >::iterator i = b->begin(); i != b->end(); ++i){ string s = (*i)->utd->GetName(); if(s == name){ return false; } } } } return true; }