void CUnitHandler::UnitDestroyed(int unitID) { UnitCategory category = ai->ut->GetCategory(unitID); const UnitDef* unitDef = ai->cb->GetUnitDef(unitID); if (category != CAT_LAST) { assert(!ai->GetUnit(unitID)->isDead); ai->GetUnit(unitID)->isDead = true; AllUnitsByType[unitDef->id].remove(unitID); AllUnitsByCat[category].remove(unitID); IdleUnitRemove(unitID); BuildTaskRemove(unitID); if (category == CAT_DEFENCE) { ai->dm->RemoveDefense(ai->cb->GetUnitPos(unitID), unitDef); } if (category == CAT_MMAKER) { MMakerRemove(unitID); } if (category == CAT_FACTORY) { FactoryRemove(unitID); } if (category == CAT_BUILDER) { // remove the builder for (std::list<BuilderTracker*>::iterator i = BuilderTrackers.begin(); i != BuilderTrackers.end(); i++) { if ((*i)->builderID == unitID) { if ((*i)->buildTaskId) BuildTaskRemove(*i); if ((*i)->taskPlanId) TaskPlanRemove(*i); if ((*i)->factoryId) FactoryBuilderRemove(*i); BuilderTracker* builderTracker = *i; BuilderTrackers.erase(i); delete builderTracker; break; } } } if (category == CAT_MEX) { MetalExtractorRemove(unitID); } if (category == CAT_NUKE) { NukeSiloRemove(unitID); } } }
void CUnitHandler::IdleUnitAdd(int unit) { //L("IdleUnitAdd: " << unit); int category = ai->ut->GetCategory(unit); if(category != -1){ const deque<Command>* mycommands = ai->cb->GetCurrentUnitCommands(unit); if(mycommands->empty()){ if(category == CAT_BUILDER) { BuilderTracker* builderTracker = GetBuilderTracker(unit); //L("it was a builder"); // Add clear here ClearOrder(builderTracker, true); if(builderTracker->idleStartFrame == -2) { // It was in the idle list allready ? IdleUnitRemove(builderTracker->builderID); } builderTracker->idleStartFrame = -2; // Its in the idle list now if(builderTracker->commandOrderPushFrame == -2) // Make shure that if the unit was just built it will have some time to leave the factory { builderTracker->commandOrderPushFrame = ai->cb->GetCurrentFrame() + 30*3; } //else if(builderTracker->commandOrderPushFrame == -) // builderTracker->commandOrderPushFrame = ; } integer2 myunit(unit,LIMBOTIME); //L("Adding unit : " << myunit.x << " To Limbo " << myunit.y); Limbo.remove(myunit); //IdleUnitRemove(unit); // This might be a better idea, but its over the edge (possible assertion) Limbo.push_back(myunit); } else { // The unit have orders still if(category == CAT_BUILDER) { BuilderTracker* builderTracker = GetBuilderTracker(unit); assert(false); DecodeOrder(builderTracker, true); } } } }
void CUnitHandler::IdleUnitAdd(int unit, int frame) { UnitCategory category = ai->ut->GetCategory(unit); if (category != CAT_LAST) { const CCommandQueue* myCommands = ai->cb->GetCurrentUnitCommands(unit); if (myCommands->empty()) { if (category == CAT_BUILDER) { BuilderTracker* builderTracker = GetBuilderTracker(unit); // add clear here ClearOrder(builderTracker, true); if (builderTracker->idleStartFrame == -2) { // it was in the idle list already? IdleUnitRemove(builderTracker->builderID); } builderTracker->idleStartFrame = -2; if (builderTracker->commandOrderPushFrame == -2) { // make sure that if the unit was just built // it will have some time to leave the factory builderTracker->commandOrderPushFrame = frame + 30 * 3; } } integer2 myunit(unit, LIMBOTIME); Limbo.remove(myunit); Limbo.push_back(myunit); } else { // the unit has orders still, so should not be idle if (category == CAT_BUILDER) { if (false) { // KLOOTNOTE: somehow we are reaching this branch // on initialization when USE_CREG is not defined, // mycommands->size() returns garbage? // // BuilderTracker* builderTracker = GetBuilderTracker(unit); // DecodeOrder(builderTracker, true); } } } } }
void CUnitHandler::UnitDestroyed(int unit) { int category = ai->ut->GetCategory(unit); const UnitDef* unitDef = ai->cb->GetUnitDef(unit); if(category != -1){ AllUnitsByType[unitDef->id]->remove(unit); AllUnitsByCat[category]->remove(unit); IdleUnitRemove(unit); BuildTaskRemove(unit); if(category == CAT_DEFENCE){ ai->dm->RemoveDefense(ai->cb->GetUnitPos(unit),unitDef); } if(category == CAT_MMAKER){ MMakerRemove(unit); } if(category == CAT_FACTORY) { FactoryRemove(unit); } if(category == CAT_BUILDER) { // Remove the builder for(list<BuilderTracker*>::iterator i = BuilderTrackers.begin(); i != BuilderTrackers.end(); i++){ if((*i)->builderID == unit) { if((*i)->buildTaskId) BuildTaskRemove(*i); if((*i)->taskPlanId) TaskPlanRemove(*i); if((*i)->factoryId) FactoryBuilderRemove(*i); BuilderTracker* builderTracker = *i; BuilderTrackers.erase(i); delete builderTracker; // Test this break; } } } } }
void CUnitHandler::BuildTaskCreate(int id) { const UnitDef* newUnitDef = ai->cb->GetUnitDef(id); const UnitCategory category = ai->ut->GetCategory(id); const float3 pos = ai->cb->GetUnitPos(id); if ((!newUnitDef->movedata || category == CAT_DEFENCE) && !newUnitDef->canfly && category != CAT_LAST) { // this needs to change, so that it can make more stuff if (category >= CAT_LAST) { return; } BuildTask bt; bt.id = -1; std::list<TaskPlan>::iterator i; for (i = TaskPlans[category].begin(); i != TaskPlans[category].end(); i++) { if (pos.distance2D(i->pos) < 1.0f && newUnitDef == i->def) { bt.category = category; bt.id = id; bt.pos = i->pos; bt.def = newUnitDef; std::list<BuilderTracker*> moveList; for (std::list<BuilderTracker*>::iterator builder = i->builderTrackers.begin(); builder != i->builderTrackers.end(); builder++) { moveList.push_back(*builder); } for (std::list<BuilderTracker*>::iterator builder = moveList.begin(); builder != moveList.end(); builder++) { TaskPlanRemove(*builder); BuildTaskAddBuilder(&bt, *builder); } // there can not be more than one found TaskPlan break; } } if (bt.id == -1) { // buildtask creation error (can happen if builder manages // to restart a dead building, or a human has taken control), // make one anyway std::stringstream msg; msg << "[CUnitHandler::BuildTaskCreate()][frame=" << ai->cb->GetCurrentFrame() << "]\n"; msg << "\tBuildTask Creation Error for task with ID " << id << "\n"; ai->GetLogger()->Log(msg.str()); if (category == CAT_DEFENCE) { ai->dm->AddDefense(pos, newUnitDef); } bt.category = category; bt.id = id; bt.pos = pos; bt.def = newUnitDef; // if we have any friendly builders for (std::list<BuilderTracker*>::iterator i = BuilderTrackers.begin(); i != BuilderTrackers.end(); i++) { BuilderTracker* builderTracker = *i; // check what builder is doing const CCommandQueue* cq = ai->cb->GetCurrentUnitCommands(builderTracker->builderID); if (!cq->empty()) { Command c = cq->front(); const bool b0 = (c.id == -newUnitDef->id && c.params[0] == pos.x && c.params[2] == pos.z); // at this pos const bool b1 = (c.id == CMD_REPAIR && c.params[0] == id); // at this unit (id) const bool b2 = (c.id == CMD_GUARD && c.params[0] == id); // at this unit (id) const bool b3 = b0 || b1 || b2; if (b3) { if (builderTracker->buildTaskId != 0) { BuildTask* buildTask = GetBuildTask(builderTracker->buildTaskId); if (buildTask->builderTrackers.size() > 1) { BuildTaskRemove(builderTracker); } else { // only builder of this thing, and now idle BuildTaskRemove(builderTracker); } } if (builderTracker->taskPlanId != 0) { GetTaskPlan(builderTracker->taskPlanId); TaskPlanRemove(builderTracker); } if (builderTracker->factoryId != 0) { FactoryBuilderRemove(builderTracker); } // this builder is now free if (builderTracker->idleStartFrame == -2) { IdleUnitRemove(builderTracker->builderID); } // add it to this task BuildTaskAddBuilder(&bt, builderTracker); msg.str(""); msg << "\tadded builder " << builderTracker->builderID << " to"; msg << " build-task with ID " << builderTracker->buildTaskId << "\n"; ai->GetLogger()->Log(msg.str()); } } } // add the task anyway BuildTasks[category].push_back(bt); } else { if (category == CAT_DEFENCE) ai->dm->AddDefense(pos,newUnitDef); BuildTasks[category].push_back(bt); } } }
void CUnitHandler::BuildTaskCreate(int id) { const UnitDef* newUnitDef = ai->cb->GetUnitDef(id); int category = ai->ut->GetCategory(id); float3 pos = ai->cb->GetUnitPos(id); if ((!newUnitDef->movedata || category == CAT_DEFENCE) && !newUnitDef->canfly && category != -1) { // this needs to change, so that it can make more stuff if (category == -1) return; assert(category >= 0); assert(category < LASTCATEGORY); BuildTask bt; bt.id = -1; redo: for (list<TaskPlan>::iterator i = TaskPlans[category].begin(); i != TaskPlans[category].end(); i++) { if(pos.distance2D(i->pos) < 1 && newUnitDef == i->def){ assert(bt.id == -1); // There can not be more than one TaskPlan that is found; bt.category = category; bt.id = id; bt.pos = i->pos; bt.def = newUnitDef; list<BuilderTracker*> moveList; for (list<BuilderTracker*>::iterator builder = i->builderTrackers.begin(); builder != i->builderTrackers.end(); builder++) { moveList.push_back(*builder); } for (list<BuilderTracker*>::iterator builder = moveList.begin(); builder != moveList.end(); builder++) { TaskPlanRemove(*builder); BuildTaskAddBuilder(&bt, *builder); } goto redo; } } if (bt.id == -1) { // buildtask creation error (can happen if builder manages // to restart a dead building, or a human has taken control), // make one anyway bt.category = category; bt.id = id; if (category == CAT_DEFENCE) ai->dm->AddDefense(pos,newUnitDef); bt.pos = pos; bt.def = newUnitDef; char text[512]; sprintf(text, "BuildTask Creation Error: %i", id); int num = BuilderTrackers.size(); if (num == 0) { // no friendly builders found } else { // iterate over the list and find the builders for (list<BuilderTracker*>::iterator i = BuilderTrackers.begin(); i != BuilderTrackers.end(); i++) { BuilderTracker* builderTracker = *i; // check what builder is doing const CCommandQueue* mycommands = ai->cb->GetCurrentUnitCommands(builderTracker->builderID); if (mycommands->size() > 0) { Command c = mycommands->front(); if ((c.id == -newUnitDef->id && c.params[0] == pos.x && c.params[2] == pos.z) // at this pos || (c.id == CMD_REPAIR && c.params[0] == id) // at this unit (id) || (c.id == CMD_GUARD && c.params[0] == id)) // at this unit (id) { if (builderTracker->buildTaskId != 0) { BuildTask* buildTask = GetBuildTask(builderTracker->buildTaskId); if (buildTask->builderTrackers.size() > 1) { BuildTaskRemove(builderTracker); } else { // only builder of this thing, and now idle BuildTaskRemove(builderTracker); } } if (builderTracker->taskPlanId != 0) { GetTaskPlan(builderTracker->taskPlanId); TaskPlanRemove(builderTracker); } if (builderTracker->factoryId != 0) { FactoryBuilderRemove(builderTracker); } if (builderTracker->customOrderId != 0) { builderTracker->customOrderId = 0; } // this builder is now free if (builderTracker->idleStartFrame == -2) IdleUnitRemove(builderTracker->builderID); // add it to this task BuildTaskAddBuilder(&bt, builderTracker); sprintf(text, "Added builder %i to buildTaskId %i (human order?)", builderTracker->builderID, builderTracker->buildTaskId); } } } } // add the task anyway BuildTasks[category].push_back(bt); } else { if (category == CAT_DEFENCE) ai->dm->AddDefense(pos,newUnitDef); BuildTasks[category].push_back(bt); } } }
void CUnitHandler::BuildTaskCreate(int id) { const UnitDef* newUnitDef = ai->cb->GetUnitDef(id); int category = ai->ut->GetCategory(id); float3 pos = ai->cb->GetUnitPos(id); if((!newUnitDef->movedata || category == CAT_DEFENCE) && !newUnitDef->canfly && category != -1){ // This thing need to change, so that it can make more stuff // TODO: Hack fix if(category == -1) return; assert(category >= 0); assert(category < LASTCATEGORY); BuildTask bt; bt.id = -1; //int killplan; //list<TaskPlan>::iterator killplan; redo: for(list<TaskPlan>::iterator i = TaskPlans[category]->begin(); i != TaskPlans[category]->end(); i++){ if(pos.distance2D(i->pos) < 1 && newUnitDef == i->def){ assert(bt.id == -1); // There can not be more than one TaskPlan that is found; bt.category = category; bt.id = id; bt.pos = i->pos; bt.def = newUnitDef; list<BuilderTracker*> moveList; for(list<BuilderTracker*>::iterator builder = i->builderTrackers.begin(); builder != i->builderTrackers.end(); builder++) { moveList.push_back(*builder); //L("Marking builder " << (*builder)->builderID << " for removal, from plan " << i->def->humanName); } for(list<BuilderTracker*>::iterator builder = moveList.begin(); builder != moveList.end(); builder++) { TaskPlanRemove(*builder); BuildTaskAddBuilder(&bt, *builder); } //bt.builders.push_back(i->builder); //killplan = i->builder; // This plan is gone now // Test it by redoing all: goto redo; // This is a temp } } if(bt.id == -1){ //L("*******BuildTask Creation Error!*********"); // This can happen. // Either a builder manges to restart a dead building, or a human have taken control... // Make a BuildTask anyway bt.category = category; bt.id = id; if(category == CAT_DEFENCE) ai->dm->AddDefense(pos,newUnitDef); bt.pos = pos; bt.def = newUnitDef; char text[512]; sprintf(text, "BuildTask Creation Error: %i", id); AIHCAddMapPoint amp; amp.label = text; amp.pos = pos; ////ai->cb->HandleCommand(&); // Try to find workers that nearby: int num = BuilderTrackers.size(); if(num == 0) { // Well what now ??? //L("Didnt find any friendly builders"); } else { // Iterate over the list and find the builders for(list<BuilderTracker*>::iterator i = BuilderTrackers.begin(); i != BuilderTrackers.end(); i++) { BuilderTracker* builderTracker = *i; // Now take a look, and see what its doing: const deque<Command>* mycommands = ai->cb->GetCurrentUnitCommands(builderTracker->builderID); if(mycommands->size() > 0) { // It have orders Command c = mycommands->front(); //L("builder: " << builderTracker->builderID); //L("c.id: " << c.id); //L("c.params[0]: " << c.params[0]); if( (c.id == -newUnitDef->id && c.params[0] == pos.x && c.params[2] == pos.z) // Its at this pos || (c.id == CMD_REPAIR && c.params[0] == id) // Its at this unit (id) || (c.id == CMD_GUARD && c.params[0] == id) ) // Its at this unit (id) { // Its making this unit // Remove the unit from its current job: bool hit = false; if(builderTracker->buildTaskId != 0) { // Hmm, why is this builder idle ??? // bool hit = true; BuildTask* buildTask = GetBuildTask(builderTracker->buildTaskId); if(buildTask->builderTrackers.size() > 1) { BuildTaskRemove(builderTracker); } else { // This is the only builder of this thing, and now its idle... BuildTaskRemove(builderTracker); // IS this smart at all ??? } } if(builderTracker->taskPlanId != 0) { assert(!hit); // bool hit = true; // Hmm, why is this builder idle ??? // // TaskPlan* taskPlan = GetTaskPlan(builderTracker->taskPlanId); TaskPlanRemove(builderTracker); } if(builderTracker->factoryId != 0) { assert(!hit); // bool hit = true; FactoryBuilderRemove(builderTracker); } if(builderTracker->customOrderId != 0) { assert(!hit); // bool hit = true; builderTracker->customOrderId = 0; } // This builder is now free. if(builderTracker->idleStartFrame == -2) IdleUnitRemove(builderTracker->builderID); // It was in the idle list // Add it to this task //L("Added builder " << builderTracker->builderID << " to this new unit buildTask"); BuildTaskAddBuilder(&bt, builderTracker); sprintf(text, "Added builder %i: to buildTaskId: %i (human order?)", builderTracker->builderID, builderTracker->buildTaskId); AIHCAddMapPoint amp2; amp2.label = text; amp2.pos = ai->cb->GetUnitPos(builderTracker->builderID); ////ai->cb->HandleCommand(&2); } else { // This builder have other orders. } } else { // This builder is without orders (idle) } } } // Add the task anyway BuildTasks[category]->push_back(bt); } else{ if(category == CAT_DEFENCE) ai->dm->AddDefense(pos,newUnitDef); BuildTasks[category]->push_back(bt); //TaskPlanRemove(*killplan); // fix } } }