示例#1
0
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);
			}
		}
	}
}
示例#3
0
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;
				}
			}
			
		}
	}
}
示例#5
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);
		}
	}
}
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(&amp);
			// 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(&amp2);
						} 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
		}
	}
}