示例#1
0
文件: AAI.cpp 项目: achoum/spring
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);
			}
		}
	}
}
示例#3
0
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);
			}
		}
	}
}