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); } } }
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; }
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::DecodeOrder(BuilderTracker* builderTracker, bool reportError) { const int frame = ai->cb->GetCurrentFrame(); const int builderID = builderTracker->builderID; const CCommandQueue* builderQ = ai->cb->GetCurrentUnitCommands(builderID); if (builderQ->size() > 0) { // builder has orders const Command* c = &builderQ->front(); const int n = c->params.size(); const int cID = c->id; if (builderQ->size() == 2 && cID == CMD_MOVE) { // it might have a move order before the real order, // take command nr. 2 if nr. 1 is a move order c = &builderQ->back(); } if (reportError) { std::stringstream msg; msg << "[CUnitHandler::DecodeOrder()][frame=" << frame << "]\n"; msg << "\tbuilder " << builderID << " claimed idle, but has"; msg << " command " << cID << " with " << n << " parameters"; msg << " (params[0]: " << ((n > 0)? c->params[0]: -1) << ")\n"; ai->GetLogger()->Log(msg.str()); } if (cID < 0) { assert(n >= 3); // it's building a unit float3 newUnitPos; newUnitPos.x = c->params[0]; newUnitPos.y = c->params[1]; newUnitPos.z = c->params[2]; const UnitDef* newUnitDef = ai->ut->unitTypes[-cID].def; // make sure that no BuildTasks exists there BuildTask* buildTask = BuildTaskExist(newUnitPos, newUnitDef); if (buildTask) { BuildTaskAddBuilder(buildTask, builderTracker); } else { // make a new TaskPlan (or join an existing one) TaskPlanCreate(builderID, newUnitPos, newUnitDef); } } if (cID == CMD_REPAIR) { assert(n >= 1); // it's repairing, find the unit being repaired int guardingID = int(c->params[0]); bool found = false; UnitCategory cat = ai->ut->GetCategory(guardingID); std::list<BuildTask>::iterator i; if (cat == CAT_LAST) { return; } for (i = BuildTasks[cat].begin(); i != BuildTasks[cat].end(); i++) { if (i->id == guardingID) { // whatever the old order was, update it now bool hit = false; if (builderTracker->buildTaskId != 0) { hit = true; // why is this builder idle? 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) { assert(!hit); hit = true; TaskPlanRemove(builderTracker); } if (builderTracker->factoryId != 0) { assert(!hit); hit = true; FactoryBuilderRemove(builderTracker); } BuildTask* bt = &*i; BuildTaskAddBuilder(bt, builderTracker); found = true; } } if (!found) { // not found, just make a custom order builderTracker->idleStartFrame = -1; } } } else { // error: this function needs a builder with orders // should not be possible because IdleUnitUpdate() // calls us only if a unit's command-queue is NOT // empty? // assert(false); std::stringstream msg; msg << "[CUnitHandler::DecodeOrder()][frame=" << frame << "]\n"; msg << "\tbuilder " << builderID << " should not have an empty queue!\n"; ai->GetLogger()->Log(msg.str()); } }
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::DecodeOrder(BuilderTracker* builderTracker, bool reportError) { // take a look and see what it's doing const CCommandQueue* mycommands = ai->cb->GetCurrentUnitCommands(builderTracker->builderID); if (mycommands->size() > 0) { // builder has orders const Command* c = &mycommands->front(); if (mycommands->size() == 2 && c->id == CMD_MOVE) { //&& (c->id == CMD_MOVE || c->id == CMD_RECLAIM)) // it might have a move order before the real order, // take command nr. 2 if nr. 1 is a move order c = &mycommands->back(); } if (reportError) { char text[512]; sprintf(text, "builder %i: claimed idle, but has command c->id: %i, c->params[0]: %f", builderTracker->builderID, c->id, c->params[0]); } if (c->id < 0) { // it's building a unit float3 newUnitPos; newUnitPos.x = c->params[0]; newUnitPos.y = c->params[1]; newUnitPos.z = c->params[2]; // c.id == -newUnitDef->id const UnitDef* newUnitDef = ai->ut->unitTypes[-c->id].def; // make sure that no BuildTasks exists there BuildTask* buildTask = BuildTaskExist(newUnitPos, newUnitDef); if (buildTask) { BuildTaskAddBuilder(buildTask, builderTracker); } else { // make a new TaskPlan (or join an existing one) TaskPlanCreate(builderTracker->builderID, newUnitPos, newUnitDef); } } if (c->id == CMD_REPAIR) { // it's repairing int guardingID = int(c->params[0]); // find the unit being repaired int category = ai->ut->GetCategory(guardingID); bool found = false; if (category == -1) return; for (list<BuildTask>::iterator i = BuildTasks[category].begin(); i != BuildTasks[category].end(); i++) { if (i->id == guardingID) { // whatever the old order was, update it now bool hit = false; if (builderTracker->buildTaskId != 0) { hit = true; // why is this builder idle? 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) { assert(!hit); hit = true; TaskPlanRemove(builderTracker); } if (builderTracker->factoryId != 0) { assert(!hit); hit = true; FactoryBuilderRemove(builderTracker); } if (builderTracker->customOrderId != 0) { assert(!hit); hit = true; builderTracker->customOrderId = 0; } BuildTask* bt = &*i; BuildTaskAddBuilder(bt, builderTracker); found = true; } } if (!found) { // not found, just make a custom order builderTracker->customOrderId = taskPlanCounter++; builderTracker->idleStartFrame = -1; } } } else { // error: this function needs a builder with orders assert(false); } }
bool CUnitHandler::BuildTaskAddBuilder (int builder, int category) { //L("BuildTaskAddBuilder: " << builder); assert(category >= 0); assert(category < LASTCATEGORY); assert(builder >= 0); assert(ai->MyUnits[builder] != NULL); BuilderTracker * builderTracker = GetBuilderTracker(builder); // Make shure this builder is free: assert(builderTracker->taskPlanId == 0); assert(builderTracker->buildTaskId == 0); assert(builderTracker->factoryId == 0); assert(builderTracker->customOrderId == 0); // 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; } } // HACK^2 Korgothe... this thing dont exist... if(TaskPlans[category]->size()) { //L("TaskPlans[category]->size()"); float largestime = 0; list<TaskPlan>::iterator besttask; int units[5000]; //redo: 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); ////L("timebuilding: " << timebuilding << " of " << i->def->humanName); // Must test if this builder can make this unit/building too if(timebuilding > largestime){ const UnitDef *buildeDef = ai->cb->GetUnitDef(builder); vector<int> * canBuildList = &ai->ut->unittypearray[buildeDef->id].canBuildList; int size = canBuildList->size(); int thisBuildingID = i->def->id; //bool canBuild = false; // Not needed, for(int j = 0; j < size; j++) { if(canBuildList->at(j) == thisBuildingID) { //canBuild = true; largestime = timebuilding; besttask = i; break; } } } int num = ai->cb->GetFriendlyUnits(units, i->pos,200); //returns all friendly units within radius from pos for(int j = 0; j < num; j++) { ////L("Found unit at spot"); if((ai->cb->GetUnitDef(units[j]) == i->def) && (ai->cb->GetUnitPos(units[j]).distance2D(i->pos)) < 1 ) { // HACK !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! //L("if((ai->cb->GetUnitDef(units[j]) == i->def) && (ai->cb->GetUnitPos(units[j]).distance2D(i->pos)) < 1 )"); //L("TODO: Kill this TaskPlan -- this is BAD -- its on a spot where a building is"); // TODO: Kill this TaskPlan // But not here... as that will mess up the iterator //assert(false); //TaskPlans[category]->erase(i); //largestime = 0; //goto redo; } } } //L("largestime: " << largestime); if(largestime > 10){ //L("joining the building of " << besttask->def->humanName); assert(builder >= 0); assert(ai->MyUnits[builder] != NULL); // This is bad. as ai->MyUnits[builder]->Build use TaskPlanCreate() // It will work however ai->MyUnits[builder]->Build(besttask->pos, besttask->def); return true; } } return false; }
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 } } }
void CUnitHandler::DecodeOrder(BuilderTracker* builderTracker, bool reportError) { reportError = reportError; // If its without orders then try to find the lost command // TODO: All of it!!!!!!!!!!!!!! // 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 const Command* c = &mycommands->front(); if(mycommands->size() == 2 && c->id == CMD_MOVE)//&& (c->id == CMD_MOVE || c->id == CMD_RECLAIM)) { // Hmm, it might have a move order before the real order // Take command nr. 2 if nr.1 is a move order c = &mycommands->back(); } //L("idle builder: " << builderTracker->builderID); //L("c->id: " << c->id); //L("c->params[0]: " << c->params[0]); char text[512]; sprintf(text, "builder %i: was clamed idle, but it have a command c->id: %i, c->params[0]: %f", builderTracker->builderID, c->id, c->params[0]); AIHCAddMapPoint amp; amp.label = text; amp.pos = ai->cb->GetUnitPos(builderTracker->builderID); ////ai->cb->HandleCommand(&); if(c->id < 0) // Its building a unit { float3 newUnitPos; newUnitPos.x = c->params[0]; newUnitPos.y = c->params[1]; newUnitPos.z = c->params[2]; // c.id == -newUnitDef->id const UnitDef* newUnitDef = ai->ut->unittypearray[-c->id].def; // Now make shure that no BuildTasks exists there BuildTask* buildTask = BuildTaskExist(newUnitPos, newUnitDef); if(buildTask) { BuildTaskAddBuilder(buildTask, builderTracker); } else // Make a new TaskPlan (or join an existing one) TaskPlanCreate(builderTracker->builderID, newUnitPos, newUnitDef); } if(c->id == CMD_REPAIR) // Its repairing ( || c.id == CMD_GUARD) { int guardingID = int(c->params[0]); // Find the unit its repairng int category = ai->ut->GetCategory(guardingID); if(category == -1) return; // This is bad.... bool found = false; for(list<BuildTask>::iterator i = BuildTasks[category]->begin(); i != BuildTasks[category]->end(); i++){ if(i->id == guardingID) { // Whatever the old order was, update it now... bool hit = false; if(builderTracker->buildTaskId != 0) { hit = true; // Hmm, why is this builder idle ??? 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); hit = true; TaskPlanRemove(builderTracker); //return; } if(builderTracker->factoryId != 0) { assert(!hit); hit = true; FactoryBuilderRemove(builderTracker); } if(builderTracker->customOrderId != 0) { assert(!hit); hit = true; builderTracker->customOrderId = 0; } BuildTask* bt = &*i; //L("Adding builder to BuildTask " << bt->id << ": " << ai->cb->GetUnitDef(bt->id)->humanName); BuildTaskAddBuilder(bt, builderTracker); found = true; } } if(found == false) { // Not found, just make a custom order //L("Not found, just make a custom order"); builderTracker->customOrderId = taskPlanCounter++; builderTracker->idleStartFrame = -1; // Its in use now } } } else { // Error: this function needs a builder with orders //L("Error: this function needs a builder with orders"); assert(false); } }