Пример #1
0
void BuildHandler::AddTask (aiTask *task)
{
	tasks.add(task);

	if (task->resourceType>=0)
		ai->taskHandlers[task->resourceType]->AddTask (task);

	BuildTable::UDef *cd = buildTable.GetCachedDef (task->def->id);
	if (cd->IsBuilding ())
	{
		task->flags |= BT_BUILDING;
		
		if (task->pos.x >= 0.0f)
			buildMap.Mark (task->def,task->pos,true);
	}

	if (cd->IsBuilder ())
		task->MarkBuilder ();

	if (task->resourceType < 0) {
		TakeResources (ai->ResourceValue (task->def->energyCost, task->def->metalCost));
		task->MarkAllocated ();
	}

	task->startFrame=ai->cb->GetCurrentFrame();

	currentUnitBuilds[task->def->id-1] ++;
	ChatDebugPrintf (ai->cb, "Added task: %s (%s)", task->def->name.c_str(), task->resourceType >= 0 ? ai->taskHandlers[task->resourceType]->GetName() : "BuildHandler");
}
Пример #2
0
void BuildTask::Initialize (CGlobals *g)
{
    if (resourceType>=0) {
        TaskFactory *tf = g->taskFactories [resourceType];
        tf->AddTask (this);
        isAllocated = false;
    } else {
        g->resourceManager->TakeResources (g->resourceManager->ResourceValue (def->energyCost,def->metalCost));
        isAllocated=true;
    }

    BuildTable::UDef *cd = buildTable.GetCachedDef (def->id);
    if (cd->IsBuilding ())
    {
        flags |= BT_BUILDING;

        // Find a build position
        SetupBuildLocation (g);
    }

    if (cd->IsBuilder ())
        MarkBuilder ();

    g->taskManager->currentUnitBuilds[def->id-1] ++;
}
Пример #3
0
void BuildHandler::OrderNewBuilder()
{
	float bestScore;
	int best=0;

	for (int a=0;a<builderTypes.size();a++)
	{
		assert (builderTypes[a]);
		BuildTable::UDef *cd = buildTable.GetCachedDef (builderTypes[a]);

		if (cd->IsBuilding())
			continue;

		// Find the best unit we can use to build this builder
		const vector<int>& bb = *cd->buildby;
		int numBuilders=0;

		for (int i=0;i<bb.size();i++)
		{
			int n = currentBuilders [bb[i]];
			numBuilders += abs(n) + (n<0)?2:0; // an inactive builder equals 2 extra active builders
		}

		float score = std::min((1+numBuilders),3) * sqrtf(cd->numBuildOptions) * cd->buildSpeed / ai->ResourceValue(cd->cost);
		if (!best || score > bestScore)
		{
			best = builderTypes[a];
			bestScore = score;
		}
	}

	if (best)
	{
		aiTask *t = AddTask (buildTable.GetDef (best),-1);
		ChatDebugPrintf (ai->cb, "Added task to increase build speed: %s\n", t->def->name.c_str());
	}
}
Пример #4
0
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;
}
Пример #5
0
void BuildHandler::FindNewJob (BuildUnit *u)
{
	BuildTable::UDef *cd = buildTable.GetCachedDef (u->def->id);
	int curFrame=ai->cb->GetCurrentFrame();

	if (cd->IsBuilding ()) {
		// factory - find a task that is not yet initialized

		for (int a=0;a<tasks.size();a++) {
			aiTask *t = tasks[a];

			if (!t->depends && t->constructors.empty () && 
				!t->IsBuilding() && buildTable.UnitCanBuild (u->def,t->def))
			{
				SetBuilderToTask (u, t);
				return;
			}
		}
	} else {
		// mobile builder
		float3 builderPos = ai->cb->GetUnitPos(u->id);
		const UnitDef *ud = u->def;
		aiTask *best=0;
		float bestScore;
		float moveSpeed = ai->cb->GetUnitSpeed (u->id);

		for(int a=0;a<tasks.size();a++)
		{
			aiTask *t = tasks[a];

			if (t->depends || !t->AreResourcesAllocated())
				continue;

			float hp = t->unit ? ai->cb->GetUnitHealth(t->unit->id) : 0.0f;
			float buildTimeLeft = u->def->buildTime*((u->def->health-hp)/u->def->health);

			 //can we build this directly or is there someone who can start it for us
			bool canBuildThis=buildTable.UnitCanBuild (u->def, t->def) ;
			if (canBuildThis || t->lead)
			{
				float buildTime=buildTimeLeft/(t->buildSpeed+ud->buildSpeed);
				float distance=0.0f;
				if (t->lead || t->def->extractsMetal) distance = (t->pos-builderPos).Length(); // position has been estimated for metal extractors
				else distance = 40 * SQUARE_SIZE; // assume a constant distance
				float moveTime=max(0.01f,(distance-150)/moveSpeed*10);
				float travelMod=buildTime/(buildTime+moveTime);			//units prefer stuff with low travel time compared to build time
				float finishMod=t->def->buildTime/(buildTimeLeft+t->def->buildTime*0.1f);			//units prefer stuff that is nearly finished
				float canBuildThisMod=canBuildThis?1.5f:1;								//units prefer to do stuff they have in their build options (less risk of guarded unit dying etc)
				float ageMod=20+sqrtf((float)(curFrame+1)-t->startFrame);
//				float buildSpeedMod=info->buildSpeed/(qb->totalBuildSpeed+info->buildSpeed);
				float score=finishMod*canBuildThisMod*travelMod*ageMod;

				if(!best||score>bestScore)
				{
					bestScore=score;
					best = t;
				}
			}
		}

		if (best)
			SetBuilderToTask (u, best);
	}
}
Пример #6
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;
}