CnC_Remastered_Collection/TIBERIANDAWN/TARGET.CPP

530 lines
32 KiB
C++

//
// Copyright 2020 Electronic Arts Inc.
//
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is free
// software: you can redistribute it and/or modify it under the terms of
// the GNU General Public License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
// in the hope that it will be useful, but with permitted additional restrictions
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
// distributed with this program. You should have received a copy of the
// GNU General Public License along with permitted additional restrictions
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
/* $Header: F:\projects\c&c\vcs\code\target.cpv 2.17 16 Oct 1995 16:51:06 JOE_BOSTIC $ */
/***********************************************************************************************
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
***********************************************************************************************
* *
* Project Name : Command & Conquer *
* *
* File Name : TARGET.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : September 10, 1993 *
* *
* Last Update : August 27, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* As_Aircraft -- Converts the target value into an aircraft pointer. *
* As_Animation -- Converts target value into animation pointer. *
* As_Building -- Converts a target value into a building object pointer. *
* As_Bullet -- Converts the target into a bullet pointer. *
* As_Cell -- Converts a target value into a cell number. *
* As_Coord -- Converts a target value into a coordinate value. *
* As_Infantry -- If the target is infantry, return a pointer to it. *
* As_Movement_Coord -- Fetches coordinate if trying to move to this target. *
* As_Object -- Converts a target value into an object pointer. *
* As_Team -- Converts a target number into a team pointer. *
* As_TeamType -- Converts a target into a team type pointer. *
* As_Techno -- Converts a target value into a TechnoClass pointer. *
* As_Trigger -- Converts specified target into a trigger pointer. *
* As_Unit -- Converts a target value into a unit pointer. *
* Target_Legal -- Determines if the specified target is legal. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
#include "target.h"
/***********************************************************************************************
* As_Trigger -- Converts specified target into a trigger pointer. *
* *
* This routine will convert the specified target number into a trigger pointer. *
* *
* INPUT: target -- The target number to convert. *
* *
* OUTPUT: Returns with the trigger pointer that the specified target number represents. If *
* it doesn't represent a legal trigger object, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/08/1995 JLB : Created. *
*=============================================================================================*/
TriggerClass * As_Trigger(TARGET target, bool check_active)
{
TriggerClass* trigger = Is_Target_Trigger(target) ? Triggers.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && trigger != NULL && !trigger->IsActive) {
trigger = NULL;
}
return(trigger);
}
/***********************************************************************************************
* As_Team -- Converts a target number into a team pointer. *
* *
* This routine will convert the specified target number into a team pointer. *
* *
* INPUT: target -- The target number to convert. *
* *
* OUTPUT: Returns with the team object that the specified target number represents. If it *
* doesn't represent a legal team then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/08/1995 JLB : Created. *
*=============================================================================================*/
TeamClass * As_Team(TARGET target, bool check_active)
{
TeamClass* team = Is_Target_Team(target) ? Teams.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && team != NULL && !team->IsActive) {
team = NULL;
}
return(team);
}
/***********************************************************************************************
* As_TeamType -- Converts a target into a team type pointer. *
* *
* This routine will convert the specified target number into a team type pointer. *
* *
* INPUT: target -- The target number to convert. *
* *
* OUTPUT: Returns with a pointer to the team type represented by the target number. If the *
* target number doesn't represent a legal team type, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/08/1995 JLB : Created. *
*=============================================================================================*/
TeamTypeClass * As_TeamType(TARGET target)
{
return(Is_Target_TeamType(target) ? TeamTypes.Raw_Ptr(Target_Value(target)) : NULL);
}
/***********************************************************************************************
* As_Animation -- Converts target value into animation pointer. *
* *
* This routine will convert the specified target number into an animation pointer. *
* *
* INPUT: target -- The target number to convert into an animation pointer. *
* *
* OUTPUT: Returns with a pointer to the legal animation that this target represents. If it *
* doesn't represent a legal animation, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/08/1995 JLB : Created. *
*=============================================================================================*/
AnimClass * As_Animation(TARGET target, bool check_active)
{
AnimClass* anim = Is_Target_Animation(target) ? Anims.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && anim != NULL && !anim->IsActive) {
anim = NULL;
}
return(anim);
}
/***********************************************************************************************
* As_Bullet -- Converts the target into a bullet pointer. *
* *
* This routine will convert the specified target number into a bullet pointer. *
* *
* INPUT: target -- The target number to convert. *
* *
* OUTPUT: Returns with a pointer to the bullet it specifies. If the target doesn't refer to *
* a legal bullet, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/08/1995 JLB : Created. *
*=============================================================================================*/
BulletClass * As_Bullet(TARGET target, bool check_active)
{
BulletClass* bullet = Is_Target_Bullet(target) ? Bullets.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && bullet != NULL && !bullet->IsActive) {
bullet = NULL;
}
return(bullet);
}
/***********************************************************************************************
* As_Aircraft -- Converts the target value into an aircraft pointer. *
* *
* This routine will convert the specified target value into an aircraft object pointer. *
* *
* INPUT: target -- The target value to convert. *
* *
* OUTPUT: Returns with a pointer to the aircraft that this target value represents. If the *
* specified target value doesn't represent an aircraft, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/27/1995 JLB : Created. *
*=============================================================================================*/
AircraftClass * As_Aircraft(TARGET target, bool check_active)
{
AircraftClass* aircraft = Is_Target_Aircraft(target) ? Aircraft.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && aircraft != NULL && !aircraft->IsActive) {
aircraft = NULL;
}
return(aircraft);
}
/***********************************************************************************************
* As_Techno -- Converts a target value into a TechnoClass pointer. *
* *
* This routine will take the target value specified and convert it into a TechnoClass *
* pointer if the target represents an object that has a TechnoClass. *
* *
* INPUT: target -- The target value to convert into a TechnoClass pointer. *
* *
* OUTPUT: Returns with a pointer to the associated object's TechnoClass. If the target *
* cannot be converted into a TechnoClass pointer, then NULL is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/02/1994 JLB : Created. *
*=============================================================================================*/
TechnoClass * As_Techno(TARGET target, bool check_active)
{
ObjectClass * obj = As_Object(target, check_active);
if (obj && obj->Is_Techno()) {
return(TechnoClass *)obj;
}
return(NULL);
}
/***********************************************************************************************
* As_Object -- Converts a target value into an object pointer. *
* *
* This routine is used to convert the target value specified into an object pointer. If *
* the target doesn't represent an object or the target value is illegal, then NULL is *
* returned. *
* *
* INPUT: target -- The target value to convert from. *
* check_active -- Check if the target is active, return NULL if not. *
* *
* OUTPUT: Returns with a pointer to the object it represent, or NULL if not an object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
ObjectClass * As_Object(TARGET target, bool check_active)
{
int val = Target_Value(target);
ObjectClass * object = NULL;
switch (Target_Kind(target)) {
case KIND_INFANTRY:
object = Infantry.Raw_Ptr(val);
break;
case KIND_UNIT:
object = Units.Raw_Ptr(val);
break;
case KIND_BUILDING:
object = Buildings.Raw_Ptr(val);
break;
case KIND_AIRCRAFT:
object = Aircraft.Raw_Ptr(val);
break;
case KIND_TERRAIN:
object = Terrains.Raw_Ptr(val);
break;
case KIND_BULLET:
object = Bullets.Raw_Ptr(val);
break;
case KIND_ANIMATION:
object = Anims.Raw_Ptr(val);
break;
default:
break;
}
/*
** Special check to ensure that a target value that references an
** invalid object will not be converted back into an object pointer.
** This condition is rare, but could occur in a network game if the
** object it refers to is destroyed between the time an event message
** is sent and when it is received.
*/
if (check_active && object != NULL && !object->IsActive) {
object = NULL;
}
return(object);
}
/***********************************************************************************************
* As_Unit -- Converts a target value into a unit pointer. *
* *
* This routine is used to convert the target value specified into a pointer to a unit *
* object. *
* *
* INPUT: target -- The target value to convert into a unit pointer. *
* *
* OUTPUT: Returns with a pointer to the unit the target value represents or NULL if not *
* a unit. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
UnitClass * As_Unit(TARGET target, bool check_active)
{
UnitClass* unit = Is_Target_Unit(target) ? Units.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && unit != NULL && !unit->IsActive) {
unit = NULL;
}
return(unit);
}
/***********************************************************************************************
* As_Infantry -- If the target is infantry, return a pointer to it. *
* *
* This routine will translate the specified target value into an infantry pointer if the *
* target actually represents an infantry object. *
* *
* INPUT: target -- The target to convert to a pointer. *
* *
* OUTPUT: Returns a pointer to the infantry object that this target value represents. If *
* the target doesn't represent an infantry object, then return NULL. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 10/17/1994 JLB : Created. *
*=============================================================================================*/
InfantryClass * As_Infantry(TARGET target, bool check_active)
{
InfantryClass* infantry = Is_Target_Infantry(target) ? Infantry.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && infantry != NULL && !infantry->IsActive) {
infantry = NULL;
}
return(infantry);
}
#ifdef NEVER
TerrainClass * As_Terrain(TARGET target)
{
return(Is_Target_Terrain(target) ? &Terrains[Target_Value(target)] : NULL);
}
#endif
/***********************************************************************************************
* As_Building -- Converts a target value into a building object pointer. *
* *
* This routine is used to convert the target value specified into a building pointer. *
* *
* INPUT: target -- The target value to convert from. *
* *
* OUTPUT: Returns with a pointer to the building object that the target value represents. *
* If it doesn't represent a building, then return NULL. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
BuildingClass * As_Building(TARGET target, bool check_active)
{
BuildingClass* building = Is_Target_Building(target) ? Buildings.Raw_Ptr(Target_Value(target)) : NULL;
if (check_active && building != NULL && !building->IsActive) {
building = NULL;
}
return(building);
}
/***********************************************************************************************
* Target_Legal -- Determines if the specified target is legal. *
* *
* This routine is used to check for the legality of the target value specified. It is *
* necessary to call this routine if there is doubt about the the legality of the target. *
* It is possible for the unit that a target value represents to be eliminated and thus *
* rendering the target value invalid. *
* *
* INPUT: target -- The target value to check. *
* *
* OUTPUT: bool; Is the target value legal? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
bool Target_Legal(TARGET target)
{
if (target == TARGET_NONE) return(false);
ObjectClass * obj = As_Object(target, false);
if (obj) {
return(obj->IsActive);
}
return(true);
}
/***********************************************************************************************
* As_Cell -- Converts a target value into a cell number. *
* *
* This routine is used to convert the target value specified, into a cell value. This is *
* necessary for find path and other procedures that need a cell value. *
* *
* INPUT: target -- The target value to convert to a cell value. *
* *
* OUTPUT: Returns with the target value expressed as a cell location. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
*=============================================================================================*/
CELL As_Cell(TARGET target)
{
return(Coord_Cell(As_Coord(target)));
}
/***********************************************************************************************
* As_Coord -- Converts a target value into a coordinate value. *
* *
* This routine is used to convert the target value specified into a coordinate value. It *
* is necessary for those procedures that require a coordinate value. *
* *
* INPUT: target -- The target value to convert. *
* *
* OUTPUT: Returns with the target expressed as a COORD value. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/27/1994 JLB : Created. *
* 11/16/1994 JLB : Simplified. *
*=============================================================================================*/
COORDINATE As_Coord(TARGET target)
{
if (Target_Legal(target)) {
/*
** Cell target values are handled as a special case. The value of the target number is
** actually the cell index number.
*/
if (Is_Target_Cell(target)) {
return(Cell_Coord((CELL)Target_Value(target)));
}
/*
** Normal targets correspond to game objects. Fetch the object pointer and then ask it
** for the center coordinate. Return the center coordinate as the target's coordinate.
*/
ObjectClass * obj = As_Object(target);
if (obj) {
/*
** If this is invalid memory or the object is dead then return 0
** This is a kludge to fix the problem of team target objects being assigned after
** the object is already destroyed - 1/15/97 3:13PM
*/
if (IsBadReadPtr ((void*)obj, sizeof (ObjectClass) ) || !obj->IsActive){
//OutputDebugString ("C&C95 - As_Coord called for invalid target object\m");
return(0x00000000L);
}
return(obj->Target_Coord());
}
}
/*
** An unrecognized target value results in a null coordinate value.
*/
return(0x00000000L);
}
/***********************************************************************************************
* As_Movement_Coord -- Fetches coordinate if trying to move to this target. *
* *
* This routine will convert the specified target into a coordinate location. This location *
* is used when moving to the target specified. For cells, this is the center of the cell. *
* For special buildings that allow docking, it is the center location of the docking *
* bay. *
* *
* INPUT: target -- The target to convert into a coordinate value. *
* *
* OUTPUT: Returns with the docking coordinate of the target value specified. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/27/1995 JLB : Created. *
*=============================================================================================*/
COORDINATE As_Movement_Coord(TARGET target)
{
if (Target_Legal(target)) {
/*
** Cell target values are handled as a special case. The value of the target number is
** actually the cell index number.
*/
if (Is_Target_Cell(target)) {
return(Cell_Coord((CELL)Target_Value(target)));
}
/*
** Normal targets correspond to game objects. Fetch the object pointer and then ask it
** for the center coordinate. Return the center coordinate as the target's coordinate.
*/
ObjectClass * obj = As_Object(target);
if (obj) {
return(obj->Docking_Coord());
}
}
/*
** An unrecognized target value results in a null coordinate value.
*/
return(0x00000000L);
}