int GetPriority (Unit e)
	{
	int		ep;

	if (!e)
		return 0;

	ep = OrderPriority[e->GetUnitOrders()] + OrderPriority[GetGroundOrders(e->GetUnitNormalRole())];
	if (e->Broken())
		ep /= 2;
	return ep;
	}
int GetNewRole (Unit e, Unit brig)
	{
	int		brole = brig->GetUnitCurrentRole();
	int		role = e->GetUnitNormalRole();
	if (e->Broken())
		role = GRO_RESERVE;
	// Swap special roles
	if (role == GRO_AIRBORNE || role == GRO_ASSAULT)
		role = brole;
	// Modify assignment role by normal role
	if (role == GRO_ATTACK && brole != GRO_ATTACK)
		role = brole;
	else if (role == GRO_DEFENSE && brole == GRO_ATTACK)
		role = GRO_ATTACK;
	return role;
	}
int BrigadeClass::MoveUnit (CampaignTime time)
	{
	Unit			e;
	int				en,me,be,te,toorder,role;
	F4PFList		nearlist = NULL;
	Objective		o;
	
	// Check if we have a valid objective
	o = GetUnitObjective();
	if (!o || !TeamInfo[GetTeam()]->gtm->IsValidObjective(GetOrders(),o))
		{
		if (o && (GetOrders() == GORD_CAPTURE || GetOrders() == GORD_ASSAULT || GetOrders() == GORD_AIRBORNE))
			SetUnitOrders(GORD_SECURE,o->Id());
		else
			{
			o = FindRetreatPath(this,3,FIND_SECONDARYONLY);
			if (!o)
				{
				// We've been cut off - surrender?
				CheckForSurrender();
				return -1;
				}
			SetUnitOrders(GORD_RESERVE,o->Id());
			}
		}

	// Check if we have elements requesting orders
	role = GetUnitCurrentRole();
	toorder = te = 0;
	e = GetFirstUnitElement();
	while (e)
		{
		te++;
		if (!e->Assigned())
			toorder++;
		e = GetNextUnitElement();
		}
	if (!te)
		{
		KillUnit();
		return 0;
		}

	// Support brigades just update their position and return
	if (FindUnitSupportRole(this))
		{
		UpdateParentStatistics();
		return 0;
		}

	// Check to make sure our orders are still valid.
//	if (!CheckTactic(GetUnitTactic()))
	ChooseTactic();

	// Upon new orders, reset our element's ordered flags && collect list of possible positions
	if (Ordered() || toorder)
		{
		Objective	o;

		o = GetUnitObjective();
		if (role == GRO_ATTACK)
			nearlist = GetChildObjectives(o, MAXLINKS_FROM_SO_OFFENSIVE, FIND_STANDARDONLY);
		else
			nearlist = GetChildObjectives(o, MAXLINKS_FROM_SO_DEFENSIVE, FIND_STANDARDONLY);

		// Eliminate any objectives we've previously been unable to find a path to

		// Clear all but attack orders (once we attack, we only stop when we break)
		e = GetFirstUnitElement();
		while (e)
			{
			if (!e->Broken() && !e->Engaged() && e->Assigned() && e->GetUnitCurrentRole() != GRO_ATTACK)
				{
				e->SetAssigned(0);
				toorder++;
				}
			else if (e->Assigned() && !OnValidObjective(e, e->GetUnitCurrentRole(), nearlist))
				{
				e->SetAssigned(0);
				toorder++;
				}
			e = GetNextUnitElement();
			}

		// Loop in here until all our elements are assigned
		while (toorder)
			{
			// Order elements
			e = GetFirstUnitElement();
			while (e)
				{
				if (!e->Assigned())
					OrderElement(e, nearlist);
				e = GetNextUnitElement();
				}
			// Check for pre-empted elements
			for (en=toorder=0; en<te; en++)
				{
				e = GetUnitElement(en);
				if (e && !e->Assigned())
					toorder++;
				}
			}

		if (nearlist)
			{
			nearlist->DeInit();
			delete nearlist;
			nearlist = NULL;
			}
		}

	// Make sure at least somebody is doing our job
	for (me=be=en=0; en<te; en++)
	{
		e = GetUnitElement(en);
		if (e)
		{
			if (e->Broken())
			{
				be++;
			}
			else if (e->GetUnitCurrentRole() == role)
			{
				me++;
			}
		}
	}

	// Check for broken status
	if (be > me)
		SetBroken(1);

	// Check if we're still valid to perform our orders
	if (!me)
		{
		if (role == GRO_ATTACK)
			SetOrders (GORD_DEFEND);				// Switch to defense orders
		else if (GetOrders() != GORD_RESERVE)
			SetUnitObjective(FalconNullId);		// We'll pick a reserve location next time through
		}

	UpdateParentStatistics();

	return 0;
	}
Example #4
0
void GroundTaskingManagerClass::AddToLists (Unit u, int to_collect)
{
	int i,role;

	// Units with valid orders are not reassigned
	if (u->GetUnitOrders() != GRO_RESERVE)
	{
		int orders = u->GetUnitOrders();
		if ((to_collect & (0x01 << orders)) && IsValidObjective(orders,u->GetUnitObjective()))
		{
			Objective	o = u->GetUnitObjective();
			GODNode		curo = objList[orders];
			while (curo)
			{
				if (curo->obj == o)
				{
					if (orders == GORD_CAPTURE)
						sOffensiveAssigned++;
#ifdef KEV_GDEBUG
					UnitCount[orders]++;
#endif
					AssignUnit(u,orders,o,999);
					// Their objective is removed from the satisfy list
					if (objList[orders])
						objList[orders] = objList[orders]->Remove(o);
					return;
				}
				curo = curo->next;
			}
		}
	}

	// Immobile units just do what they do best..
	if (u->GetMovementType() == NoMove)
	{
		GridIndex	x,y;
		Objective	o;
		float		d=-1.0F;
		u->GetLocation(&x,&y);
		o = FindNearestObjective(x,y,&d);
		if (!o || d > 2.0F || GetRoE(o->GetTeam(),owner,ROE_GROUND_FIRE) == ROE_ALLOWED)
		{
			// Overrun!
			u->KillUnit();
			return;
		}
		i = GetGroundOrders(u->GetUnitNormalRole());
#ifdef KEV_GDEBUG
		UnitCount[i]++;
#endif
		AssignUnit(u,i,o,999);
		if (objList[i])
			objList[i] = objList[i]->Remove(o);
		return;
	}

	// Broken/unsupplied units get tasked as reserve only
	if (u->Broken() || u->GetUnitSupply() < 50)
	{
		AddToList(u, GORD_RESERVE);
		return;
	}

	u->SetUnitOrders(GORD_RESERVE);
	u->SetAssigned(0);

	// Check for one role units
	role = u->GetUnitNormalRole();
	if (role == GRO_FIRESUPPORT || role == GRO_AIRDEFENSE || role == GRO_ENGINEER) // KCK: Radar units here?
	{
		AddToList(u, GetGroundOrders(role));
		AddToList(u, GORD_RESERVE);
		return;
	}

	// Add it to a list for each type of orders it's capible of performing
	for (i=0; i<GORD_LAST; i++)
	{
		if (!(to_collect & (0x01 << i)))
			continue;
		if (i == GORD_ASSAULT && u->GetUnitNormalRole() != GRO_ASSAULT)
			continue;
		if (i == GORD_COMMANDO && !u->Commando())
			continue;
		if (i == GORD_AIRBORNE && u->GetUnitNormalRole() != GRO_AIRBORNE)
			continue;
		if (i == GORD_SUPPORT || i == GORD_REPAIR || i == GORD_AIRDEFENSE)
			continue;
		if (i == GORD_RADAR && u->GetUnitNormalRole() != GRO_RECON)
			continue;
		if (!i || u->GetUnitRoleScore(GetGroundRole(i), CALC_MAX, 0) > MIN_ALLOWABLE_ROLE_SCORE)
		{
			// Add to canidate list
			AddToList(u, i);
		}
	}
}