CnC_Remastered_Collection

Command and Conquer: Red Alert
Log | Files | Refs | README | LICENSE

VESSEL.CPP (111373B)


      1 //
      2 // Copyright 2020 Electronic Arts Inc.
      3 //
      4 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is free 
      5 // software: you can redistribute it and/or modify it under the terms of 
      6 // the GNU General Public License as published by the Free Software Foundation, 
      7 // either version 3 of the License, or (at your option) any later version.
      8 
      9 // TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed 
     10 // in the hope that it will be useful, but with permitted additional restrictions 
     11 // under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT 
     12 // distributed with this program. You should have received a copy of the 
     13 // GNU General Public License along with permitted additional restrictions 
     14 // with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
     15 
     16 /* $Header: /CounterStrike/VESSEL.CPP 1     3/03/97 10:26a Joe_bostic $ */
     17 /***********************************************************************************************
     18  ***              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               ***
     19  ***********************************************************************************************
     20  *                                                                                             *
     21  *                 Project Name : Command & Conquer                                            *
     22  *                                                                                             *
     23  *                    File Name : VESSEL.CPP                                                   *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : 03/13/96                                                     *
     28  *                                                                                             *
     29  *                  Last Update : July 31, 1996 [JLB]                                          *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   VesselClass::AI -- Handles the AI processing for vessel objects.                          *
     34  *   VesselClass::Assign_Destination -- Assign a destination for this vessel.                  *
     35  *   VesselClass::Can_Enter_Cell -- Determines if the vessel can enter the cell specified.     *
     36  *   VesselClass::Can_Fire -- Determines if this vessel can fire its weapon.                   *
     37  *   VesselClass::Is_Allowed_To_Recloak -- Can the vessel recloak now?                         *
     38  *   VesselClass::Class_Of -- Fetches a reference to the vessel's class data.                  *
     39  *   VesselClass::Combat_AI -- Handles firing and target selection for the vessel.             *
     40  *   VesselClass::Debug_Dump -- Dumps the vessel status information to the mono monitor.       *
     41  *   VesselClass::Draw_It -- Draws the vessel.                                                 *
     42  *   VesselClass::Edge_Of_World_AI -- Determine if vessel is off the edge of the world.        *
     43  *   VesselClass::Enter_Idle_Mode -- Causes the vessel to enter its default idle mode.         *
     44  *   VesselClass::Fire_Coord -- Fetches the coordinate the firing originates from.             *
     45  *   VesselClass::Greatest_Threat -- Determines the greatest threat (best target) for the vesse*
     46  *   VesselClass::Init -- Initialize the vessel heap system.                                   *
     47  *   VesselClass::Mission_Retreat -- Perform the retreat mission.                              *
     48  *   VesselClass::Overlap_List -- Fetches the overlap list for this vessel object.             *
     49  *   VesselClass::Per_Cell_Process -- Performs once-per-cell action.                           *
     50  *   VesselClass::Read_INI -- Read the vessel data from the INI database.                      *
     51  *   VesselClass::Repair_AI -- Process any self-repair required of this vessel.                *
     52  *   VesselClass::Rotation_AI -- Handles turret and body rotation for this vessel.             *
     53  *   VesselClass::Shape_Number -- Calculates the shape number for the ship body.               *
     54  *   VesselClass::Start_Driver -- Starts the vessel by reserving the location it is moving to. *
     55  *   VesselClass::Take_Damage -- Assign damage to the vessel.                                  *
     56  *   VesselClass::VesselClass -- Constructor for vessel class objects.                         *
     57  *   VesselClass::What_Action -- Determines action to perform on specified cell.               *
     58  *   VesselClass::Write_INI -- Write all vessel scenario data to the INI database.             *
     59  *   VesselClass::~VesselClass -- Destructor for vessel objects.                               *
     60  *   operator delete -- Deletes a vessel's memory block.                                       *
     61  *   operator new -- Allocates a vessel object memory block.                                   *
     62  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     63 
     64 
     65 #include "function.h"
     66 
     67 
     68 /***********************************************************************************************
     69  * VesselClass::VesselClass -- Constructor for vessel class objects.                           *
     70  *                                                                                             *
     71  *    This is the normal constructor for vessel class objects. It will set up a vessel that    *
     72  *    is valid excepting that it won't be placed on the map.                                   *
     73  *                                                                                             *
     74  * INPUT:   classid  -- The type of vessel this will be.                                       *
     75  *                                                                                             *
     76  *          house    -- The owner of this vessel.                                              *
     77  *                                                                                             *
     78  * OUTPUT:  none                                                                               *
     79  *                                                                                             *
     80  * WARNINGS:   none                                                                            *
     81  *                                                                                             *
     82  * HISTORY:                                                                                    *
     83  *   03/14/1996 JLB : Created.                                                                 *
     84  *=============================================================================================*/
     85 VesselClass::VesselClass(VesselType classid, HousesType house) :
     86 	DriveClass(RTTI_VESSEL, Vessels.ID(this), house),
     87 	Class(VesselTypes.Ptr((int)classid)),
     88 	IsToSelfRepair(false),
     89 	IsSelfRepairing(false),
     90 	DoorShutCountDown(0),
     91 	PulseCountDown(0),
     92 	SecondaryFacing(PrimaryFacing)
     93 {
     94 	House->Tracking_Add(this);
     95 
     96 	/*
     97 	**	The ammo member is actually part of the techno class, but must be initialized
     98 	**	manually here because this is where we first have access to the class pointer.
     99 	*/
    100 	Ammo = Class->MaxAmmo;
    101 
    102 	/*
    103 	**	For two shooters, clear out the second shot flag -- it will be set the first time
    104 	**	the object fires. For non two shooters, set the flag since it will never be cleared
    105 	**	and the second shot flag tells the system that normal rearm times apply -- this is
    106 	**	what is desired for non two shooters.
    107 	*/
    108 	IsSecondShot = !Class->Is_Two_Shooter();
    109 	Strength = Class->MaxStrength;
    110 
    111 	/*
    112 	**	The techno class cloakabilty flag is set according to the type
    113 	**	class cloakability flag.
    114 	*/
    115 	IsCloakable = Class->IsCloakable;
    116 
    117 	/*
    118 	** Keep count of the number of units created.
    119 	*/
    120 //	if (Session.Type == GAME_INTERNET) {
    121 //		House->UnitTotals->Increment_Unit_Total((int)classid);
    122 //	}
    123 }
    124 
    125 
    126 /***********************************************************************************************
    127  * VesselClass::~VesselClass -- Destructor for vessel objects.                                 *
    128  *                                                                                             *
    129  *    The destructor will destroy the vessel and ensure that it is properly removed from the   *
    130  *    game engine.                                                                             *
    131  *                                                                                             *
    132  * INPUT:   none                                                                               *
    133  *                                                                                             *
    134  * OUTPUT:  none                                                                               *
    135  *                                                                                             *
    136  * WARNINGS:   none                                                                            *
    137  *                                                                                             *
    138  * HISTORY:                                                                                    *
    139  *   03/14/1996 JLB : Created.                                                                 *
    140  *=============================================================================================*/
    141 VesselClass::~VesselClass(void)
    142 {
    143 	if (GameActive && Class.Is_Valid()) {
    144 
    145 		/*
    146 		**	Remove this member from any team it may be associated with. This must occur at the
    147 		**	top most level of the inheritance hierarchy because it may call virtual functions.
    148 		*/
    149 		if (Team.Is_Valid()) {
    150 			Team->Remove(this);
    151 			Team = NULL;
    152 		}
    153 
    154 		House->Tracking_Remove(this);
    155 
    156 		/*
    157 		**	If there are any cargo members, delete them.
    158 		*/
    159 		while (Is_Something_Attached()) {
    160 			delete Detach_Object();
    161 		}
    162 
    163 		Limbo();
    164 	}
    165 	ID = -1;
    166 }
    167 
    168 
    169 /***********************************************************************************************
    170  * operator new -- Allocates a vessel object memory block.                                     *
    171  *                                                                                             *
    172  *    This routine is used to allocate a block of memory from the vessel heap. If there is     *
    173  *    no more space in the heap, then this routine will return NULL.                           *
    174  *                                                                                             *
    175  * INPUT:   none                                                                               *
    176  *                                                                                             *
    177  * OUTPUT:  Returns with the pointer to the allocated block of memory.                         *
    178  *                                                                                             *
    179  * WARNINGS:   This routine could return NULL.                                                 *
    180  *                                                                                             *
    181  * HISTORY:                                                                                    *
    182  *   03/14/1996 JLB : Created.                                                                 *
    183  *=============================================================================================*/
    184 void * VesselClass::operator new(size_t)
    185 {
    186 	void * ptr = Vessels.Alloc();
    187 	if (ptr != NULL) {
    188 		((VesselClass *)ptr)->Set_Active();
    189 	}
    190 	return(ptr);
    191 }
    192 
    193 
    194 /***********************************************************************************************
    195  * operator delete -- Deletes a vessel's memory block.                                         *
    196  *                                                                                             *
    197  *    This overloaded delete operator will return the vessel's memory back to the pool of      *
    198  *    memory used for vessel allocation.                                                       *
    199  *                                                                                             *
    200  * INPUT:   ptr   -- Pointer to the vessel's memory block.                                     *
    201  *                                                                                             *
    202  * OUTPUT:  none                                                                               *
    203  *                                                                                             *
    204  * WARNINGS:   none                                                                            *
    205  *                                                                                             *
    206  * HISTORY:                                                                                    *
    207  *   03/14/1996 JLB : Created.                                                                 *
    208  *=============================================================================================*/
    209 void VesselClass::operator delete(void * ptr)
    210 {
    211 	if (ptr != NULL) {
    212 		assert(((VesselClass *)ptr)->IsActive);
    213 		((VesselClass *)ptr)->IsActive = false;
    214 	}
    215 	Vessels.Free((VesselClass *)ptr);
    216 }
    217 
    218 
    219 /***********************************************************************************************
    220  * VesselClass::Class_Of -- Fetches a reference to the vessel's class data.                    *
    221  *                                                                                             *
    222  *    This routine will return with a reference to the static class data for this vessel.      *
    223  *                                                                                             *
    224  * INPUT:   none                                                                               *
    225  *                                                                                             *
    226  * OUTPUT:  Returns with a reference to the class data structure associated with this vessel.  *
    227  *                                                                                             *
    228  * WARNINGS:   none                                                                            *
    229  *                                                                                             *
    230  * HISTORY:                                                                                    *
    231  *   03/14/1996 JLB : Created.                                                                 *
    232  *=============================================================================================*/
    233 ObjectTypeClass const & VesselClass::Class_Of(void) const
    234 {
    235 	assert(IsActive);
    236 
    237 	return(*Class);
    238 }
    239 
    240 
    241 /***********************************************************************************************
    242  * VesselClass::Can_Enter_Cell -- Determines if the vessel can enter the cell specified.       *
    243  *                                                                                             *
    244  *    This routine is used by find path and other movement logic to determine if this          *
    245  *    vessel can enter the cell specified.                                                     *
    246  *                                                                                             *
    247  * INPUT:   cell  -- The cell to check this vessel against.                                    *
    248  *                                                                                             *
    249  * OUTPUT:  Returns with the movement restriction associated with movement into this object.   *
    250  *                                                                                             *
    251  * WARNINGS:   none                                                                            *
    252  *                                                                                             *
    253  * HISTORY:                                                                                    *
    254  *   03/14/1996 JLB : Created.                                                                 *
    255  *=============================================================================================*/
    256 MoveType VesselClass::Can_Enter_Cell(CELL cell, FacingType ) const
    257 {
    258 	assert(Vessels.ID(this) == ID);
    259 	assert(IsActive);
    260 
    261 	if ((unsigned)cell >= MAP_CELL_TOTAL) return(MOVE_NO);
    262 
    263 	CellClass const * cellptr = &Map[cell];
    264 
    265 	/*
    266 	**	Moving off the edge of the map is not allowed unless
    267 	**	this is a loaner vehicle.
    268 	*/
    269 	if (!ScenarioInit && !Map.In_Radar(cell) && !Is_Allowed_To_Leave_Map()) {
    270 		return(MOVE_NO);
    271 	}
    272 
    273 	MoveType retval = MOVE_OK;
    274 
    275 	/*
    276 	**	If there is blocking terrain (such as ice), then the vessel
    277 	**	can't move there.
    278 	*/
    279 	if (cellptr->Cell_Terrain() != NULL) {
    280 		return(MOVE_NO);
    281 	}
    282 
    283 	/*
    284 	**	If the cell is out and out impassable because of underlying terrain, then
    285 	**	return this immutable fact.
    286 	*/
    287 	if (Ground[cellptr->Land_Type()].Cost[Class->Speed] == 0) {
    288 		return(MOVE_NO);
    289 	}
    290 
    291 	/*
    292 	**	If some allied object has reserved the cell, then consider the cell
    293 	**	as blocked by a moving object.
    294 	*/
    295 	if (cellptr->Flag.Composite) {
    296 
    297 		if (cellptr->Flag.Occupy.Building) {
    298 			return(MOVE_NO);
    299 		}
    300 
    301 		TechnoClass * techno = cellptr->Cell_Techno();
    302 		if (techno != NULL && techno->Is_Cloaked(this)) {
    303 			return(MOVE_CLOAK);
    304 		}
    305 
    306 		/*
    307 		**	If reserved by a vehicle, then consider this blocked terrain.
    308 		*/
    309 		if (cellptr->Flag.Occupy.Vehicle) {
    310 			retval = MOVE_MOVING_BLOCK;
    311 		}
    312 	}
    313 
    314 	/*
    315 	**	Return with the most severe reason why this cell would be impassable.
    316 	*/
    317 	return(retval);
    318 }
    319 
    320 
    321 /***********************************************************************************************
    322  * VesselClass::Shape_Number -- Calculates the shape number for the ship body.                 *
    323  *                                                                                             *
    324  *    This routine will return with the shape number to use for the ship's body.               *
    325  *                                                                                             *
    326  * INPUT:   none                                                                               *
    327  *                                                                                             *
    328  * OUTPUT:  Returns with the shape number to use for the ship's body when drawing.             *
    329  *                                                                                             *
    330  * WARNINGS:   none                                                                            *
    331  *                                                                                             *
    332  * HISTORY:                                                                                    *
    333  *   07/31/1996 JLB : Created.                                                                 *
    334  *=============================================================================================*/
    335 int VesselClass::Shape_Number(void) const
    336 {
    337 	/*
    338 	**	For eight facing units, adjust the facing number accordingly.
    339 	*/
    340 	FacingType facing = Dir_Facing(PrimaryFacing.Current());
    341 
    342 	int shapenum = UnitClass::BodyShape[Dir_To_16(PrimaryFacing)*2]>>1;
    343 
    344 	/*
    345 	**	Special case code for transport. The north/south facing is in frame
    346 	**	0. The east/west facing is in frame 3.
    347 	*/
    348 	if (*this == VESSEL_TRANSPORT) {
    349 		shapenum = 0;
    350 	}
    351 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
    352 	if (*this == VESSEL_CARRIER) {
    353 		shapenum = 0;
    354 	}
    355 #endif
    356 	/*
    357 	**	Door opening and closing animation stage check.
    358 	*/
    359 	if (!Is_Door_Closed()) {
    360 		shapenum = Door_Stage();
    361 	}
    362 
    363 	return(shapenum);
    364 }
    365 
    366 
    367 /***********************************************************************************************
    368  * VesselClass::Draw_It -- Draws the vessel.                                                   *
    369  *                                                                                             *
    370  *    Draws the vessel on the tactical display. This routine is called by the map rendering    *
    371  *    process to display the vessel.                                                           *
    372  *                                                                                             *
    373  * INPUT:   x,y   -- The pixel coordinate to draw this vessel at.                              *
    374  *                                                                                             *
    375  *          window-- The window to base clipping and coordinates upon when drawing.            *
    376  *                                                                                             *
    377  * OUTPUT:  none                                                                               *
    378  *                                                                                             *
    379  * WARNINGS:   none                                                                            *
    380  *                                                                                             *
    381  * HISTORY:                                                                                    *
    382  *   03/14/1996 JLB : Created.                                                                 *
    383  *=============================================================================================*/
    384 void VesselClass::Draw_It(int x, int y, WindowNumberType window) const
    385 {
    386 	assert(Vessels.ID(this) == ID);
    387 	assert(IsActive);
    388 
    389 	/*
    390 	**	Verify the legality of the unit class.
    391 	*/
    392 	void const * shapefile = Get_Image_Data();
    393 	if (shapefile == NULL) return;
    394 
    395 	/*
    396 	** Need to know the shape name for the overlay now. ST - 8/19/2019 1:37PM
    397 	*/
    398 	const char *turret_shape_name = NULL;
    399 
    400 	/*
    401 	**	If drawing of this unit is not explicitly prohibited, then proceed
    402 	**	with the render process.
    403 	*/
    404 	const bool is_hidden = (Visual_Character() == VISUAL_HIDDEN) && (window != WINDOW_VIRTUAL);
    405 	if (!is_hidden) {
    406 		int			facing = Dir_To_32(PrimaryFacing);
    407 		int			tfacing = Dir_To_32(SecondaryFacing);
    408 		DirType		rotation = DIR_N;
    409 		int			scale = 0x0100;
    410 
    411 		/*
    412 		**	Actually perform the draw. Overlay an optional shimmer effect as necessary.
    413 		*/
    414 		Techno_Draw_Object(shapefile, Shape_Number(), x, y, window, rotation, scale);
    415 
    416 		/*
    417 		**	If there is a turret, then it must be rendered as well. This may include
    418 		**	firing animation if required.
    419 		*/
    420 		if (Class->IsTurretEquipped) {
    421 			int xx = x;
    422 			int yy = y;
    423 
    424 			/*
    425 			**	Determine which turret shape to use. This depends on if there
    426 			**	is any firing animation in progress.
    427 			*/
    428 			int shapenum = TechnoClass::BodyShape[tfacing]+32;
    429 			DirType turdir = DirType(Dir_To_16(PrimaryFacing)*16);
    430 
    431 			switch (Class->Type) {
    432 				case VESSEL_CA:
    433 					turret_shape_name = "TURR";
    434 					shapefile = Class->TurretShapes;
    435 					shapenum = TechnoClass::BodyShape[Dir_To_32(SecondaryFacing)];
    436 					Class->Turret_Adjust(turdir, xx, yy);
    437 					// Add shape file name forl new shape draw intercept. ST - 8/19/2019 1:42PM
    438 					//Techno_Draw_Object(shapefile, shapenum, xx, yy, window);
    439 					Techno_Draw_Object_Virtual(shapefile, shapenum, xx, yy, window, DIR_N, 0x0100, turret_shape_name);
    440 					xx = x;
    441 					yy = y;
    442 					turdir = DirType(Dir_To_16(PrimaryFacing+DIR_S)*16);
    443 					Class->Turret_Adjust(turdir, xx, yy);
    444 					break;
    445 
    446 				case VESSEL_DD:
    447 					turret_shape_name = "SSAM";
    448 					shapefile = Class->SamShapes;
    449 					shapenum = TechnoClass::BodyShape[Dir_To_32(SecondaryFacing)];
    450 					Class->Turret_Adjust(turdir, xx, yy);
    451 					break;
    452 
    453 				case VESSEL_PT:
    454 					turret_shape_name = "MGUN";
    455 					shapefile = Class->MGunShapes;
    456 					shapenum = TechnoClass::BodyShape[Dir_To_32(SecondaryFacing)];
    457 					Class->Turret_Adjust(turdir, xx, yy);
    458 					break;
    459 
    460 				default:
    461 					shapenum = TechnoClass::BodyShape[Dir_To_32(SecondaryFacing)];
    462 					Class->Turret_Adjust(turdir, xx, yy);
    463 					break;
    464 			}
    465 
    466 			/*
    467 			**	Actually perform the draw. Overlay an optional shimmer effect as necessary.
    468 			*/
    469 			// Add shape file name forl new shape draw intercept. ST - 8/19/2019 1:42PM
    470 			if (turret_shape_name) {
    471 				Techno_Draw_Object_Virtual(shapefile, shapenum, xx, yy, window, DIR_N, 0x0100, turret_shape_name);
    472 			} else {
    473 				Techno_Draw_Object(shapefile, shapenum, xx, yy, window);
    474 			}
    475 		}
    476 	}
    477 
    478 	DriveClass::Draw_It(x, y, window);
    479 
    480 	/*
    481 	** Patch so the transport will draw its passengers on top of itself.
    482 	*/
    483 	if (!Is_Door_Closed() && IsTethered && In_Radio_Contact() && !Contact_With_Whom()->IsInLimbo) {
    484 		TechnoClass * contact = Contact_With_Whom();
    485 		assert(contact->IsActive);
    486 
    487 		int xxx = x + ((int)Lepton_To_Pixel((int)Coord_X(contact->Render_Coord())) - (int)Lepton_To_Pixel((int)Coord_X(Render_Coord())));
    488 		int yyy = y + ((int)Lepton_To_Pixel((int)Coord_Y(contact->Render_Coord())) - (int)Lepton_To_Pixel((int)Coord_Y(Render_Coord())));
    489 		contact->Draw_It(xxx, yyy, window);
    490 		contact->IsToDisplay = false;
    491 	}
    492 }
    493 
    494 
    495 #ifdef CHEAT_KEYS
    496 /***********************************************************************************************
    497  * VesselClass::Debug_Dump -- Dumps the vessel status information to the mono monitor.         *
    498  *                                                                                             *
    499  *    This routine will display the vessel's status information. The information is dumped to  *
    500  *    the monochrome monitor.                                                                  *
    501  *                                                                                             *
    502  * INPUT:   mono  -- Pointer to the monochrome screen that the information will be displayed   *
    503  *                   to.                                                                       *
    504  *                                                                                             *
    505  * OUTPUT:  none                                                                               *
    506  *                                                                                             *
    507  * WARNINGS:   none                                                                            *
    508  *                                                                                             *
    509  * HISTORY:                                                                                    *
    510  *   03/20/1996 JLB : Created.                                                                 *
    511  *=============================================================================================*/
    512 void VesselClass::Debug_Dump(MonoClass * mono) const
    513 {
    514 	assert(Vessels.ID(this) == ID);
    515 	assert(IsActive);
    516 
    517 	mono->Set_Cursor(0, 0);
    518 	mono->Print(Text_String(TXT_DEBUG_SHIP));
    519 	mono->Set_Cursor(47, 5);mono->Printf("%02X:%02X", SecondaryFacing.Current(), SecondaryFacing.Desired());
    520 
    521 	mono->Fill_Attrib(66, 13, 12, 1, IsSelfRepairing ? MonoClass::INVERSE : MonoClass::NORMAL);
    522 	mono->Fill_Attrib(66, 14, 12, 1, IsToSelfRepair ? MonoClass::INVERSE : MonoClass::NORMAL);
    523 	DriveClass::Debug_Dump(mono);
    524 }
    525 #endif
    526 
    527 
    528 /***********************************************************************************************
    529  * VesselClass::Overlap_List -- Fetches the overlap list for this vessel object.               *
    530  *                                                                                             *
    531  *    This routine will fetch the overlap list for this vessel type. It takes into             *
    532  *    consideration any movement the vessel may be doing.                                      *
    533  *                                                                                             *
    534  * INPUT:   none                                                                               *
    535  *                                                                                             *
    536  * OUTPUT:  Returns with a pointer to the overlap list for this vessel.                        *
    537  *                                                                                             *
    538  * WARNINGS:   none                                                                            *
    539  *                                                                                             *
    540  * HISTORY:                                                                                    *
    541  *   03/20/1996 JLB : Created.                                                                 *
    542  *=============================================================================================*/
    543 short const * VesselClass::Overlap_List(bool redraw) const
    544 {
    545 	assert(Vessels.ID(this) == ID);
    546 	assert(IsActive);
    547 
    548 #ifdef PARTIAL
    549 	if (Height == 0 && redraw && Class->DimensionData != NULL) {
    550 		Rect rect;
    551 		int shapenum = Shape_Number();
    552 		if (Class->DimensionData[shapenum].Is_Valid()) {
    553 			rect = Class->DimensionData[shapenum];
    554 		} else {
    555 			rect = Class->DimensionData[shapenum] = Shape_Dimensions(Get_Image_Data(), shapenum);
    556 		}
    557 
    558 		if (IsSelected) {
    559 			rect = Union(rect, Rect(-32, 32, 64, 64));
    560 		}
    561 
    562 		return(Coord_Spillage_List(Coord, rect, true));
    563 	}
    564 #else
    565 	redraw = redraw;
    566 #endif
    567 
    568 	return(Coord_Spillage_List(Coord, 56)+1);
    569 }
    570 
    571 
    572 /***********************************************************************************************
    573  * VesselClass::AI -- Handles the AI processing for vessel objects.                            *
    574  *                                                                                             *
    575  *    This routine is called once for each vessel object during each main game loop. All       *
    576  *    normal AI processing is handled here. This includes dispatching and maintaining any      *
    577  *    processing that is specific to vessel objects.                                           *
    578  *                                                                                             *
    579  * INPUT:   none                                                                               *
    580  *                                                                                             *
    581  * OUTPUT:  none                                                                               *
    582  *                                                                                             *
    583  * WARNINGS:   none                                                                            *
    584  *                                                                                             *
    585  * HISTORY:                                                                                    *
    586  *   03/20/1996 JLB : Created.                                                                 *
    587  *   07/16/1996 JLB : Prefers anti-sub weapons if firing on subs.                              *
    588  *=============================================================================================*/
    589 void VesselClass::AI(void)
    590 {
    591 	assert(Vessels.ID(this) == ID);
    592 	assert(IsActive);
    593 
    594 	if (Mission == MISSION_NONE && MissionQueue == MISSION_NONE) {
    595 		Enter_Idle_Mode();
    596 	}
    597 
    598 	/*
    599 	**	HACK ALERT:
    600 	**	If the ship finds itself in a hunt order but it has no weapons, then tell it
    601 	**	to sail off the map instead.
    602 	*/
    603 	if (Mission == MISSION_HUNT && !Is_Weapon_Equipped()) {
    604 		Assign_Mission(MISSION_RETREAT);
    605 	}
    606 
    607 	/*
    608 	**	Act on new orders if the unit is at a good position to do so.
    609 	*/
    610 	if (!IsDriving && Is_Door_Closed() /*Mission != MISSION_UNLOAD*/) {
    611 		Commence();
    612 	}
    613 
    614 #ifndef CLIPDRAW
    615 	if (Map.In_View(Coord_Cell(Center_Coord()))) {
    616 		Mark(MARK_CHANGE);
    617 	}
    618 #endif
    619 
    620 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
    621 // Re-stock the ammo of any on-board helicopters on an aircraft carrier.
    622 	if (*this == VESSEL_CARRIER && How_Many()) {
    623 		if (!MoebiusCountDown) {
    624 			MoebiusCountDown = Rule.ReloadRate * TICKS_PER_MINUTE;
    625 			ObjectClass *obj = Attached_Object();
    626 			while (obj) {
    627 				long bogus;
    628 				((AircraftClass *)obj)->Receive_Message(this,RADIO_RELOAD,bogus);
    629 				obj = (obj->Next);
    630 			}
    631 		}
    632 	}
    633 #endif
    634 	/*
    635 	**	Process base class AI routine. If as a result of this, the vessel gets
    636 	**	destroyed, then detect this fact and bail early.
    637 	*/
    638 	DriveClass::AI();
    639 	if (!IsActive) {
    640 		return;
    641 	}
    642 
    643 	/*
    644 	**	Handle body and turret rotation.
    645 	*/
    646 	Rotation_AI();
    647 
    648 	/*
    649 	**	Handle any combat processing required.
    650 	*/
    651 	Combat_AI();
    652 
    653 	/*
    654 	**	Delete this unit if it finds itself off the edge of the map and it is in
    655 	**	guard or other static mission mode.
    656 	*/
    657 	if (Edge_Of_World_AI()) {
    658 		return;
    659 	}
    660 
    661 	if (Class->Max_Passengers() > 0) {
    662 
    663 		/*
    664 		**	Double check that there is a passenger that is trying to load or unload.
    665 		**	If not, then close the door.
    666 		*/
    667 		if (!Is_Door_Closed() && Mission != MISSION_UNLOAD && Transmit_Message(RADIO_TRYING_TO_LOAD) != RADIO_ROGER && !(long)DoorShutCountDown) {
    668 			LST_Close_Door();
    669 		}
    670 	}
    671 
    672 	/*
    673 	**	Don't start a new mission unless the vehicle is in the center of
    674 	**	a cell (not driving) and the door (if any) is closed.
    675 	*/
    676 	if (!IsDriving && Is_Door_Closed()/*&& Mission != MISSION_UNLOAD*/) {
    677 		Commence();
    678 	}
    679 
    680 	/*
    681 	** Do a step of repair here, if appropriate.
    682 	*/
    683 	Repair_AI();
    684 }
    685 
    686 
    687 /***********************************************************************************************
    688  * VesselClass::Per_Cell_Process -- Performs once-per-cell action.                             *
    689  *                                                                                             *
    690  *    This routine is called when the vessel travels one cell. It handles any processes that   *
    691  *    must occur on a per-cell basis.                                                          *
    692  *                                                                                             *
    693  * INPUT:   why   -- Specifies the circumstances under which this routine was called.          *
    694  *                                                                                             *
    695  * OUTPUT:  none                                                                               *
    696  *                                                                                             *
    697  * WARNINGS:   none                                                                            *
    698  *                                                                                             *
    699  * HISTORY:                                                                                    *
    700  *   03/19/1996 JLB : Created.                                                                 *
    701  *=============================================================================================*/
    702 void VesselClass::Per_Cell_Process(PCPType why)
    703 {
    704 	assert(Vessels.ID(this) == ID);
    705 	assert(IsActive);
    706 
    707 	BStart(BENCH_PCP);
    708 
    709 	if (why == PCP_END) {
    710 		CELL cell = Coord_Cell(Coord);
    711 
    712 		/*
    713 		**	The unit performs looking around at this time. If the
    714 		**	unit moved further than one square during the last track
    715 		**	move, don't do an incremental look. Do a full look around
    716 		**	instead.
    717 		*/
    718 		Look(!IsPlanningToLook);
    719 		IsPlanningToLook = false;
    720 
    721 		if (IsToSelfRepair) {
    722 			for (FacingType face = FACING_N; face < FACING_COUNT; face++) {
    723 				CELL cell = Coord_Cell(Adjacent_Cell(Center_Coord(), face));
    724 				SmartPtr<BuildingClass> whom;
    725 				whom = Map[cell].Cell_Building();
    726 				if (whom != NULL && ((*whom == STRUCT_SHIP_YARD) || (*whom == STRUCT_SUB_PEN)) ) {
    727 
    728 					// MBL 04.27.2020: Make only audible to the correct player
    729 					// if (IsOwnedByPlayer) Speak(VOX_REPAIRING);
    730 					if (IsOwnedByPlayer) Speak(VOX_REPAIRING, House);
    731 
    732 					IsSelfRepairing = true;
    733 					IsToSelfRepair = false;
    734 					break;
    735 				}
    736 			}
    737 		}
    738 
    739 		/*
    740 		**	If this is a loaner unit and is is off the edge of the
    741 		**	map, then it gets eliminated.
    742 		*/
    743 		if (Edge_Of_World_AI()) {
    744 			BEnd(BENCH_PCP);
    745 			return;
    746 		}
    747 	}
    748 
    749 	if (IsActive) {
    750 		DriveClass::Per_Cell_Process(why);
    751 	}
    752 	BEnd(BENCH_PCP);
    753 }
    754 
    755 
    756 /***********************************************************************************************
    757  * VesselClass::What_Action -- Determines what action would occur if clicked on object.        *
    758  *                                                                                             *
    759  *    Use this function to determine what action would likely occur if the specified object    *
    760  *    were clicked on while this unit was selected as current. This function controls, not     *
    761  *    only the action to perform, but indirectly controls the cursor shape to use as well.     *
    762  *                                                                                             *
    763  * INPUT:   object   -- The object that to check for against "this" object.                    *
    764  *                                                                                             *
    765  * OUTPUT:  Returns with the default action to perform. If no clear action can be determined,  *
    766  *          then ACTION_NONE is returned.                                                      *
    767  *                                                                                             *
    768  * WARNINGS:   none                                                                            *
    769  *                                                                                             *
    770  * HISTORY:                                                                                    *
    771  *   04/16/1996 BWG : Created.                                                                 *
    772  *=============================================================================================*/
    773 ActionType VesselClass::What_Action(ObjectClass const * object) const
    774 {
    775 	assert(Vessels.ID(this) == ID);
    776 	assert(IsActive);
    777 
    778 	ActionType action = DriveClass::What_Action(object);
    779 
    780 	if (action == ACTION_SELF) {
    781 		if (Class->Max_Passengers() == 0 || !How_Many() ) {
    782 			action = ACTION_NONE;
    783 		} else {
    784 // check to see if the transporter can unload.
    785 			bool found = 0;
    786 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
    787 		if (*this != VESSEL_CARRIER)
    788 #endif
    789 			for (FacingType face = FACING_N; face < FACING_COUNT && !found; face++) {
    790 				CELL cellnum = Adjacent_Cell(Coord_Cell(Coord), face);
    791 				CellClass * cell = &Map[cellnum];
    792 				if (Map.In_Radar(cellnum)) {
    793 					if (Ground[cell->Land_Type()].Cost[SPEED_FOOT] == 0 || cell->Flag.Occupy.Building || cell->Flag.Occupy.Vehicle || cell->Flag.Occupy.Monolith || (cell->Flag.Composite & 0x01F) == 0x01F) {
    794 						continue;
    795 					} else {
    796 						found = true;
    797 					}
    798 				}
    799 			}
    800 			if (!found) {
    801 				action = ACTION_NONE;
    802 			}
    803 		}
    804 	}
    805 
    806 	/*
    807 	**	Special return to friendly repair factory action.
    808 	*/
    809 	if (House->IsPlayerControl && action == ACTION_SELECT && object->What_Am_I() == RTTI_BUILDING) {
    810 		BuildingClass * building = (BuildingClass *)object;
    811 
    812 		if (building->Class->ToBuild == RTTI_VESSELTYPE && building->House->Is_Ally(this)) {
    813 			action = ACTION_ENTER;
    814 		}
    815 	}
    816 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
    817 	if (action == ACTION_ATTACK && object->What_Am_I() == RTTI_VESSEL &&
    818 		 (*this == VESSEL_MISSILESUB || *this == VESSEL_CA) ) {
    819 		 	action = ACTION_NOMOVE;
    820 	}
    821 #endif
    822 	/*
    823 	**	If it doesn't know what to do with the object, then just
    824 	**	say it can't move there.
    825 	*/
    826 	if (action == ACTION_NONE) action = ACTION_NOMOVE;
    827 
    828 	return(action);
    829 }
    830 
    831 
    832 /***********************************************************************************************
    833  * VesselClass::Active_Click_With -- Intercepts the active click to see if deployment is possib*
    834  *                                                                                             *
    835  *    This routine intercepts the active click operation. It check to see if this is a self    *
    836  *    deployment request (MCV's have this ability). If it is, then the object is initiated     *
    837  *    to self deploy. In the other cases, it passes the operation down to the lower            *
    838  *    classes for processing.                                                                  *
    839  *                                                                                             *
    840  * INPUT:   action   -- The action requested of the unit.                                      *
    841  *                                                                                             *
    842  *          object   -- The object that the mouse pointer is over.                             *
    843  *                                                                                             *
    844  * OUTPUT:  none                                                                               *
    845  *                                                                                             *
    846  * WARNINGS:   none                                                                            *
    847  *                                                                                             *
    848  * HISTORY:                                                                                    *
    849  *   04/16/1996 BWG : Created.                                                                 *
    850  *=============================================================================================*/
    851 void VesselClass::Active_Click_With(ActionType action, ObjectClass * object)
    852 {
    853 	assert(Vessels.ID(this) == ID);
    854 	assert(IsActive);
    855 
    856 //	if (action != What_Action(object)) {
    857 		action = What_Action(object);
    858 		switch (action) {
    859 			case ACTION_ENTER:
    860 				action = ACTION_MOVE;
    861 				// BRR 10/18/96 IsToSelfRepair = true;
    862 				break;
    863 
    864 			default:
    865 //				action = ACTION_NONE;
    866 				break;
    867 		}
    868 //	}
    869 //	if (action == ACTION_ENTER) {
    870 		// BRR 10/18/96 IsToSelfRepair = true;
    871 //		action = ACTION_MOVE;
    872 //	} else {
    873 //		if (action != ACTION_NONE) {
    874 			// BRR 10/18/96 IsSelfRepairing = IsToSelfRepair = false;
    875 //		}
    876 //	}
    877 
    878 	DriveClass::Active_Click_With(action, object);
    879 }
    880 
    881 
    882 /***********************************************************************************************
    883  * VesselClass::Active_Click_With -- Performs specified action on specified cell.              *
    884  *                                                                                             *
    885  *    This routine is called when the mouse has been clicked over a cell and this unit must    *
    886  *    now respond. Notice that this is merely a placeholder function that exists because there *
    887  *    is another function of the same name that needs to be overloaded. C++ has scoping        *
    888  *    restrictions when there are two identically named functions that are overridden in       *
    889  *    different classes -- it handles it badly, hence the existence of this routine.           *
    890  *                                                                                             *
    891  * INPUT:   action   -- The action to perform on the cell specified.                           *
    892  *                                                                                             *
    893  *          cell     -- The cell that the action is to be performed on.                        *
    894  *                                                                                             *
    895  * OUTPUT:  none                                                                               *
    896  *                                                                                             *
    897  * WARNINGS:   none                                                                            *
    898  *                                                                                             *
    899  * HISTORY:                                                                                    *
    900  *   04/16/1996 BWG : Created.                                                                 *
    901  *=============================================================================================*/
    902 void VesselClass::Active_Click_With(ActionType action, CELL cell)
    903 {
    904 	assert(Vessels.ID(this) == ID);
    905 	assert(IsActive);
    906 
    907 	// BRR 10/18/96 IsToSelfRepair = false;
    908 //	if (action != ACTION_NONE) {
    909 		// BRR 10/18/96 IsSelfRepairing = false;
    910 //	}
    911 	DriveClass::Active_Click_With(action, cell);
    912 }
    913 
    914 
    915 /***********************************************************************************************
    916  * VesselClass::Take_Damage -- Assign damage to the vessel.                                    *
    917  *                                                                                             *
    918  *    This routine is called to apply damage to this vessel. The amount and type of damage     *
    919  *    to apply is passed as parameters. This routine could end up destroying the vessel.       *
    920  *                                                                                             *
    921  * INPUT:   damage   -- Reference to the amount of damage to apply to this vessel. The damage  *
    922  *                      value will be adjusted so that the actual damage applied will be       *
    923  *                      stored into this variable for possible subsequent examination.         *
    924  *                                                                                             *
    925  *          distance -- The distance from the center of the damage to the vessel itself.       *
    926  *                                                                                             *
    927  *          warhead  -- The warhead type of damage to apply.                                   *
    928  *                                                                                             *
    929  *          source   -- The perpetrator of this damage. Knowing who was responsible allows     *
    930  *                      retaliation logic.                                                     *
    931  *                                                                                             *
    932  *          forced   -- Is this damage forced upon the vessel by some supernatural means?      *
    933  *                                                                                             *
    934  * OUTPUT:  Returns with the result of the damage applied. This enumeration indicates the      *
    935  *          general effect of the damage. Examine this return value to see if the vessel       *
    936  *          has been destroyed.                                                                *
    937  *                                                                                             *
    938  * WARNINGS:   The vessel could be destroyed by the call to this routine!                      *
    939  *                                                                                             *
    940  * HISTORY:                                                                                    *
    941  *   05/13/1996 JLB : Created.                                                                 *
    942  *=============================================================================================*/
    943 ResultType VesselClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source, bool forced)
    944 {
    945 	assert(Vessels.ID(this) == ID);
    946 	assert(IsActive);
    947 
    948 	ResultType res = RESULT_NONE;
    949 
    950 	/*
    951 	**	In order for a this to be damaged, it must either be a unit
    952 	**	with a crew or a sandworm.
    953 	*/
    954 	res = FootClass::Take_Damage(damage, distance, warhead, source, forced);
    955 
    956 	if (res == RESULT_DESTROYED) {
    957 		Death_Announcement(source);
    958 		if (Class->Explosion != ANIM_NONE) {
    959 			AnimType anim = Class->Explosion;
    960 
    961 			new AnimClass(anim, Coord);
    962 
    963 			/*
    964 			**	Very strong units that have an explosion will also rock the
    965 			**	screen when they are destroyed.
    966 			*/
    967 			if (Class->MaxStrength > 400) {
    968 				int shakes = Class->MaxStrength / 150;
    969 				Shake_The_Screen(shakes, Owner());
    970 				if (source && Owner() != source->Owner()) {
    971 					Shake_The_Screen(shakes, source->Owner());
    972 				}
    973 			}
    974 		}
    975 
    976 		/*
    977 		**	Possibly have the crew member run away.
    978 		*/
    979 		Mark(MARK_UP);
    980 		while (Is_Something_Attached()) {
    981 			FootClass * object = Detach_Object();
    982 
    983 			/*
    984 			**	Only infantry can run from a destroyed vehicle. Even then, it is not a sure
    985 			**	thing.
    986 			*/
    987 			object->Record_The_Kill(source);
    988 			delete object;
    989 		}
    990 
    991 		/*
    992 		**	Finally, delete the vehicle.
    993 		*/
    994 		delete this;
    995 
    996 	} else {
    997 
    998 		/*
    999 		**	When damaged and below half strength, start smoking if
   1000 		**	it isn't already smoking (and it's not a submarine).
   1001 		*/
   1002 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   1003 		if (Health_Ratio() <= Rule.ConditionYellow && !IsAnimAttached && (*this != VESSEL_SS && *this != VESSEL_MISSILESUB) ) {
   1004 #else
   1005 		if (Health_Ratio() <= Rule.ConditionYellow && !IsAnimAttached && (*this != VESSEL_SS) ) {
   1006 #endif
   1007 			AnimClass * anim = new AnimClass(ANIM_SMOKE_M, Coord_Add(Coord, XYP_Coord(0, -8)));
   1008 			if (anim != NULL) anim->Attach_To(this);
   1009 		}
   1010 	}
   1011 	return(res);
   1012 }
   1013 
   1014 
   1015 /***********************************************************************************************
   1016  * VesselClass::Can_Fire -- Determines if this vessel can fire its weapon.                     *
   1017  *                                                                                             *
   1018  *    This routine is used to determine if this vessel can fire its weapon at the target       *
   1019  *    specified.                                                                               *
   1020  *                                                                                             *
   1021  * INPUT:   target   -- The target candidate to determine if firing upon is valid.             *
   1022  *                                                                                             *
   1023  *          which    -- Which weapon to use when considering the candidate as a potential      *
   1024  *                      target.                                                                *
   1025  *                                                                                             *
   1026  * OUTPUT:  Returns with the fire error type. This enum indicates if the vessel and fire. If   *
   1027  *          it can't fire, then the enum indicates why.                                        *
   1028  *                                                                                             *
   1029  * WARNINGS:   none                                                                            *
   1030  *                                                                                             *
   1031  * HISTORY:                                                                                    *
   1032  *   05/13/1996 JLB : Created.                                                                 *
   1033  *=============================================================================================*/
   1034 FireErrorType VesselClass::Can_Fire(TARGET target, int which) const
   1035 {
   1036 	assert(Vessels.ID(this) == ID);
   1037 	assert(IsActive);
   1038 
   1039 	DirType			dir;					// The facing to impart upon the projectile.
   1040 	int				diff;
   1041 
   1042 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
   1043 	if (*this == VESSEL_CARRIER) {
   1044 		if(!How_Many() || Arm) {
   1045 			return(FIRE_REARM);
   1046 		} else {
   1047 			return(FIRE_OK);
   1048 		}
   1049 	}
   1050 #endif
   1051 	FireErrorType	fire = DriveClass::Can_Fire(target, which);
   1052 if(*this==VESSEL_DD) {
   1053 Mono_Set_Cursor(0,0);
   1054 }
   1055 	if (fire == FIRE_OK || fire == FIRE_CLOAKED) {
   1056 		WeaponTypeClass const * weapon = (which == 0) ? Class->PrimaryWeapon : Class->SecondaryWeapon;
   1057 
   1058 		/*
   1059 		**	Ensure that a torpedo will never be fired upon a non naval target.
   1060 		** Unless that non-naval target is a naval building (sub pen/ship yard)
   1061 		*/
   1062 		bool isseatarget = Is_Target_Vessel(target);
   1063 		bool isbridgetarget = false;
   1064 		if (weapon->Bullet->IsSubSurface) {
   1065 			isbridgetarget = Is_Target_Cell(target);	// enable shooting at bridges
   1066 			isseatarget |= isbridgetarget;
   1067 		}
   1068 		BuildingClass * bldg = ::As_Building(target);
   1069 		if (bldg != NULL && bldg->Class->Speed == SPEED_FLOAT) {
   1070 			isseatarget = true;
   1071 		}
   1072 
   1073 		dir = Direction(target);
   1074 
   1075 		if (weapon->Bullet->IsSubSurface) {
   1076 			if (!isseatarget && Is_Target_Object(target)) {
   1077 				return(FIRE_CANT);
   1078 			}
   1079 
   1080 			/*
   1081 			** If it's a torpedo, let's check line-of-sight to make sure that
   1082 			** there's only water squares between us and the target.
   1083 			*/
   1084 			ObjectClass * obj = As_Object(target);
   1085 			COORDINATE coord = Center_Coord();
   1086 			if (obj != NULL) {
   1087 				int totaldist = ::Distance(coord, obj->Center_Coord());
   1088 				while (totaldist > CELL_LEPTON_W) {
   1089 					coord = Coord_Move(coord, dir, CELL_LEPTON_W);
   1090 					if (Map[coord].Land_Type() != LAND_WATER) {
   1091 						if (!isbridgetarget) {
   1092 							return(FIRE_RANGE);
   1093 						}
   1094 					}
   1095 
   1096 					/*
   1097 					** Check for friendly boats in the way.
   1098 					*/
   1099 					TechnoClass * tech = Map[coord].Cell_Techno();
   1100 					if (tech != NULL && tech != this && House->Is_Ally(tech)) {
   1101 						return(FIRE_RANGE);
   1102 					}
   1103 					totaldist -= CELL_LEPTON_W;
   1104 				}
   1105 			}
   1106 		}
   1107 
   1108 		/*
   1109 		**	Depth charges are only good against submarines.
   1110 		*/
   1111 		if (weapon->Bullet->IsAntiSub) {
   1112 			if (!isseatarget) {
   1113 				return(FIRE_CANT);
   1114 			} else {
   1115 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   1116 				if (Is_Target_Vessel(target) && (*As_Vessel(target) != VESSEL_SS && *As_Vessel(target) != VESSEL_MISSILESUB) ) {
   1117 #else
   1118 				if (Is_Target_Vessel(target) && *As_Vessel(target) != VESSEL_SS) {
   1119 #endif
   1120 					if (!Is_Target_Vessel(target) || !weapon->Bullet->IsSubSurface) {
   1121 						return(FIRE_CANT);
   1122 					}
   1123 				}
   1124 			}
   1125 		} else {
   1126 #ifdef FIXIT_CSII	//	checked - ajw 9/28/98
   1127 			if (Is_Target_Vessel(target) && (*As_Vessel(target) == VESSEL_SS || *As_Vessel(target) == VESSEL_MISSILESUB)) {
   1128 #else
   1129 			if (Is_Target_Vessel(target) && *As_Vessel(target) == VESSEL_SS) {
   1130 #endif
   1131 				return(FIRE_CANT);
   1132 			}
   1133 		}
   1134 
   1135 		/*
   1136 		**	If this unit cannot fire while moving, then bail.
   1137 		*/
   1138 		if (!Class->IsTurretEquipped && Target_Legal(NavCom)) {
   1139 			return(FIRE_MOVING);
   1140 		}
   1141 
   1142 		/*
   1143 		**	If the turret is rotating and the projectile isn't a homing type, then
   1144 		**	firing must be delayed until the rotation stops.
   1145 		*/
   1146 		if (!IsFiring && IsRotating && weapon->Bullet->ROT == 0) {
   1147 			return(FIRE_ROTATING);
   1148 		}
   1149 
   1150 		/*
   1151 		**	Determine if the turret facing isn't too far off of facing the target.
   1152 		*/
   1153 		if (Class->IsTurretEquipped) {
   1154 			diff = SecondaryFacing.Difference(dir);
   1155 		} else {
   1156 			diff = PrimaryFacing.Difference(dir);
   1157 		}
   1158 		diff = ABS(diff);
   1159 
   1160 		if (weapon->Bullet->ROT != 0) {
   1161 			diff >>= 2;
   1162 		}
   1163 		if (diff > 8) {
   1164 			return(FIRE_FACING);
   1165 		}
   1166 	}
   1167 	return(fire);
   1168 }
   1169 
   1170 
   1171 /***********************************************************************************************
   1172  * VesselClass::Fire_Coord -- Fetches the coordinate the firing originates from.               *
   1173  *                                                                                             *
   1174  *    This routine is called to determine the coordinate that a fired projectile will          *
   1175  *    originate from.                                                                          *
   1176  *                                                                                             *
   1177  * INPUT:   which -- Which weapon is this query directed at?                                   *
   1178  *                                                                                             *
   1179  * OUTPUT:  Returns with the coordinate where a projectile would appear if it were fired.      *
   1180  *                                                                                             *
   1181  * WARNINGS:   none                                                                            *
   1182  *                                                                                             *
   1183  * HISTORY:                                                                                    *
   1184  *   05/13/1996 JLB : Created.                                                                 *
   1185  *=============================================================================================*/
   1186 FireDataType VesselClass::Fire_Data(int which) const
   1187 {
   1188 	assert(Vessels.ID(this) == ID);
   1189 	assert(IsActive);
   1190 
   1191 	COORDINATE coord = Center_Coord();
   1192 
   1193 	if (*this == VESSEL_CA) {
   1194 		if (IsSecondShot) {
   1195 			coord = Coord_Move(coord, PrimaryFacing + DIR_S, 0x0100);
   1196 		} else {
   1197 			coord = Coord_Move(coord, PrimaryFacing, 0x0100);
   1198 		}
   1199 		coord = Coord_Move(coord, DIR_N, 0x0030);
   1200 		return{coord,0x0040};
   1201 	}
   1202 
   1203 	if (*this == VESSEL_PT) {
   1204 		coord = Coord_Move(coord, PrimaryFacing, 0x0080);
   1205 		coord = Coord_Move(coord, DIR_N, 0x0020);
   1206 		return{coord,0x0010};
   1207 	}
   1208 
   1209 	return(DriveClass::Fire_Data(which));
   1210 }
   1211 
   1212 COORDINATE VesselClass::Fire_Coord(int which) const
   1213 {
   1214 	assert(Vessels.ID(this) == ID);
   1215 	assert(IsActive);
   1216 
   1217 	COORDINATE coord = Center_Coord();
   1218 
   1219 	if (*this == VESSEL_CA) {
   1220 		if (IsSecondShot) {
   1221 			coord = Coord_Move(coord, PrimaryFacing + DIR_S, 0x0100);
   1222 		} else {
   1223 			coord = Coord_Move(coord, PrimaryFacing, 0x0100);
   1224 		}
   1225 		coord = Coord_Move(coord, DIR_N, 0x0030);
   1226 		coord = Coord_Move(coord, Turret_Facing(), 0x0040);
   1227 		return(coord);
   1228 	}
   1229 
   1230 	if (*this == VESSEL_PT) {
   1231 		coord = Coord_Move(coord, PrimaryFacing, 0x0080);
   1232 		coord = Coord_Move(coord, DIR_N, 0x0020);
   1233 		coord = Coord_Move(coord, Turret_Facing(), 0x0010);
   1234 		return(coord);
   1235 	}
   1236 
   1237 	return(DriveClass::Fire_Coord(which));
   1238 }
   1239 
   1240 
   1241 /***********************************************************************************************
   1242  * VesselClass::Init -- Initialize the vessel heap system.                                     *
   1243  *                                                                                             *
   1244  *    This routine is used to clear out the vessel heap. It is called whenever a scenario is   *
   1245  *    being initialized prior to scenario or saved game loading.                               *
   1246  *                                                                                             *
   1247  * INPUT:   none                                                                               *
   1248  *                                                                                             *
   1249  * OUTPUT:  none                                                                               *
   1250  *                                                                                             *
   1251  * WARNINGS:   All vessel objects are invalid after this routine is called.                    *
   1252  *                                                                                             *
   1253  * HISTORY:                                                                                    *
   1254  *   05/13/1996 JLB : Created.                                                                 *
   1255  *=============================================================================================*/
   1256 void VesselClass::Init(void)
   1257 {
   1258 	Vessels.Free_All();
   1259 }
   1260 
   1261 
   1262 /***********************************************************************************************
   1263  * VesselClass::Greatest_Threat -- Determines the greatest threat (best target) for the vessel *
   1264  *                                                                                             *
   1265  *    This routine is used by ships to determine what target they should go after.             *
   1266  *                                                                                             *
   1267  * INPUT:   threat   -- The threat type that this ship should go after (as determined by the   *
   1268  *                      team mission or general self defense principles).                      *
   1269  *                                                                                             *
   1270  * OUTPUT:  Returns with the target that this ship should attack.                              *
   1271  *                                                                                             *
   1272  * WARNINGS:   none                                                                            *
   1273  *                                                                                             *
   1274  * HISTORY:                                                                                    *
   1275  *   05/13/1996 JLB : Created.                                                                 *
   1276  *=============================================================================================*/
   1277 TARGET VesselClass::Greatest_Threat(ThreatType threat) const
   1278 {
   1279 	if (*this == VESSEL_SS) {
   1280 		threat = threat & ThreatType(THREAT_RANGE|THREAT_AREA);
   1281 		threat = threat | THREAT_BOATS;
   1282 
   1283 		//BG: get subs to attack buildings also.
   1284 		threat = threat | THREAT_BUILDINGS;
   1285 		threat = threat | THREAT_FACTORIES;
   1286 	} else {
   1287 		if ((threat & (THREAT_GROUND|THREAT_POWER|THREAT_FACTORIES|THREAT_TIBERIUM|THREAT_BASE_DEFENSE|THREAT_BOATS)) == 0) {
   1288 			if (Class->PrimaryWeapon != NULL) {
   1289 				threat = threat | Class->PrimaryWeapon->Allowed_Threats();
   1290 			}
   1291 
   1292 			if (Class->SecondaryWeapon != NULL) {
   1293 				threat = threat | Class->SecondaryWeapon->Allowed_Threats();
   1294 			}
   1295 
   1296 //			threat = threat | THREAT_GROUND | THREAT_BOATS;
   1297 		}
   1298 
   1299 		// Cruisers can never hit infantry anyway, so take 'em out of the list
   1300 		// of possible targets.
   1301 		if (*this == VESSEL_CA) {
   1302 			threat = (ThreatType) (threat & (~THREAT_INFANTRY));
   1303 		}
   1304 	}
   1305 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
   1306 	if (*this == VESSEL_CARRIER) {
   1307 		return(TARGET_NONE);
   1308 	}
   1309 #endif
   1310 	return(FootClass::Greatest_Threat(threat));
   1311 }
   1312 
   1313 
   1314 /***********************************************************************************************
   1315  * VesselClass::Enter_Idle_Mode -- Causes the vessel to enter its default idle mode.           *
   1316  *                                                                                             *
   1317  *    This routine is called when the vessel is finished with what it is doing, but the next   *
   1318  *    action is not known. This routine will determine what is the appropriate course of       *
   1319  *    action for this vessel and then start it doing that.                                     *
   1320  *                                                                                             *
   1321  * INPUT:   none                                                                               *
   1322  *                                                                                             *
   1323  * OUTPUT:  none                                                                               *
   1324  *                                                                                             *
   1325  * WARNINGS:   none                                                                            *
   1326  *                                                                                             *
   1327  * HISTORY:                                                                                    *
   1328  *   07/09/1996 JLB : Created.                                                                 *
   1329  *=============================================================================================*/
   1330 void VesselClass::Enter_Idle_Mode(bool )
   1331 {
   1332 	assert(Vessels.ID(this) == ID);
   1333 	assert(IsActive);
   1334 
   1335 	MissionType	order = MISSION_GUARD;
   1336 
   1337 	/*
   1338 	**	A movement mission without a NavCom would be pointless to have a radio contact since
   1339 	**	no radio coordination occurs on a just a simple movement mission.
   1340 	*/
   1341 	if (Mission == MISSION_MOVE && !Target_Legal(NavCom)) {
   1342 		Transmit_Message(RADIO_OVER_OUT);
   1343 	}
   1344 
   1345 	Handle_Navigation_List();
   1346 	if (Target_Legal(NavCom)) {
   1347 		order = MISSION_MOVE;
   1348 	} else {
   1349 
   1350 		if (Class->PrimaryWeapon == NULL) {
   1351 			if (IsALoaner && Class->Max_Passengers() > 0 && Is_Something_Attached() && !Team) {
   1352 				order = MISSION_UNLOAD;
   1353 			} else {
   1354 				order = MISSION_GUARD;
   1355 				Assign_Target(TARGET_NONE);
   1356 				Assign_Destination(TARGET_NONE);
   1357 			}
   1358 
   1359 		} else {
   1360 
   1361 			if (Mission == MISSION_GUARD || Mission == MISSION_GUARD_AREA || MissionControl[Mission].IsParalyzed || MissionControl[Mission].IsZombie) {
   1362 				return;
   1363 			}
   1364 
   1365 			if (House->IsHuman || Team.Is_Valid()) {
   1366 				order = MISSION_GUARD;
   1367 			} else {
   1368 				if (House->IQ < Rule.IQGuardArea) {
   1369 					order = MISSION_GUARD;
   1370 				} else {
   1371 					order = MISSION_GUARD_AREA;
   1372 				}
   1373 			}
   1374 		}
   1375 	}
   1376 	Assign_Mission(order);
   1377 }
   1378 
   1379 
   1380 /***********************************************************************************************
   1381  * VesselClass::Receive_Message -- Handles receiving a radio message.                          *
   1382  *                                                                                             *
   1383  *    This is the handler function for when a vessel receives a radio                          *
   1384  *    message. Typical use of this is when a unit unloads from a lst                           *
   1385  *    class so that clearing of the transport is successful.                                   *
   1386  *                                                                                             *
   1387  * INPUT:   from     -- Pointer to the originator of the message.                              *
   1388  *                                                                                             *
   1389  *          message  -- The radio message received.                                            *
   1390  *                                                                                             *
   1391  *          param    -- Reference to an optional parameter the might be needed to return       *
   1392  *                      information back to the originator of the message.                     *
   1393  *                                                                                             *
   1394  * OUTPUT:  Returns with the radio message response.                                           *
   1395  *                                                                                             *
   1396  * WARNINGS:   none                                                                            *
   1397  *                                                                                             *
   1398  * HISTORY:                                                                                    *
   1399  *   05/31/1996 BWG : Created.                                                                 *
   1400  *=============================================================================================*/
   1401 RadioMessageType VesselClass::Receive_Message(RadioClass * from, RadioMessageType message, long & param)
   1402 {
   1403 	assert(Vessels.ID(this) == ID);
   1404 	assert(IsActive);
   1405 
   1406 	switch (message) {
   1407 
   1408 		/*
   1409 		**	Asks if the passenger can load on this transport.
   1410 		*/
   1411 		case RADIO_CAN_LOAD:
   1412 			if (Class->Max_Passengers() == 0 || from == NULL || !House->Is_Ally(from->Owner())) return(RADIO_STATIC);
   1413 			if (How_Many() < Class->Max_Passengers()) {
   1414 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
   1415 	if(*this == VESSEL_CARRIER && from->What_Am_I() == RTTI_AIRCRAFT) {
   1416 		return(RADIO_ROGER);
   1417 	}
   1418 #endif
   1419 			/*
   1420 			** Before saying "Sure, come on board", make sure we're adjacent to
   1421 			** the shore.
   1422 			*/
   1423 				CELL cell;
   1424 				Desired_Load_Dir(from, cell);
   1425 				if(cell) {
   1426 					return(RADIO_ROGER);
   1427 				}
   1428 			}
   1429 			return(RADIO_NEGATIVE);
   1430 
   1431 		/*
   1432 		**	This message is sent by the passenger when it determines that it has
   1433 		**	entered the transport.
   1434 		*/
   1435 		case RADIO_IM_IN:
   1436 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
   1437 	if(*this != VESSEL_CARRIER) {
   1438 #endif
   1439 			if (How_Many() == Class->Max_Passengers()) {
   1440 				LST_Close_Door();
   1441 			} else {
   1442 				DoorShutCountDown = TICKS_PER_SECOND;
   1443 			}
   1444 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
   1445 	}
   1446 #endif
   1447 			return(RADIO_ATTACH);
   1448 
   1449 		/*
   1450 		**	Docking maintenance message received. Check to see if new orders should be given
   1451 		**	to the impatient unit.
   1452 		*/
   1453 		case RADIO_DOCKING:
   1454 
   1455 			/*
   1456 			**	If this transport is moving, then always abort the docking request.
   1457 			*/
   1458 			if (IsDriving || Target_Legal(NavCom)) {
   1459 				return(RADIO_NEGATIVE);
   1460 			}
   1461 
   1462 			/*
   1463 			**	Check for the case of a docking message arriving from a unit that does not
   1464 			**	have formal radio contact established. This might be a unit that is standing
   1465 			**	by. If this transport is free to proceed with normal docking operation, then
   1466 			**	establish formal contact now. If the transport is completely full, then break
   1467 			**	off contact. In all other cases, just tell the pending unit to stand by.
   1468 			*/
   1469 			if (Contact_With_Whom() != from) {
   1470 
   1471 				/*
   1472 				**	Can't ever load up so tell the passenger to bug off.
   1473 				*/
   1474 				if (How_Many() >= Class->Max_Passengers()) {
   1475 					return(RADIO_NEGATIVE);
   1476 				}
   1477 
   1478 				/*
   1479 				**	Establish contact and let the loading process proceed normally.
   1480 				*/
   1481 				if (!In_Radio_Contact()) {
   1482 					param = TARGET_NONE;
   1483 					Transmit_Message(RADIO_HELLO, from);
   1484 					Transmit_Message(RADIO_MOVE_HERE, param);
   1485 					return(RADIO_ROGER);
   1486 				} else {
   1487 
   1488 					/*
   1489 					**	This causes the potential passenger to think that all is ok and to
   1490 					**	hold on for a bit.
   1491 					*/
   1492 					return(RADIO_ROGER);
   1493 				}
   1494 			}
   1495 
   1496 			/*
   1497 			**
   1498 			*/
   1499 			if (Class->Max_Passengers() > 0 && *this == VESSEL_TRANSPORT && How_Many() < Class->Max_Passengers()) {
   1500 				DriveClass::Receive_Message(from, message, param);
   1501 
   1502 				if (!IsDriving && !IsRotating) {
   1503 //				if (!IsDriving && !IsRotating && !IsTethered) {
   1504 
   1505 					/*
   1506 					**	If the potential passenger needs someplace to go, then figure out a good
   1507 					**	spot and tell it to go.
   1508 					*/
   1509 					if (Transmit_Message(RADIO_NEED_TO_MOVE, from) == RADIO_ROGER) {
   1510 
   1511 						CELL cell;
   1512 						DirType dir = Desired_Load_Dir(from, cell);
   1513 
   1514 						/*
   1515 						**	If no adjacent free cells are detected, then passenger loading
   1516 						**	cannot occur. Break radio contact.
   1517 						*/
   1518 						if (cell == 0) {
   1519 							Transmit_Message(RADIO_OVER_OUT, from);
   1520 						} else {
   1521 							param = (long)::As_Target(cell);
   1522 
   1523 							/*
   1524 							**	If it is now facing the correct direction, then open the
   1525 							**	transport doors. Close the doors if the transport is full or needs
   1526 							**	to rotate.
   1527 							*/
   1528 							if (!Is_Door_Open()) {
   1529 								LST_Open_Door();
   1530 							}
   1531 
   1532 							/*
   1533 							**	Tell the potential passenger where it should go. If the passenger is
   1534 							**	already at the staging location, then tell it to move onto the transport
   1535 							**	directly.
   1536 							*/
   1537 							if (Transmit_Message(RADIO_MOVE_HERE, param, from) == RADIO_YEA_NOW_WHAT) {
   1538 								if (Is_Door_Open()) {
   1539 									param = (long)As_Target();
   1540 									Transmit_Message(RADIO_TETHER);
   1541 									if (Transmit_Message(RADIO_MOVE_HERE, param, from) != RADIO_ROGER) {
   1542 										Transmit_Message(RADIO_OVER_OUT, from);
   1543 									} else {
   1544 										Contact_With_Whom()->Unselect();
   1545 									}
   1546 								}
   1547 							}
   1548 						}
   1549 					}
   1550 				}
   1551 				return(RADIO_ROGER);
   1552 			}
   1553 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
   1554 			if (Class->Max_Passengers() > 0 && *this == VESSEL_CARRIER && How_Many() < Class->Max_Passengers()) {
   1555 				TechnoClass::Receive_Message(from, message, param);
   1556 				/*
   1557 				**	Establish contact with the object if this building isn't already in contact
   1558 				**	with another.
   1559 				*/
   1560 				if (!In_Radio_Contact()) {
   1561 					Transmit_Message(RADIO_HELLO, from);
   1562 				}
   1563 				if (Transmit_Message(RADIO_NEED_TO_MOVE) == RADIO_ROGER) {
   1564 					param = As_Target();
   1565 					if (Transmit_Message(RADIO_MOVE_HERE, param) == RADIO_YEA_NOW_WHAT) {
   1566 						Transmit_Message(RADIO_TETHER);
   1567 					}
   1568 				}
   1569 				return(RADIO_ROGER);
   1570 			}
   1571 #endif
   1572 			break;
   1573 
   1574 		/*
   1575 		**	When this message is received, it means that the other object
   1576 		**	has already turned its radio off. Turn this radio off as well.
   1577 		*/
   1578 		case RADIO_OVER_OUT:
   1579 			if (Mission == MISSION_RETURN) {
   1580 				Assign_Mission(MISSION_GUARD);
   1581 			}
   1582 			DriveClass::Receive_Message(from, message, param);
   1583 			return(RADIO_ROGER);
   1584 
   1585 	}
   1586 	return(DriveClass::Receive_Message(from, message, param));
   1587 }
   1588 
   1589 
   1590 /***********************************************************************************************
   1591  * VesselClass::Desired_Load_Dir -- Determines the best cell and facing for loading.           *
   1592  *                                                                                             *
   1593  *    This routine examines the unit and adjacent cells in order to find the best facing       *
   1594  *    for the transport and best staging cell for the potential passengers. This location is   *
   1595  *    modified by adjacent cell passability and direction of the potential passenger.          *
   1596  *                                                                                             *
   1597  * INPUT:   passenger   -- Pointer to the potential passenger.                                 *
   1598  *                                                                                             *
   1599  *          moveto      -- Reference to the cell number that specifies where the potential     *
   1600  *                         passenger should move to first.                                     *
   1601  *                                                                                             *
   1602  * OUTPUT:  Returns with the direction the transport should face before opening the transport  *
   1603  *          door.                                                                              *
   1604  *                                                                                             *
   1605  * WARNINGS:   none                                                                            *
   1606  *                                                                                             *
   1607  * HISTORY:                                                                                    *
   1608  *   06/01/1996 BWG : Created.                                                                 *
   1609  *=============================================================================================*/
   1610 DirType VesselClass::Desired_Load_Dir(ObjectClass * passenger, CELL & moveto) const
   1611 {
   1612 	assert(Vessels.ID(this) == ID);
   1613 	assert(IsActive);
   1614 
   1615 	/*
   1616 	**	Determine the ideal facing that provides the least resistance. This would be the direction
   1617 	**	of the potential passenger or the current transport facing if it is going to unload.
   1618 	*/
   1619 	DirType faceto;
   1620 	if (passenger != NULL) {
   1621 		faceto = Direction(passenger);
   1622 	} else {
   1623 		faceto = PrimaryFacing.Current() + DIR_S;
   1624 	}
   1625 
   1626 	/*
   1627 	**	Sweep through the adjacent cells in order to find the best candidate.
   1628 	*/
   1629 	FacingType bestdir = FACING_N;
   1630 	int bestval = -1;
   1631 	for (FacingType face = FACING_N; face < FACING_COUNT; face++) {
   1632 		int value = 0;
   1633 		CELL cellnum = Adjacent_Cell(Coord_Cell(Coord), face);
   1634 
   1635 		/*
   1636 		**	Base the initial value of the potential cell according to whether the passenger is
   1637 		**	allowed to enter the cell. If it can't, then give such a negative value to the
   1638 		**	cell so that it is prevented from ever choosing that cell for load/unload.
   1639 		*/
   1640 		if (passenger != NULL) {
   1641 			value = (passenger->Can_Enter_Cell(cellnum) == MOVE_OK || Coord_Cell(passenger->Coord) == cellnum) ? 128 : -128;
   1642 		} else {
   1643 			CellClass * cell = &Map[cellnum];
   1644 			if (Ground[cell->Land_Type()].Cost[SPEED_FOOT] == 0 || cell->Flag.Occupy.Building || cell->Flag.Occupy.Vehicle || cell->Flag.Occupy.Monolith || (cell->Flag.Composite & 0x01F) == 0x01F) {
   1645 				value = -128;
   1646 			} else {
   1647 				if (cell->Cell_Techno() && !House->Is_Ally(cell->Cell_Techno())) {
   1648 					value = -128;
   1649 				} else {
   1650 					value = 128;
   1651 				}
   1652 			}
   1653 		}
   1654 
   1655 #if(0)
   1656 		/*
   1657 		**	Give more weight to the cells that require the least rotation of the transport or the
   1658 		**	least roundabout movement for the potential passenger.
   1659 		*/
   1660 		value -= (int)ABS((int)(signed char)Facing_Dir(face) - (int)(signed char)faceto);
   1661 		if (face == FACING_S) {
   1662 			value -= 100;
   1663 		}
   1664 		if (face == FACING_SW || face == FACING_SE) value += 64;
   1665 #endif
   1666 		/*
   1667 		**	If the value for the potential cell is greater than the last recorded potential
   1668 		**	value, then record this cell as the best candidate.
   1669 		*/
   1670 		if (bestval == -1 || value > bestval) {
   1671 			bestval = value;
   1672 			bestdir = face;
   1673 //		} else {
   1674 //			ObjectClass * obj = Map[cellnum].Cell_Occupier();
   1675 //			if (obj) obj->Scatter(Coord, true);
   1676 		}
   1677 	}
   1678 
   1679 	/*
   1680 	**	If a suitable direction was found, then return with the direction value.
   1681 	*/
   1682 	moveto = 0;
   1683 	if (bestval > 0) {
   1684 		static DirType _desired_to_actual[FACING_COUNT] = {DIR_S, DIR_SW, DIR_NW, DIR_NW, DIR_NE, DIR_NE, DIR_NE, DIR_SE};
   1685 
   1686 		moveto = Adjacent_Cell(Coord_Cell(Coord), bestdir);
   1687 		return(_desired_to_actual[bestdir]);
   1688 	}
   1689 	return(DIR_N);
   1690 }
   1691 
   1692 
   1693 /***********************************************************************************************
   1694  * VesselClass::LST_Open_Door -- Opens a LST door.                                             *
   1695  *                                                                                             *
   1696  *    This routine will initiate opening of the doors on the LST.                              *
   1697  *                                                                                             *
   1698  * INPUT:   none                                                                               *
   1699  *                                                                                             *
   1700  * OUTPUT:  none                                                                               *
   1701  *                                                                                             *
   1702  * WARNINGS:   none                                                                            *
   1703  *                                                                                             *
   1704  * HISTORY:                                                                                    *
   1705  *   06/01/1996 BWG : Created.                                                                 *
   1706  *=============================================================================================*/
   1707 void VesselClass::LST_Open_Door(void)
   1708 {
   1709 	assert(Vessels.ID(this) == ID);
   1710 	assert(IsActive);
   1711 
   1712 	if (!IsDriving && !IsRotating) {
   1713 		Open_Door(5, 6);
   1714 	}
   1715 }
   1716 
   1717 
   1718 /***********************************************************************************************
   1719  * VesselClass::LST_Close_Door -- Closes a LST door.                                           *
   1720  *                                                                                             *
   1721  *    This routine will initiate closing of the LST door.                                      *
   1722  *                                                                                             *
   1723  * INPUT:   none                                                                               *
   1724  *                                                                                             *
   1725  * OUTPUT:  none                                                                               *
   1726  *                                                                                             *
   1727  * WARNINGS:   none                                                                            *
   1728  *                                                                                             *
   1729  * HISTORY:                                                                                    *
   1730  *   06/01/1996 BWG : Created.                                                                 *
   1731  *=============================================================================================*/
   1732 void VesselClass::LST_Close_Door(void)
   1733 {
   1734 	assert(Vessels.ID(this) == ID);
   1735 	assert(IsActive);
   1736 
   1737 	Close_Door(5, 6);
   1738 }
   1739 
   1740 
   1741 /***********************************************************************************************
   1742  * VesselClass::Mission_Unload -- Handles unloading cargo.                                     *
   1743  *                                                                                             *
   1744  *    This is the AI control sequence for when a transport desires to unload its cargo.	     *
   1745  *                                                                                             *
   1746  * INPUT:   none                                                                               *
   1747  *                                                                                             *
   1748  * OUTPUT:  Returns with the delay before calling this routine again.                          *
   1749  *                                                                                             *
   1750  * WARNINGS:   none                                                                            *
   1751  *                                                                                             *
   1752  * HISTORY:                                                                                    *
   1753  *   06/01/1996 BWG : Created.                                                                 *
   1754  *=============================================================================================*/
   1755 int VesselClass::Mission_Unload(void)
   1756 {
   1757 	assert(Vessels.ID(this) == ID);
   1758 	assert(IsActive);
   1759 
   1760 	enum {
   1761 		INITIAL_CHECK,
   1762 		MANEUVERING,
   1763 		OPENING_DOOR,
   1764 		UNLOADING,
   1765 		CLOSING_DOOR
   1766 	};
   1767 	DirType	dir;
   1768 	CELL		cell;
   1769 
   1770 	switch (Class->Type) {
   1771 		case VESSEL_TRANSPORT:
   1772 			switch (Status) {
   1773 				case INITIAL_CHECK:
   1774 					dir = Desired_Load_Dir(NULL, cell);
   1775 					if (How_Many() > 0 && cell != 0) {
   1776 						Do_Turn(dir);
   1777 						Status = MANEUVERING;
   1778 						return(1);
   1779 					} else {
   1780 						if (!How_Many()) {	// don't break out if still carrying passengers
   1781 							Assign_Mission(MISSION_GUARD);
   1782 						}
   1783 					}
   1784 					break;
   1785 
   1786 				case MANEUVERING:
   1787 					if (!IsRotating) {
   1788 						LST_Open_Door();
   1789 						if (Is_Door_Opening()) {
   1790 							Status = OPENING_DOOR;
   1791 							return(1);
   1792 						}
   1793 					}
   1794 					break;
   1795 
   1796 				case OPENING_DOOR:
   1797 					if (Is_Door_Open()) {
   1798 						Status = UNLOADING;
   1799 						return(1);
   1800 					} else {
   1801 						if (!Is_Door_Opening()) {
   1802 							Status = INITIAL_CHECK;
   1803 						}
   1804 					}
   1805 					break;
   1806 
   1807 				case UNLOADING:
   1808 					if (How_Many()) {
   1809 
   1810 						/*
   1811 						**	Don't do anything if still in radio contact.
   1812 						*/
   1813 						if (In_Radio_Contact()) return(TICKS_PER_SECOND);
   1814 
   1815 						FootClass * passenger = Detach_Object();
   1816 
   1817 						if (passenger != NULL) {
   1818 							DirType toface = DIR_S + PrimaryFacing;
   1819 							bool placed = false;
   1820 
   1821 							for (FacingType face = FACING_N; face < FACING_COUNT; face++) {
   1822 								DirType newface = toface + Facing_Dir(face);
   1823 								CELL newcell = Adjacent_Cell(Coord_Cell(Coord), newface);
   1824 
   1825 								if (passenger->Can_Enter_Cell(newcell) == MOVE_OK) {
   1826 									ScenarioInit++;
   1827 									passenger->Unlimbo(Coord_Move(Coord, newface, CELL_LEPTON_W/2), newface);
   1828 									ScenarioInit--;
   1829 									passenger->Assign_Mission(MISSION_MOVE);
   1830 									passenger->Assign_Destination(::As_Target(newcell));
   1831 									passenger->Commence();
   1832 									Transmit_Message(RADIO_HELLO, passenger);
   1833 									Transmit_Message(RADIO_TETHER, passenger);
   1834 									if (passenger->What_Am_I() == RTTI_UNIT) {
   1835 										((UnitClass *)passenger)->IsToScatter = true;
   1836 									}
   1837 									placed = true;
   1838 									break;
   1839 								}
   1840 							}
   1841 
   1842 							/*
   1843 							** If the attached unit could NOT be deployed, then re-attach
   1844 							**	it and then bail out of this deploy process.
   1845 							*/
   1846 							if (!placed) {
   1847 								Attach(passenger);
   1848 
   1849 								/*
   1850 								**	Tell everyone around the transport to scatter.
   1851 								*/
   1852 								for (FacingType face = FACING_N; face < FACING_COUNT; face++) {
   1853 									CellClass * cellptr = Map[Coord].Adjacent_Cell(face);
   1854 									if (cellptr && cellptr->Is_Clear_To_Move(SPEED_TRACK, true, true)) {
   1855 										cellptr->Incoming(0, true);
   1856 									}
   1857 								}
   1858 
   1859 //								Status = CLOSING_DOOR;
   1860 							}
   1861 							else {
   1862 								passenger->Look(false);
   1863 							}
   1864 						}
   1865 					} else {
   1866 						Status = CLOSING_DOOR;
   1867 					}
   1868 					break;
   1869 
   1870 				/*
   1871 				**	Close LST door in preparation for normal operation.
   1872 				*/
   1873 				case CLOSING_DOOR:
   1874 					if (Is_Door_Open()) {
   1875 						LST_Close_Door();
   1876 					}
   1877 					if (Is_Door_Closed()) {
   1878 						if (IsALoaner) {
   1879 							Assign_Mission(MISSION_RETREAT);
   1880 						} else {
   1881 							Assign_Mission(MISSION_GUARD);
   1882 						}
   1883 					}
   1884 					break;
   1885 			}
   1886 			break;
   1887 
   1888 		default:
   1889 			break;
   1890 	}
   1891 	return(MissionControl[Mission].Normal_Delay());
   1892 }
   1893 
   1894 
   1895 /***********************************************************************************************
   1896  * VesselClass::Assign_Destination -- Assign a destination for this vessel.                    *
   1897  *                                                                                             *
   1898  *    This routine is called when a destination is to be assigned to this vessel.              *
   1899  *                                                                                             *
   1900  * INPUT:   target   -- The destination to assign to this vessel.                              *
   1901  *                                                                                             *
   1902  * OUTPUT:  none                                                                               *
   1903  *                                                                                             *
   1904  * WARNINGS:   none                                                                            *
   1905  *                                                                                             *
   1906  * HISTORY:                                                                                    *
   1907  *   07/09/1996 JLB : Created.                                                                 *
   1908  *=============================================================================================*/
   1909 void VesselClass::Assign_Destination(TARGET target)
   1910 {
   1911 	assert(IsActive);
   1912 
   1913 	/*
   1914 	**	Abort early if there is anything wrong with the parameters
   1915 	**	or the unit already is assigned the specified destination.
   1916 	*/
   1917 	if (target == NavCom) return;
   1918 
   1919 	/*
   1920 	**	Transport vehicles must tell all passengers that are about to load, that they
   1921 	**	cannot proceed. This is accomplished with a radio message to this effect.
   1922 	*/
   1923 	if (In_Radio_Contact() && Class->Max_Passengers() > 0 && (Contact_With_Whom()->Is_Infantry() || Contact_With_Whom()->What_Am_I() == RTTI_UNIT)) {
   1924 		long param = TARGET_NONE;
   1925 		Transmit_Message(RADIO_MOVE_HERE, param);		// should stop objects heading toward this transport.
   1926 		Transmit_Message(RADIO_OVER_OUT);
   1927 		if (!Is_Door_Closed()) {
   1928 			LST_Close_Door();
   1929 		}
   1930 	}
   1931 
   1932 	if (!Is_Door_Closed()) {
   1933 		LST_Close_Door();
   1934 	}
   1935 
   1936 	DriveClass::Assign_Destination(target);
   1937 }
   1938 
   1939 
   1940 /***********************************************************************************************
   1941  * VesselClass::Pip_Count -- Fetches the number of pips to display on vessel.                  *
   1942  *                                                                                             *
   1943  *    This routine is used to fetch the number of "fullness" pips to display on the vessel.    *
   1944  *    This will be the number of passengers on a transport.                                    *
   1945  *                                                                                             *
   1946  * INPUT:   none                                                                               *
   1947  *                                                                                             *
   1948  * OUTPUT:  Returns with the number of pips to draw on this unit.                              *
   1949  *                                                                                             *
   1950  * WARNINGS:   none                                                                            *
   1951  *                                                                                             *
   1952  * HISTORY:                                                                                    *
   1953  *   06/25/1995 JLB : Created.                                                                 *
   1954  *=============================================================================================*/
   1955 int VesselClass::Pip_Count(void) const
   1956 {
   1957 	if (Techno_Type_Class()->Max_Passengers() > 0) {
   1958 		int passengers = 0;
   1959 		ObjectClass const * object = Attached_Object();
   1960 		for (int index = 0; index < Class_Of().Max_Pips(); index++) {
   1961 			if (object != NULL) {
   1962 				passengers++;
   1963 				object = object->Next;
   1964 			}
   1965 		}
   1966 		return passengers;
   1967 	}
   1968 
   1969 	return 0;
   1970 }
   1971 
   1972 
   1973 /***********************************************************************************************
   1974  * VesselClass::Mission_Retreat -- Perform the retreat mission.                                *
   1975  *                                                                                             *
   1976  *    This will cause the vessel to run away from the battlefield. It searches for an escape   *
   1977  *    map edge according to the reinforcement edge specified in the house.                     *
   1978  *                                                                                             *
   1979  * INPUT:   none                                                                               *
   1980  *                                                                                             *
   1981  * OUTPUT:  Returns with the number of game frames to delay before this routine is called      *
   1982  *          again.                                                                             *
   1983  *                                                                                             *
   1984  * WARNINGS:   none                                                                            *
   1985  *                                                                                             *
   1986  * HISTORY:                                                                                    *
   1987  *   07/09/1996 JLB : Created.                                                                 *
   1988  *=============================================================================================*/
   1989 int VesselClass::Mission_Retreat(void)
   1990 {
   1991 	assert(Vessels.ID(this) == ID);
   1992 	assert(IsActive);
   1993 
   1994 	enum {
   1995 		PICK_RETREAT_POINT,
   1996 		TRAVEL
   1997 	};
   1998 	switch (Status) {
   1999 		case PICK_RETREAT_POINT:
   2000 			IsALoaner = true;
   2001 			if (!Target_Legal(NavCom)) {
   2002 //				CELL cell = Map.Calculated_Cell(House->Control.Edge, (Team.Is_Valid()) ? Team->Class->Origin : -1, -1, Class->Speed);
   2003 				CELL cell = Map.Calculated_Cell(House->Control.Edge, (Team.Is_Valid()) ? Team->Class->Origin : -1, Coord_Cell(Center_Coord()), Class->Speed);
   2004 				if (Team.Is_Valid()) {
   2005 					Team->Remove(this);
   2006 				}
   2007 				Assign_Destination(::As_Target(cell));
   2008 			}
   2009 			Status = TRAVEL;
   2010 			return(1);
   2011 
   2012 		case TRAVEL:
   2013 			if (!Target_Legal(NavCom)) {
   2014 				Status = PICK_RETREAT_POINT;
   2015 			}
   2016 			break;
   2017 
   2018 		default:
   2019 			break;
   2020 	}
   2021 	return(MissionControl[Mission].Normal_Delay());
   2022 }
   2023 
   2024 
   2025 /***********************************************************************************************
   2026  * VesselClass::Is_Allowed_To_Recloak -- Can the vessel recloak now?                           *
   2027  *                                                                                             *
   2028  *    Asking this question is part of the recloak process. If the answer is no, then           *
   2029  *    recloaking is postponed. This facilitates keeping submarines visible for longer than     *
   2030  *    they otherwise would be.                                                                 *
   2031  *                                                                                             *
   2032  * INPUT:   none                                                                               *
   2033  *                                                                                             *
   2034  * OUTPUT:  bool; Can this vessel recloak now?                                                 *
   2035  *                                                                                             *
   2036  * WARNINGS:   none                                                                            *
   2037  *                                                                                             *
   2038  * HISTORY:                                                                                    *
   2039  *   07/09/1996 BWG : Created.                                                                 *
   2040  *=============================================================================================*/
   2041 bool VesselClass::Is_Allowed_To_Recloak(void) const
   2042 {
   2043 	return(PulseCountDown == 0);
   2044 }
   2045 
   2046 
   2047 /***********************************************************************************************
   2048  * VesselClass::Read_INI -- Read the vessel data from the INI database.                        *
   2049  *                                                                                             *
   2050  *    This will read and create all vessels specified in the INI database. This routine is     *
   2051  *    called when the scenario starts.                                                         *
   2052  *                                                                                             *
   2053  * INPUT:   ini   -- Reference to the INI database to read the vessel data from.               *
   2054  *                                                                                             *
   2055  * OUTPUT:  none                                                                               *
   2056  *                                                                                             *
   2057  * WARNINGS:   Vessels will be created and placed on the map by this function.                 *
   2058  *                                                                                             *
   2059  * HISTORY:                                                                                    *
   2060  *   07/09/1996 JLB : Created.                                                                 *
   2061  *=============================================================================================*/
   2062 void VesselClass::Read_INI(CCINIClass & ini)
   2063 {
   2064 	VesselClass	* vessel;			// Working vessel pointer.
   2065 	HousesType	inhouse;			// Vessel house.
   2066 	VesselType	classid;			// Vessel class.
   2067 	char			buf[128];
   2068 
   2069 	int len = ini.Entry_Count(INI_Name());
   2070 	for (int index = 0; index < len; index++) {
   2071 		char const * entry = ini.Get_Entry(INI_Name(), index);
   2072 
   2073 		ini.Get_String(INI_Name(), entry, NULL, buf, sizeof(buf));
   2074 		inhouse = HouseTypeClass::From_Name(strtok(buf, ","));
   2075 		if (inhouse != HOUSE_NONE) {
   2076 			classid = VesselTypeClass::From_Name(strtok(NULL, ","));
   2077 
   2078 			if (classid != VESSEL_NONE) {
   2079 
   2080 				if (HouseClass::As_Pointer(inhouse) != NULL) {
   2081 					vessel = new VesselClass(classid, inhouse);
   2082 					if (vessel != NULL) {
   2083 
   2084 						/*
   2085 						**	Read the raw data.
   2086 						*/
   2087 						int strength = atoi(strtok(NULL, ",\r\n"));
   2088 
   2089 						CELL cell = atoi(strtok(NULL, ",\r\n"));
   2090 
   2091 						COORDINATE coord = Cell_Coord(cell);
   2092 
   2093 						DirType dir = (DirType)atoi(strtok(NULL, ",\r\n"));
   2094 						MissionType mission = MissionClass::Mission_From_Name(strtok(NULL, ",\n\r"));
   2095 
   2096 						vessel->Trigger = NULL;
   2097 						TriggerTypeClass * tp = TriggerTypeClass::From_Name(strtok(NULL, ",\r\n"));
   2098 						if (tp != NULL) {
   2099 							TriggerClass * tt = Find_Or_Make(tp);
   2100 							if (tt != NULL) {
   2101 								tt->AttachCount++;
   2102 								vessel->Trigger = tt;
   2103 							}
   2104 						}
   2105 
   2106 						if (vessel->Unlimbo(coord, dir)) {
   2107 							vessel->Strength = (int)vessel->Class->MaxStrength * fixed(strength, 256);
   2108 							if (vessel->Strength > vessel->Class->MaxStrength-3) vessel->Strength = vessel->Class->MaxStrength;
   2109 	//						vessel->Strength = Fixed_To_Cardinal(vessel->Class->MaxStrength, strength);
   2110 							if (Session.Type == GAME_NORMAL || vessel->House->IsHuman) {
   2111 								vessel->Assign_Mission(mission);
   2112 								vessel->Commence();
   2113 							} else {
   2114 								vessel->Enter_Idle_Mode();
   2115 							}
   2116 
   2117 						} else {
   2118 
   2119 							/*
   2120 							**	If the vessel could not be unlimboed, then this is a catastrophic error
   2121 							**	condition. Delete the vessel.
   2122 							*/
   2123 							delete vessel;
   2124 						}
   2125 					}
   2126 				}
   2127 			}
   2128 		}
   2129 	}
   2130 }
   2131 
   2132 
   2133 /***********************************************************************************************
   2134  * VesselClass::Write_INI -- Write all vessel scenario data to the INI database.               *
   2135  *                                                                                             *
   2136  *    This routine is used to add the vessel data (needed for scenario start) to the INI       *
   2137  *    database specified. If there was any preexisting vessel data in the database, it will    *
   2138  *    be cleared                                                                               *
   2139  *                                                                                             *
   2140  * INPUT:   ini   -- Reference to the ini database to store the vessel data into.              *
   2141  *                                                                                             *
   2142  * OUTPUT:  none                                                                               *
   2143  *                                                                                             *
   2144  * WARNINGS:   none                                                                            *
   2145  *                                                                                             *
   2146  * HISTORY:                                                                                    *
   2147  *   07/09/1996 JLB : Created.                                                                 *
   2148  *=============================================================================================*/
   2149 void VesselClass::Write_INI(CCINIClass & ini)
   2150 {
   2151 	/*
   2152 	**	First, clear out all existing vessel data from the ini file.
   2153 	*/
   2154 	ini.Clear(INI_Name());
   2155 
   2156 	/*
   2157 	**	Write the vessel data out.
   2158 	*/
   2159 	for (int index = 0; index < Vessels.Count(); index++) {
   2160 		VesselClass * vessel = Vessels.Ptr(index);
   2161 		if (vessel != NULL && !vessel->IsInLimbo && vessel->IsActive) {
   2162 			char	uname[10];
   2163 			char	buf[128];
   2164 
   2165 			sprintf(uname, "%d", index);
   2166 			sprintf(buf, "%s,%s,%d,%u,%d,%s,%s",
   2167 				vessel->House->Class->IniName,
   2168 				vessel->Class->IniName,
   2169 				vessel->Health_Ratio()*256,
   2170 				Coord_Cell(vessel->Coord),
   2171 				vessel->PrimaryFacing.Current(),
   2172 				MissionClass::Mission_Name(vessel->Mission),
   2173 				vessel->Trigger.Is_Valid() ? vessel->Trigger->Class->IniName : "None"
   2174 				);
   2175 			ini.Put_String(INI_Name(), uname, buf);
   2176 		}
   2177 	}
   2178 }
   2179 
   2180 
   2181 /***********************************************************************************************
   2182  * VesselClass::Start_Driver -- Starts the vessel by reserving the location it is moving to.   *
   2183  *                                                                                             *
   2184  *    This routine is called when the vessel starts moving. It will reserve the destination    *
   2185  *    cell so that it won't be occupied by another vessel as this one is travelling.           *
   2186  *                                                                                             *
   2187  * INPUT:   headto   -- The coordinate that will be headed to.                                 *
   2188  *                                                                                             *
   2189  * OUTPUT:  bool; Was the destination location successfully marked?                            *
   2190  *                                                                                             *
   2191  * WARNINGS:   none                                                                            *
   2192  *                                                                                             *
   2193  * HISTORY:                                                                                    *
   2194  *   07/09/1996 JLB : Created.                                                                 *
   2195  *=============================================================================================*/
   2196 bool VesselClass::Start_Driver(COORDINATE & headto)
   2197 {
   2198 	assert(Vessels.ID(this) == ID);
   2199 	assert(IsActive);
   2200 
   2201 	if (DriveClass::Start_Driver(headto) && IsActive) { //BG IsActive can be cleared by Start_Driver
   2202 		Mark_Track(headto, MARK_DOWN);
   2203 		return(true);
   2204 	}
   2205 	return(false);
   2206 }
   2207 
   2208 
   2209 /***********************************************************************************************
   2210  * VesselClass::What_Action -- Determines action to perform on specified cell.                 *
   2211  *                                                                                             *
   2212  *    This routine will determine what action to perform if the mouse were clicked over the    *
   2213  *    cell specified.																								  *
   2214  *                                                                                             *
   2215  * INPUT:   cell  -- The cell that the mouse might be clicked on.                              *
   2216  *                                                                                             *
   2217  * OUTPUT:  Returns with the action type that this unit will perform if the mouse were         *
   2218  *          clicked of the cell specified.                                                     *
   2219  *                                                                                             *
   2220  * WARNINGS:   none                                                                            *
   2221  *                                                                                             *
   2222  * HISTORY:                                                                                    *
   2223  *   07/11/1996 BWG : Created.                                                                 *
   2224  *=============================================================================================*/
   2225 ActionType VesselClass::What_Action(CELL cell) const
   2226 {
   2227 	assert(Vessels.ID(this) == ID);
   2228 	assert(IsActive);
   2229 
   2230 	ActionType action = DriveClass::What_Action(cell);
   2231 	if (action == ACTION_NOMOVE && Map[cell].Land_Type() == LAND_BEACH) {
   2232 		return(ACTION_MOVE);
   2233 	}
   2234 
   2235 	if (action == ACTION_NOMOVE && Class->PrimaryWeapon != NULL && Class->PrimaryWeapon->Bullet->IsSubSurface && Map[cell].Is_Bridge_Here()) {
   2236 		return(ACTION_ATTACK);
   2237 	}
   2238 	return(action);
   2239 }
   2240 
   2241 
   2242 /***********************************************************************************************
   2243  * VesselClass::Rotation_AI -- Handles turret and body rotation for this vessel.               *
   2244  *                                                                                             *
   2245  *    Any turret or body rotation for this vessel will be handled by this routine.             *
   2246  *                                                                                             *
   2247  * INPUT:   none                                                                               *
   2248  *                                                                                             *
   2249  * OUTPUT:  none                                                                               *
   2250  *                                                                                             *
   2251  * WARNINGS:   Only call this routine once per vessel per game logic loop.                     *
   2252  *                                                                                             *
   2253  * HISTORY:                                                                                    *
   2254  *   07/29/1996 JLB : Created.                                                                 *
   2255  *=============================================================================================*/
   2256 void VesselClass::Rotation_AI(void)
   2257 {
   2258 	if (Target_Legal(TarCom) && !IsRotating) {
   2259 		DirType dir = Direction(TarCom);
   2260 
   2261 		if (Class->IsTurretEquipped) {
   2262 			SecondaryFacing.Set_Desired(dir);
   2263 		}
   2264 	}
   2265 
   2266 	IsRotating = false;
   2267 	if (Class->IsTurretEquipped) {
   2268 
   2269 		if (SecondaryFacing.Is_Rotating()) {
   2270 			Mark(MARK_CHANGE_REDRAW);
   2271 			if (SecondaryFacing.Rotation_Adjust((Class->ROT * House->GroundspeedBias)+1)) {
   2272 				Mark(MARK_CHANGE_REDRAW);
   2273 			}
   2274 
   2275 			/*
   2276 			**	If no further rotation is necessary, flag that the rotation
   2277 			**	has stopped.
   2278 			*/
   2279 			IsRotating = SecondaryFacing.Is_Rotating();
   2280 		}
   2281 	}
   2282 }
   2283 
   2284 
   2285 /***********************************************************************************************
   2286  * VesselClass::Combat_AI -- Handles firing and target selection for the vessel.               *
   2287  *                                                                                             *
   2288  *    This routine will process firing logic for the vessel. It includes searching for targets *
   2289  *    and performing any adjustments necessary to bring the target to bear.                    *
   2290  *                                                                                             *
   2291  * INPUT:   none                                                                               *
   2292  *                                                                                             *
   2293  * OUTPUT:  none                                                                               *
   2294  *                                                                                             *
   2295  * WARNINGS:   Only call this routine once per vessel per game logic loop.                     *
   2296  *                                                                                             *
   2297  * HISTORY:                                                                                    *
   2298  *   07/29/1996 JLB : Created.                                                                 *
   2299  *=============================================================================================*/
   2300 void VesselClass::Combat_AI(void)
   2301 {
   2302 	if (Target_Legal(TarCom) && Is_Weapon_Equipped()) {
   2303 
   2304 		/*
   2305 		**	Determine which weapon can fire. First check for the primary weapon. If that weapon
   2306 		**	cannot fire, then check any secondary weapon. If neither weapon can fire, then the
   2307 		**	failure code returned is that from the primary weapon.
   2308 		*/
   2309 		int primary = What_Weapon_Should_I_Use(TarCom);
   2310 		FireErrorType ok = Can_Fire(TarCom, primary);
   2311 
   2312 		switch (ok) {
   2313 			case FIRE_OK:
   2314 				Fire_At(TarCom, primary);
   2315 				break;
   2316 
   2317 			case FIRE_FACING:
   2318 				if (Class->IsTurretEquipped) {
   2319 					SecondaryFacing.Set_Desired(Direction(TarCom));
   2320 				} else {
   2321 					if (!PrimaryFacing.Is_Rotating()) {
   2322 						PrimaryFacing.Set_Desired(Direction(TarCom));
   2323 					}
   2324 				}
   2325 				break;
   2326 
   2327 			case FIRE_CLOAKED:
   2328 				Mark(MARK_OVERLAP_UP);
   2329 				IsFiring = false;
   2330 				Mark(MARK_OVERLAP_DOWN);
   2331 				Do_Uncloak();
   2332 				break;
   2333 		}
   2334 	}
   2335 }
   2336 
   2337 
   2338 /***********************************************************************************************
   2339  * VesselClass::Edge_Of_World_AI -- Determine if vessel is off the edge of the world.          *
   2340  *                                                                                             *
   2341  *    In addition to detecting the edge of world case, this routine will delete the vessel     *
   2342  *    if it occurs.                                                                            *
   2343  *                                                                                             *
   2344  * INPUT:   none                                                                               *
   2345  *                                                                                             *
   2346  * OUTPUT:  bool; Was the vessel deleted by this routine?                                      *
   2347  *                                                                                             *
   2348  * WARNINGS:   Be sure to examine the return value and if true, abort any further processing   *
   2349  *             for this vessel since it has been deleted. This routine should be called once   *
   2350  *             per vessel per game logic loop.                                                 *
   2351  *                                                                                             *
   2352  * HISTORY:                                                                                    *
   2353  *   07/29/1996 JLB : Created.                                                                 *
   2354  *=============================================================================================*/
   2355 bool VesselClass::Edge_Of_World_AI(void)
   2356 {
   2357 	if (!IsDriving && !Map.In_Radar(Coord_Cell(Coord)) && IsLocked) {
   2358 		if (Team.Is_Valid()) Team->IsLeaveMap = true;
   2359 		Stun();
   2360 		delete this;
   2361 		return(true);
   2362 	}
   2363 	return(false);
   2364 }
   2365 
   2366 
   2367 /***********************************************************************************************
   2368  * VesselClass::Repair_AI -- Process any self-repair required of this vessel.                  *
   2369  *                                                                                             *
   2370  *    When a vessel repairs, it does so 'by itself' and not under direct control of another    *
   2371  *    object. This self repair logic is processed here. Upon repair completion of money        *
   2372  *    exhuastion, the repair process will terminate.                                           *
   2373  *                                                                                             *
   2374  * INPUT:   none                                                                               *
   2375  *                                                                                             *
   2376  * OUTPUT:  none                                                                               *
   2377  *                                                                                             *
   2378  * WARNINGS:   Call this routine only once per vessel per game logic loop.                     *
   2379  *                                                                                             *
   2380  * HISTORY:                                                                                    *
   2381  *   07/29/1996 BWG : Created.                                                                 *
   2382  *=============================================================================================*/
   2383 void VesselClass::Repair_AI(void)
   2384 {
   2385 	if (IsSelfRepairing) {
   2386 		if ((Frame % (TICKS_PER_MINUTE * Rule.RepairRate)) == 0) {
   2387 			Mark(MARK_CHANGE);
   2388 			int cost = Class->Repair_Cost();
   2389 			int step = Class->Repair_Step();
   2390 
   2391 			if (House->Available_Money() >= cost) {
   2392 				House->Spend_Money(cost);
   2393 				Strength += step;
   2394 				if (Strength >= Class->MaxStrength) {
   2395 					Strength = Class->MaxStrength;
   2396 					IsSelfRepairing = IsToSelfRepair = false;
   2397 
   2398 					// MBL 04.27.2020: Make only audible to the correct player
   2399 					// if (IsOwnedByPlayer) Speak(VOX_UNIT_REPAIRED);
   2400 					if (IsOwnedByPlayer) Speak(VOX_UNIT_REPAIRED, House);
   2401 				}
   2402 			}
   2403 		}
   2404 	}
   2405 }
   2406 
   2407 #ifdef FIXIT_CARRIER	//	checked - ajw 9/28/98
   2408 /***********************************************************************************************
   2409  * VesselClass::Fire_At -- Try to fire upon the target specified.                              *
   2410  *                                                                                             *
   2411  *    This routine is the auto-fire logic for the ship. It will check                          *
   2412  *    to see if we're an aircraft carrier, and if so, launch one of our                        *
   2413  *    aircraft.  If we're not an aircraft carrier, it lets the higher-level                    *
   2414  *    Fire_At logic take over.                                                                 *
   2415  *                                                                                             *
   2416  * INPUT:   target   -- The target to fire upon.                                               *
   2417  *                                                                                             *
   2418  *          which    -- Which weapon to use when firing. 0=primary, 1=secondary.               *
   2419  *                                                                                             *
   2420  * OUTPUT:  bool; Did firing occur?                                                            *
   2421  *                                                                                             *
   2422  * WARNINGS:   none                                                                            *
   2423  *                                                                                             *
   2424  * HISTORY:                                                                                    *
   2425  *   04/26/1994 JLB : Created.                                                                 *
   2426  *=============================================================================================*/
   2427 BulletClass * VesselClass::Fire_At(TARGET target, int which)
   2428 {
   2429 	//PG assert(Units.ID(this) == ID);
   2430 	assert(IsActive);
   2431 
   2432 	if (*this == VESSEL_CARRIER) {
   2433 		Arm = CarrierLaunchDelay;
   2434 		FootClass * passenger = Detach_Object();
   2435 		if (passenger != NULL) {
   2436 			ScenarioInit++;
   2437 			passenger->Unlimbo(Center_Coord());
   2438 			ScenarioInit--;
   2439 			passenger->Assign_Mission(MISSION_ATTACK);
   2440 			passenger->Assign_Target(TarCom);
   2441 			passenger->Commence();
   2442 // If we've launched our last aircraft, discontinue attacking.
   2443 			if (!How_Many()) Assign_Target(TARGET_NONE);
   2444 		}
   2445 	} else {
   2446 		return DriveClass::Fire_At(target, which);
   2447 	}
   2448 	return (NULL);
   2449 }
   2450 
   2451 #endif