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;
}
Example #3
0
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;
}