// use this only if the unit does not have any orders at the moment void CUnitHandler::ClearOrder(BuilderTracker* builderTracker, bool reportError) { bool hit = false; const int frame = ai->cb->GetCurrentFrame(); const int builderID = builderTracker->builderID; const int buildTaskID = builderTracker->buildTaskId; const int factoryID = builderTracker->factoryId; const CCommandQueue* q = ai->cb->GetCurrentUnitCommands(builderID); assert(q->empty() || !reportError); if (buildTaskID != 0) { hit = true; BuildTask* buildTask = GetBuildTask(buildTaskID); std::stringstream msg; msg << "[CUnitHandler::ClearOrder()][frame=" << frame << "]\n"; msg << "\tbuilder " << builderID << " is reported idle but"; msg << " still has a build-task with ID " << (buildTaskID) << "\n"; ai->GetLogger()->Log(msg.str()); 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; const TaskPlan* taskPlan = GetTaskPlan(builderTracker->taskPlanId); const std::string& taskName = taskPlan->def->humanName; std::stringstream msg; msg << "[CUnitHandler::ClearOrder()][frame=" << frame << "]\n"; msg << "\tbuilder " << builderID << " is reported idle but"; msg << " still has a task-plan named \"" << (taskName) << "\"\n"; ai->GetLogger()->Log(msg.str()); // mask this build-spot as bad ai->dm->MaskBadBuildSpot(taskPlan->pos); // TODO: remove all builders from this plan if (reportError) { std::list<BuilderTracker*> builderTrackers = taskPlan->builderTrackers; std::list<BuilderTracker*>::iterator i; for (i = builderTrackers.begin(); i != builderTrackers.end(); i++) { TaskPlanRemove(*i); ai->GetUnit((*i)->builderID)->Stop(); } } else { TaskPlanRemove(builderTracker); } } if (factoryID != 0) { assert(!hit); hit = true; std::stringstream msg; msg << "[CUnitHandler::ClearOrder()][frame=" << frame << "]\n"; msg << "\tbuilder " << builderID << " is reported idle but"; msg << " still has a factory ID of " << factoryID << "\n"; ai->GetLogger()->Log(msg.str()); // remove the builder from its job FactoryBuilderRemove(builderTracker); } assert(builderTracker->buildTaskId == 0); assert(builderTracker->taskPlanId == 0); assert(builderTracker->factoryId == 0); }
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::VerifyOrder(BuilderTracker* builderTracker) { // if it's without orders then try to find the lost command (TODO) const CCommandQueue* mycommands = ai->cb->GetCurrentUnitCommands(builderTracker->builderID); bool commandFound = false; bool hit = false; if (!mycommands->empty()) { // it has orders const Command* c = &mycommands->front(); if (mycommands->size() == 2) { // it might have a reclaim order, or terrain change order // take command nr. 2 c = &mycommands->back(); } if (builderTracker->buildTaskId != 0) { hit = true; // test that this builder is on repair on this unit BuildTask* buildTask = GetBuildTask(builderTracker->buildTaskId); commandFound = ((c->id == CMD_REPAIR ) && (c->params[0] == builderTracker->buildTaskId)) || ((c->id == -buildTask->def->id) && (c->params[0] == buildTask->pos.x ) && (c->params[2] == buildTask->pos.z )); if (!commandFound) { return false; } } if (builderTracker->taskPlanId != 0) { assert(!hit); hit = true; TaskPlan* taskPlan = GetTaskPlan(builderTracker->taskPlanId); if ((c->id == -taskPlan->def->id) && (c->params[0] == taskPlan->pos.x) && (c->params[2] == taskPlan->pos.z)) commandFound = true; else return false; } if (builderTracker->factoryId != 0) { assert(!hit); hit = true; if (c->id == CMD_GUARD && c->params[0] == builderTracker->factoryId) commandFound = true; else return false; } if (!commandFound) { hit = true; commandFound = (c->id == CMD_RECLAIM || c->id == CMD_MOVE || c->id == CMD_REPAIR); } if (hit && commandFound) { // it's on the right job return true; } } else { if (builderTracker->idleStartFrame == -2) { 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 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); } } }
// use this only if the unit does not have any orders at the moment void CUnitHandler::ClearOrder(BuilderTracker* builderTracker, bool reportError) { bool hit = false; const CCommandQueue* mycommands = ai->cb->GetCurrentUnitCommands(builderTracker->builderID); assert(mycommands->empty() || !reportError); if (builderTracker->buildTaskId != 0) { // why is this builder idle? hit = true; BuildTask* buildTask = GetBuildTask(builderTracker->buildTaskId); char text[512]; sprintf(text, "builder %i: was idle, but it is on buildTaskId: %i (stuck?)", builderTracker->builderID, 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; // why is this builder idle? TaskPlan* taskPlan = GetTaskPlan(builderTracker->taskPlanId); char text[512]; sprintf(text, "builder %i: was idle, but it is on taskPlanId: %s (masking this spot)", builderTracker->builderID, taskPlan->def->humanName.c_str()); ai->dm->MaskBadBuildSpot(taskPlan->pos); // TODO: fix this, remove all builders from this plan if (reportError) { list<BuilderTracker*> builderTrackers = taskPlan->builderTrackers; for (list<BuilderTracker*>::iterator i = builderTrackers.begin(); i != builderTrackers.end(); i++) { TaskPlanRemove(*i); ai->MyUnits[(*i)->builderID]->Stop(); } } else { TaskPlanRemove(builderTracker); } } if (builderTracker->factoryId != 0) { assert(!hit); hit = true; // why is this builder idle? char text[512]; sprintf(text, "builder %i: was idle, but it is on factoryId: %i (removing the builder from the job)", builderTracker->builderID, builderTracker->factoryId); FactoryBuilderRemove(builderTracker); } if (builderTracker->customOrderId != 0) { assert(!hit); hit = true; // why is this builder idle? // no tracking of custom orders yet // char text[512]; // sprintf(text, "builder %i: was idle, but it is on customOrderId: %i (removing the builder from the job)", unit, builderTracker->customOrderId); builderTracker->customOrderId = 0; } assert(builderTracker->buildTaskId == 0); assert(builderTracker->taskPlanId == 0); assert(builderTracker->factoryId == 0); assert(builderTracker->customOrderId == 0); }
/* Use this only if the unit dont have any orders at the moment */ void CUnitHandler::ClearOrder(BuilderTracker* builderTracker, bool reportError) { bool hit = false; const deque<Command>* mycommands = ai->cb->GetCurrentUnitCommands(builderTracker->builderID); assert(mycommands->empty() || !reportError); if(builderTracker->buildTaskId != 0) { // Hmm, why is this builder idle ??? hit = true; //L("builder " << builderTracker->builderID << " was idle, but it is on buildTaskId : " << builderTracker->buildTaskId); BuildTask* buildTask = GetBuildTask(builderTracker->buildTaskId); char text[512]; sprintf(text, "builder %i: was idle, but it is on buildTaskId: %i (stuck?)", builderTracker->builderID, builderTracker->buildTaskId); AIHCAddMapPoint amp; amp.label = text; amp.pos = buildTask->pos; ////ai->cb->HandleCommand(&); 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 ??? } //return; } if(builderTracker->taskPlanId != 0) { assert(!hit); hit = true; // Hmm, why is this builder idle ??? // TaskPlan* taskPlan = GetTaskPlan(builderTracker->taskPlanId); //L("builder " << builderTracker->builderID << " was idle, but it is on taskPlanId : " << taskPlan->def->humanName << " (masking this spot)"); char text[512]; sprintf(text, "builder %i: was idle, but it is on taskPlanId: %s (masking this spot)", builderTracker->builderID, taskPlan->def->humanName.c_str()); AIHCAddMapPoint amp; amp.label = text; amp.pos = taskPlan->pos; ////ai->cb->HandleCommand(&); ai->dm->MaskBadBuildSpot(taskPlan->pos); // TODO: fix this: Remove all builders from this plan. if(reportError) { list<BuilderTracker*> builderTrackers = taskPlan->builderTrackers; // This is a copy of the list for(list<BuilderTracker*>::iterator i = builderTrackers.begin(); i != builderTrackers.end(); i++) { TaskPlanRemove(*i); ai->MyUnits[(*i)->builderID]->Stop(); // Stop the units on the way to this plan } } else { TaskPlanRemove(builderTracker); } //return; } if(builderTracker->factoryId != 0) { assert(!hit); hit = true; // Hmm, why is this builder idle ??? //L("builder " << builderTracker->builderID << " was idle, but it is on factoryId : " << builderTracker->factoryId) << " (removing the builder from the job)"; char text[512]; sprintf(text, "builder %i: was idle, but it is on factoryId: %i (removing the builder from the job)", builderTracker->builderID, builderTracker->factoryId); AIHCAddMapPoint amp; amp.label = text; amp.pos = ai->cb->GetUnitPos(builderTracker->factoryId); ////ai->cb->HandleCommand(&); FactoryBuilderRemove(builderTracker); } if(builderTracker->customOrderId != 0) { assert(!hit); hit = true; // Hmm, why is this builder idle ? // No tracking of custom orders yet... //L("builder " << builderTracker->builderID << " was idle, but it is on customOrderId : " << builderTracker->customOrderId << " (removing the builder from the job)"); //char text[512]; //sprintf(text, "builder %i: was idle, but it is on customOrderId: %i (removing the builder from the job)", unit, builderTracker->customOrderId); //AIHCAddMapPoint amp; //amp.label = text; //amp.pos = ai->cb->GetUnitPos(builderTracker->builderID); //////ai->cb->HandleCommand(&); builderTracker->customOrderId = 0; } assert(builderTracker->buildTaskId == 0); assert(builderTracker->taskPlanId == 0); assert(builderTracker->factoryId == 0); assert(builderTracker->customOrderId == 0); }
bool CUnitHandler::VerifyOrder(BuilderTracker* builderTracker) { // 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); bool commandFound = false; if(mycommands->size() > 0) { // It have orders const Command* c = &mycommands->front(); if(mycommands->size() == 2)//&& (c->id == CMD_MOVE || c->id == CMD_RECLAIM)) { // Hmm, it might have a reclame order, or terrain change order // Take command nr. 2 // Infact, take command nr. 2 anyway... c = &mycommands->back(); } ////L("idle builder: " << builderTracker->builderID); ////L("c.id: " << c.id); ////L("c.params[0]: " << c.params[0]); bool hit = false; if(builderTracker->buildTaskId != 0) { hit = true; // Test that this builder is on repair on this unit: BuildTask* buildTask = GetBuildTask(builderTracker->buildTaskId); if(c->id == CMD_REPAIR && c->params[0] == builderTracker->buildTaskId || (c->id == -buildTask->def->id && c->params[0] == buildTask->pos.x && c->params[2] == buildTask->pos.z)) commandFound = true; // Its ok else return false; } if(builderTracker->taskPlanId != 0) { assert(!hit); hit = true; TaskPlan* taskPlan = GetTaskPlan(builderTracker->taskPlanId); if(c->id == -taskPlan->def->id && c->params[0] == taskPlan->pos.x && c->params[2] == taskPlan->pos.z) commandFound = true; // Its ok else return false; } if(builderTracker->factoryId != 0) { assert(!hit); hit = true; if(c->id == CMD_GUARD && c->params[0] == builderTracker->factoryId) commandFound = true; // Its ok else return false; } if(builderTracker->customOrderId != 0) { assert(!hit); hit = true; // The CMD_MOVE is for human control stuff, CMD_REPAIR is for repairs of just made stuff // CMD_GUARD.... ? if(c->id == CMD_RECLAIM || c->id == CMD_MOVE || c->id == CMD_REPAIR) commandFound = true; // Its ok else { //assert(false); return false; } } if(hit && commandFound) { // Its on the right job return true; } } else { if(builderTracker->idleStartFrame == -2) { return true; } } return false; }