CnC_Remastered_Collection

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

COMBAT.CPP (12480B)


      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:   F:\projects\c&c\vcs\code\combat.cpv   2.17   16 Oct 1995 16:48:32   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 : COMBAT.CPP                                                   *
     24  *                                                                                             *
     25  *                   Programmer : Joe L. Bostic                                                *
     26  *                                                                                             *
     27  *                   Start Date : September 19, 1994                                           *
     28  *                                                                                             *
     29  *                  Last Update : January 1, 1995 [JLB]                                        *
     30  *                                                                                             *
     31  *---------------------------------------------------------------------------------------------*
     32  * Functions:                                                                                  *
     33  *   Explosion_Damage -- Inflict an explosion damage affect.                                   *
     34  *   Modify_Damage -- Adjusts damage to reflect the nature of the target.                      *
     35  * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
     36 
     37 #include	"function.h"
     38 
     39 int Modify_Damage(int damage, WarheadType warhead, ArmorType armor);
     40 void Explosion_Damage(COORDINATE coord, unsigned strength, TechnoClass *source, WarheadType warhead);
     41 
     42 
     43 /***********************************************************************************************
     44  * Modify_Damage -- Adjusts damage to reflect the nature of the target.                        *
     45  *                                                                                             *
     46  *    This routine is the core of combat tactics. It implements the                            *
     47  *    affect various armor types have against various weapon types. By                         *
     48  *    careful exploitation of this table, tactical advantage can be                            *
     49  *    obtained.                                                                                *
     50  *                                                                                             *
     51  * INPUT:   damage   -- The damage points to process.                                          *
     52  *                                                                                             *
     53  *          warhead  -- The source of the damage points.                                       *
     54  *                                                                                             *
     55  *          armor    -- The type of armor defending against the damage.                        *
     56  *                                                                                             *
     57  *          distance -- The distance (in leptons) from the source of the damage.               *
     58  *                                                                                             *
     59  * OUTPUT:  Returns with the adjusted damage points to inflict upon the                        *
     60  *          target.                                                                            *
     61  *                                                                                             *
     62  * WARNINGS:   none                                                                            *
     63  *                                                                                             *
     64  * HISTORY:                                                                                    *
     65  *   04/16/1994 JLB : Created.                                                                 *
     66  *   04/17/1994 JLB : Always does a minimum of damage.                                         *
     67  *   01/01/1995 JLB : Takes into account distance from damage source.                          *
     68  *=============================================================================================*/
     69 int Modify_Damage(int damage, WarheadType warhead, ArmorType armor, int distance)
     70 {
     71 	/*
     72 	**	If there is no raw damage value to start with, then
     73 	**	there can be no modified damage either.
     74 	*/
     75 	if (Special.IsInert || !damage || warhead == WARHEAD_NONE) return(0);
     76 
     77 	WarheadTypeClass const * whead = &Warheads[warhead];
     78 
     79 	damage = Fixed_To_Cardinal(damage, whead->Modifier[armor]);
     80 
     81 	/*
     82 	**	Reduce damage according to the distance from the impact point.
     83 	*/
     84 	if (damage) {
     85 //		if (distance < 0x0010) damage *= 2;			// Double damage for direct hits.
     86 		distance >>= whead->SpreadFactor;
     87 		distance = Bound(distance, 0, 16);
     88 		damage >>= distance;
     89 	}
     90 
     91 	/*
     92 	**	If damage was indicated, then it should never drop below one damage point regardless
     93 	**	of modifiers. This allows a very weak attacker to eventually destroy anything it
     94 	**	fires upon, given enough time.
     95 	*/
     96 	return(damage);
     97 }
     98 
     99 
    100 /***********************************************************************************************
    101  * Explosion_Damage -- Inflict an explosion damage affect.                                     *
    102  *                                                                                             *
    103  *    Processes the collateral damage affects typically caused by an                           *
    104  *    explosion.                                                                               *
    105  *                                                                                             *
    106  * INPUT:   coord    -- The coordinate of ground zero.                                         *
    107  *                                                                                             *
    108  *          strength -- Raw damage points at ground zero.                                      *
    109  *                                                                                             *
    110  *          source   -- Source of the explosion (who is responsible).                          *
    111  *                                                                                             *
    112  *          warhead  -- The kind of explosion to process.                                      *
    113  *                                                                                             *
    114  * OUTPUT:  none                                                                               *
    115  *                                                                                             *
    116  * WARNINGS:   This routine can consume some time and will affect the AI                       *
    117  *             of nearby enemy units (possibly).                                               *
    118  *                                                                                             *
    119  * HISTORY:                                                                                    *
    120  *   08/16/1991 JLB : Created.                                                                 *
    121  *   11/30/1991 JLB : Uses coordinate system.                                                  *
    122  *   12/27/1991 JLB : Radius of explosion damage effect.                                       *
    123  *   04/13/1994 JLB : Streamlined.                                                             *
    124  *   04/16/1994 JLB : Warhead damage type modifier.                                            *
    125  *   04/17/1994 JLB : Cleaned up.                                                              *
    126  *   06/20/1994 JLB : Uses object pointers to distribute damage.                               *
    127  *   06/20/1994 JLB : Source is a pointer.                                                     *
    128  *=============================================================================================*/
    129 void Explosion_Damage(COORDINATE coord, unsigned strength, TechnoClass * source, WarheadType warhead)
    130 {
    131 	CELL				cell;			// Cell number under explosion.
    132 	ObjectClass *	object;			// Working object pointer.
    133 	ObjectClass *	objects[32];	// Maximum number of objects that can be damaged.
    134 	int				distance;	// Distance to unit.
    135 	int				range;		// Damage effect radius.
    136 	int				index;
    137 	int				count;		// Number of vehicle IDs in list.
    138 
    139 	if (!strength || Special.IsInert || warhead == WARHEAD_NONE) return;
    140 
    141 	WarheadTypeClass const * whead = &Warheads[warhead];
    142 	range = ICON_LEPTON_W + (ICON_LEPTON_W >> 1);
    143 	cell = Coord_Cell(coord);
    144 	if ((unsigned)cell >= MAP_CELL_TOTAL) return;
    145 //	if (!Map.In_Radar(cell)) return;
    146 
    147 	CellClass * cellptr = &Map[cell];
    148 	ObjectClass * impacto = cellptr->Cell_Occupier();
    149 
    150 	/*
    151 	**	Fill the list of unit IDs that will have damage
    152 	**	assessed upon them. The units can be lifted from
    153 	**	the cell data directly.
    154 	*/
    155 	count = 0;
    156 	for (FacingType i = FACING_NONE; i < FACING_COUNT; i++) {
    157 		/*
    158 		**	Fetch a pointer to the cell to examine. This is either
    159 		**	an adjacent cell or the center cell. Damage never spills
    160 		**	further than one cell away.
    161 		*/
    162 		if (i != FACING_NONE) {
    163 			cellptr = Map[cell].Adjacent_Cell(i);
    164 			if (!cellptr) continue;
    165 		}
    166 
    167 		/*
    168 		**	Add all objects in this cell to the list of objects to possibly apply
    169 		** damage to. The list stops building when the object pointer list becomes
    170 		** full.  Do not include overlapping objects; selection state can affect
    171 		** the overlappers, and this causes multiplayer games to go out of sync.
    172 		*/
    173 		object = cellptr->Cell_Occupier();
    174 		while (object) {
    175 			if (!object->IsToDamage && object != source) {
    176 				object->IsToDamage = true;
    177 				objects[count++] = object;
    178 				if (count >= (sizeof(objects)/sizeof(objects[0]))) break;
    179 			}
    180 			object = object->Next;
    181 		}
    182  		if (count >= (sizeof(objects)/sizeof(objects[0]))) break;
    183 	}
    184 
    185 	/*
    186 	**	Sweep through the units to be damaged and damage them. When damaging
    187 	**	buildings, consider a hit on any cell the building occupies as if it
    188 	**	were a direct hit on the building's center.
    189 	*/
    190 	for (index = 0; index < count; index++) {
    191 		object = objects[index];
    192 
    193 		object->IsToDamage = false;
    194 		if (object->What_Am_I() == RTTI_BUILDING && impacto == object) {
    195 			distance = 0;
    196 		} else {
    197 			distance = Distance(coord, object->Center_Coord());
    198 		}
    199 		if (object->IsDown && !object->IsInLimbo && distance < range) {
    200 			int damage = strength;
    201 
    202 			/*
    203 			**	High explosive does double damage against aircraft.
    204 			*/
    205 			if (warhead == WARHEAD_HE && object->What_Am_I() == RTTI_AIRCRAFT) {
    206 				damage *= 2;
    207 			}
    208 
    209 			/*
    210 			**	Apply the damage to the object.
    211 			*/
    212 			if (damage) {
    213 				object->Take_Damage(damage, distance, warhead, source);
    214 			}
    215 		}
    216 	}
    217 
    218 	/*
    219 	**	If there is a wall present at this location, it may be destroyed. Check to
    220 	**	make sure that the warhead is of the kind that can destroy walls.
    221 	*/
    222 	cellptr = &Map[cell];
    223 	cellptr->Reduce_Tiberium(strength / 10);
    224 	if (cellptr->Overlay != OVERLAY_NONE) {
    225 		OverlayTypeClass const * optr = &OverlayTypeClass::As_Reference(cellptr->Overlay);
    226 
    227 		if (optr->IsWall) {
    228 			if (whead->IsWallDestroyer || (whead->IsWoodDestroyer && optr->IsWooden)) {
    229 				Map[cell].Reduce_Wall(strength);
    230 			}
    231 		}
    232 	}
    233 }