aiUnit* BuildHandler::UnitCreated (int id) { float bestDis; aiTask *best=0, *t; aiUnit *unit = 0; float3 pos = ai->cb->GetUnitPos (id); const UnitDef* def = ai->cb->GetUnitDef (id); for (int a=0;a<tasks.size();a++) if (!tasks[a]->unit && tasks[a]->lead && tasks[a]->def == def) { float d = pos.distance2D (tasks[a]->pos); if (!best || d < bestDis) { best = tasks[a]; bestDis = d; } } if (!best || bestDis > 200) { // TODO: Find a way to deal with these outcasts... return new aiUnit; } t = best; if (t->IsBuilder()) { BuildUnit *bu = new BuildUnit; bu->owner = this; t->unit = bu; bu->UpdateTimeout(ai->cb); t->unit = bu; logPrintf ("New builder created. %s\n", t->def->name.c_str()); return bu; } assert (t->destHandler); unit = t->destHandler->CreateUnit (id); unit->owner = this; t->AddDeathDependence (unit); t->unit = unit; return unit; }
void BuildHandler::InitiateTask (aiTask *task) { BuildUnit *lead = 0; assert (!task->constructors.empty()); assert (!task->lead); // Find a new lead builder for (int a=0;a<task->constructors.size();a++) { BuildUnit *b = task->constructors [a]; if (task->constructors[a]->tasks.front () != task) continue; if (buildTable.UnitCanBuild (b->def, task->def)) { lead = b; break; } } if (!lead) { for (int a=0;a<task->constructors.size();a++) { BuildUnit *u = task->constructors[a]; task->DeleteDeathDependence (u); u->DependentDied (task); u->DeleteDeathDependence (task); } task->constructors.clear(); task->buildSpeed = 0.0f; return; } float3 builderPos = ai->cb->GetUnitPos (lead->id); Command c; BuildTable::UDef* cd = buildTable.GetCachedDef (task->def->id); if (cd->IsBuilding()) { if (!FindTaskBuildPos (task,lead)) return; c.params.resize(3); c.params[0]=task->pos.x; c.params[1]=task->pos.y; c.params[2]=task->pos.z; MapInfo *i = ai->map.GetMapInfo (task->pos); if (i)i->buildstate += cd->IsBuilder () ? BLD_FACTORY : 1; if (aiConfig.debug) ai->cb->DrawUnit (task->def->name.c_str(), task->pos, 0.0f, 800, ai->cb->GetMyTeam(), true, true); } else task->pos = builderPos; c.id = -task->def->id; ai->cb->GiveOrder (lead->id, &c); task->lead = lead; }
void BuildTask::InitializeLeadBuilder (CGlobals *g) { BuildUnit *leadc = 0;// lead builder candidate assert (!constructors.empty()); assert (!lead); // Find a new lead builder for (int a=0; a<constructors.size(); a++) { BuildUnit *b = constructors [a]; if (constructors[a]->tasks.front () != this) continue; if (buildTable.UnitCanBuild (b->def, def)) { leadc = b; break; } } if (!leadc) // No candidate for lead builder? { for (int a=0; a<constructors.size(); a++) { BuildUnit *u = constructors[a]; DeleteDeathDependence (u); u->DependentDied (this); u->DeleteDeathDependence (this); } constructors.clear(); buildSpeed = 0.0f; return; } float3 builderPos = g->cb->GetUnitPos (leadc->id); Command c; BuildTable::UDef* cd = buildTable.GetCachedDef (def->id); if (cd->IsBuilding()) { if (def->extractsMetal && spotID>=0) { MetalSpot *spot = g->metalmap->GetSpot (spotID); if (spot->unit) { assert (spot->unit->def->extractsMetal < def->extractsMetal); // create a reclaim task and make this depends on the reclaim task ReclaimUnitTask *rt = new ReclaimUnitTask; g->taskManager->AddTask (rt); AddDeathDependence (rt); depends = rt; rt->SetReclaimTarget (spot->unit); return; } } if (pos.x < 0.0f) { if (!SetupBuildLocation (g)) return; } c.params.resize(3); c.params[0]=pos.x; c.params[1]=pos.y; c.params[2]=pos.z; if (aiConfig.debug) g->cb->DrawUnit (def->name.c_str(), pos, 0.0f, 800, g->cb->GetMyTeam(), true, true); } else pos = builderPos; c.id = -def->id; g->cb->GiveOrder (leadc->id, &c); lead = leadc; }