⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unithandler.cpp

📁 这是整套横扫千军3D版游戏的源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	int category = ai->ut->GetCategory(builtdef);

	if (category == -1)
		return false;

	assert(category >= 0);
	assert(category < LASTCATEGORY);

	for (list<BuildTask>::iterator i = BuildTasks[category].begin(); i != BuildTasks[category].end(); i++) {
		if (i->pos.distance2D(pos) < 1 && ai->ut->GetCategory(i->def) == category) {
			return &*i;
		}
	}
	return NULL;
}



bool CUnitHandler::BuildTaskAddBuilder(int builder, int category) {
	assert(category >= 0);
	assert(category < LASTCATEGORY);
	assert(builder >= 0);
	assert(ai->MyUnits[builder] != NULL);
	BuilderTracker* builderTracker = GetBuilderTracker(builder);

	// make sure this builder is free
	// KLOOTNOTE: no longer use assertions
	// since new code for extractor upgrading
	// (in CBuildUp) seems to trigger them?
	bool b1 = (builderTracker->taskPlanId == 0);
	bool b2 = (builderTracker->buildTaskId == 0);
	bool b3 = (builderTracker->factoryId == 0);
	bool b4 = (builderTracker->customOrderId == 0);

	if (!b1 || !b2 || !b3 || !b4) {
		return false;
	}

	// see if there are any BuildTasks that it can join
	if (BuildTasks[category].size()) {
		float largestime = 0;
		list<BuildTask>::iterator besttask;

		for (list<BuildTask>::iterator i = BuildTasks[category].begin(); i != BuildTasks[category].end(); i++) {
			float timebuilding = ai->math->ETT(*i) - ai->math->ETA(builder, ai->cb->GetUnitPos(i->id));
			if (timebuilding > largestime) {
				largestime = timebuilding;
				besttask = i;
			}
		}

		if (largestime > 0) {
			BuildTaskAddBuilder(&*besttask, builderTracker);
			ai->MyUnits[builder]->Repair(besttask->id);
			return true;
		}
	}

	if (TaskPlans[category].size()) {
			float largestime = 0;
			list<TaskPlan>::iterator besttask;

			for (list<TaskPlan>::iterator i = TaskPlans[category].begin(); i != TaskPlans[category].end(); i++) {
				float timebuilding = (i->def->buildTime / i->currentBuildPower) - ai->math->ETA(builder, i->pos);

				// must test if this builder can make this unit/building too
				if (timebuilding > largestime) {
					const UnitDef* builderDef = ai->cb->GetUnitDef(builder);
					vector<int>* canBuildList = &ai->ut->unitTypes[builderDef->id].canBuildList;
					int size = canBuildList->size();
					int thisBuildingID = i->def->id;

					for (int j = 0; j < size; j++) {
						if (canBuildList->at(j) == thisBuildingID) {
							largestime = timebuilding;
							besttask = i;
							break;
						}
					}
				}
			}

			if (largestime > 10) {
				assert(builder >= 0);
				assert(ai->MyUnits[builder] !=  NULL);
				// this is bad, as ai->MyUnits[builder]->Build uses TaskPlanCreate()
				ai->MyUnits[builder]->Build(besttask->pos, besttask->def, -1);
				return true;
		}
	}

	return false;
}




void CUnitHandler::TaskPlanCreate(int builder, float3 pos, const UnitDef* builtdef) {
	int category = ai->ut->GetCategory(builtdef);

	// HACK
	if (category == -1)
		return;

	assert(category >= 0);
	assert(category < LASTCATEGORY);

	// find this builder
	BuilderTracker* builderTracker = GetBuilderTracker(builder);

	// make sure this builder is free
	// KLOOTNOTE: no longer use assertions
	// since new code for extractor upgrading
	// (in CBuildUp) seems to trigger them?
	bool b1 = (builderTracker->taskPlanId == 0);
	bool b2 = (builderTracker->buildTaskId == 0);
	bool b3 = (builderTracker->factoryId == 0);
	bool b4 = (builderTracker->customOrderId == 0);

	if (!b1 || !b2 || !b3 || !b4) {
		return;
	}


	bool existingtp = false;
	for (list<TaskPlan>::iterator i = TaskPlans[category].begin(); i != TaskPlans[category].end(); i++) {
		if (pos.distance2D(i->pos) < 20 && builtdef == i->def) {
			// make sure there are no other TaskPlans
			assert(!existingtp);
			existingtp = true;
			TaskPlanAdd(&*i, builderTracker);
		}
	}
	if (!existingtp) {
		TaskPlan tp;
		tp.pos = pos;
		tp.def = builtdef;
		tp.defName = builtdef->name;
		tp.currentBuildPower = 0;
		tp.id = taskPlanCounter++;
		TaskPlanAdd(&tp, builderTracker);

		if (category == CAT_DEFENCE)
			ai->dm->AddDefense(pos,builtdef);

		TaskPlans[category].push_back(tp);
	}
}

void CUnitHandler::TaskPlanAdd(TaskPlan* taskPlan, BuilderTracker* builderTracker) {
	taskPlan->builders.push_back(builderTracker->builderID);
	taskPlan->builderTrackers.push_back(builderTracker);
	taskPlan->currentBuildPower += ai->cb->GetUnitDef(builderTracker->builderID)->buildSpeed;
	assert(builderTracker->buildTaskId == 0);
	assert(builderTracker->taskPlanId == 0);
	assert(builderTracker->factoryId == 0);
	assert(builderTracker->customOrderId == 0);
	builderTracker->taskPlanId = taskPlan->id;
}

void CUnitHandler::TaskPlanRemove(BuilderTracker* builderTracker) {
	list<TaskPlan>::iterator killplan;
	list<int>::iterator killBuilder;
	// make sure this builder is in a TaskPlan
	assert(builderTracker->buildTaskId == 0);
	assert(builderTracker->taskPlanId != 0);
	assert(builderTracker->factoryId == 0);
	assert(builderTracker->customOrderId == 0);
	builderTracker->taskPlanId = 0;
	int builder = builderTracker->builderID;
	bool found = false;
	bool found2 = false;

	for (int k = 0; k < LASTCATEGORY;k++) {
		for (list<TaskPlan>::iterator i = TaskPlans[k].begin(); i != TaskPlans[k].end(); i++) {
			for (list<int>::iterator j = i->builders.begin(); j != i->builders.end(); j++) {
				if (*j == builder) {
					killplan = i;
					killBuilder = j;
					assert(!found);
					found = true;
					found2 = true;
				}
			}
		}
		if (found2) {
			for (list<BuilderTracker*>::iterator i = killplan->builderTrackers.begin(); i != killplan->builderTrackers.end(); i++) {
				if (builderTracker == *i) {
					// give it time to change command
					builderTracker->commandOrderPushFrame = ai->cb->GetCurrentFrame();
					killplan->builderTrackers.erase(i);
					break;
				}
			}

			killplan->builders.erase(killBuilder);

			if (killplan->builders.size() == 0) {
				// TaskPlan lost all its workers, remove
				if (ai->ut->GetCategory(killplan->def) == CAT_DEFENCE)
					ai->dm->RemoveDefense(killplan->pos, killplan->def);

				TaskPlans[k].erase(killplan);
			}

			found2 = false;
		}
	}

	if (!found) {
		assert(false);
	}
}

TaskPlan* CUnitHandler::GetTaskPlan(int taskPlanId) {
	for (int k = 0; k < LASTCATEGORY;k++) {
		for (list<TaskPlan>::iterator i = TaskPlans[k].begin(); i != TaskPlans[k].end(); i++) {
			if (i->id == taskPlanId)
				return  &*i;
		}
	}

	// this better not happen
	assert(false);
	return 0;
}



// not used
bool CUnitHandler::TaskPlanExist(float3 pos, const UnitDef* builtdef) {
	int category = ai->ut->GetCategory(builtdef);

	if (category == -1)
		return false;

	assert(category >= 0);
	assert(category < LASTCATEGORY);

	for (list<TaskPlan>::iterator i = TaskPlans[category].begin(); i != TaskPlans[category].end(); i++) {
		if (i->pos.distance2D(pos) < 100 && ai->ut->GetCategory(i->def) == category) {
			return true;
		}
	}
	return false;
}





void CUnitHandler::MetalExtractorAdd(int extractorID) {
	if (ai->ut->GetCategory(extractorID) == CAT_MEX) {
		MetalExtractor newMex;
		newMex.id = extractorID;
		newMex.buildFrame = ai->cb->GetCurrentFrame();
		MetalExtractors.push_back(newMex);
	} else {
		assert(false);
	}
}

void CUnitHandler::MetalExtractorRemove(int extractorID) {
	for (vector<MetalExtractor>::iterator i = MetalExtractors.begin(); i != MetalExtractors.end(); i++) {
		if (i->id == extractorID) {
			MetalExtractors.erase(i);
			break;
		}
	}
}



inline bool CompareExtractors(const MetalExtractor& l, const MetalExtractor& r) {
	// higher frame means more recently built
	return (l.buildFrame < r.buildFrame);
}

// returns the ID of the oldest (in
// frames) metal extractor built
int CUnitHandler::GetOldestMetalExtractor(void) {
	std::sort(MetalExtractors.begin(), MetalExtractors.end(), &CompareExtractors);

	return (MetalExtractors.size() > 0)? (MetalExtractors.begin())->id: -1;
}



void CUnitHandler::NukeSiloAdd(int siloID) {
	if (ai->ut->GetCategory(siloID) == CAT_NUKE) {
		NukeSilo newSilo;
		newSilo.id = siloID;
		newSilo.numNukesReady = 0;
		newSilo.numNukesQueued = 0;
		NukeSilos.push_back(newSilo);
	} else {
		assert(false);
	}
}

void CUnitHandler::NukeSiloRemove(int siloID) {
	for (list<NukeSilo>::iterator i = NukeSilos.begin(); i != NukeSilos.end(); i++) {
		if (i->id == siloID) {
			NukeSilos.erase(i);
			break;
		}
	}
}




// add a new factory
void CUnitHandler::FactoryAdd(int factory) {
	if (ai->ut->GetCategory(factory) == CAT_FACTORY) {
		Factory newFact;
		newFact.id = factory;
		Factories.push_back(newFact);
	} else {
		assert(false);
	}
}

void CUnitHandler::FactoryRemove(int id) {
	list<Factory>::iterator iter;
	bool factoryFound = false;

	for (list<Factory>::iterator i = Factories.begin(); i != Factories.end(); i++) {
		if (i->id == id) {
			iter = i;
			factoryFound = true;
			break;
		}
	}
	if (factoryFound) {
		// remove all builders from this plan
		list<BuilderTracker*> builderTrackers = iter->supportBuilderTrackers;

		for (list<BuilderTracker*>::iterator i = builderTrackers.begin(); i != builderTrackers.end(); i++) {
			FactoryBuilderRemove(*i);
		}

		Factories.erase(iter);
	}
}



bool CUnitHandler::FactoryBuilderAdd(int builder) {
	BuilderTracker* builderTracker = GetBuilderTracker(builder);
	return FactoryBuilderAdd(builderTracker);
}



bool CUnitHandler::FactoryBuilderAdd(BuilderTracker* builderTracker) {
	assert(builderTracker->buildTaskId == 0);
	assert(builderTracker->taskPlanId == 0);
	assert(builderTracker->factoryId == 0);
	assert(builderTracker->customOrderId == 0);

	for (list<Factory>::iterator i = Factories.begin(); i != Factories.end(); i++) {
		float totalbuildercost = 0.0f;

		// HACK
		for (list<int>::iterator j = i->supportbuilders.begin(); j != i->supportbuilders.end(); j++) {
			totalbuildercost += ai->math->GetUnitCost(*j);
		}

		if (totalbuildercost < ai->math->GetUnitCost(i->id) * BUILDERFACTORYCOSTRATIO) {
			builderTracker->factoryId = i->id;
			i->supportbuilders.push_back(builderTracker->builderID);
			i->supportBuilderTrackers.push_back(builderTracker);
			ai->MyUnits[builderTracker->builderID]->Guard(i->id);
			return true;
		}
	}

	return false;
}

void CUnitHandler::FactoryBuilderRemove(BuilderTracker* builderTracker) {
	assert(builderTracker->buildTaskId == 0);
	assert(builderTracker->taskPlanId == 0);
	assert(builderTracker->factoryId != 0);
	assert(builderTracker->customOrderId == 0);
	list<Factory>::iterator killfactory;

	for (list<Factory>::iterator i = Factories.begin(); i != Factories.end(); i++) {
		if (builderTracker->factoryId == i->id) {
			i->supportbuilders.remove(builderTracker->builderID);
			i->supportBuilderTrackers.remove(builderTracker);
			builderTracker->factoryId = 0;
			// give it time to change command
			builderTracker->commandOrderPushFrame = ai->cb->GetCurrentFrame();
		}
	}
}





void CUnitHandler::BuilderReclaimOrder(int builderId, float3 pos) {
	pos = pos;
	BuilderTracker* builderTracker = GetBuilderTracker(builderId);
	assert(builderTracker->buildTaskId == 0);
	assert(builderTracker->taskPlanId == 0);
	assert(builderTracker->factoryId == 0);
	assert(builderTracker->customOrderId == 0);
	// Just use taskPlanCounter for the id.
	builderTracker->customOrderId = taskPlanCounter++;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -