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);
	}
}
Esempio n. 2
0
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::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(&amp);
		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);
	}
}