void AAI::UnitMoveFailed(int unit) { const UnitDef *def = cb->GetUnitDef(unit); if(ut->units[unit].cons) { AAIConstructor* builder = ut->units[unit].cons; if(builder->task == BUILDING) { if(builder->construction_unit_id == -1) { --bt->units_dynamic[builder->construction_def_id].requested; --ut->futureUnits[builder->construction_category]; // clear up buildmap etc. execute->ConstructionFailed(builder->build_pos, builder->construction_def_id); // free builder builder->ConstructionFinished(); } } } }
void AAIConstructor::CheckAssistance() { if(factory) { // check if another factory of that type needed if(buildque->size() >= cfg->MAX_BUILDQUE_SIZE - 1 && assistants.size() >= cfg->MAX_ASSISTANTS-1) { if(ai->bt->units_dynamic[def_id].active < cfg->MAX_FACTORIES_PER_TYPE && ai->bt->units_dynamic[def_id].requested <= 0) { ai->bt->units_dynamic[def_id].requested += 1; if(ai->execute->urgency[STATIONARY_CONSTRUCTOR] < 1) ai->execute->urgency[STATIONARY_CONSTRUCTOR] = 1; for(list<int>::iterator j = bt->units_static[def_id].canBuildList.begin(); j != bt->units_static[def_id].canBuildList.end(); ++j) bt->units_dynamic[*j].constructorsRequested += 1; } } // check if support needed if(assistants.size() < cfg->MAX_ASSISTANTS) { bool assist = false; if(buildque->size() > 2) assist = true; else if(construction_def_id && (bt->unitList[construction_def_id-1]->buildTime/(30.0f * bt->unitList[def_id-1]->buildSpeed) > cfg->MIN_ASSISTANCE_BUILDTIME)) assist = true; if(assist) { AAIConstructor* assistant = ai->ut->FindClosestAssistant(ai->cb->GetUnitPos(unit_id), 5, true); if(assistant) { assistants.insert(assistant->unit_id); assistant->AssistConstruction(unit_id); } } } // check if assistants are needed anymore else if(!assistants.empty() && buildque->empty() && !construction_def_id) { //cb->SendTextMsg("factory releasing assistants",0); ReleaseAllAssistants(); } } if(builder && build_task) { // prevent assisting when low on ressources if(ai->execute->averageMetalSurplus < 0.1) { if(construction_category == METAL_MAKER) { if(ai->execute->averageEnergySurplus < 0.5 * ai->bt->unitList[construction_def_id-1]->energyUpkeep) return; } else if(construction_category != EXTRACTOR && construction_category != POWER_PLANT) return; } float buildtime = ai->bt->unitList[construction_def_id-1]->buildTime / ai->bt->unitList[def_id-1]->buildSpeed; if(buildtime > cfg->MIN_ASSISTANCE_BUILDTIME && assistants.size() < cfg->MAX_ASSISTANTS) { // com only allowed if buildpos is inside the base bool commander = false; int x = build_pos.x / ai->map->xSectorSize; int y = build_pos.z / ai->map->ySectorSize; if(x >= 0 && y >= 0 && x < ai->map->xSectors && y < ai->map->ySectors) { if(ai->map->sector[x][y].distance_to_base == 0) commander = true; } AAIConstructor* assistant = ai->ut->FindClosestAssistant(build_pos, 5, commander); if(assistant) { assistants.insert(assistant->unit_id); assistant->AssistConstruction(unit_id, construction_unit_id); } } } }
void AAIConstructor::CheckAssistance() { if(factory) { // check if another factory of that type needed if(buildque->size() >= cfg->MAX_BUILDQUE_SIZE - 2 && assistants.size() >= cfg->MAX_ASSISTANTS-2) { if(ai->Getbt()->units_dynamic[def_id].active + ai->Getbt()->units_dynamic[def_id].requested + ai->Getbt()->units_dynamic[def_id].under_construction < cfg->MAX_FACTORIES_PER_TYPE) { ai->Getbt()->units_dynamic[def_id].requested += 1; if(ai->Getexecute()->urgency[STATIONARY_CONSTRUCTOR] < 1.5f) ai->Getexecute()->urgency[STATIONARY_CONSTRUCTOR] = 1.5f; for(list<int>::iterator j = ai->Getbt()->units_static[def_id].canBuildList.begin(); j != ai->Getbt()->units_static[def_id].canBuildList.end(); ++j) ai->Getbt()->units_dynamic[*j].constructorsRequested += 1; } } // check if support needed if(assistants.size() < cfg->MAX_ASSISTANTS) { bool assist = false; if(buildque->size() > 2) assist = true; else if(ai->Getbt()->IsValidUnitDefID(construction_def_id)) { float buildtime = 1e6; if (buildspeed > 0) { //FIXME why use *1/30 here? below there is exactly the same code w/o it, so what's the correct one? buildtime = ai->Getbt()->GetUnitDef(construction_def_id).buildTime / (30.0f * buildspeed); } if (buildtime > cfg->MIN_ASSISTANCE_BUILDTIME) assist = true; } if(assist) { AAIConstructor* assistant = ai->Getut()->FindClosestAssistant(ai->Getcb()->GetUnitPos(unit_id), 5, true); if(assistant) { assistants.insert(assistant->unit_id); assistant->AssistConstruction(unit_id); } } } // check if assistants are needed anymore else if(!assistants.empty() && buildque->empty() && !ai->Getbt()->IsValidUnitDefID(construction_def_id)) { //ai->LogConsole("factory releasing assistants"); ReleaseAllAssistants(); } } if(builder && build_task) { // prevent assisting when low on ressources if(ai->Getexecute()->averageMetalSurplus < 0.1) { if(construction_category == METAL_MAKER) { if(ai->Getexecute()->averageEnergySurplus < 0.5 * ai->Getbt()->GetUnitDef(construction_def_id).energyUpkeep) return; } else if(construction_category != EXTRACTOR && construction_category != POWER_PLANT) return; } float buildtime = 1e6; if (buildspeed > 0) { buildtime = ai->Getbt()->GetUnitDef(construction_def_id).buildTime / buildspeed; } if((buildtime > cfg->MIN_ASSISTANCE_BUILDTIME) && (assistants.size() < cfg->MAX_ASSISTANTS)) { // com only allowed if buildpos is inside the base bool commander = false; int x = build_pos.x / ai->Getmap()->xSectorSize; int y = build_pos.z / ai->Getmap()->ySectorSize; if(x >= 0 && y >= 0 && x < ai->Getmap()->xSectors && y < ai->Getmap()->ySectors) { if(ai->Getmap()->sector[x][y].distance_to_base == 0) commander = true; } AAIConstructor* assistant = ai->Getut()->FindClosestAssistant(build_pos, 5, commander); if(assistant) { assistants.insert(assistant->unit_id); assistant->AssistConstruction(unit_id, construction_unit_id); } } } }