Exemplo n.º 1
0
bool CUnitHandler::BuildTaskAddBuilder(int builderID, UnitCategory category) {
	assert(category < CAT_LAST);
	assert(builderID >= 0);
	assert(ai->GetUnit(builderID) != NULL);

	CUNIT* u = ai->GetUnit(builderID);
	BuilderTracker* builderTracker = GetBuilderTracker(builderID);

	const UnitDef* builderDef = ai->cb->GetUnitDef(builderID);
	const int frame = ai->cb->GetCurrentFrame();

	// make sure this builder is free
	const bool b1 = (builderTracker->taskPlanId == 0);
	const bool b2 = (builderTracker->buildTaskId == 0);
	const bool b3 = (builderTracker->factoryId == 0);
	const bool b4 = builderDef->canAssist;
	const bool b5 = (category == CAT_FACTORY && frame >= 18000);

	if (!b1 || !b2 || !b3 || !b4) {
		if (b5) {
			// note that FactoryBuilderAdd() asserts b1 through b4
			// immediately after BuildTaskAddBuilder() is tried and
			// fails in BuildUp(), so at least those must be true
			// (and so should b5 in most of the *A mods)

			std::stringstream msg;
				msg << "[CUnitHandler::BuildTaskAddBuilder()][frame=" << frame << "]\n";
				msg << "\tbuilder " << builderID << " not able to be added to CAT_FACTORY build-task\n";
				msg << "\tb1: " << b1 << ", b2: " << b2 << ", b3: " << b3;
				msg << ", b4: " << b4 << ", b5: " << b5;
			ai->GetLogger()->Log(msg.str());
		}

		return false;
	}

	// see if there are any BuildTasks that it can join
	if (BuildTasks[category].size() > 0) {
		float largestTime = 0.0f;
		std::list<BuildTask>::iterator task;
		std::list<BuildTask>::iterator bestTask;

		for (task = BuildTasks[category].begin(); task != BuildTasks[category].end(); task++) {
			float buildTime = ai->math->ETT(*task) - ai->math->ETA(builderID, ai->cb->GetUnitPos(task->id));

			if (buildTime > largestTime) {
				largestTime = buildTime;
				bestTask = task;
			}
		}

		if (largestTime > 0.0f) {
			BuildTaskAddBuilder(&*bestTask, builderTracker);
			u->Repair(bestTask->id);
			return true;
		}
	}

	// see if there any joinable TaskPlans
	if (TaskPlans[category].size() > 0) {
		float largestTime = 0.0f;
		std::list<TaskPlan>::iterator plan;
		std::list<TaskPlan>::iterator bestPlan;

		for (plan = TaskPlans[category].begin(); plan != TaskPlans[category].end(); plan++) {
			float buildTime = (plan->def->buildTime / plan->currentBuildPower) - ai->math->ETA(builderID, plan->pos);

			// must test if this builder can make this unit/building too
			if (buildTime > largestTime) {
				const std::vector<int>* canBuildList = &ai->ut->unitTypes[builderDef->id].canBuildList;
				const int buildListSize = canBuildList->size();

				for (int j = 0; j < buildListSize; j++) {
					if (canBuildList->at(j) == plan->def->id) {
						largestTime = buildTime;
						bestPlan = plan;
						break;
					}
				}
			}
		}

		if (largestTime > 10.0f) {
			assert(builderID >= 0);

			// bad, CUNIT::Build() uses TaskPlanCreate()
			// should we really give build orders here?
			// return u->Build(bestPlan->pos, bestPlan->def, -1);
			// TaskPlanCreate(builderID, bestPlan->pos, bestPlan->def);
			return true;
		}
	}

	if (b5) {
		std::stringstream msg;
			msg << "[CUnitHandler::BuildTaskAddBuilder()][frame=" << frame << "]\n";
			msg << "\tno joinable CAT_FACTORY build-tasks or task-plans for builder " << builderID;
		ai->GetLogger()->Log(msg.str());
	}

	return false;
}