//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
// software: you can redistribute it and/or modify it under the terms of 
// the GNU General Public License as published by the Free Software Foundation, 
// either version 3 of the License, or (at your option) any later version.

// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
// in the hope that it will be useful, but with permitted additional restrictions 
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
// distributed with this program. You should have received a copy of the 
// GNU General Public License along with permitted additional restrictions 
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection

/* $Header: /CounterStrike/REINF.CPP 1     3/03/97 10:25a Joe_bostic $ */
/***********************************************************************************************
 ***              C O N F I D E N T I A L  ---  W E S T W O O D  S T U D I O S               ***
 ***********************************************************************************************
 *                                                                                             *
 *                 Project Name : Command & Conquer                                            *
 *                                                                                             *
 *                    File Name : REINF.CPP                                                    *
 *                                                                                             *
 *                   Programmer : Joe L. Bostic                                                *
 *                                                                                             *
 *                   Start Date : May 24, 1994                                                 *
 *                                                                                             *
 *                  Last Update : July 26, 1996 [JLB]                                          *
 *                                                                                             *
 *---------------------------------------------------------------------------------------------*
 * Functions:                                                                                  *
 *   Create_Air_Reinforcement -- Creates air strike reinforcement                              *
 *   Create_Special_Reinforcement -- Ad hoc reinforcement handler.                             *
 *   Do_Reinforcements -- Create and place a reinforcement team.                               *
 *   _Consists_Only_Of_Infantry -- Determine if this group consists only of infantry.          *
 *   _Create_Group -- Create a group given team specification.                                 *
 *   _Pop_Group_Out_Of_Object -- Process popping the group out of the object.                  *
 *   _Who_Can_Pop_Out_Of -- Find a suitable host for these reinforcements.                     *
 *   _Need_To_Take -- Examines unit to determine if it should be confiscated.                  *
 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */

#include	"function.h"


/***********************************************************************************************
 * _Pop_Group_Out_Of_Object -- Process popping the group out of the object.                    *
 *                                                                                             *
 *    This routine will cause the group to pop out of the object specified.                    *
 *                                                                                             *
 * INPUT:   group    -- Pointer to the first object in the group to be popped out.             *
 *                                                                                             *
 *          object   -- Pointer to the object that the group is to pop out of.                 *
 *                                                                                             *
 * OUTPUT:  bool; Was the group popped out of the specified object?                            *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   06/25/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
static bool _Pop_Group_Out_Of_Object(FootClass * group, TechnoClass * object)
{
	assert(group != NULL && object != NULL);
	int quantity = 0;

	/*
	**	Take every infantry member of this group and detach it from the group list
	**	and then make it pop out of the candidate source.
	*/
	while (group != NULL) {
		TechnoClass * todo = group;
		group = (FootClass *)(ObjectClass *)group->Next;
		todo->Next = NULL;

		switch (object->What_Am_I()) {

			/*
			**	The infantry just walks out of a building.
			*/
			case RTTI_BUILDING:
				if (object->Exit_Object(todo) != 2) {
					delete todo;
				} else {
					++quantity;
				}
				break;

			/*
			**	Infantry get attached to transport vehicles and then unload.
			*/
			case RTTI_UNIT:
			case RTTI_VESSEL:
			case RTTI_AIRCRAFT:
				object->Attach((FootClass *)todo);
				object->Assign_Mission(MISSION_UNLOAD);
				++quantity;
				break;

			default:
				delete todo;
				break;
		}
	}

	return (quantity != 0);
}


/***********************************************************************************************
 * _Need_To_Take -- Examines unit to determine if it should be confiscated.                    *
 *                                                                                             *
 *    The unit is examined and if the owning house needs to confiscate it, then this routine   *
 *    will return TRUE. In other cases, the unit should be left to its own devices.            *
 *                                                                                             *
 * INPUT:   unit  -- Pointer to the object to examine.                                         *
 *                                                                                             *
 * OUTPUT:  bool; Should the object be confiscated by the player so that it becomes one of     *
 *                his normal game objects?                                                     *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   07/26/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
bool _Need_To_Take(AircraftClass const * air)
{
	if (*air == AIRCRAFT_YAK || *air == AIRCRAFT_MIG) {
		int deficit = air->House->Get_Quantity(STRUCT_AIRSTRIP);
//		int deficit = air->House->Get_Quantity(STRUCT_AIRSTRIP) - (air->House->Get_Quantity(AIRCRAFT_YAK)+air->House->Get_Quantity(AIRCRAFT_MIG));

		/*
		**	Loop through all aircraft and subtract all the ones that are NOT loaners.
		*/
		for (int index = 0; index < Aircraft.Count(); index++) {
			AircraftClass const * airptr = Aircraft.Ptr(index);
			if ((*airptr == AIRCRAFT_YAK || *airptr == AIRCRAFT_MIG) && airptr->IsOwnedByPlayer && !airptr->IsALoaner && airptr != air) {
				deficit -= 1;
				if (deficit == 0) break;
			}
		}

		if (deficit > 0) return(true);
	}
	return(false);
}


/***********************************************************************************************
 * _Create_Group -- Create a group given team specification.                                   *
 *                                                                                             *
 *    This routine will create all members of the group as specified by the team type.         *
 *                                                                                             *
 * INPUT:   teamtype -- Pointer to the team type that specifies what objects should be         *
 *                      created in this group.                                                 *
 *                                                                                             *
 * OUTPUT:  Returns with a pointer to the first member of the group created.                   *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   06/25/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
static FootClass * _Create_Group(TeamTypeClass const * teamtype)
{
	assert(teamtype != NULL);

	TeamClass * team = new TeamClass(teamtype);
	if (team != NULL) {
		team->Force_Active();
	}

	bool hasunload = false;
	for (int tm = 0; tm < teamtype->MissionCount; tm++) {
		if (teamtype->MissionList[tm].Mission == TMISSION_UNLOAD) {
			hasunload = true;
			break;
		}
	}

	/*
	**	Now that the official source for the reinforcement has been determined, the
	**	objects themselves must be created.
	*/
	FootClass * transport = NULL;
	FootClass * object = NULL;
	for (int index = 0; index < teamtype->ClassCount; index++) {
		TechnoTypeClass const * tclass = teamtype->Members[index].Class;

		for (int sub = 0; sub < teamtype->Members[index].Quantity; sub++) {
			ScenarioInit++;
			FootClass * temp = (FootClass *)tclass->Create_One_Of(HouseClass::As_Pointer(teamtype->House));
			ScenarioInit--;

			if (temp != NULL) {

				/*
				**	Add the member to the team.
				*/
				if (team != NULL) {
					ScenarioInit++;
					bool ok = team->Add(temp);
//Mono_Printf("Added to team = %d.\n", ok);Keyboard->Get();

					ScenarioInit--;
					temp->IsInitiated = true;
				}

				if (temp->What_Am_I() == RTTI_AIRCRAFT && !_Need_To_Take((AircraftClass const *)temp)) {
					temp->IsALoaner = true;
				}

				/*
				**	Build the list of transporters and passengers.
				*/
				if (tclass->Max_Passengers() > 0) {

					/*
					**	Link to the list of transports.
					*/
					temp->Next = transport;
					transport = temp;

				} else {

					/*
					**	Link to the list of normal objects.
					*/
					temp->Next = object;
					object = temp;
				}
			}
		}
	}

	/*
	**	If the group consists of transports and normal objects, then assign the normal
	**	objects to be passengers on the transport.
	*/
	if (transport != NULL && object != NULL) {
		transport->Attach(object);

		/*
		**	HACK ALERT! If the this team has an unload mission, then flag the transport
		**	as a loaner so that it will exit from the map when the unload process is
		**	complete, but only if the transport is an aircraft type.
		*/
		if (hasunload && (transport->What_Am_I() == RTTI_AIRCRAFT || transport->What_Am_I() == RTTI_VESSEL)) {
			transport->IsALoaner = true;
		}
	}

	/*
	**	For JUST transport helicopters, consider the loaner a gift if there are
	**	no passengers.
	*/
	if (transport != NULL && object == NULL && transport->What_Am_I() == RTTI_AIRCRAFT && *((AircraftClass *)transport) == AIRCRAFT_TRANSPORT) {
		transport->IsALoaner = false;
	}

	if (transport == 0 && object == 0) {
		if (team != NULL) delete team;
		return(NULL);
	}

	/*
	**	If this group consists only of non-transport object, then just return with a pointer
	**	to the first member of the group.
	*/
	if (transport == NULL) {
		return(object);
	}

	return(transport);
}


/***********************************************************************************************
 * _Consists_Only_Of_Infantry -- Determine if this group consists only of infantry.            *
 *                                                                                             *
 *    Use this to determine if the specified group only contains infantry. Such a reinforcement*
 *    group is a candidate for popping out of a building or transport vehicle rather than      *
 *    driving/walking/sailing/flying onto the map under its own power.                         *
 *                                                                                             *
 * INPUT:   first -- Pointer to the first object in the group to examine.                      *
 *                                                                                             *
 * OUTPUT:  bool; Is the entire group composed of infantry type units?                         *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   06/25/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
static bool _Consists_Only_Of_Infantry(FootClass const * first)
{
	while (first != NULL) {
		if (first->What_Am_I() != RTTI_INFANTRY) {
			return(false);
		}
		first = (FootClass const *)((ObjectClass *)first->Next);
	}
	return(true);
}


/***********************************************************************************************
 * _Who_Can_Pop_Out_Of -- Find a suitable host for these reinforcements.                       *
 *                                                                                             *
 *    This routine is used to scan nearby locations to determine if there is a suitable host   *
 *    for these reinforcements to "pop out of" (apologies to Aliens). Typical hosts include    *
 *    buildings and transport vehicles (of any kind).                                          *
 *                                                                                             *
 * INPUT:   origin   -- The cell that should be scanned from. Only this location and immediate *
 *                      adjacent locations will be scanned.                                    *
 *                                                                                             *
 * OUTPUT:  Returns with a pointer to a suitable host. If none could be found then NULL is     *
 *          returned.                                                                          *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   06/25/1996 JLB : Created.                                                                 *
 *=============================================================================================*/
static TechnoClass * _Who_Can_Pop_Out_Of(CELL origin)
{
	CellClass * cellptr = &Map[origin];
	TechnoClass * candidate = NULL;

	for (int f = -1; f < 8; f++) {
		CellClass * ptr = cellptr;
		if (f != -1) {
			ptr = ptr->Adjacent_Cell(FacingType(f));
			if (!ptr) continue;
		}

		BuildingClass * building = ptr->Cell_Building();
		if (building && building->Strength > 0) {
			candidate = building;
		}

		UnitClass * unit = ptr->Cell_Unit();
		if (unit && unit->Strength && unit->Class->Max_Passengers() > 0) {
			return(unit);
		}
	}
	return(candidate);
}


/***********************************************************************************************
 * Do_Reinforcements -- Create and place a reinforcement team.                                 *
 *                                                                                             *
 *    This routine is called when a reinforcement team must be created and placed on the map.  *
 *    It will create all members of the team and place them at the location determined from    *
 *    the team composition. The reinforcement team should follow team orders until overridden  *
 *    by AI or player intervention.                                                            *
 *                                                                                             *
 * INPUT:   teamtype -- Pointer to the team type to create as a reinforcement.                 *
 *                                                                                             *
 * OUTPUT:  Was the reinforcement successfully created and placed?                             *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   05/08/1995 JLB : Created.                                                                 *
 *   05/18/1995 JLB : Returns success or failure condition.                                    *
 *   06/19/1995 JLB : Announces reinforcements.                                                *
 *   02/15/1996 JLB : Recognizes team reinforcement location.                                  *
 *=============================================================================================*/
bool Do_Reinforcements(TeamTypeClass const * teamtype)
{
	assert(teamtype != 0);

	/*
	**	perform some preliminary checks for validity.
	*/
	if (!teamtype || !teamtype->ClassCount) return(false);

	/*
	**	HACK ALERT!
	**	Give this team an attack waypoint mission that will attack the waypoint location of this
	**	team if there are no team missions previously assigned.
	*/
	if (teamtype->MissionCount == 0) {
		TeamTypeClass * tt = (TeamTypeClass *)teamtype;
		tt->MissionCount = 1;
		tt->MissionList[0].Mission = TMISSION_ATT_WAYPT;
		tt->MissionList[0].Data.Value = teamtype->Origin;
	}

	FootClass * object = _Create_Group(teamtype);


//Mono_Printf("%d-%s (object=%p, team=%d).\n", __LINE__, __FILE__, object, object->Team.Is_Valid());Keyboard->Get();


	/*
	**	Bail on this reinforcement if no reinforcements could be created.
	**	This is probably because the object maximum was reached.
	*/
	if (!object) {
		return(false);
	}

	/*
	**	Special case code to handle infantry types that run from a building. This presumes
	**	that infantry are never a transport (which is safe to do).
	*/
	if (object != NULL && teamtype->Origin != -1 && _Consists_Only_Of_Infantry(object)) {

		/*
		**	Search for an object that these infantry can pop out of.
		*/
		TechnoClass * candidate = _Who_Can_Pop_Out_Of(Scen.Waypoint[teamtype->Origin]);

		if (candidate != NULL) {
			return(_Pop_Group_Out_Of_Object(object, candidate));
		}
	}

	/*
	**	The reinforcements must be delivered the old fashioned way -- by moving onto the
	**	map using their own power. First order of business is to determine where they
	**	should arrive from.
	*/
	SourceType source = HouseClass::As_Pointer(teamtype->House)->Control.Edge;
	if (source == SOURCE_NONE) {
		source = SOURCE_NORTH;
	}

	/*
	**	Pick the location where the reinforcements appear and then place
	**	them there.
	*/
	bool placed = false;

	FacingType eface = (FacingType)(source << 1);	// Facing to enter map.

	CELL cell = Map.Calculated_Cell(source, teamtype->Origin, -1, object->Techno_Type_Class()->Speed);
#ifdef FIXIT_ANTS
	/*
	**	For the ants, they will pop out of the ant hill directly.
	*/
	if (teamtype->Origin != -1 && object->What_Am_I() == RTTI_UNIT && 
			(*((UnitClass*)object) == UNIT_ANT1 ||
			*((UnitClass*)object) == UNIT_ANT2 ||
			*((UnitClass*)object) == UNIT_ANT3))  {
		CELL newcell = Scen.Waypoint[teamtype->Origin];
		if (newcell != -1)  {
			if (Map[newcell].TType == TEMPLATE_HILL01)  {
				cell = newcell;
			}
		}
	}
#endif

	CELL newcell = cell;

	FootClass * o = (FootClass *)(ObjectClass *)object->Next;
	object->Next = 0;
	bool okvoice = false;
	while (newcell > 0 && object != NULL) {
		DirType desiredfacing = Facing_Dir(eface);
		if (object->What_Am_I() == RTTI_AIRCRAFT) {
			desiredfacing = Random_Pick(DIR_N, DIR_MAX);
		}

		ScenarioInit++;
		if (object->Unlimbo(Cell_Coord(newcell), desiredfacing)) {
			okvoice = true;

			/*
			**	If this object is part of a team, then the mission for this
			**	object will be guard. The team handler will assign the proper
			**	mission that it should follow.
			*/
			if (object->What_Am_I() != RTTI_AIRCRAFT) {
				object->Assign_Mission(MISSION_GUARD);
				object->Commence();
			}

		} else {

			/*
			**	Could not unlimbo at location specified so find an adjacent location that it can
			**	be unlimboed at. If this fails, then abort the whole placement process.
			*/
			FacingType adj;
			for (adj = FACING_N; adj < FACING_COUNT; adj++) {
				CELL trycell = Adjacent_Cell(newcell, adj);
				if (!Map.In_Radar(trycell) && object->Can_Enter_Cell(trycell, adj) == MOVE_OK) {
					newcell = trycell;
					break;
				}
			}
			if (adj < FACING_COUNT) continue;
			newcell = 0;
		}
		ScenarioInit--;

		object = o;
		if (object != NULL) {
			o = (FootClass *)(ObjectClass *)object->Next;
			object->Next = 0;
		}
	}

	/*
	**	If there are still objects that could not be placed, then delete them.
	*/
	if (o != NULL) {
		while (o != NULL) {
			FootClass * old = o;
			o = (FootClass *)(ObjectClass *)o->Next;
			old->Next = 0;

			delete old;
		}
	}

	/*
	**	Announce when the reinforcements have arrived.
	*/
	if (okvoice && teamtype->House == PlayerPtr->Class->House) {
		Speak(VOX_REINFORCEMENTS, NULL, newcell ? Cell_Coord(newcell) : 0);
	}

	return(true);
}


/***********************************************************************************************
 * Create_Special_Reinforcement -- Ad hoc reinforcement handler.                               *
 *                                                                                             *
 *    Use this routine to bring on a reinforcement that hasn't been anticipated by the trigger *
 *    system. An example of this would be replacement harvesters or airfield ordered units.    *
 *    The appropriate transport is created (if necessary) and a mission is assigned such that  *
 *    the object will legally bring itself onto the playing field.                             *
 *                                                                                             *
 * INPUT:   house    -- The owner of this reinforcement.                                       *
 *                                                                                             *
 *          type     -- The object to bring on.                                                *
 *                                                                                             *
 *          another  -- This is reserved for the transport class in those cases where the      *
 *                      transport MUST be forced to a specific type.                           *
 *                                                                                             *
 *          mission  -- The mission to assign this reinforcement team.                         *
 *                                                                                             *
 *          argument -- Optional team mission argument (usually a waypoint).                   *
 *                                                                                             *
 * OUTPUT:  Was the special reinforcement created without error?                               *
 *                                                                                             *
 * WARNINGS:   This routine will fail if a team type cannot be created.                        *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   07/04/1995 JLB : Created.                                                                 *
 *=============================================================================================*/
bool Create_Special_Reinforcement(HouseClass * house, TechnoTypeClass const * type, TechnoTypeClass const * another, TeamMissionType mission, int argument)
{
	assert(house != 0);
	assert(type != 0);

	if (house && type) {
		TeamTypeClass * team = new TeamTypeClass();

		if (team) {

			/*
			**	If there is no overridden mission assign to this special reinforcement, then
			**	we must assign something. If not, the reinforcement will just sit at the edge
			**	of the map.
			*/
			if (!another && mission == TMISSION_NONE) {
				mission = TMISSION_MOVECELL;
				argument = Map.Calculated_Cell(house->Control.Edge);
			}

			/*
			**	Fill in the team characteristics.
			*/
			strcpy((char *)&team->IniName[0], "TEMP");
			team->IsReinforcable = false;
			team->IsTransient = true;
			team->ClassCount = 1;
			team->Members[0].Class = type;
			team->Members[0].Quantity = 1;
			team->MissionCount = 1;
			if (mission == TMISSION_NONE) {
				team->MissionList[0].Mission	= TMISSION_UNLOAD;
				team->MissionList[0].Data.Value = WAYPT_REINF;
			} else {
				team->MissionList[0].Mission	= mission;
				team->MissionList[0].Data.Value = argument;
			}
			team->House = house->Class->House;
			if (another) {
				team->ClassCount++;
				team->Members[1].Class = another;
				team->Members[1].Quantity = 1;
			}

			bool ok = Do_Reinforcements(team);
			if (!ok) delete team;
			return(ok);
		}
	}
	return(false);
}


/***********************************************************************************************
 * Create_Air_Reinforcement -- Creates air strike reinforcement                                *
 *                                                                                             *
 *    This routine is used to launch an airstrike. It will create the necessary aircraft and   *
 *    assign them to attack the target specified. This routine bypasses the normal             *
 *    reinforcement logic since it doesn't need the sophistication of unloading and following  *
 *    team mission lists.                                                                      *
 *                                                                                             *
 * INPUT:   house    -- The perpetrator of this air strike.                                    *
 *                                                                                             *
 *          air      -- The type of aircraft to make up this airstrike.                        *
 *                                                                                             *
 *          number   -- The number of aircraft in this airstrike.                              *
 *                                                                                             *
 *          mission  -- The mission to assign the aircraft.                                    *
 *                                                                                             *
 *          tarcom   -- The target to assign these aircraft.                                   *
 *                                                                                             *
 *          navcom   -- The navigation target to assign (if necessary).                        *
 *                                                                                             *
 * OUTPUT:  Returns the number of aircraft created for this airstrike.                         *
 *                                                                                             *
 * WARNINGS:   none                                                                            *
 *                                                                                             *
 * HISTORY:                                                                                    *
 *   07/04/1995 JLB : Commented.                                                               *
 *=============================================================================================*/
int Create_Air_Reinforcement(HouseClass * house, AircraftType air, int number, MissionType mission, TARGET tarcom, TARGET navcom, InfantryType passenger)
{
	assert(house != 0);
	assert((unsigned)air < AIRCRAFT_COUNT);
	assert(number != 0);
	assert((unsigned)mission < MISSION_COUNT);
	/*
	** Get a pointer to the class of the object that we are going to create.
	*/
	TechnoTypeClass const * type = (TechnoTypeClass *)&AircraftTypeClass::As_Reference(air);

	/*
	** Abort the airstrike if Tanya is the passenger and she's dead.
	*/
	if (passenger == INFANTRY_TANYA && IsTanyaDead) {
		number = 0;
	}

	/*
	** Loop through the number of objects we are supposed to create and
	** 	create and place them on the map.
	*/
	int sub;
	for (sub = 0; sub < number; sub++) {

		/*
		** Create one of the required objects.  If this fails we could have
		** a real problem.
		*/
		ScenarioInit++;
		TechnoClass * obj = (TechnoClass *)type->Create_One_Of(house);
		ScenarioInit--;
		if (!obj) return(sub);

		/*
		** Flying objects always have the IsALoaner bit set.
		*/
		obj->IsALoaner = true;

		/*
		** Find a cell for the object to come in on.  This is stolen from the
		** the code that handles a SOURCE_AIR in the normal logic.
		*/
		SourceType source = house->Control.Edge;
		switch (source) {
			case SOURCE_NORTH:
			case SOURCE_EAST:
			case SOURCE_SOUTH:
			case SOURCE_WEST:
				break;

			default:
				source = SOURCE_NORTH;
				break;
		}
		CELL newcell = Map.Calculated_Cell(source, -1, -1, SPEED_WINGED);

		/*
		** Try and place the object onto the map.
		*/
		ScenarioInit++;
		int placed = obj->Unlimbo(Cell_Coord(newcell), DIR_N);
		ScenarioInit--;
		if (placed) {

			/*
			** If we succeeded in placing the obj onto the map then
			** now we need to give it a mission and destination.
			*/
			obj->Assign_Mission(mission);

			/*
			** If a navcom was specified then set it.
			*/
			if (navcom != TARGET_NONE) {
				obj->Assign_Destination(navcom);
			}

			/*
			** If a tarcom was specified then set it.
			*/
			if (tarcom != TARGET_NONE) {
				obj->Assign_Target(tarcom);
			}

			/*
			**	Assign generic passenger value here. This value is used to determine
			**	if this aircraft should drop parachute reinforcements.
			*/
			if (obj->What_Am_I() == RTTI_AIRCRAFT) {
				AircraftClass * aircraft = (AircraftClass *)obj;
				if (passenger != INFANTRY_NONE) {
					aircraft->Passenger = passenger;
				}
//				if (Passenger == INFANTRY_TANYA) {
//					aircraft->Ammo = 1;
					//aircraft->AttacksRemaining = 1;
//				}
			}

			/*
			** Start the object into action.
			*/
			obj->Commence();
		} else {
			delete obj;
			sub--;
			return(sub);
		}
	}
	return(sub);
}