📄 unithandler.cpp
字号:
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 + -