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::IdleUnitRemove(int unit) { int category = ai->ut->GetCategory(unit); if (category != -1) { IdleUnits[category].remove(unit); if (category == CAT_BUILDER) { BuilderTracker* builderTracker = GetBuilderTracker(unit); builderTracker->idleStartFrame = -1; if (builderTracker->commandOrderPushFrame == -2) { // bad } // update the order start frame builderTracker->commandOrderPushFrame = ai->cb->GetCurrentFrame(); // assert(builderTracker->buildTaskId == 0); // assert(builderTracker->taskPlanId == 0); // assert(builderTracker->factoryId == 0); } list<integer2>::iterator tempunit; bool foundit = false; for (list<integer2>::iterator i = Limbo.begin(); i != Limbo.end(); i++) { if (i->x == unit) { tempunit = i; foundit = true; } } if (foundit) Limbo.erase(tempunit); } }
void CUnitHandler::BuilderReclaimOrder(int builderId, const float3&) { BuilderTracker* builderTracker = GetBuilderTracker(builderId); assert(builderTracker->buildTaskId == 0); assert(builderTracker->taskPlanId == 0); assert(builderTracker->factoryId == 0); taskPlanCounter++; }
void CUnitHandler::IdleUnitAdd(int unit, int frame) { int category = ai->ut->GetCategory(unit); if (category != -1) { 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 if (category == CAT_BUILDER) { if (false) { // KLOOTNOTE: somehow we are now reaching this branch // on initialization when USE_CREG is not defined, // mycommands->size() returns garbage? BuilderTracker* builderTracker = GetBuilderTracker(unit); DecodeOrder(builderTracker, true); } } } } }
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++; }
void CUnitHandler::TaskPlanCreate(int builder, float3 pos, const UnitDef* builtdef) { UnitCategory category = ai->ut->GetCategory(builtdef); // HACK if (category >= CAT_LAST) { return; } // find this builder BuilderTracker* builderTracker = GetBuilderTracker(builder); // make sure this builder is free bool b1 = (builderTracker->taskPlanId == 0); bool b2 = (builderTracker->buildTaskId == 0); bool b3 = (builderTracker->factoryId == 0); if (!b1 || !b2 || !b3) { return; } bool existingTP = false; for (std::list<TaskPlan>::iterator i = TaskPlans[category].begin(); i != TaskPlans[category].end(); i++) { if (pos.distance2D(i->pos) < 20.0f && builtdef == i->def) { // make sure there are no other TaskPlans if (!existingTP) { existingTP = true; TaskPlanAdd(&*i, builderTracker); } else { std::stringstream msg; msg << "[CUnitHandler::TaskPlanCreate()][frame=" << ai->cb->GetCurrentFrame() << "]\n"; msg << "\ttask-plan for \"" << builtdef->humanName << "\" already present"; msg << " at position <" << pos.x << ", " << pos.y << ", " << pos.z << ">\n"; ai->GetLogger()->Log(msg.str()); } } } 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::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::TaskPlanCreate(int builder, float3 pos, const UnitDef* builtdef) { int category = ai->ut->GetCategory(builtdef); // TODO: Temp hack if(category == -1) return; assert(category >= 0); assert(category < LASTCATEGORY); // Find this builder: BuilderTracker * builderTracker = GetBuilderTracker(builder); // Make shure this builder is free: assert(builderTracker->buildTaskId == 0); assert(builderTracker->taskPlanId == 0); assert(builderTracker->factoryId == 0); assert(builderTracker->customOrderId == 0); 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){ assert(!existingtp); // Make shure there are no other TaskPlan there existingtp = true; TaskPlanAdd(&*i, builderTracker); } } if(!existingtp){ TaskPlan tp; tp.pos = pos; tp.def = builtdef; 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::IdleUnitRemove(int unit) { int category = ai->ut->GetCategory(unit); if(category != -1){ ////L("removing unit"); //L("IdleUnitRemove(): " << unit); IdleUnits[category]->remove(unit); if(category == CAT_BUILDER) { BuilderTracker* builderTracker = GetBuilderTracker(unit); builderTracker->idleStartFrame = -1; // Its not in the idle list now if(builderTracker->commandOrderPushFrame == -2) { // bad ////L("bad"); } builderTracker->commandOrderPushFrame = ai->cb->GetCurrentFrame(); // Update the order start frame... //assert(builderTracker->buildTaskId == 0); //assert(builderTracker->taskPlanId == 0); //assert(builderTracker->factoryId == 0); } ////L("removed from list"); list<integer2>::iterator tempunit; bool foundit = false; for(list<integer2>::iterator i = Limbo.begin(); i != Limbo.end(); i++){ if(i->x == unit){ tempunit = i; foundit=true; //L("foundit=true;"); } } if(foundit) Limbo.erase(tempunit); ////L("removed from limbo"); } }
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::FactoryBuilderAdd(int builderID) { CUNIT* unit = ai->GetUnit(builderID); BuilderTracker* builderTracker = GetBuilderTracker(builderID); return ((unit->def()->canAssist) && FactoryBuilderAdd(builderTracker)); }
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; }
bool CUnitHandler::FactoryBuilderAdd(int builder) { BuilderTracker* builderTracker = GetBuilderTracker(builder); return FactoryBuilderAdd(builderTracker); }
bool CUnitHandler::FactoryBuilderAdd(int builderID) { bool b = (ai->MyUnits[builderID]->def())->canAssist; BuilderTracker* builderTracker = GetBuilderTracker(builderID); return (b && FactoryBuilderAdd(builderTracker)); }
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; }