CnC_Remastered_Collection/TIBERIANDAWN/OBJECT.CPP

1714 lines
98 KiB
C++
Raw Permalink Normal View History

//
// 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\object.cpv 2.17 16 Oct 1995 16:49:22 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 : OBJECT.CPP *
* *
* Programmer : Joe L. Bostic *
* *
* Start Date : April 29, 1994 *
* *
* Last Update : August 13, 1995 [JLB] *
* *
*---------------------------------------------------------------------------------------------*
* Functions: *
* ObjectClass::Debug_Dump -- Displays status of the object class to the mono monitor. *
* ObjectClass::Detach_All -- Removes the object from all tracking systems. *
* ObjectClass::Detach_This_From_All -- Detatches this object from all others. *
* ObjectClass::Fire_Out -- Informs object that attached animation has finished. *
* ObjectClass::Get_Mission -- Fetches the current mission of this object. *
* ObjectClass::Init -- Initializes the basic object system. *
* ObjectClass::Limbo -- Brings the object into a state of limbo. *
* ObjectClass::Mark -- Handles basic marking logic. *
* ObjectClass::Mark_For_Redraw -- Marks object and system for redraw. *
* ObjectClass::Move -- Moves (by force) the object in the desired direction. *
* ObjectClass::ObjectClass -- Default constructor for objects. *
* ObjectClass::Passive_Click_With -- Right mouse button click process. *
* ObjectClass::Receive_Message -- Processes an incoming radio message. *
* ObjectClass::Render -- Displays the object onto the map. *
* ObjectClass::Repair -- Handles object repair control. *
* ObjectClass::Revealed -- Reveals this object to the house specified. *
* ObjectClass::Select -- Try to make this object the "selected" object. *
* ObjectClass::Sell_Back -- Sells the object -- if possible. *
* ObjectClass::Take_Damage -- Applies damage to the object. *
* ObjectClass::Unlimbo -- Brings the object into the game system. *
* ObjectClass::Unselect -- This will un-select the object if it was selected. *
* ObjectClass::Value -- Fetches the target value of this object. *
* ObjectClass::What_Action -- Deteremines what action to perform on specified object. *
* ObjectClass::What_Am_I -- RTTI query of this object type. *
* ObjectTypeClass::Cost_Of -- Returns the cost to buy this unit. *
* ObjectTypeClass::Dimensions -- Gets the dimensions of the object in pixels. *
* ObjectTypeClass::Get_Cameo_Data -- Fetches pointer to cameo data for this object type. *
* ObjectTypeClass::Max_Pips -- Fetches the maximum pips allowed for this object. *
* ObjectTypeClass::ObjectTypeClass -- Normal constructor for object type class objects. *
* ObjectTypeClass::Occupy_List -- Returns with simple occupation list for object. *
* ObjectTypeClass::One_Time -- Handles one time processing for object types. *
* ObjectTypeClass::Overlap_List -- Returns a pointer to a simple overlap list. *
* ObjectTypeClass::Time_To_Build -- Fetches the time to construct this object. *
* ObjectTypeClass::Who_Can_Build_Me -- Finds the factory building that can build this object*
* ObjectClass::What_Action -- Returns with the action to perform for this object. *
* ObjectClass::In_Which_Layer -- Fetches what layer this object is located in. *
* ObjectClass::Is_Techno -- Checks to see if this object is a techno type. *
* ObjectClass::Get_Ownable -- Fetches the house owner legality options for this object. *
* ObjectClass::Can_Repair -- Queries whether this object can be repaired. *
* ObjectClass::Can_Demolish -- Queries whether this object can be sold back. *
* ObjectClass::Can_Player_Fire -- Can the player give this object an attack mission? *
* ObjectClass::Can_Player_Move -- Can the player give this object a movement mission? *
* ObjectClass::Target_Coord -- Fetches the coordinate if this object is a target. *
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#include "function.h"
/*
** Selected objects have a special marking box around them. This is the shapes that are
** used for this purpose.
*/
void const * ObjectTypeClass::SelectShapes = 0;
void const * ObjectTypeClass::PipShapes = 0;
bool ObjectClass::Is_Infantry(void) const
{
return(false);
}
/***********************************************************************************************
* ObjectTypeClass::ObjectTypeClass -- Normal constructor for object type class objects. *
* *
* This is the base constructor that is used when constructing the object type classes. *
* Every tangible game piece type calls this constructor for the ObjectTypeClass. This *
* class holds static information that is common to objects in general. *
* *
* INPUT: see below... *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 03/23/1995 JLB : Created. *
*=============================================================================================*/
ObjectTypeClass::ObjectTypeClass(
bool is_sentient,
bool is_flammable,
bool is_crushable,
bool is_stealthy,
bool is_selectable,
bool is_legal_target,
bool is_insignificant,
bool is_immune,
int name,
char const *ini,
ArmorType armor,
unsigned short strength) :
AbstractTypeClass(name, ini)
{
IsSentient = is_sentient;
IsFlammable = is_flammable;
IsCrushable = is_crushable;
IsStealthy = is_stealthy;
IsSelectable = is_selectable;
IsLegalTarget = is_legal_target;
IsInsignificant = is_insignificant;
IsImmune = is_immune;
Armor = armor;
MaxStrength = strength;
ImageData = NULL;
//RadarIcon = NULL;
}
/***********************************************************************************************
* ObjectTypeClass::Max_Pips -- Fetches the maximum pips allowed for this object. *
* *
* This routine will return the maximum number of pips that can be displayed for this *
* object. When dealing with generic objects, this value is always zero. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the number of pip boxes (empty or otherwise) to display. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
int ObjectTypeClass::Max_Pips(void) const
{
return(0);
}
/***********************************************************************************************
* ObjectTypeClass::Dimensions -- Gets the dimensions of the object in pixels. *
* *
* This routine will fetch the dimensions of this object expressed as pixels width and *
* pixels height. This information can be used to intelligently update the clipping *
* rectangles. *
* *
* INPUT: width -- Reference to the width variable that will be filled in. *
* *
* height -- Reference to the height variable that will be filled in. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
void ObjectTypeClass::Dimensions(int &width, int &height) const
{
width = 10;
height = 10;
}
/***********************************************************************************************
* ObjectTypeClass::Cost_Of -- Returns the cost to buy this unit. *
* *
* This routine will return the cost to purchase this unit. This routine is expected to be *
* overridden by the objects that can actually be purchased. All other object types can *
* simply return zero since this value won't be used. *
* *
* INPUT: none *
* *
* OUTPUT: Returns the cost of the object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
int ObjectTypeClass::Cost_Of(void) const
{
return(0);
}
/***********************************************************************************************
* ObjectTypeClass::Time_To_Build -- Fetches the time to construct this object. *
* *
* This routine will fetch the time in takes to construct this object. Objects that can *
* be constructed will override this routine in order to return a useful value. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the time units (arbitrary) that it takes to construct this object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
int ObjectTypeClass::Time_To_Build(HousesType ) const
{
return(0);
}
/***********************************************************************************************
* ObjectTypeClass::Who_Can_Build_Me -- Finds the factory building that can build this object. *
* *
* This routine will search for a factory building that can build this object type. *
* *
* INPUT: <NA> this routine is just here to be overridden by other classes. *
* *
* OUTPUT: Returns with a pointer to the building that can construct the object specified. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
BuildingClass * ObjectTypeClass::Who_Can_Build_Me(bool, bool, HousesType) const
{
return(NULL);
}
/***********************************************************************************************
* ObjectTypeClass::Get_Cameo_Data -- Fetches pointer to cameo data for this object type. *
* *
* This routine will return with the cameo data pointer for this object type. It is *
* expected that objects that can appear on the sidebar will override this routine in order *
* to provide proper cameo data pointer. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with a pointer to the cameo shape data. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
void const * ObjectTypeClass::Get_Cameo_Data(void) const
{
return(NULL);
}
/***********************************************************************************************
* ObjectClass::ObjectClass -- Default constructor for objects. *
* *
* This is the default constructor for objects. It is called as an inherent part of the *
* construction process for all the normal game objects instantiated. It serves merely to *
* initialize the object values to a common (default) state. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: Objects always start in a state of limbo. They must be Unlimbo()ed before they *
* can be used. *
* *
* HISTORY: *
* 09/24/1994 JLB : Created. *
*=============================================================================================*/
ObjectClass::ObjectClass(void)
{
Coord = 0xFFFFFFFFL; // Some bogus illegal value.
Next = 0; // Not part of any object list.
Trigger = 0; // No associated trigger.
IsToDamage = false;
IsToDisplay = false; // Redraw is presumed unnecessary.
IsInLimbo = true; // Always presumed to start in limbo state.
IsSelected = false; // Limboed units cannot be selected.
IsDown = false; // Limboed units cannot be on the map.
IsAnimAttached = false; // Anim is not attached.
Strength = 255; // nominal strength value
IsSelectedMask = 0; // Mask showing who has selected this object
}
/***********************************************************************************************
* ObjectClass::What_Am_I -- RTTI query of this object type. *
* *
* This routine will never be called, but is here for completeness. Every object that *
* is derived from object class must overload this function and return their own proper *
* object RTTI value. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the RTTI value that coresponds to the object's type. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
RTTIType ObjectClass::What_Am_I(void) const
{
return(RTTI_OBJECT);
}
/***********************************************************************************************
* ObjectClass::What_Action -- Deteremines what action to perform on specified object. *
* *
* This routine will return that action that this object could perform if the mouse were *
* clicked over the object specified. *
* *
* INPUT: object -- Pointer to the object to check this object against when determining *
* the action to perform. *
* *
* OUTPUT: It returns that action that will be performed if the mouse were clicked over the *
* object. Since non-derived objects cannot do anything, and cannot even be *
* instantiated, this routine will always return ACTION_NONE. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
ActionType ObjectClass::What_Action(ObjectClass *) const
{
return(ACTION_NONE);
}
/***********************************************************************************************
* ObjectClass::What_Action -- Returns with the action to perform for this object. *
* *
* This routine is called when information on a potential action if the mouse were clicked *
* on the cell specified. This routine merely serves as a virtual placeholder so that *
* object types that can actually perform some action will override this routine to provide *
* true functionality. *
* *
* INPUT: cell -- The cell that the mouse is over and might be clicked on. *
* *
* OUTPUT: Returns with the action that this object would try to perform if the mouse were *
* clicked. Since objects at this level have no ability to do anything, this routine *
* will always returns ACTION_NONE unless it is overridden. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
ActionType ObjectClass::What_Action(CELL) const
{
return(ACTION_NONE);
}
/***********************************************************************************************
* ObjectClass::In_Which_Layer -- Fetches what layer this object is located in. *
* *
* The default layer for object location is the LAYER_GROUND. Aircraft will override this *
* routine and make adjustments as necessary according to the aircraft's altitude. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the layer that this object is located in. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
LayerType ObjectClass::In_Which_Layer(void) const
{
return(LAYER_GROUND);
}
/***********************************************************************************************
* ObjectClass::Is_Techno -- Checks to see if this object is a techno type. *
* *
* Most active objects in the game are of the techno type. This routine will return true *
* if called on an object that is derived from TechnoClass. The RTTI interface is *
* insufficient for this purpose -- hence the existence of this routine. *
* *
* INPUT: none *
* *
* OUTPUT: Is this object derived from the TechnoClass object? This is true for units, *
* infantry, aircraft, and buildings. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Is_Techno(void) const
{
return(false);
}
/***********************************************************************************************
* ObjectClass::Get_Ownable -- Fetches the house owner legality options for this object. *
* *
* This routine will return the ownable bits for this object. Objects at this level can't *
* really be owned by anyone, but return the full spectrum of legality just to be safe. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the ownable flags (as a combined bitfield) for this object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
unsigned char ObjectClass::Get_Ownable(void) const
{
return(0xff);
}
/***********************************************************************************************
* ObjectClass::Can_Repair -- Queries whether this object can be repaired. *
* *
* Most objects cannot be repaired. This routine defaults to returning "false", but is *
* overridden by derived functions defined by object types that can support repair. *
* *
* INPUT: none *
* *
* OUTPUT: Can this object be repaired? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Can_Repair(void) const
{
return(false);
}
/***********************************************************************************************
* ObjectClass::Can_Demolish -- Queries whether this object can be sold back. *
* *
* This routine is used to determine if this object can be sold. Most objects cannot be *
* but for those objects that can, this routine will be overridden as necessary. *
* *
* INPUT: none *
* *
* OUTPUT: Can this object be sold back? Typically, the answer is no. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Can_Demolish(void) const
{
return(false);
}
bool ObjectClass::Can_Demolish_Unit(void) const
{
return(false);
}
Command & Conquer Remastered post-launch patch Improvements to harvester resource finding logic. Don't allow the Advanced Comm Center to be capturable in skirmish or multiplayer. Increased failed pathfinding fudge factor. Buildings accept the Guard command if they can attack. Don't allow force capturing of ally structures. Fixes for laser Orcas in S3cr3t M1ss10n. Properly restore them after save. Reset Orcas after loads. Fixed flag animation rendering in CTF. Potentially fix a crash if aircraft are destroyed outside the map bounds. Fixed legacy Obelisk line rendering. Fix out-of-bounds crash in TD; issue was already fixed in RA. Disable capture flag on Commandos. Drop the flag when entering the limbo state. Fixed end game race condition, winning team ID is always sent before individual player win/lose messages. Fixed Chan spawn on SCB10EA. Don't show enter cursor for enemy units on refineries and repair pads. Changing right-click support for first put building on hold, and then subsequenct right-clicks to decrement that queue count for 1x or 5x; Then, 1x or 5x Left click will resume from hold. Don't debug reveal legacy rendering when a player is defeated. Fixed crash when loading saves of custom campaign maps. Reset harvester archived target when given a direct harvest order. Prevent NOD cargo planes from being force attacked. Fixed unit selection on load. Migrated queued repair pad functionality from RA to TD. Randomly animate infantry in area guard mode. Fixed crash accessing inactive objects. Added some walls in SCG08EB to prevent civilians from killing themselves. TD + RA: Audio: Overiding "Our base is under attack" cooldown timing from legacy from 2 minutes to 30 seconds, so it will be heard 4x as often. Fixed adjacent cell out-of-bounds crash issues. Kill player on disconnect Fixed and improved build time calculations to be consistent between TD and RA. Don't show health bars for cloaked Stealth Tanks in the legacy renderer. Fix selection of individual control groups after mixed selection. More adjustments to SCG08EB; switch C7 to C5, and add civilian AI to avoid Tiberium. Extra safety checks for units that have no weapons and aircraft that can't hunt. Fix loading of multiple infantry onto an APC. Additional safety checks for invalid coordinates. Prevent units from being instantly repaired. Fix map passability. Fail Allied mission 5B if the spy re-boards the starting transport (matches 5A and 5C behavior). Fixed multiplayer formation move causing units to move at light speed. Ignore movement destination checks if a unit is part of a mission-driven team. Fix buffer overrun crash. Ignore mines when determining win conditions. Fixed river passability in Blue Lakes.
2020-06-23 04:43:21 +12:00
bool ObjectClass::Can_Capture(void) const
{
return(false);
}
/***********************************************************************************************
* ObjectClass::Can_Player_Fire -- Can the player give this object an attack mission? *
* *
* This routine is used to determine if attacking is an option under player control with *
* respect to this unit. This routine will be overridden as necessary for those objects *
* that have the ability to attack. *
* *
* INPUT: none *
* *
* OUTPUT: Can this object be given an attack order by the player? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Can_Player_Fire(void) const
{
return(false);
}
/***********************************************************************************************
* ObjectClass::Can_Player_Move -- Can the player give this object a movement mission? *
* *
* This routine is used to determine if the player has the ability to command this object *
* with a movement mission. This routine will be overridden as necessary to support this *
* ability. *
* *
* INPUT: none *
* *
* OUTPUT: Can this object be given a movement mission by the player? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Can_Player_Move(void) const
{
return(false);
}
/***********************************************************************************************
* ObjectClass::Target_Coord -- Fetches the coordinate if this object is a target. *
* *
* When the coordinate to use when firing at this object is needed, this routine will *
* provide it. Normal objects just use the center of the object for this, but there are *
* some more sophisticated objects that are not fired upon the center. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the coordinate to fire at if this object is a target. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 08/13/1995 JLB : Created. *
*=============================================================================================*/
COORDINATE ObjectClass::Target_Coord(void) const
{
return(Center_Coord());
}
COORDINATE ObjectClass::Center_Coord(void) const {return Coord;};
COORDINATE ObjectClass::Render_Coord(void) const {return(Center_Coord());}
COORDINATE ObjectClass::Docking_Coord(void) const {return(Center_Coord());}
COORDINATE ObjectClass::Sort_Y(void) const {return Coord;};
FireDataType ObjectClass::Fire_Data(int which) const {return{Fire_Coord(which),0};}
COORDINATE ObjectClass::Fire_Coord(int ) const {return Coord;};
void ObjectClass::Record_The_Kill(TechnoClass * ) {};
void ObjectClass::Do_Shimmer(void) {};
int ObjectClass::Exit_Object(TechnoClass *) {return 0;};
void ObjectClass::Hidden(void) {};
void ObjectClass::Look(bool ) {};
void ObjectClass::Active_Click_With(ActionType , ObjectClass *) {};
void ObjectClass::Active_Click_With(ActionType , CELL ) {};
void ObjectClass::Clicked_As_Target(HousesType house, int) {}; // 2019/09/20 JAS - Added record of who clicked on the object
bool ObjectClass::In_Range(COORDINATE , int) const {return false;};
int ObjectClass::Weapon_Range(int) const {return 0x0000;};
TARGET ObjectClass::As_Target(void) const {return TARGET_NONE;};
void ObjectClass::Scatter(COORDINATE , bool, bool) {};
bool ObjectClass::Catch_Fire(void) {return false;};
/***********************************************************************************************
* ObjectClass::Fire_Out -- Informs object that attached animation has finished. *
* *
* This routine is called if there is an attached animation on this object and that *
* animation has finished. Typically, this is necessary for when trees are on fire. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/24/1995 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Fire_Out(void)
{
}
/***********************************************************************************************
* ObjectClass::Value -- Fetches the target value of this object. *
* *
* This routine will return the target value of this object. The higher the number, the *
* better the object will be as a target. This routine is called when searching for *
* targets. Generic objects have no target potential, and this routine returns zero to *
* reflect that. Other object types will override this routine to return the appropriate *
* target value. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the value of this object as a target. Higher values mean better *
* target. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/24/1995 JLB : Created. *
*=============================================================================================*/
int ObjectClass::Value(void) const
{
return(0);
}
/***********************************************************************************************
* ObjectClass::Get_Mission -- Fetches the current mission of this object. *
* *
* Generic objects don't have a mission, so this routine will just return MISSION_NONE. *
* However, techno objects do have a mission and this routine is overloaded to handle *
* those objects in order to return the correct mission value. *
* *
* INPUT: none *
* *
* OUTPUT: Returns with the current mission being followed by this object. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/24/1995 JLB : Created. *
*=============================================================================================*/
MissionType ObjectClass::Get_Mission(void) const
{
return(MISSION_NONE);
}
/***********************************************************************************************
* ObjectClass::Repair -- Handles object repair control. *
* *
* This routine will control object repair mode. At the object level, no repair is *
* possible, so it is expected that any object that can repair will override this function *
* as necessary. *
* *
* INPUT: control -- The repair control parameter. *
* 0 = turn repair off *
* 1 = turn repair on *
* -1 = toggle repair state *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/24/1995 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Repair(int )
{
}
/***********************************************************************************************
* ObjectClass::Sell_Back -- Sells the object -- if possible. *
* *
* This routine is called to sell back the object. Override this routine for the more *
* sophisticated objects that can actually be sold back. Normal objects can't be sold and *
* this routine does nothing as a consequence. *
* *
* INPUT: control -- How to control the sell state of this object. *
* 0 = stop selling. *
* 1 = start selling. *
* -1 = toggle selling state. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Sell_Back(int )
{
}
/***********************************************************************************************
* ObjectClass::Move -- Moves (by force) the object in the desired direction. *
* *
* This routine will instantly move the object one cell in the specified direction. It *
* moves the object by force. This is typically ONLY used by the scenario editor *
* process. *
* *
* INPUT: facing -- The direction to move the object. *
* *
* OUTPUT: none *
* *
* WARNINGS: Naturally, this can cause illegal placement situations -- use with caution. *
* *
* HISTORY: *
* 06/19/1994 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Move(FacingType facing)
{
COORDINATE coord;
Mark(MARK_UP);
coord = Adjacent_Cell(Coord, facing);
if (Can_Enter_Cell(Coord_Cell(coord)) == MOVE_OK) {
Coord = coord;
}
Mark(MARK_DOWN);
}
// Object selection list is switched with player context for GlyphX. ST - 4/17/2019 9:42AM
extern void Logic_Switch_Player_Context(ObjectClass *object);
/***********************************************************************************************
* ObjectClass::Unselect -- This will un-select the object if it was selected. *
* *
* This routine brings a currently selected object into an unselected state. This is *
* needed when another object becomes selected as well as if the object is destroyed. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/19/1994 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Unselect(void)
{
//if (IsSelected) {
// Updated to function for multiplayer - 6/26/2019 JAS
if (Is_Selected_By_Player()) {
if (In_Which_Layer()==LAYER_GROUND){
Mark(MARK_OVERLAP_UP);
}
//IsSelected = false;
// Updated to function for multiplayer - 6/26/2019 JAS
Set_Unselected_By_Player();
if (In_Which_Layer()==LAYER_GROUND){
Mark(MARK_OVERLAP_DOWN);
}
}
}
/***********************************************************************************************
* ObjectClass::Unselect_All_Players -- This will un-select the object if it was selected *
* from all players *
* *
* This routine brings a currently selected object into an unselected state for all players.*
* This is needed when the object is destroyed. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/25/2019 JAS : Created. *
*=============================================================================================*/
void ObjectClass::Unselect_All_Players(void)
{
CurrentObject.Delete_All(this);
if (In_Which_Layer() == LAYER_GROUND) {
Mark(MARK_OVERLAP_UP);
}
IsSelected = false;
IsSelectedMask = 0;
if (In_Which_Layer() == LAYER_GROUND) {
Mark(MARK_OVERLAP_DOWN);
}
}
/***********************************************************************************************
* ObjectClass::Unselect_All_Players_Except_Owner -- This will un-select the object if it was *
* selected for all players except for the object's owner *
* *
* This routine brings a currently selected object into an unselected state for all players.*
* This is needed when the object cloaks. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/28/2019 JAS : Created. *
*=============================================================================================*/
void ObjectClass::Unselect_All_Players_Except_Owner(void)
{
CurrentObject.Delete_All_Except(this, Owner());
if (In_Which_Layer() == LAYER_GROUND) {
Mark(MARK_OVERLAP_UP);
}
int owner_mask = 1 << Owner();
if (IsSelectedMask & owner_mask)
{
IsSelected = true;
IsSelectedMask = owner_mask;
}
else
{
IsSelected = false;
IsSelectedMask = 0;
}
if (In_Which_Layer() == LAYER_GROUND) {
Mark(MARK_OVERLAP_DOWN);
}
}
/***********************************************************************************************
* ObjectClass::Select -- Try to make this object the "selected" object. *
* *
* This routine is used to make this object into the one that is "selected". A selected *
* object usually displays a floating bar graph and is available to be given orders from *
* the player's I/O. *
* *
* INPUT: allow_mixed -- Allow a mix of player and non-player controlled units? *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/19/1994 JLB : Created. *
* 06/12/1995 JLB : Cannot select a loaner object. *
* 07/23/1995 JLB : Adds to head or tail depending on leader type flag. *
*=============================================================================================*/
bool ObjectClass::Select(bool allow_mixed)
{
// if (!Debug_Map && (IsSelected || !Class_Of().IsSelectable)) return(false);
// Updated to function for multiplayer - 6/26/2019 JAS
if (!Debug_Map && (Is_Selected_By_Player() || !Class_Of().IsSelectable)) return(false);
if (Can_Player_Move() && Is_Techno() && ((TechnoClass *)this)->IsALoaner) return(false);
/*
** Don't allow selection of object when in building placement mode.
*/
if (Map.PendingObject) return(false);
if (!allow_mixed) {
/*
** If selecting an object of a different house than the player's, make sure that
** the entire selection list is cleared.
*/
for (int i = 0; i < CurrentObject.Count(); i++) {
if (Owner() != CurrentObject[i]->Owner()) {
Unselect_All();
break;
}
}
}
if (In_Which_Layer()==LAYER_GROUND){
Mark(MARK_OVERLAP_UP);
}
//IsSelected = true;
// Updated to function for multiplayer - 6/26/2019 JAS
Set_Selected_By_Player();
if (In_Which_Layer()==LAYER_GROUND){
Mark(MARK_OVERLAP_DOWN);
}
return(true);
}
/***********************************************************************************************
* ObjectClass::Render -- Displays the object onto the map. *
* *
* This routine will determine the location of the object and if it is roughly on the *
* visible screen, it will display it. Not displaying objects that are not on the screen *
* will save valuable time. *
* *
* INPUT: bool; Should the render be forced regardless of whether the object is flagged to *
* be redrawn? *
* *
* OUTPUT: bool; Was the draw code called for this object? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/19/1994 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Render(bool forced)
{
int x,y;
COORDINATE coord = Render_Coord();
CELL cell = Coord_Cell(coord);
if (Debug_Map || Debug_Unshroud || ((forced || IsToDisplay) && IsDown && !IsInLimbo)) {
IsToDisplay = false;
/*
** Draw the path as lines on the map if so directed and the object is one that
** contains a path.
*/
//if (Special.IsShowPath && IsSelected) {
// Updated to function for multiplayer - 6/26/2019 JAS
if (Special.IsShowPath && Is_Selected_By_Player()) {
switch (What_Am_I()) {
case RTTI_INFANTRY:
case RTTI_UNIT:
FootClass * foot = (FootClass *)this;
CELL cell;
int oldx, oldy;
if (foot->Head_To_Coord() && foot->Path[0] != FACING_NONE) {
cell = Adjacent_Cell(Coord_Cell(foot->Head_To_Coord()), (FacingType)((foot->Path[0] + FACING_S) & FACING_NW));
Map.Coord_To_Pixel(Cell_Coord(cell), oldx, oldy);
for (int index = 0; index < MAX_PATH; index++) {
if (foot->Path[index] == FACING_NONE) break;
cell = Adjacent_Cell(cell, foot->Path[index]);
if (Map.Coord_To_Pixel(Cell_Coord(cell), x, y)) {
LogicPage->Draw_Line(oldx, 8+oldy, x, 8+y, BLACK);
}
oldx = x;
oldy = y;
}
}
break;
}
}
if (Map.Coord_To_Pixel(coord, x, y)) {
/*
** Draw the object itself
*/
Draw_It(x, y, WINDOW_TACTICAL);
#ifdef SCENARIO_EDITOR
/*
** Draw the trigger attached to the object. Draw_It is window-
** relative, so add the window's x-coord to 'x'.
*/
if (Debug_Map && Trigger) {
Fancy_Text_Print(Trigger->Get_Name(), x + (WinX<<3), y, PINK, TBLACK, TPF_CENTER | TPF_NOSHADOW | TPF_6POINT);
}
#endif
return(true);
}
}
return(false);
}
#ifdef CHEAT_KEYS
/***********************************************************************************************
* ObjectClass::Debug_Dump -- Displays status of the object class to the mono monitor. *
* *
* This routine is used to display the current status of the object class to the mono *
* monitor. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 06/02/1994 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Debug_Dump(MonoClass *mono) const
{
mono->Text_Print("X", 16 + (IsToDisplay?2:0), 18);
mono->Text_Print("X", 16 + (IsActive?2:0), 3);
mono->Text_Print("X", 16 + (IsInLimbo?2:0), 4);
//mono->Text_Print("X", 16 + (IsSelected?2:0), 7);
// Updated to function for multiplayer - 6/26/2019 JAS
mono->Text_Print("X", 16 + (Is_Selected_By_Player() ?2:0), 7);
mono->Set_Cursor(56, 1);
mono->Printf("%08lX", Coord);
mono->Set_Cursor(14, 1);mono->Printf("[%04X]", As_Target());
mono->Set_Cursor(20, 3);mono->Printf("%2d[%d]", Strength, Class_Of().MaxStrength);
}
#endif
/***********************************************************************************************
* ObjectTypeClass::Occupy_List -- Returns with simple occupation list for object. *
* *
* This routine returns a pointer to a simple occupation list for this object. Since at *
* this tier of the object class chain, the exact shape of the object is indeterminate, *
* this function merely returns a single cell occupation list. This actually works for *
* most vehicles. *
* *
* INPUT: none *
* *
* OUTPUT: Returns a pointer to a simple occupation list. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/28/1994 JLB : Created. *
*=============================================================================================*/
short const * ObjectTypeClass::Occupy_List(bool) const
{
static short const _list[] = {0, REFRESH_EOL};
return(_list);
}
/***********************************************************************************************
* ObjectTypeClass::Overlap_List -- Returns a pointer to a simple overlap list. *
* *
* This function returns a pointer to an overlap list for the object. An overlap list is *
* the offsets from the object's cell to get the cells the imagery overlaps, but is object *
* is not considered to occupy. Since at this stage, the overlap information is not *
* available, this function merely returns a pointer to an empty list. *
* *
* INPUT: none *
* *
* OUTPUT: Returns a pointer to the generic overlap list. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/28/1994 JLB : Created. *
*=============================================================================================*/
short const * ObjectTypeClass::Overlap_List(void) const
{
static short const _list[] = {REFRESH_EOL};
return(_list);
}
/***********************************************************************************************
* ObjectTypeClass::One_Time -- Handles one time processing for object types. *
* *
* This routine is used to handle the once per game processing required for object types. *
* This consists of loading any data and initializing any data tables the game requires. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: This routine goes to disk. *
* *
* HISTORY: *
* 11/01/1994 JLB : Created. *
*=============================================================================================*/
void ObjectTypeClass::One_Time(void)
{
SelectShapes = MixFileClass::Retrieve("SELECT.SHP");
#if (FRENCH)
PipShapes = Hires_Retrieve("PIPS_F.SHP");
#else
#if (GERMAN)
PipShapes = Hires_Retrieve("PIPS_G.SHP");
#else
PipShapes = Hires_Retrieve("PIPS.SHP");
#endif
#endif
}
/***********************************************************************************************
* ObjectClass::Mark_For_Redraw -- Marks object and system for redraw. *
* *
* This routine will mark the object and inform the display system *
* that appropriate rendering is needed. Whenever it is determined *
* that an object needs to be redrawn, call this routine. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: This is a subordinate function to the function Mark(). If an object needs to *
* be redrawn it is probably better to call the function Mark(MARK_CHANGE) rather *
* than this function. This function does not inform the map system that *
* overlapping objects are to be redrawn and thus unless you are really sure that *
* this routine should be called, don't. *
* *
* HISTORY: *
* 05/08/1994 JLB : Created. *
* 12/23/1994 JLB : Flags map and flags unit only. *
*=============================================================================================*/
void ObjectClass::Mark_For_Redraw(void)
{
if (!IsToDisplay) {
IsToDisplay = true;
/*
** This tells the map rendering logic to "go through the motions" and call the
** rendering function. In the rendering function, it will sort out what gets
** rendered and what doesn't.
*/
Map.Flag_To_Redraw(false);
}
}
/***********************************************************************************************
* ObjectClass::Limbo -- Brings the object into a state of limbo. *
* *
* An object brought into a state of limbo by this routine can be safely deleted. This *
* routine will remove the object from all game lists and tracking systems. It is called *
* prior to deleting the object or placing the object "on ice". *
* *
* INPUT: none *
* *
* OUTPUT: bool; Was the object successfully placed in limbo? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/24/1994 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Limbo(void)
{
if (GameActive && !IsInLimbo) {
//Unselect();
// Updated to function for multiplayer - 6/26/2019 JAS
Unselect_All_Players();
Detach_All();
Mark(MARK_UP);
/*
** Remove the object from the appropriate display list.
*/
Map.Remove(this, In_Which_Layer());
/*
** Remove the object from the logic processing list.
*/
if (Class_Of().IsSentient) {
Logic.Delete(this);
}
Hidden();
IsInLimbo = true;
IsToDisplay = false;
return(true);
}
return(false);
}
/***********************************************************************************************
* ObjectClass::Unlimbo -- Brings the object into the game system. *
* *
* This routine will place the object into the game tracking and display systems. It is *
* called as a consequence of creating the object. Every game object must be unlimboed at *
* some point. *
* *
* INPUT: coord -- The coordinate to place the object into the game system. *
* *
* dir (optional) -- initial facing direction for this object *
* *
* OUTPUT: bool; Was the game object successfully unlimboed? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/24/1994 JLB : Created. *
* 12/23/1994 JLB : Sets object strength. *
*=============================================================================================*/
bool ObjectClass::Unlimbo(COORDINATE coord, DirType )
{
if (GameActive && IsInLimbo && !IsDown) {
if (ScenarioInit || Can_Enter_Cell(Coord_Cell(coord), FACING_NONE) == MOVE_OK) {
IsInLimbo = false;
IsToDisplay = false;
Coord = Class_Of().Coord_Fixup(coord);
if (Mark(MARK_DOWN)) {
if (IsActive) {
/*
** Add the object to the appropriate map layer. This layer is used
** for rendering purposes.
*/
if (In_Which_Layer() != LAYER_NONE) {
Map.Submit(this, In_Which_Layer());
}
if (Class_Of().IsSentient) {
Logic.Submit(this);
}
}
return(true);
}
}
}
return(false);
}
/***********************************************************************************************
* ObjectClass::Detach_All -- Removes the object from all tracking systems. *
* *
* This routine will take the object and see that it is removed from all miscellaneous *
* tracking systems in the game. This operation is vital when deleting an object. It is *
* necessary so that when the object is removed from the game, existing game objects won't *
* be referencing a now invalid game object. This typically affects the targeting *
* and navigation computers of other game objects. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/24/1994 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Detach_All(bool all)
{
/*
** Unselect this object if it was selected.
*/
//if (all || Owner() != PlayerPtr->Class->House) {
// Unselect();
//}
//Added some error handling incase there was an issue removing the object - JAS 6/28/2019
if (all) {
//Unselect();
// Updated to function for multiplayer - 6/28/2019 JAS
Unselect_All_Players();
}
else
{
Unselect_All_Players_Except_Owner();
}
//End of change - JAS 6/28/2019
Map.Detach(this);
/*
** Remove from targeting computers.
*/
Detach_This_From_All(As_Target(), all);
}
/***********************************************************************************************
* ObjectClass::Detach_This_From_All -- Detatches this object from all others. *
* *
* This routine sweeps through all game objects and makes sure that it is no longer *
* referenced by them. Typically, this is called in preparation for the object's death *
* or limbo state. *
* *
* INPUT: target -- This object expressed as a target number. *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 05/08/1995 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Detach_This_From_All(TARGET target, bool all)
{
int index;
if (Target_Legal(target)) {
for (index = 0; index < Houses.Count(); index++) {
Houses.Ptr(index)->Detach(target, all);
}
for (index = 0; index < Teams.Count(); index++) {
Teams.Ptr(index)->Detach(target, all);
}
for (index = 0; index < Units.Count(); index++) {
Units.Ptr(index)->Detach(target, all);
}
for (index = 0; index < Infantry.Count(); index++) {
Infantry.Ptr(index)->Detach(target, all);
}
for (index = 0; index < Aircraft.Count(); index++) {
Aircraft.Ptr(index)->Detach(target, all);
}
for (index = 0; index < Buildings.Count(); index++) {
Buildings.Ptr(index)->Detach(target, all);
}
for (index = 0; index < Bullets.Count(); index++) {
Bullets.Ptr(index)->Detach(target, all);
}
for (index = 0; index < Anims.Count(); index++) {
Anims.Ptr(index)->Detach(target, all);
}
}
}
/***********************************************************************************************
* ObjectClass::Receive_Message -- Processes an incoming radio message. *
* *
* Any radio message received that applies to objects in general are handled by this *
* routine. Typically, this is the "redraw" message, which occurs when another object is *
* loading or unloading and thus overlapping. *
* *
* INPUT: message -- The message received. *
* *
* OUTPUT: Returns with the appropriate radio response. If the message was recognized, then *
* RADIO_ROGER is returned, otherwise, just RADIO_STATIC is returned. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 09/24/1994 JLB : Created. *
*=============================================================================================*/
RadioMessageType ObjectClass::Receive_Message(RadioClass *, RadioMessageType message, long & )
{
switch (message) {
/*
** This message serves as a rendering convenience. It lets the system
** know that there might be a visual conflict and the unit in radio
** contact should be redrawn. This typically occurs when a vehicle
** is being unloaded from a hover lander.
*/
case RADIO_REDRAW:
Mark(MARK_CHANGE);
return(RADIO_ROGER);
default:
break;
}
return(RADIO_STATIC);
}
/***********************************************************************************************
* ObjectClass::Take_Damage -- Applies damage to the object. *
* *
* This routine applies damage to the object according to the damage parameters. It handles *
* reducing the strength of the object and also returns the result of that damage. The *
* result value can be examined to determine if the object was destroyed, greatly damaged, *
* or other results. *
* *
* INPUT: damage -- Reference to the damage number to apply. This number will be adjusted *
* according to defensive armor and distance. Examine this value after *
* the call to determine the actual amount of damage applied. *
* *
* distance -- The distance (in leptons) from the center of the damage causing *
* explosion to the object itself. *
* *
* warhead -- The warhead type that is causing the damage. *
* *
* OUTPUT: Returns the ResultType that indicates what the affect of the damage was. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 11/29/1994 JLB : Created. *
* 12/27/1994 JLB : Trigger event processing for attacked or destroyed. *
* 01/01/1995 JLB : Reduces damage greatly depending on range. *
*=============================================================================================*/
ResultType ObjectClass::Take_Damage(int & damage, int distance, WarheadType warhead, TechnoClass * source)
{
ResultType result = RESULT_NONE;
int oldstrength = Strength;
if (oldstrength && damage && !Class_Of().IsImmune) {
int maxstrength = Class_Of().MaxStrength;
/*
** Modify damage based on the warhead type and the armor of the object. This results
** in a reduced damage value, but never below 1 damage point.
*/
damage = Modify_Damage(damage, warhead, Class_Of().Armor, distance);
if (!damage) return(RESULT_NONE);
/*
** At this point, we KNOW that at least light damage has occurred.
*/
result = RESULT_LIGHT;
/*
** A non-fatal blow has occurred. Check to see if the object transitioned to below
** half strength or if it is now down to one hit point.
*/
if (oldstrength > damage) {
if (oldstrength >= (maxstrength >> 1) && (oldstrength-damage) < (maxstrength >> 1)) {
result = RESULT_HALF;
}
} else {
/*
** When an object is damaged to destruction, it will instead stop at one
** damage point. This will prolong the damage state as well as
** give greater satisfaction when it is finally destroyed.
*/
damage = oldstrength;
}
/*
** Apply the damage to the object.
*/
Strength = oldstrength - damage;
/*
** Check to see if the object is majorly damaged or destroyed.
*/
switch (Strength) {
case 0:
Record_The_Kill(source);
result = RESULT_DESTROYED;
Detach_All();
break;
case 1:
result = RESULT_MAJOR;
break;
default:
break;
}
/*
** Handle any trigger event associated with this object.
*/
if (source && Trigger && result != RESULT_DESTROYED) {
Trigger->Spring(EVENT_ATTACKED, this);
}
/*
** If any damage was assessed and this object is selected, then flag
** the object to be redrawn so that the health bar will be updated.
*/
//if (result != RESULT_NONE && IsSelected) {
// Updated to function for multiplayer - 6/26/2019 JAS
if (result != RESULT_NONE && Is_Selected_By_Player()) {
Mark(MARK_CHANGE);
}
}
/*
** Return with the result of the damage taken.
*/
return(result);
}
/***********************************************************************************************
* ObjectClass::Mark -- Handles basic marking logic. *
* *
* This routine handles the base logic for marking an object up or down on the map. It *
* manages the IsDown flag as well as flagging the object to be redrawn if necessary. *
* Whenever an object is to be marked, it should call this base class function first. If *
* this function returns true, then the higher level function should proceed with its own *
* logic. *
* *
* INPUT: mark -- The marking method to use for this object. It can be either MARK_DOWN, *
* MARK_UP, or MARK_CHANGE. *
* *
* OUTPUT: bool; Was the object marked successfully? *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/23/1995 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Mark(MarkType mark)
{
TechnoClass *tech;
CELL cell;
int threat;
HousesType house;
if (!IsInLimbo && IsActive) {
/*
** A mark for change is always successful UNLESS the object
** is not placed down or has already been flagged as changed
** this game frame.
*/
if (mark == MARK_CHANGE) {
if (IsToDisplay) return(false);
if (IsDown == true) {
Mark_For_Redraw();
return(true);
}
return(false);
}
/*
** Handle adding or removing the object in the cells' overlap lists
*/
if (mark == MARK_OVERLAP_UP) {
if (IsDown == true) {
Map.Overlap_Up(Coord_Cell(Coord),this);
Mark_For_Redraw();
return(true);
}
}
if (mark == MARK_OVERLAP_DOWN) {
if (IsDown == true) {
Map.Overlap_Down(Coord_Cell(Coord),this);
Mark_For_Redraw();
return(true);
}
}
/*
** It is important to know whether the object is a techno class
** or not to see if we have to adjust the regional threat ratings
*/
if (Is_Techno()) {
tech = (TechnoClass *)this;
threat = tech->Risk();
house = tech->Owner();
cell = Coord_Cell(Coord);
} else
tech = NULL;
/*
** Marking down is only successful if the object isn't already
** placed down.
*/
if (mark == MARK_DOWN && !IsDown) {
if (tech && GameToPlay == GAME_NORMAL) {
Map[cell].Adjust_Threat(house, threat);
}
IsDown = true;
Mark_For_Redraw();
return(true);
}
/*
** Lifting up is only successful if the object isn't already
** lifted up from the map.
*/
if (mark == MARK_UP && IsDown) {
if (tech && GameToPlay == GAME_NORMAL) {
Map[cell].Adjust_Threat(house, -threat);
}
Map.Overlap_Up(Coord_Cell(Coord), this);
IsDown = false;
return(true);
}
}
return(false);
}
/***********************************************************************************************
* ObjectClass::Init -- Initializes the basic object system. *
* *
* This routine should be called when the basic object system needs to be initialized. This *
* occurs when the scenario is about to be loaded. *
* *
* INPUT: none *
* *
* OUTPUT: none *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 01/23/1995 JLB : Created. *
*=============================================================================================*/
void ObjectClass::Init(void)
{
CurrentObject.Clear_All();
}
/***********************************************************************************************
* ObjectClass::Revealed -- Reveals this object to the house specified. *
* *
* This routine is called when this object gets revealed to the house specified. *
* *
* INPUT: house -- Pointer to the house that this object is being revealed to. *
* *
* OUTPUT: Was this object revealed for the first time to this house? Generic objects always *
* return true unless an invalid house pointer was specified. *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 07/19/1995 JLB : Created. *
*=============================================================================================*/
bool ObjectClass::Revealed(HouseClass * house)
{
return(house != NULL);
}
/***********************************************************************************************
* ObjectClass::Set_Selected_By_Player -- Set this object as selected by the given player or *
* the default player. *
* *
* INPUT: Player pointer *
* *
* OUTPUT: *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 6/25/2019 - JAS *
*=============================================================================================*/
void ObjectClass::Set_Selected_By_Player(HouseClass *player)
{
if (!player || !player->Class) {
player = PlayerPtr;
}
HousesType house = player->Class->House;
if (((TechnoTypeClass const &)Class_Of()).IsLeader) {
CurrentObject.Add_Head(house, this);
}
else {
CurrentObject.Add(house, this);
}
int shift = (int)house;
IsSelectedMask |= (1 << shift);
if (GameToPlay == GAME_NORMAL && player == PlayerPtr) {
IsSelected = true;
}
}
/***********************************************************************************************
* ObjectClass::Set_Unselected_By_Player -- Set this object as unselected by the given player *
* orthe default player. *
* *
* INPUT: Player pointer *
* *
* OUTPUT: *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 6/25/2019 - JAS *
*=============================================================================================*/
void ObjectClass::Set_Unselected_By_Player(HouseClass *player)
{
if (!player || !player->Class) {
player = PlayerPtr;
}
HousesType house = player->Class->House;
CurrentObject.Delete(house, this);
int shift = (int)house;
IsSelectedMask &= ~(1 << shift);
if (GameToPlay == GAME_NORMAL && player == PlayerPtr) {
IsSelected = false;
}
}
/***********************************************************************************************
* ObjectClass::Is_Selected_By_Player -- Has this object been selected by the given player *
* *
* INPUT: Player pointer *
* *
* OUTPUT: True if selected by that player *
* *
* WARNINGS: none *
* *
* HISTORY: *
* 6/25/2019 - JAS *
*=============================================================================================*/
bool ObjectClass::Is_Selected_By_Player(HouseClass *player) const
{
if (player && player->Class) {
int shift = (int)player->Class->House;
return (IsSelectedMask & (1 << shift)) ? true : false;
}
else {
int shift = (int)PlayerPtr->Class->House;
return (IsSelectedMask & (1 << shift)) ? true : false;
}
return false;
}
// These can't be made inline (for various reasons).
short const * ObjectClass::Occupy_List(bool placement) const {return(Class_Of().Occupy_List(placement));};
short const * ObjectClass::Overlap_List(void) const {return(Class_Of().Overlap_List());};
BuildingClass * ObjectClass::Who_Can_Build_Me(bool intheory, bool legal) const {return(Class_Of().Who_Can_Build_Me(intheory, legal, Owner()));};
unsigned ObjectClass::Health_Ratio(void) const {return(Cardinal_To_Fixed(Class_Of().MaxStrength, Strength));};
int ObjectClass::Full_Name(void) const {return Class_Of().Full_Name();};