mirror of
https://github.com/electronicarts/CnC_Generals_Zero_Hour.git
synced 2025-12-16 23:51:41 -05:00
Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.
This commit is contained in:
983
Generals/Code/GameEngine/Include/GameLogic/AI.h
Normal file
983
Generals/Code/GameEngine/Include/GameLogic/AI.h
Normal file
@@ -0,0 +1,983 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AI.h //
|
||||
// AI header file
|
||||
// Author: Michael S. Booth, November 2000
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _AI_H_
|
||||
#define _AI_H_
|
||||
|
||||
#include "Common/Snapshot.h"
|
||||
#include "Common/SubsystemInterface.h"
|
||||
#include "Common/GameMemory.h"
|
||||
#include "Common/GameType.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
|
||||
class AIGroup;
|
||||
class AttackPriorityInfo;
|
||||
class BuildListInfo;
|
||||
class CommandButton;
|
||||
class Object;
|
||||
class PartitionFilter;
|
||||
class Path;
|
||||
class Pathfinder;
|
||||
class Player;
|
||||
class PolygonTrigger;
|
||||
class UpgradeTemplate;
|
||||
class WeaponTemplate;
|
||||
|
||||
enum GUICommandType;
|
||||
enum HackerAttackMode;
|
||||
enum WeaponSetType;
|
||||
enum WeaponLockType;
|
||||
enum SpecialPowerType;
|
||||
|
||||
typedef std::vector<ObjectID> VecObjectID;
|
||||
typedef VecObjectID::iterator VecObjectIDIt;
|
||||
|
||||
typedef std::list<Object *> ListObjectPtr;
|
||||
typedef ListObjectPtr::iterator ListObjectPtrIt;
|
||||
|
||||
enum AIDebugOptions
|
||||
{
|
||||
AI_DEBUG_NONE = 0,
|
||||
AI_DEBUG_PATHS,
|
||||
AI_DEBUG_TERRAIN,
|
||||
AI_DEBUG_CELLS,
|
||||
AI_DEBUG_GROUND_PATHS,
|
||||
AI_DEBUG_END
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
// multiply by the owner type, either AI or human
|
||||
AI_VISIONFACTOR_OWNERTYPE = 0x01,
|
||||
|
||||
// multiply by the "mood" of the unit
|
||||
AI_VISIONFACTOR_MOOD = 0x02,
|
||||
|
||||
// If we want to consider the inner radius, we will specify guard inner. Otherwise, use guard outer.
|
||||
AI_VISIONFACTOR_GUARDINNER = 0x04,
|
||||
};
|
||||
enum {MAX_AI_UPGRADES = 20};
|
||||
|
||||
typedef struct {
|
||||
Int m_numSkills;
|
||||
ScienceType m_skills[MAX_AI_UPGRADES];
|
||||
} TSkillSet;
|
||||
|
||||
class AISideInfo : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AISideInfo, "AISideInfo")
|
||||
public:
|
||||
AISideInfo( void ) : m_easy(0), m_normal(1), m_hard(2), m_next(NULL)
|
||||
{
|
||||
m_side.clear();
|
||||
m_baseDefenseStructure1.clear();
|
||||
}
|
||||
|
||||
AsciiString m_side; ///< Name of the side
|
||||
Int m_easy; ///< Number of gatherers to use in easy, normal & hard
|
||||
Int m_normal;
|
||||
Int m_hard;
|
||||
TSkillSet m_skillSet1;
|
||||
TSkillSet m_skillSet2;
|
||||
TSkillSet m_skillSet3;
|
||||
TSkillSet m_skillSet4;
|
||||
TSkillSet m_skillSet5;
|
||||
AsciiString m_baseDefenseStructure1;
|
||||
AISideInfo *m_next;
|
||||
};
|
||||
EMPTY_DTOR(AISideInfo)
|
||||
|
||||
class AISideBuildList : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AISideBuildList, "AISideBuildList")
|
||||
public:
|
||||
AISideBuildList( AsciiString side );
|
||||
//~AISideBuildList();
|
||||
|
||||
void addInfo(BuildListInfo *info);
|
||||
|
||||
public:
|
||||
AsciiString m_side; ///< Name of the faction.
|
||||
BuildListInfo* m_buildList; ///< Build list for the faction.
|
||||
AISideBuildList* m_next;
|
||||
};
|
||||
|
||||
|
||||
|
||||
class TAiData : public Snapshot
|
||||
{
|
||||
public:
|
||||
TAiData();
|
||||
~TAiData();
|
||||
|
||||
void addSideInfo(AISideInfo *info);
|
||||
void addFactionBuildList(AISideBuildList *buildList);
|
||||
|
||||
// --------------- inherited from Snapshot interface --------------
|
||||
void crc( Xfer *xfer );
|
||||
void xfer( Xfer *xfer );
|
||||
void loadPostProcess( void );
|
||||
|
||||
Real m_structureSeconds; // Try to build a structure every N seconds.
|
||||
Real m_teamSeconds; // Try to build a team every N seconds.
|
||||
Int m_resourcesWealthy; // How many resources to be wealthy.
|
||||
Int m_resourcesPoor; // How few resources to be poor.
|
||||
UnsignedInt m_forceIdleFramesCount; // How many frames does a unit need to be Idle before it can begin looking for enemies?
|
||||
Real m_structuresWealthyMod; // Factor to multiply m_structurFrames by if we are wealthy.
|
||||
Real m_teamWealthyMod; // Factor to multiply m_teamFrames by if we are wealthy.
|
||||
Real m_structuresPoorMod; // Factor to multiply m_structureFrames by if we are poor.
|
||||
Real m_teamPoorMod; // Factor to multiply m_teamFrames if we are poor.
|
||||
Real m_teamResourcesToBuild; // Amount of the resources needed to build a team required before we start.
|
||||
Real m_guardInnerModifierAI; // Multiply the AI unit's vision by this much == guard inner circle.
|
||||
Real m_guardOuterModifierAI; // Multiply the AI unit's vision by this much == guard outer circle.
|
||||
Real m_guardInnerModifierHuman; // Multiply the human unit's vision by this much == guard inner circle
|
||||
Real m_guardOuterModifierHuman; // Multiply the human unit's vision by this much == guard outer circle
|
||||
UnsignedInt m_guardChaseUnitFrames; // Number of frames for which a unit should
|
||||
UnsignedInt m_guardEnemyScanRate; // rate to scan for enemies while guarding
|
||||
UnsignedInt m_guardEnemyReturnScanRate; // rate to scan for enemies while guarding but returning
|
||||
|
||||
Real m_wallHeight; // Height of special wall units can walk on top of.
|
||||
|
||||
Real m_alertRangeModifier; // When a unit is alert, its range will be modified by this value
|
||||
Real m_aggressiveRangeModifier; // When a unit is aggressive, its range will be modified by this value
|
||||
|
||||
/* The attack priority distance modifier changes relative values. The relative priority
|
||||
is reduced by the distance away, divided by the modifier.
|
||||
Example: tanks are priority 10, powerplants priority 15, and modifier = 100.0
|
||||
If a powerplant is 700 feet away from the attacker, and the tank is
|
||||
100 feet, the effective priority for tank is 9 (10-(100/100), and the
|
||||
effective priority for powerplant is 8 (15 -(700/100). So the tanks
|
||||
would be attacked first because their distance weighted priority is greater. */
|
||||
Real m_attackPriorityDistanceModifier; // Distance to reduce a relative AttackPriority by 1.
|
||||
|
||||
|
||||
/*
|
||||
How close to a waypoint does a group of units have to be to consider itself at the waypoint?
|
||||
m_skirmishGroupFudgeValue is multiplied by the number of the units in the group asking if its
|
||||
close enough to determine this.
|
||||
|
||||
So for instance (if m_skirmishGroupFudgeValue was 5), if 2 units are walking along a path,
|
||||
they would check to see if they were less than 10 feet away from the waypoint in order
|
||||
to say they were close enough. A group of 10 units would consider themselves close enough
|
||||
if they were within 50 feet of the waypoint.
|
||||
*/
|
||||
Real m_skirmishGroupFudgeValue;
|
||||
|
||||
Real m_maxRecruitDistance; // Maximum distance away that units can be recruited.
|
||||
Real m_repulsedDistance; // How far a repulsed unit will run past vision range before stopping.
|
||||
Bool m_enableRepulsors; // Is repulsion enabled?
|
||||
|
||||
Bool m_forceSkirmishAI; // If true, forces skirmish ai instead of solo ai for development until the skirmish ui is done. jba.
|
||||
Bool m_rotateSkirmishBases; // If true, rotates skirmish ai bases to face the center of the map. jba.
|
||||
|
||||
Bool m_attackUsesLineOfSight; // If true, attack for units with KINDOF_ATTACK_NEEDS_LINE_OF_SIGHT uses line of sight. jba.
|
||||
|
||||
Bool m_attackIgnoreInsignificantBuildings; // If true, attack for ALL UNITS ignores buildings that are hostile that are not significant. jkmcd
|
||||
|
||||
// Group pathfind info.
|
||||
Int m_minInfantryForGroup; // We need at least this many to do it.
|
||||
Int m_minVehiclesForGroup; // We need at least this many vehicles to do it.
|
||||
Real m_minDistanceForGroup; // We need to move at least this far to do it.
|
||||
Real m_distanceRequiresGroup; // If we are moving this far or farther, force group moving.
|
||||
Real m_minClumpDensity; // What density constitues a clump. .5 means units occupying 1/2 of their bounding area.
|
||||
|
||||
Int m_infantryPathfindDiameter; // Diameter of path in cells for infantry.
|
||||
Int m_vehiclePathfindDiameter; // Diameter of path in cells for vehicles.
|
||||
|
||||
Int m_rebuildDelaySeconds; // Seconds to delay rebuilding after a base building is destroyed or captured.
|
||||
|
||||
Real m_supplyCenterSafeRadius; // Radius to scan for enemies to determine safety.
|
||||
|
||||
Real m_aiDozerBoredRadiusModifier; // Modifies ai dozers scan range so the move out farther than human ones.
|
||||
Bool m_aiCrushesInfantry; // If true, AI vehicles will attempt to crush infantry.
|
||||
|
||||
AISideInfo *m_sideInfo;
|
||||
|
||||
AISideBuildList *m_sideBuildLists;
|
||||
|
||||
TAiData *m_next;
|
||||
} ;
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The AI subsystem is responsible for the implementation of
|
||||
* the Artificial Intelligence of the game. This includes
|
||||
* the behaviors or all game entities, pathfinding, etc.
|
||||
*/
|
||||
class AI : public SubsystemInterface, public Snapshot
|
||||
{
|
||||
public:
|
||||
AI( void );
|
||||
~AI();
|
||||
|
||||
virtual void init( void ); ///< initialize AI to default values
|
||||
virtual void reset( void ); ///< reset the AI system to prepare for a new map
|
||||
virtual void update( void ); ///< do one frame of AI computation
|
||||
|
||||
inline Pathfinder *pathfinder( void ) { return m_pathfinder; } ///< public access to the pathfind system
|
||||
enum
|
||||
{
|
||||
CAN_SEE = 1 << 0,
|
||||
CAN_ATTACK = 1 << 1,
|
||||
IGNORE_INSIGNIFICANT_BUILDINGS = 1 << 2,
|
||||
ATTACK_BUILDINGS = 1 << 3,
|
||||
WITHIN_ATTACK_RANGE = 1 << 4,
|
||||
UNFOGGED = 1 << 5
|
||||
};
|
||||
Object *findClosestEnemy( const Object *me, Real range, UnsignedInt qualifiers,
|
||||
const AttackPriorityInfo *info=NULL, PartitionFilter *optionalFilter=NULL);
|
||||
|
||||
Object *findClosestRepulsor( const Object *me, Real range);
|
||||
|
||||
Object *findClosestAlly( const Object *me, Real range, UnsignedInt qualifiers);
|
||||
|
||||
// --------------- inherited from Snapshot interface --------------
|
||||
void crc( Xfer *xfer );
|
||||
void xfer( Xfer *xfer );
|
||||
void loadPostProcess( void );
|
||||
|
||||
// AI Groups -----------------------------------------------------------------------------------------------
|
||||
AIGroup *createGroup( void ); ///< instantiate a new AI Group
|
||||
void destroyGroup( AIGroup *group ); ///< destroy the given AI Group
|
||||
AIGroup *findGroup( UnsignedInt id ); ///< return the AI Group with the given ID
|
||||
|
||||
// Formation info
|
||||
enum FormationID getNextFormationID(void);
|
||||
|
||||
static void parseAiDataDefinition( INI* ini );
|
||||
const TAiData *getAiData() {return m_aiData;}
|
||||
|
||||
// Note: Does not work for things that do not have AI. (This is in AI.h, after all)
|
||||
static Real getAdjustedVisionRangeForObject(const Object *object, Int factorsToConsider);
|
||||
|
||||
static void parseSideInfo( INI* ini, void *instance, void *store, const void *userData ); ///< Parse the image part of the INI file
|
||||
static void parseSkirmishBuildList( INI* ini, void *instance, void *store, const void *userData ); ///< Parse the image part of the INI file
|
||||
static void parseStructure( INI* ini, void *instance, void *store, const void *userData ); ///< Parse the image part of the INI file
|
||||
static void parseSkillSet( INI* ini, void *instance, void *store, const void *userData ); ///< Parse the image part of the INI file
|
||||
static void parseScience( INI* ini, void *instance, void *store, const void *userData ); ///< Parse the image part of the INI file
|
||||
|
||||
inline UnsignedInt getNextGroupID( void ) { return ++m_nextGroupID; }
|
||||
|
||||
protected:
|
||||
Pathfinder *m_pathfinder; ///< the pathfinding system
|
||||
std::list<AIGroup *> m_groupList; ///< the list of AIGroups
|
||||
TAiData *m_aiData;
|
||||
void newOverride(void);
|
||||
void addSideInfo(AISideInfo *info);
|
||||
|
||||
UnsignedInt m_nextGroupID;
|
||||
FormationID m_nextFormationID;
|
||||
};
|
||||
|
||||
extern AI *TheAI; ///< the Artificial Intelligence singleton
|
||||
|
||||
|
||||
class Waypoint;
|
||||
class Team;
|
||||
class Weapon;
|
||||
|
||||
// Note - written out in save/load xfer and .map files, don't change these numbers.
|
||||
enum AttitudeType { AI_SLEEP = -2, AI_PASSIVE=-1, AI_NORMAL=0, AI_ALERT=1, AI_AGGRESSIVE=2, AI_INVALID=3 }; ///< AI "attitude" behavior modifiers
|
||||
|
||||
enum CommandSourceType;
|
||||
|
||||
typedef UnsignedInt CommandSourceMask;
|
||||
|
||||
#ifdef DEFINE_COMMANDSOURCEMASK_NAMES
|
||||
static const char *TheCommandSourceMaskNames[] =
|
||||
{
|
||||
"FROM_PLAYER",
|
||||
"FROM_SCRIPT",
|
||||
"FROM_AI",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
|
||||
enum AICommandType // Stored in save file, do not reorder/renumber. jba.
|
||||
{
|
||||
AICMD_MOVE_TO_POSITION = 0,
|
||||
AICMD_MOVE_TO_OBJECT,
|
||||
AICMD_TIGHTEN_TO_POSITION,
|
||||
AICMD_MOVE_TO_POSITION_AND_EVACUATE,
|
||||
AICMD_MOVE_TO_POSITION_AND_EVACUATE_AND_EXIT,
|
||||
AICMD_IDLE,
|
||||
AICMD_FOLLOW_WAYPOINT_PATH,
|
||||
AICMD_FOLLOW_WAYPOINT_PATH_AS_TEAM,
|
||||
AICMD_FOLLOW_USER_PATH, //Created by player in waypoint mode (this one will create little waypoint markers)
|
||||
AICMD_FOLLOW_PATH,
|
||||
AICMD_FOLLOW_EXITPRODUCTION_PATH, // same as AICMD_FOLLOW_PATH, but only used when exiting your production facility.
|
||||
AICMD_ATTACK_OBJECT,
|
||||
AICMD_FORCE_ATTACK_OBJECT,
|
||||
AICMD_ATTACK_TEAM,
|
||||
AICMD_ATTACK_POSITION,
|
||||
AICMD_ATTACKMOVE_TO_POSITION,
|
||||
AICMD_ATTACKFOLLOW_WAYPOINT_PATH,
|
||||
AICMD_ATTACKFOLLOW_WAYPOINT_PATH_AS_TEAM,
|
||||
AICMD_HUNT,
|
||||
AICMD_REPAIR,
|
||||
#ifdef ALLOW_SURRENDER
|
||||
AICMD_PICK_UP_PRISONER,
|
||||
AICMD_RETURN_PRISONERS,
|
||||
#endif
|
||||
AICMD_RESUME_CONSTRUCTION,
|
||||
AICMD_GET_HEALED,
|
||||
AICMD_GET_REPAIRED,
|
||||
AICMD_ENTER,
|
||||
AICMD_DOCK,
|
||||
AICMD_EXIT,
|
||||
AICMD_EVACUATE,
|
||||
AICMD_EXECUTE_RAILED_TRANSPORT,
|
||||
AICMD_GO_PRONE,
|
||||
AICMD_GUARD_POSITION,
|
||||
AICMD_GUARD_OBJECT,
|
||||
AICMD_GUARD_AREA,
|
||||
AICMD_DEPLOY_ASSAULT_RETURN,
|
||||
AICMD_ATTACK_AREA,
|
||||
AICMD_HACK_INTERNET,
|
||||
AICMD_FACE_OBJECT,
|
||||
AICMD_FACE_POSITION,
|
||||
AICMD_RAPPEL_INTO, // note that this applies to the rappeller.
|
||||
AICMD_COMBATDROP, // note that this applies to the thing-being-rappelled-from.
|
||||
AICMD_COMMANDBUTTON_POS,
|
||||
AICMD_COMMANDBUTTON_OBJ,
|
||||
AICMD_COMMANDBUTTON,
|
||||
AICMD_WANDER,
|
||||
AICMD_WANDER_IN_PLACE,
|
||||
AICMD_PANIC,
|
||||
AICMD_BUSY,
|
||||
AICMD_FOLLOW_WAYPOINT_PATH_EXACT,
|
||||
AICMD_FOLLOW_WAYPOINT_PATH_AS_TEAM_EXACT,
|
||||
AICMD_MOVE_AWAY_FROM_UNIT,
|
||||
AICMD_FOLLOW_PATH_APPEND,
|
||||
AICMD_MOVE_TO_POSITION_EVEN_IF_SLEEPING, // same as AICMD_MOVE_TO_POSITION, but even AI_SLEEP units respond.
|
||||
AICMD_GUARD_TUNNEL_NETWORK,
|
||||
|
||||
AICMD_NUM_COMMANDS // keep last
|
||||
};
|
||||
|
||||
struct AICommandParms
|
||||
{
|
||||
AICommandType m_cmd;
|
||||
CommandSourceType m_cmdSource;
|
||||
Coord3D m_pos;
|
||||
Object* m_obj;
|
||||
Object* m_otherObj;
|
||||
const Team* m_team;
|
||||
std::vector<Coord3D> m_coords;
|
||||
const Waypoint* m_waypoint;
|
||||
const PolygonTrigger* m_polygon;
|
||||
Int m_intValue; /// misc usage
|
||||
DamageInfo m_damage;
|
||||
const CommandButton* m_commandButton;
|
||||
Path* m_path;
|
||||
|
||||
AICommandParms(AICommandType cmd, CommandSourceType cmdSource);
|
||||
};
|
||||
|
||||
class AICommandParmsStorage
|
||||
{
|
||||
private:
|
||||
AICommandType m_cmd;
|
||||
CommandSourceType m_cmdSource;
|
||||
Coord3D m_pos;
|
||||
ObjectID m_obj;
|
||||
ObjectID m_otherObj;
|
||||
AsciiString m_teamName;
|
||||
std::vector<Coord3D> m_coords;
|
||||
const Waypoint* m_waypoint;
|
||||
const PolygonTrigger* m_polygon;
|
||||
Int m_intValue; /// misc usage
|
||||
DamageInfo m_damage;
|
||||
const CommandButton* m_commandButton;
|
||||
Path* m_path;
|
||||
|
||||
public:
|
||||
void store(const AICommandParms& parms);
|
||||
void reconstitute(AICommandParms& parms) const;
|
||||
void doXfer(Xfer *xfer);
|
||||
};
|
||||
|
||||
/**
|
||||
AI interface. AIGroups, or Objects with an AIUpdate can be given these commands.
|
||||
|
||||
NOTE NOTE NOTE: all of these may be overridden and possibly deferred by various AI classes,
|
||||
so they are NOT ALLOWED TO RETURN ANY VALUES, since the particular command issued might
|
||||
not be executed immediately...
|
||||
*/
|
||||
class AICommandInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual void aiDoCommand(const AICommandParms* parms) = 0;
|
||||
|
||||
inline void aiMoveToPosition( const Coord3D *pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_MOVE_TO_POSITION, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiMoveToPositionEvenIfSleeping( const Coord3D *pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_MOVE_TO_POSITION_EVEN_IF_SLEEPING, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiMoveToObject( Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_MOVE_TO_OBJECT, cmdSource);
|
||||
parms.m_obj = obj;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiTightenToPosition( const Coord3D *pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_TIGHTEN_TO_POSITION, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiMoveToAndEvacuate( const Coord3D *pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_MOVE_TO_POSITION_AND_EVACUATE, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiMoveToAndEvacuateAndExit( const Coord3D *pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_MOVE_TO_POSITION_AND_EVACUATE_AND_EXIT, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiIdle(CommandSourceType cmdSource)
|
||||
{
|
||||
AICommandParms parms(AICMD_IDLE, cmdSource);
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiBusy(CommandSourceType cmdSource)
|
||||
{
|
||||
AICommandParms parms(AICMD_BUSY, cmdSource);
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFollowWaypointPath( const Waypoint *way, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FOLLOW_WAYPOINT_PATH, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FOLLOW_WAYPOINT_PATH_EXACT, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FOLLOW_WAYPOINT_PATH_AS_TEAM, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFollowWaypointPathExactAsTeam( const Waypoint *way, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FOLLOW_WAYPOINT_PATH_AS_TEAM_EXACT, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFollowExitProductionPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource);
|
||||
parms.m_coords = *path;
|
||||
parms.m_obj = ignoreObject;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource);
|
||||
parms.m_coords = *path;
|
||||
parms.m_obj = ignoreObject;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFollowPathAppend( const Coord3D* pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FOLLOW_PATH_APPEND, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ATTACK_OBJECT, cmdSource);
|
||||
parms.m_obj = victim;
|
||||
parms.m_intValue = maxShotsToFire;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FORCE_ATTACK_OBJECT, cmdSource);
|
||||
parms.m_obj = victim;
|
||||
parms.m_intValue = maxShotsToFire;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiAttackTeam( const Team *team, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ATTACK_TEAM, cmdSource);
|
||||
parms.m_team = team;
|
||||
parms.m_intValue = maxShotsToFire;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiAttackPosition( const Coord3D *pos, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ATTACK_POSITION, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
parms.m_intValue = maxShotsToFire;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiAttackMoveToPosition( const Coord3D *pos, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ATTACKMOVE_TO_POSITION, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
parms.m_intValue = maxShotsToFire;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiAttackFollowWaypointPath( const Waypoint *way, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ATTACKFOLLOW_WAYPOINT_PATH, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
parms.m_intValue = maxShotsToFire;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiAttackFollowWaypointPathAsTeam( const Waypoint *way, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ATTACKFOLLOW_WAYPOINT_PATH_AS_TEAM, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
parms.m_intValue = maxShotsToFire;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiHunt( CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_HUNT, cmdSource);
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiAttackArea( const PolygonTrigger *areaToGuard, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ATTACK_AREA, cmdSource);
|
||||
parms.m_polygon = areaToGuard;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiRepair( Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_REPAIR, cmdSource);
|
||||
parms.m_obj = obj;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
#ifdef ALLOW_SURRENDER
|
||||
inline void aiPickUpPrisoner( Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms( AICMD_PICK_UP_PRISONER, cmdSource );
|
||||
parms.m_obj = obj;
|
||||
aiDoCommand( &parms );
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ALLOW_SURRENDER
|
||||
inline void aiReturnPrisoners( Object *prison, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms( AICMD_RETURN_PRISONERS, cmdSource );
|
||||
parms.m_obj = prison;
|
||||
aiDoCommand( &parms );
|
||||
}
|
||||
#endif
|
||||
|
||||
inline void aiResumeConstruction( Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_RESUME_CONSTRUCTION, cmdSource);
|
||||
parms.m_obj = obj;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiGetHealed( Object *healDepot, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_GET_HEALED, cmdSource);
|
||||
parms.m_obj = healDepot;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiGetRepaired( Object *repairDepot, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_GET_REPAIRED, cmdSource);
|
||||
parms.m_obj = repairDepot;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiEnter( Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_ENTER, cmdSource);
|
||||
parms.m_obj = obj;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiDock( Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_DOCK, cmdSource);
|
||||
parms.m_obj = obj;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiExit( Object *objectToExit, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_EXIT, cmdSource);
|
||||
parms.m_obj = objectToExit;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiEvacuate( Bool exposeStealthUnits, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_EVACUATE, cmdSource);
|
||||
if( exposeStealthUnits )
|
||||
parms.m_intValue = 1;
|
||||
else
|
||||
parms.m_intValue = 0;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiExecuteRailedTransport( CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms( AICMD_EXECUTE_RAILED_TRANSPORT, cmdSource );
|
||||
aiDoCommand( &parms );
|
||||
}
|
||||
|
||||
inline void aiGoProne( const DamageInfo *damageInfo, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_GO_PRONE, cmdSource);
|
||||
parms.m_damage = *damageInfo;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiGuardPosition( const Coord3D *pos, GuardMode guardMode, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_GUARD_POSITION, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
parms.m_intValue = guardMode;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiGuardObject( Object *objToGuard, GuardMode guardMode, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_GUARD_OBJECT, cmdSource);
|
||||
parms.m_obj = objToGuard;
|
||||
parms.m_intValue = guardMode;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiGuardArea( const PolygonTrigger *areaToGuard, GuardMode guardMode, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_GUARD_AREA, cmdSource);
|
||||
parms.m_polygon = areaToGuard;
|
||||
parms.m_intValue = guardMode;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiGuardTunnelNetwork( GuardMode guardMode, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_GUARD_TUNNEL_NETWORK, cmdSource);
|
||||
parms.m_intValue = guardMode;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiHackInternet( CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_HACK_INTERNET, cmdSource);
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFaceObject( Object *target, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FACE_OBJECT, cmdSource);
|
||||
parms.m_obj = target;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiFacePosition( const Coord3D *pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_FACE_POSITION, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiRappelInto( Object *target, const Coord3D& pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_RAPPEL_INTO, cmdSource);
|
||||
parms.m_obj = target;
|
||||
parms.m_pos = pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiCombatDrop( Object *target, const Coord3D& pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_COMBATDROP, cmdSource);
|
||||
parms.m_obj = target;
|
||||
parms.m_pos = pos;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiDoCommandButton( const CommandButton *commandButton, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_COMMANDBUTTON, cmdSource);
|
||||
parms.m_commandButton = commandButton;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiDoCommandButtonAtPosition( const CommandButton *commandButton, const Coord3D *pos, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_COMMANDBUTTON_POS, cmdSource);
|
||||
parms.m_pos = *pos;
|
||||
parms.m_commandButton = commandButton;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiDoCommandButtonAtObject( const CommandButton *commandButton, Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_COMMANDBUTTON_OBJ, cmdSource);
|
||||
parms.m_obj = obj;
|
||||
parms.m_commandButton = commandButton;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiMoveAwayFromUnit( Object *obj, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_MOVE_AWAY_FROM_UNIT, cmdSource);
|
||||
parms.m_obj = obj;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiWander( const Waypoint *way, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_WANDER, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiWanderInPlace(CommandSourceType cmdSource)
|
||||
{
|
||||
AICommandParms parms(AICMD_WANDER_IN_PLACE, cmdSource);
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
inline void aiPanic( const Waypoint *way, CommandSourceType cmdSource )
|
||||
{
|
||||
AICommandParms parms(AICMD_PANIC, cmdSource);
|
||||
parms.m_waypoint = way;
|
||||
aiDoCommand(&parms);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* An "AIGroup" is a simple collection of AI objects, used by the AI
|
||||
* for such things as Group Pathfinding.
|
||||
*/
|
||||
class AIGroup : public MemoryPoolObject, public Snapshot
|
||||
{
|
||||
private:
|
||||
void groupAttackObjectPrivate( Bool forced, Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
|
||||
|
||||
public:
|
||||
|
||||
// --------------- inherited from Snapshot interface --------------
|
||||
void crc( Xfer *xfer );
|
||||
void xfer( Xfer *xfer );
|
||||
void loadPostProcess( void );
|
||||
|
||||
void groupMoveToPosition( const Coord3D *pos, Bool addWaypoint, CommandSourceType cmdSource );
|
||||
void groupMoveToAndEvacuate( const Coord3D *pos, CommandSourceType cmdSource ); ///< move to given position(s)
|
||||
void groupMoveToAndEvacuateAndExit( const Coord3D *pos, CommandSourceType cmdSource ); ///< move to given position & unload transport.
|
||||
void groupIdle(CommandSourceType cmdSource); ///< Enter idle state.
|
||||
void groupScatter(CommandSourceType cmdSource); ///< Enter idle state.
|
||||
void groupCreateFormation(CommandSourceType cmdSource); ///< Make the current selection a user formation.
|
||||
void groupTightenToPosition( const Coord3D *pos, Bool addWaypoint, CommandSourceType cmdSource ); ///< move to given position(s)
|
||||
void groupFollowWaypointPath( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
void groupFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
void groupFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
void groupFollowWaypointPathAsTeamExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
void groupFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource );///< follow the path defined by the given array of points
|
||||
void groupAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
groupAttackObjectPrivate(false, victim, maxShotsToFire, cmdSource);
|
||||
}
|
||||
void groupForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource )
|
||||
{
|
||||
groupAttackObjectPrivate(true, victim, maxShotsToFire, cmdSource);
|
||||
}
|
||||
void groupAttackTeam( const Team *team, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack the given team
|
||||
void groupAttackPosition( const Coord3D *pos, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given spot
|
||||
void groupAttackMoveToPosition( const Coord3D *pos, Int maxShotsToFire, CommandSourceType cmdSource ); ///< Attack move to the location
|
||||
void groupHunt( CommandSourceType cmdSource ); ///< begin "seek and destroy"
|
||||
void groupRepair( Object *obj, CommandSourceType cmdSource ); ///< repair the given object
|
||||
void groupResumeConstruction( Object *obj, CommandSourceType cmdSource ); ///< resume construction on the object
|
||||
void groupGetHealed( Object *healDepot, CommandSourceType cmdSource ); ///< go get healed at the heal depot
|
||||
void groupGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< go get repaired at the repair depot
|
||||
void groupEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object
|
||||
void groupDock( Object *obj, CommandSourceType cmdSource ); ///< get near given object and wait for enter clearance
|
||||
void groupExit( Object *objectToExit, CommandSourceType cmdSource ); ///< get out of this Object
|
||||
void groupEvacuate( CommandSourceType cmdSource ); ///< empty its contents
|
||||
void groupExecuteRailedTransport( CommandSourceType cmdSource ); ///< execute railed transport events
|
||||
void groupGoProne( const DamageInfo *damageInfo, CommandSourceType cmdSource ); ///< life altering state change, if this AI can do it
|
||||
void groupGuardPosition( const Coord3D *pos, GuardMode guardMode, CommandSourceType cmdSource ); ///< guard the given spot
|
||||
void groupGuardObject( Object *objToGuard, GuardMode guardMode, CommandSourceType cmdSource ); ///< guard an object
|
||||
void groupGuardArea( const PolygonTrigger *areaToGuard, GuardMode guardMode, CommandSourceType cmdSource ); ///< guard an area
|
||||
void groupAttackArea( const PolygonTrigger *areaToGuard, CommandSourceType cmdSource ); ///< guard an area
|
||||
void groupHackInternet( CommandSourceType cmdSource ); ///< Begin hacking the internet for free cash from the heavens.
|
||||
void groupDoSpecialPower( UnsignedInt specialPowerID, UnsignedInt commandOptions );
|
||||
void groupDoSpecialPowerAtObject( UnsignedInt specialPowerID, Object *object, UnsignedInt commandOptions );
|
||||
void groupDoSpecialPowerAtLocation( UnsignedInt specialPowerID, const Coord3D *location, const Object *object, UnsignedInt commandOptions );
|
||||
#ifdef ALLOW_SURRENDER
|
||||
void groupSurrender( const Object *objWeSurrenderedTo, Bool surrender, CommandSourceType cmdSource );
|
||||
#endif
|
||||
void groupCheer( CommandSourceType cmdSource );
|
||||
void groupSell( CommandSourceType cmdSource );
|
||||
void groupToggleOvercharge( CommandSourceType cmdSource );
|
||||
#ifdef ALLOW_SURRENDER
|
||||
void groupPickUpPrisoner( Object *prisoner, CommandSourceType cmdSource ); ///< pick up prisoner
|
||||
void groupReturnToPrison( Object *prison, CommandSourceType cmdSource ); ///< return to prison
|
||||
#endif
|
||||
void groupCombatDrop( Object *target, const Coord3D& pos, CommandSourceType cmdSource );
|
||||
void groupDoCommandButton( const CommandButton *commandButton, CommandSourceType cmdSource );
|
||||
void groupDoCommandButtonAtPosition( const CommandButton *commandButton, const Coord3D *pos, CommandSourceType cmdSource );
|
||||
void groupDoCommandButtonAtObject( const CommandButton *commandButton, Object *obj, CommandSourceType cmdSource );
|
||||
void groupSetEmoticon( const AsciiString &name, Int duration );
|
||||
void groupOverrideSpecialPowerDestination( SpecialPowerType spType, const Coord3D *loc, CommandSourceType cmdSource );
|
||||
|
||||
void setAttitude( AttitudeType tude ); ///< set the behavior modifier for this agent
|
||||
AttitudeType getAttitude( void ) const; ///< get the current behavior modifier state
|
||||
|
||||
Bool isIdle() const;
|
||||
//Definition of busy -- when explicitly in the busy state. Moving or attacking is not considered busy!
|
||||
Bool isBusy() const;
|
||||
Bool isGroupAiDead() const;
|
||||
|
||||
// Returns an object that can perform the special power. Useful for making queries on the Action Manager
|
||||
Object *getSpecialPowerSourceObject( UnsignedInt specialPowerID );
|
||||
|
||||
// Returns an object that has a command button for the GUI command type.
|
||||
Object *getCommandButtonSourceObject( GUICommandType type );
|
||||
|
||||
// Group methods --------------------------------------------------------------------------------
|
||||
Bool isMember( Object *obj ); ///< return true if object is in this group
|
||||
|
||||
Real getSpeed( void ); ///< return the speed of the group's slowest member
|
||||
Bool getCenter( Coord3D *center ); ///< compute centroid of group
|
||||
Bool getMinMaxAndCenter( Coord2D *min, Coord2D *max, Coord3D *center );
|
||||
void computeIndividualDestination( Coord3D *dest, const Coord3D *groupDest,
|
||||
Object *obj, const Coord3D *center, Bool isFormation ); ///< compute destination of individual object, based on group destination
|
||||
Int getCount( void ); ///< return the number of objects in the group
|
||||
Bool isEmpty( void ); ///< returns true if the group has no members
|
||||
void queueUpgrade( const UpgradeTemplate *upgrade ); ///< queue an upgrade
|
||||
|
||||
void add( Object *obj ); ///< add object to group
|
||||
|
||||
// returns true if remove destroyed the group for us.
|
||||
Bool remove( Object *obj);
|
||||
|
||||
// If the group contains any objects not owned by ownerPlayer, return TRUE.
|
||||
Bool containsAnyObjectsNotOwnedByPlayer( const Player *ownerPlayer );
|
||||
|
||||
// Remove any objects that aren't owned by the player, and return true if the group was destroyed due to emptiness
|
||||
Bool removeAnyObjectsNotOwnedByPlayer( const Player *ownerPlayer );
|
||||
|
||||
UnsignedInt getID( void );
|
||||
|
||||
///< get IDs for every object in this group
|
||||
const VecObjectID& getAllIDs ( void ) const;
|
||||
|
||||
void recomputeGroupSpeed() { m_dirty = true; }
|
||||
|
||||
void setMineClearingDetail( Bool set );
|
||||
Bool setWeaponLockForGroup( WeaponSlotType weaponSlot, WeaponLockType lockType ); ///< Set the groups' weapon choice.
|
||||
void releaseWeaponLockForGroup(WeaponLockType lockType);///< Clear each guys weapon choice
|
||||
void setWeaponSetFlag( WeaponSetType wst );
|
||||
|
||||
protected:
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AIGroup, "AIGroupPool" ); ///< @todo Set real numbers for mem alloc
|
||||
|
||||
ListObjectPtrIt internalRemove(ListObjectPtrIt iterToRemove);
|
||||
|
||||
Bool friend_moveInfantryToPos( const Coord3D *pos, CommandSourceType cmdSource );
|
||||
Bool friend_moveVehicleToPos( const Coord3D *pos, CommandSourceType cmdSource );
|
||||
void friend_moveFormationToPos( const Coord3D *pos, CommandSourceType cmdSource );
|
||||
Bool friend_computeGroundPath( const Coord3D *pos, CommandSourceType cmdSource );
|
||||
|
||||
private:
|
||||
// AIGroups must be created through TheAI->createGroup()
|
||||
friend class AI;
|
||||
AIGroup( void );
|
||||
|
||||
void recompute( void ); ///< recompute various group info, such as speed, leader, etc
|
||||
|
||||
ListObjectPtr m_memberList; ///< the list of member Objects
|
||||
UnsignedInt m_memberListSize; ///< the size of the list of member Objects
|
||||
|
||||
Real m_speed; ///< maximum speed of group (slowest member)
|
||||
Bool m_dirty; ///< "dirty bit" - if true then group speed, leader, needs recompute
|
||||
|
||||
UnsignedInt m_id; ///< the unique ID of this group
|
||||
Path *m_groundPath; ///< Group ground path.
|
||||
|
||||
mutable VecObjectID m_lastRequestedIDList; ///< this is used so we can return by reference, saving a copy
|
||||
};
|
||||
|
||||
|
||||
#endif // _AI_H_
|
||||
208
Generals/Code/GameEngine/Include/GameLogic/AIDock.h
Normal file
208
Generals/Code/GameEngine/Include/GameLogic/AIDock.h
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AIDock.h
|
||||
// Docking behavior
|
||||
// Author: Michael S. Booth, February 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _AI_DOCK_H_
|
||||
#define _AI_DOCK_H_
|
||||
|
||||
#include "Common/GameMemory.h"
|
||||
#include "GameLogic/AIStateMachine.h"
|
||||
|
||||
/**
|
||||
* The states of the Docking state machine.
|
||||
*/
|
||||
enum
|
||||
{
|
||||
AI_DOCK_APPROACH, ///< given a queue pos, move to it
|
||||
AI_DOCK_WAIT_FOR_CLEARANCE, ///< wait for dock to give us enter clearance
|
||||
AI_DOCK_ADVANCE_POSITION, ///< Advance in approach position as line moves forward
|
||||
AI_DOCK_MOVE_TO_ENTRY, ///< move to the dock entrance
|
||||
AI_DOCK_MOVE_TO_DOCK, ///< move to the actual dock position
|
||||
AI_DOCK_PROCESS_DOCK, ///< invoke the dock's action until it is done
|
||||
AI_DOCK_MOVE_TO_EXIT, ///< move to the dock exit, can exit the dock machine
|
||||
AI_DOCK_MOVE_TO_RALLY ///< Move to rally if desired, exit the dock machine no matter what
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The docking state machine.
|
||||
*/
|
||||
class AIDockMachine : public StateMachine
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AIDockMachine, "AIDockMachinePool" );
|
||||
|
||||
public:
|
||||
/**
|
||||
* The implementation of this constructor defines the states
|
||||
* used by this machine.
|
||||
*/
|
||||
AIDockMachine( Object *owner );
|
||||
|
||||
static Bool ableToAdvance( State *thisState, void* userData ); // Condition for scooting forward in line while waiting
|
||||
virtual void halt(void); ///< Stops the state machine & disables it in preparation for deleting it.
|
||||
|
||||
Int m_approachPosition; ///< The Approach Position I am holding, to make scoot forward checks quicker.
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
};
|
||||
|
||||
// Please do not use these states in some other machine. I know that wouldn't even make sense, but they
|
||||
// cast their getMachine to an AIDock machine to store stuff across states so you'd crash.
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockApproachState : public AIInternalMoveToState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockApproachState, "AIDockApproachState")
|
||||
public:
|
||||
AIDockApproachState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIDockApproachState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
virtual StateReturnType update( void );
|
||||
protected:
|
||||
// snapshot interface STUBBED.
|
||||
virtual void crc( Xfer *xfer ){};
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess(){};
|
||||
};
|
||||
EMPTY_DTOR(AIDockApproachState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockWaitForClearanceState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockWaitForClearanceState, "AIDockWaitForClearanceState")
|
||||
public:
|
||||
AIDockWaitForClearanceState( StateMachine *machine ) : State( machine, "AIDockWaitForClearanceState" ), m_enterFrame(0) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
UnsignedInt m_enterFrame;
|
||||
protected:
|
||||
// snapshot interface STUBBED.
|
||||
virtual void crc( Xfer *xfer ){};
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess(){};
|
||||
};
|
||||
EMPTY_DTOR(AIDockWaitForClearanceState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockAdvancePositionState : public AIInternalMoveToState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockAdvancePositionState, "AIDockAdvancePositionState")
|
||||
public:
|
||||
AIDockAdvancePositionState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIDockApproachState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
virtual StateReturnType update( void );
|
||||
};
|
||||
EMPTY_DTOR(AIDockAdvancePositionState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockMoveToEntryState : public AIInternalMoveToState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockMoveToEntryState, "AIDockMoveToEntryState")
|
||||
public:
|
||||
AIDockMoveToEntryState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIDockMoveToEntryState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
virtual StateReturnType update( void );
|
||||
};
|
||||
EMPTY_DTOR(AIDockMoveToEntryState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockMoveToDockState : public AIInternalMoveToState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockMoveToDockState, "AIDockMoveToDockState")
|
||||
public:
|
||||
AIDockMoveToDockState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIDockMoveToDockState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
virtual StateReturnType update( void );
|
||||
};
|
||||
EMPTY_DTOR(AIDockMoveToDockState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockMoveToRallyState : public AIInternalMoveToState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockMoveToRallyState, "AIDockMoveToRallyState")
|
||||
public:
|
||||
AIDockMoveToRallyState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIDockMoveToRallyState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
virtual StateReturnType update( void );
|
||||
};
|
||||
EMPTY_DTOR(AIDockMoveToRallyState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockProcessDockState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockProcessDockState, "AIDockProcessDockState")
|
||||
public:
|
||||
AIDockProcessDockState( StateMachine *machine );
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
virtual StateReturnType update( void );
|
||||
|
||||
void setNextDockActionFrame();//This puts a delay between callings of Action to tweak the speed of docking.
|
||||
UnsignedInt m_nextDockActionFrame;// In the unlikely event of saving a game in the middle of docking, you may
|
||||
// complete a Action a few frames sooner than you would have: It does not need to be saved.
|
||||
Object* findMyDrone();
|
||||
|
||||
protected:
|
||||
// snapshot interface STUBBED.
|
||||
virtual void crc( Xfer *xfer ){};
|
||||
virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
|
||||
virtual void loadPostProcess(){};
|
||||
|
||||
private:
|
||||
ObjectID m_droneID; ///< If I have a drone, the drone will get repaired too.
|
||||
|
||||
};
|
||||
EMPTY_DTOR(AIDockProcessDockState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
class AIDockMoveToExitState : public AIInternalMoveToState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIDockMoveToExitState, "AIDockMoveToExitState")
|
||||
public:
|
||||
AIDockMoveToExitState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIDockMoveToExitState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
virtual StateReturnType update( void );
|
||||
};
|
||||
EMPTY_DTOR(AIDockMoveToExitState)
|
||||
|
||||
//-----------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
#endif // _AI_DOCK_H_
|
||||
268
Generals/Code/GameEngine/Include/GameLogic/AIGuard.h
Normal file
268
Generals/Code/GameEngine/Include/GameLogic/AIGuard.h
Normal file
@@ -0,0 +1,268 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: AIGuard.h
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* EA Pacific */
|
||||
/* Confidential Information */
|
||||
/* Copyright (C) 2001 - All Rights Reserved */
|
||||
/* DO NOT DISTRIBUTE */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Project: RTS3 */
|
||||
/* File name: AIGuard.h */
|
||||
/* Created: John K. McDonald, Jr., 3/29/2002 */
|
||||
/* Desc: // Define Guard states for AI */
|
||||
/* Revision History: */
|
||||
/* 3/29/2002 : Initial creation */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _H_AIGUARD_
|
||||
#define _H_AIGUARD_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////
|
||||
#include "Common/GameMemory.h"
|
||||
#include "GameLogic/AIStateMachine.h"
|
||||
#include "GameLogic/GameLogic.h"
|
||||
#include "GameLogic/Object.h"
|
||||
#include "GameLogic/AI.h"
|
||||
|
||||
// DEFINES ////////////////////////////////////////////////////////////////////
|
||||
// TYPE DEFINES ///////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
// prevent collisions with other states that we might use, (namely AI_IDLE)
|
||||
AI_GUARD_INNER = 5000, ///< Attack anything within this area till death
|
||||
AI_GUARD_IDLE, ///< Wait till something shows up to attack.
|
||||
AI_GUARD_OUTER, ///< Attack anything within this area that has been aggressive, until the timer expires
|
||||
AI_GUARD_RETURN, ///< Restore to a position within the inner circle
|
||||
AI_GUARD_GET_CRATE, ///< Pick up a crate from an enemy we killed.
|
||||
AI_GUARD_ATTACK_AGGRESSOR, ///< Attack something that attacked me (that I can attack)
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class ExitConditions : public AttackExitConditionsInterface
|
||||
{
|
||||
public:
|
||||
|
||||
enum ExitConditionsEnum
|
||||
{
|
||||
ATTACK_ExitIfOutsideRadius = 0x01,
|
||||
ATTACK_ExitIfExpiredDuration = 0x02,
|
||||
ATTACK_ExitIfNoUnitFound = 0x04
|
||||
};
|
||||
|
||||
Int m_conditionsToConsider;
|
||||
Coord3D m_center; // can be updated at any time by owner
|
||||
Real m_radiusSqr; // can be updated at any time by owner
|
||||
UnsignedInt m_attackGiveUpFrame; // frame at which we give up (if using)
|
||||
|
||||
ExitConditions() : m_attackGiveUpFrame(0), m_conditionsToConsider(0), m_radiusSqr(0.0f)
|
||||
{
|
||||
//Added By Sadullah Nader
|
||||
// Initializations missing and needed
|
||||
m_center.zero();
|
||||
}
|
||||
|
||||
virtual Bool shouldExit(const StateMachine* machine) const;
|
||||
};
|
||||
|
||||
|
||||
// FORWARD DECLARATIONS ///////////////////////////////////////////////////////
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AIGuardMachine : public StateMachine
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AIGuardMachine, "AIGuardMachinePool" );
|
||||
|
||||
private:
|
||||
ObjectID m_targetToGuard;
|
||||
const PolygonTrigger * m_areaToGuard;
|
||||
Coord3D m_positionToGuard;
|
||||
ObjectID m_nemesisToAttack;
|
||||
GuardMode m_guardMode;
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
public:
|
||||
/**
|
||||
* The implementation of this constructor defines the states
|
||||
* used by this machine.
|
||||
*/
|
||||
AIGuardMachine( Object *owner );
|
||||
Object* findTargetToGuardByID( void ) { return TheGameLogic->findObjectByID(m_targetToGuard); }
|
||||
void setTargetToGuard( const Object *object ) { m_targetToGuard = object ? object->getID() : INVALID_ID; }
|
||||
|
||||
const Coord3D *getPositionToGuard( void ) const { return &m_positionToGuard; }
|
||||
void setTargetPositionToGuard( const Coord3D *pos) { m_positionToGuard = *pos; }
|
||||
|
||||
const PolygonTrigger *getAreaToGuard( void ) const { return m_areaToGuard; }
|
||||
void setAreaToGuard( const PolygonTrigger *area) { m_areaToGuard = area; }
|
||||
|
||||
void setNemesisID(ObjectID id) { m_nemesisToAttack = id; }
|
||||
ObjectID getNemesisID() const { return m_nemesisToAttack; }
|
||||
|
||||
GuardMode getGuardMode() const { return m_guardMode; }
|
||||
void setGuardMode(GuardMode guardMode) { m_guardMode = guardMode; }
|
||||
|
||||
Bool lookForInnerTarget(void);
|
||||
|
||||
static Real getStdGuardRange(const Object* obj);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AIGuardInnerState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIGuardInnerState, "AIGuardInnerState")
|
||||
public:
|
||||
AIGuardInnerState( StateMachine *machine ) : State( machine, "AIGuardInner" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AIGuardMachine* getGuardMachine() { return (AIGuardMachine*)getMachine(); }
|
||||
|
||||
ExitConditions m_exitConditions;
|
||||
AIAttackState *m_attackState;
|
||||
};
|
||||
EMPTY_DTOR(AIGuardInnerState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AIGuardIdleState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIGuardIdleState, "AIGuardIdleState")
|
||||
public:
|
||||
AIGuardIdleState( StateMachine *machine ) : State( machine, "AIGuardIdleState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AIGuardMachine* getGuardMachine() { return (AIGuardMachine*)getMachine(); }
|
||||
|
||||
UnsignedInt m_nextEnemyScanTime;
|
||||
Coord3D m_guardeePos; ///< Where the object we are guarding was last.
|
||||
};
|
||||
EMPTY_DTOR(AIGuardIdleState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AIGuardOuterState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIGuardOuterState, "AIGuardOuterState")
|
||||
public:
|
||||
AIGuardOuterState( StateMachine *machine ) : State( machine, "AIGuardOuter" )
|
||||
{
|
||||
m_attackState = NULL;
|
||||
}
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AIGuardMachine* getGuardMachine() { return (AIGuardMachine*)getMachine(); }
|
||||
|
||||
ExitConditions m_exitConditions;
|
||||
AIAttackState *m_attackState;
|
||||
};
|
||||
EMPTY_DTOR(AIGuardOuterState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AIGuardReturnState : public AIInternalMoveToState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIGuardReturnState, "AIGuardReturnState")
|
||||
private:
|
||||
AIGuardMachine* getGuardMachine() { return (AIGuardMachine*)getMachine(); }
|
||||
public:
|
||||
AIGuardReturnState( StateMachine *machine ) : AIInternalMoveToState( machine, "AIGuardReturn" )
|
||||
{
|
||||
m_nextReturnScanTime = 0;
|
||||
}
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
UnsignedInt m_nextReturnScanTime;
|
||||
};
|
||||
EMPTY_DTOR(AIGuardReturnState)
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AIGuardPickUpCrateState : public AIPickUpCrateState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIGuardPickUpCrateState, "AIGuardPickUpCrateState")
|
||||
public:
|
||||
AIGuardPickUpCrateState( StateMachine *machine );
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
};
|
||||
EMPTY_DTOR(AIGuardPickUpCrateState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AIGuardAttackAggressorState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AIGuardAttackAggressorState, "AIGuardAttackAggressorState")
|
||||
public:
|
||||
AIGuardAttackAggressorState( StateMachine *machine );
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AIGuardMachine* getGuardMachine() { return (AIGuardMachine*)getMachine(); }
|
||||
ExitConditions m_exitConditions;
|
||||
AIAttackState *m_attackState;
|
||||
};
|
||||
|
||||
EMPTY_DTOR(AIGuardAttackAggressorState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#endif /* _H_AIGUARD_ */
|
||||
973
Generals/Code/GameEngine/Include/GameLogic/AIPathfind.h
Normal file
973
Generals/Code/GameEngine/Include/GameLogic/AIPathfind.h
Normal file
@@ -0,0 +1,973 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AIPathfind.h
|
||||
// AI pathfinding system
|
||||
// Author: Michael S. Booth, October 2001
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _PATHFIND_H_
|
||||
#define _PATHFIND_H_
|
||||
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/GameMemory.h"
|
||||
#include "Common/Snapshot.h"
|
||||
//#include "GameLogic/Locomotor.h" // no, do not include this, unless you like long recompiles
|
||||
#include "GameLogic/LocomotorSet.h"
|
||||
|
||||
class Bridge;
|
||||
class Object;
|
||||
class Weapon;
|
||||
class PathfindZoneManager;
|
||||
|
||||
// How close is close enough when moving.
|
||||
|
||||
#define PATHFIND_CLOSE_ENOUGH 1.0f
|
||||
#define PATH_MAX_PRIORITY 0x7FFFFFFF
|
||||
|
||||
#define INFANTRY_MOVES_THROUGH_INFANTRY
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* PathNodes are used to create a final Path to return from the
|
||||
* pathfinder. Note that these are not used during the A* search.
|
||||
*/
|
||||
class PathNode : public MemoryPoolObject
|
||||
{
|
||||
public:
|
||||
PathNode();
|
||||
|
||||
Coord3D *getPosition( void ) { return &m_pos; } ///< return position of this node
|
||||
const Coord3D *getPosition( void ) const { return &m_pos; } ///< return position of this node
|
||||
void setPosition( const Coord3D *pos ) { m_pos = *pos; } ///< set the position of this path node
|
||||
|
||||
const Coord3D *computeDirectionVector( void ); ///< compute direction to next node
|
||||
|
||||
PathNode *getNext( void ) { return m_next; } ///< return next node in the path
|
||||
PathNode *getPrevious( void ) { return m_prev; } ///< return previous node in the path
|
||||
const PathNode *getNext( void ) const { return m_next; } ///< return next node in the path
|
||||
const PathNode *getPrevious( void ) const { return m_prev; } ///< return previous node in the path
|
||||
|
||||
PathfindLayerEnum getLayer( void ) const { return m_layer; } ///< return layer of this node.
|
||||
void setLayer( PathfindLayerEnum layer ) { m_layer = layer; } ///< set the layer of this path node
|
||||
|
||||
void setNextOptimized( PathNode *node );
|
||||
|
||||
PathNode *getNextOptimized(Coord2D* dir = NULL, Real* dist = NULL) ///< return next node in optimized path
|
||||
{
|
||||
if (dir)
|
||||
*dir = m_nextOptiDirNorm2D;
|
||||
if (dist)
|
||||
*dist = m_nextOptiDist2D;
|
||||
return m_nextOpti;
|
||||
}
|
||||
|
||||
const PathNode *getNextOptimized(Coord2D* dir = NULL, Real* dist = NULL) const ///< return next node in optimized path
|
||||
{
|
||||
if (dir)
|
||||
*dir = m_nextOptiDirNorm2D;
|
||||
if (dist)
|
||||
*dist = m_nextOptiDist2D;
|
||||
return m_nextOpti;
|
||||
}
|
||||
|
||||
void setCanOptimize(Bool canOpt) { m_canOptimize = canOpt;}
|
||||
Bool getCanOptimize( void ) const { return m_canOptimize;}
|
||||
|
||||
/// given a list, prepend this node, return new list
|
||||
PathNode *prependToList( PathNode *list );
|
||||
|
||||
/// given a list, append this node, return new list. slow implementation.
|
||||
/// @todo optimize this
|
||||
PathNode *appendToList( PathNode *list );
|
||||
|
||||
/// given a node, append to this node
|
||||
void append( PathNode *list );
|
||||
|
||||
public:
|
||||
mutable Int m_id; // Used in Path::xfer() to save & recreate the path list.
|
||||
|
||||
private:
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( PathNode, "PathNodePool" ); ///< @todo Set real numbers for mem alloc
|
||||
|
||||
PathNode* m_nextOpti; ///< next node in the optimized path
|
||||
PathNode* m_next; ///< next node in the path
|
||||
PathNode* m_prev; ///< previous node in the path
|
||||
Coord3D m_pos; ///< position of node in space
|
||||
PathfindLayerEnum m_layer; ///< Layer for this section.
|
||||
Bool m_canOptimize; ///< True if this cell can be optimized out.
|
||||
|
||||
Real m_nextOptiDist2D; ///< if nextOpti is nonnull, the dist to it.
|
||||
Coord2D m_nextOptiDirNorm2D; ///< if nextOpti is nonnull, normalized dir vec towards it.
|
||||
|
||||
};
|
||||
|
||||
// this doesn't actually seem to be a particularly useful win,
|
||||
// performance-wise, so I didn't enable it. (srj)
|
||||
#define NO_CPOP_STARTS_FROM_PREV_SEG
|
||||
|
||||
struct ClosestPointOnPathInfo
|
||||
{
|
||||
Real distAlongPath;
|
||||
Coord3D posOnPath;
|
||||
PathfindLayerEnum layer;
|
||||
};
|
||||
|
||||
/**
|
||||
* This class encapsulates a "path" returned by the Pathfinder.
|
||||
*/
|
||||
class Path : public MemoryPoolObject, public Snapshot
|
||||
{
|
||||
public:
|
||||
Path();
|
||||
|
||||
PathNode *getFirstNode( void ) { return m_path; }
|
||||
PathNode *getLastNode( void ) { return m_pathTail; }
|
||||
|
||||
void updateLastNode( const Coord3D *pos );
|
||||
|
||||
void prependNode( const Coord3D *pos, PathfindLayerEnum layer ); ///< Create a new node at the head of the path
|
||||
void appendNode( const Coord3D *pos, PathfindLayerEnum layer ); ///< Create a new node at the end of the path
|
||||
void setBlockedByAlly(Bool blocked) {m_blockedByAlly = blocked;}
|
||||
Bool getBlockedByAlly(void) {return m_blockedByAlly;}
|
||||
void optimize( const Object *obj, LocomotorSurfaceTypeMask acceptableSurfaces, Bool blocked ); ///< Optimize the path to discard redundant nodes
|
||||
|
||||
void optimizeGroundPath( Bool crusher, Int diameter ); ///< Optimize the ground path to discard redundant nodes
|
||||
|
||||
/// Given a location, return nearest location on path, and along-path dist to end as function result
|
||||
void computePointOnPath( const Object *obj, const LocomotorSet& locomotorSet, const Coord3D& pos, ClosestPointOnPathInfo& out);
|
||||
|
||||
/// Given a location, return nearest location on path, and along-path dist to end as function result
|
||||
void peekCachedPointOnPath( Coord3D& pos ) const {pos = m_cpopOut.posOnPath;}
|
||||
|
||||
/// Given a flight path, compute the distance to goal (0 if we are past it) & return the goal pos.
|
||||
Real computeFlightDistToGoal( const Coord3D *pos, Coord3D& goalPos );
|
||||
|
||||
/// Given a location, return closest location on path, and along-path dist to end as function result
|
||||
void markOptimized(void) {m_isOptimized = true;}
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
protected:
|
||||
enum {MAX_CPOP=20}; ///< Max times we will return the cached cpop.
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( Path, "PathPool" ); ///< @todo Set real numbers for mem alloc
|
||||
|
||||
PathNode* m_path; ///< The list of PathNode objects that define the path
|
||||
PathNode* m_pathTail;
|
||||
Bool m_isOptimized; ///< True if the path has been optimized
|
||||
Bool m_blockedByAlly; ///< An ally needs to move off of this path.
|
||||
// caching info for computePointOnPath.
|
||||
Bool m_cpopValid;
|
||||
Int m_cpopCountdown; ///< We only return the same cpop MAX_CPOP times. It is occasionally possible to get stuck.
|
||||
Coord3D m_cpopIn;
|
||||
ClosestPointOnPathInfo m_cpopOut;
|
||||
const PathNode* m_cpopRecentStart;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------------------------
|
||||
|
||||
// See GameType.h for
|
||||
// enum {LAYER_INVALID = 0, LAYER_GROUND = 1, LAYER_TOP=2 };
|
||||
|
||||
// Fits in 4 bits for now
|
||||
enum {MAX_WALL_PIECES = 128};
|
||||
|
||||
class PathfindCellInfo
|
||||
{
|
||||
friend class PathfindCell;
|
||||
public:
|
||||
static void allocateCellInfos(void);
|
||||
static void releaseCellInfos(void);
|
||||
|
||||
static PathfindCellInfo * getACellInfo(PathfindCell *cell, const ICoord2D &pos);
|
||||
static void releaseACellInfo(PathfindCellInfo *theInfo);
|
||||
|
||||
protected:
|
||||
static PathfindCellInfo *s_infoArray;
|
||||
static PathfindCellInfo *s_firstFree; ///<
|
||||
|
||||
|
||||
PathfindCellInfo *m_nextOpen, *m_prevOpen; ///< for A* "open" list, shared by closed list
|
||||
|
||||
PathfindCellInfo *m_pathParent; ///< "parent" cell from pathfinder
|
||||
PathfindCell *m_cell; ///< Cell this info belongs to currently.
|
||||
|
||||
UnsignedShort m_totalCost, m_costSoFar; ///< cost estimates for A* search
|
||||
|
||||
/// have to include cell's coordinates, since cells are often accessed via pointer only
|
||||
ICoord2D m_pos;
|
||||
|
||||
ObjectID m_goalUnitID; ///< The objectID of the ground unit whose goal this is.
|
||||
ObjectID m_posUnitID; ///< The objectID of the ground unit that is occupying this cell.
|
||||
ObjectID m_goalAircraftID; ///< The objectID of the aircraft whose goal this is.
|
||||
|
||||
ObjectID m_obstacleID; ///< the object ID who overlaps this cell
|
||||
|
||||
UnsignedInt m_isFree:1;
|
||||
UnsignedInt m_blockedByAlly:1;///< True if this cell is blocked by an allied unit.
|
||||
UnsignedInt m_obstacleIsFence:1;///< True if occupied by a fence.
|
||||
UnsignedInt m_obstacleIsTransparent:1;///< True if obstacle is transparent (undefined if obstacleid is invalid)
|
||||
/// @todo Do we need both mark values in this cell? Can't store a single value and compare it?
|
||||
UnsignedInt m_open:1; ///< place for marking this cell as on the open list
|
||||
UnsignedInt m_closed:1; ///< place for marking this cell as on the closed list
|
||||
};
|
||||
|
||||
/**
|
||||
* This represents one cell in the pathfinding grid.
|
||||
* These cells categorize the world into idealized cellular states,
|
||||
* and are also used for efficient A* pathfinding.
|
||||
* @todo Optimize memory usage of pathfind grid.
|
||||
*/
|
||||
class PathfindCell
|
||||
{
|
||||
public:
|
||||
|
||||
enum CellType
|
||||
{
|
||||
CELL_CLEAR = 0x00, ///< clear, unobstructed ground
|
||||
CELL_WATER = 0x01, ///< water area
|
||||
CELL_CLIFF = 0x02, ///< steep altitude change
|
||||
CELL_RUBBLE = 0x03, ///< Cell is occupied by rubble.
|
||||
CELL_OBSTACLE = 0x04, ///< impassable area
|
||||
CELL_unused = 0x08, ///< Unused.
|
||||
CELL_IMPASSABLE = 0x0B ///< Just plain impassable except for aircraft.
|
||||
};
|
||||
|
||||
enum CellFlags
|
||||
{
|
||||
NO_UNITS = 0x00, ///< No units in this cell.
|
||||
UNIT_GOAL = 0x01, ///< A unit is heading to this cell.
|
||||
UNIT_PRESENT_MOVING = 0x02, ///< A unit is moving through this cell.
|
||||
UNIT_PRESENT_FIXED = 0x03, ///< A unit is stationary in this cell.
|
||||
UNIT_GOAL_OTHER_MOVING = 0x05 ///< A unit is moving through this cell, and another unit has this as it's goal.
|
||||
};
|
||||
|
||||
/// reset the cell
|
||||
void reset( );
|
||||
|
||||
PathfindCell(void);
|
||||
~PathfindCell(void);
|
||||
|
||||
void setTypeAsObstacle( Object *obstacle, Bool isFence, const ICoord2D &pos ); ///< flag this cell as an obstacle, from the given one
|
||||
void removeObstacle( Object *obstacle ); ///< flag this cell as an obstacle, from the given one
|
||||
void setType( CellType type ); ///< set the cell type
|
||||
CellType getType( void ) const { return (CellType)m_type; } ///< get the cell type
|
||||
CellFlags getFlags( void ) const { return (CellFlags)m_flags; } ///< get the cell type
|
||||
Bool isAircraftGoal( void) const {return m_aircraftGoal != 0;}
|
||||
|
||||
Bool isObstaclePresent( ObjectID objID ) const; ///< return true if the given object ID is registered as an obstacle in this cell
|
||||
|
||||
Bool isObstacleTransparent( ) const{return m_info?m_info->m_obstacleIsTransparent:false; } ///< return true if the obstacle in the cell is KINDOF_CAN_SEE_THROUGHT_STRUCTURE
|
||||
|
||||
Bool isObstacleFence( void ) const {return m_info?m_info->m_obstacleIsFence:false; }///< return true if the given obstacle in the cell is a fence.
|
||||
|
||||
/// Return estimated cost from given cell to reach goal cell
|
||||
UnsignedInt costToGoal( PathfindCell *goal );
|
||||
|
||||
UnsignedInt costToHierGoal( PathfindCell *goal );
|
||||
|
||||
UnsignedInt costSoFar( PathfindCell *parent );
|
||||
|
||||
/// put self on "open" list in ascending cost order, return new list
|
||||
PathfindCell *putOnSortedOpenList( PathfindCell *list );
|
||||
|
||||
/// remove self from "open" list
|
||||
PathfindCell *removeFromOpenList( PathfindCell *list );
|
||||
|
||||
/// put self on "closed" list, return new list
|
||||
PathfindCell *putOnClosedList( PathfindCell *list );
|
||||
|
||||
/// remove self from "closed" list
|
||||
PathfindCell *removeFromClosedList( PathfindCell *list );
|
||||
|
||||
/// remove all cells from closed list.
|
||||
static Int releaseClosedList( PathfindCell *list );
|
||||
|
||||
/// remove all cells from closed list.
|
||||
static Int releaseOpenList( PathfindCell *list );
|
||||
|
||||
inline PathfindCell *getNextOpen(void) {return m_info->m_nextOpen?m_info->m_nextOpen->m_cell:NULL;}
|
||||
|
||||
inline UnsignedShort getXIndex(void) const {return m_info->m_pos.x;}
|
||||
inline UnsignedShort getYIndex(void) const {return m_info->m_pos.y;}
|
||||
|
||||
inline Bool isBlockedByAlly(void) const {return m_info->m_blockedByAlly;}
|
||||
inline void setBlockedByAlly(Bool blocked) {m_info->m_blockedByAlly = (blocked!=0);}
|
||||
|
||||
inline Bool getOpen(void) const {return m_info->m_open;}
|
||||
inline Bool getClosed(void) const {return m_info->m_closed;}
|
||||
inline UnsignedInt getCostSoFar(void) const {return m_info->m_costSoFar;}
|
||||
inline UnsignedInt getTotalCost(void) const {return m_info->m_totalCost;}
|
||||
|
||||
inline void setCostSoFar(UnsignedInt cost) {m_info->m_costSoFar = cost;}
|
||||
inline void setTotalCost(UnsignedInt cost) {m_info->m_totalCost = cost;}
|
||||
|
||||
void setParentCell(PathfindCell* parent);
|
||||
void clearParentCell(void);
|
||||
void setParentCellHierarchical(PathfindCell* parent);
|
||||
inline PathfindCell* getParentCell(void) const {return m_info->m_pathParent?m_info->m_pathParent->m_cell:NULL;}
|
||||
|
||||
Bool startPathfind( PathfindCell *goalCell );
|
||||
Bool getPinched(void) const {return m_pinched;}
|
||||
void setPinched(Bool pinch) {m_pinched = pinch; }
|
||||
|
||||
Bool allocateInfo(const ICoord2D &pos);
|
||||
void releaseInfo(void);
|
||||
Bool hasInfo(void) const {return m_info!=NULL;}
|
||||
UnsignedShort getZone(void) const {return m_zone;}
|
||||
void setZone(UnsignedShort zone) {m_zone = zone;}
|
||||
void setGoalUnit(ObjectID unit, const ICoord2D &pos );
|
||||
void setGoalAircraft(ObjectID unit, const ICoord2D &pos );
|
||||
void setPosUnit(ObjectID unit, const ICoord2D &pos );
|
||||
inline ObjectID getGoalUnit(void) const {ObjectID id = m_info?m_info->m_goalUnitID:INVALID_ID; return id;}
|
||||
inline ObjectID getGoalAircraft(void) const {ObjectID id = m_info?m_info->m_goalAircraftID:INVALID_ID; return id;}
|
||||
inline ObjectID getPosUnit(void) const {ObjectID id = m_info?m_info->m_posUnitID:INVALID_ID; return id;}
|
||||
|
||||
inline ObjectID getObstacleID(void) const {ObjectID id = m_info?m_info->m_obstacleID:INVALID_ID; return id;}
|
||||
|
||||
void setLayer( PathfindLayerEnum layer ) { m_layer = layer; } ///< set the cell layer
|
||||
PathfindLayerEnum getLayer( void ) const { return (PathfindLayerEnum)m_layer; } ///< get the cell layer
|
||||
|
||||
void setConnectLayer( PathfindLayerEnum layer ) { m_connectsToLayer = layer; } ///< set the cell layer connect id
|
||||
PathfindLayerEnum getConnectLayer( void ) const { return (PathfindLayerEnum)m_connectsToLayer; } ///< get the cell layer connect id
|
||||
|
||||
private:
|
||||
PathfindCellInfo *m_info;
|
||||
UnsignedShort m_zone:14; ///< Zone. Each zone is a set of adjacent terrain type. If from & to in the same zone, you can successfully pathfind. If not,
|
||||
// you still may be able to if you can cross multiple terrain types.
|
||||
UnsignedShort m_aircraftGoal:1; //< This is an aircraft goal cell.
|
||||
UnsignedShort m_pinched:1; //< This cell is surrounded by obstacle cells.
|
||||
UnsignedByte m_type:4; ///< what type of cell terrain this is.
|
||||
UnsignedByte m_flags:4; ///< what type of units are in or moving through this cell.
|
||||
UnsignedByte m_connectsToLayer:4; ///< This cell can pathfind onto this layer, if > LAYER_TOP.
|
||||
UnsignedByte m_layer:4; ///< Layer of this cell.
|
||||
};
|
||||
|
||||
typedef PathfindCell *PathfindCellP;
|
||||
|
||||
|
||||
// how close a unit has to be in z to interact with the layer.
|
||||
#define LAYER_Z_CLOSE_ENOUGH_F 10.0f
|
||||
/**
|
||||
* This class represents a bridge in the map. This is effectively
|
||||
* a sub-rectangle of the big pathfind map.
|
||||
*/
|
||||
class PathfindLayer
|
||||
{
|
||||
public:
|
||||
PathfindLayer();
|
||||
~PathfindLayer();
|
||||
public:
|
||||
void reset(void);
|
||||
Bool init(Bridge *theBridge, PathfindLayerEnum layer);
|
||||
void allocateCells(const IRegion2D *extent);
|
||||
void allocateCellsForWallLayer(const IRegion2D *extent, ObjectID *wallPieces, Int numPieces);
|
||||
void classifyCells();
|
||||
void classifyWallCells(ObjectID *wallPieces, Int numPieces);
|
||||
Bool setDestroyed(Bool destroyed);
|
||||
Bool isUnused(void); // True if it doesn't contain a bridge.
|
||||
Bool isDestroyed(void) {return m_destroyed;} // True if it has been destroyed.
|
||||
PathfindCell *getCell(Int x, Int y);
|
||||
Int getZone(void) {return m_zone;}
|
||||
void setZone(Int zone) {m_zone = zone;}
|
||||
void applyZone(void); // Propagates m_zone to all cells.
|
||||
void getStartCellIndex(ICoord2D *start) {*start = m_startCell;}
|
||||
void getEndCellIndex(ICoord2D *end) {*end = m_endCell;}
|
||||
|
||||
ObjectID getBridgeID(void);
|
||||
Bool connectsZones(PathfindZoneManager *zm, const LocomotorSet& locomotorSet,Int zone1, Int zone2);
|
||||
Bool isPointOnWall(ObjectID *wallPieces, Int numPieces, const Coord3D *pt);
|
||||
|
||||
#if defined _DEBUG || defined _INTERNAL
|
||||
void doDebugIcons(void) ;
|
||||
#endif
|
||||
protected:
|
||||
void classifyLayerMapCell( Int i, Int j , PathfindCell *cell, Bridge *theBridge);
|
||||
void classifyWallMapCell( Int i, Int j, PathfindCell *cell , ObjectID *wallPieces, Int numPieces);
|
||||
|
||||
private:
|
||||
PathfindCell *m_blockOfMapCells; ///< Pathfinding map - contains iconic representation of the map
|
||||
PathfindCell **m_layerCells; ///< Pathfinding map indexes - contains matrix indexing into the map.
|
||||
Int m_width; // Number of cells in x
|
||||
Int m_height; // Number of cells in y
|
||||
Int m_xOrigin; // Index of first cell in x
|
||||
Int m_yOrigin; // Index of first cell in y
|
||||
ICoord2D m_startCell; // pathfind cell indexes for center cell on the from side.
|
||||
ICoord2D m_endCell; // pathfind cell indexes for center cell on the to side.
|
||||
|
||||
PathfindLayerEnum m_layer;
|
||||
Int m_zone; // Whole bridge is in same zone.
|
||||
Bridge *m_bridge; // Corresponding bridge in TerrainLogic.
|
||||
Bool m_destroyed;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#define PATHFIND_CELL_SIZE 10
|
||||
#define PATHFIND_CELL_SIZE_F 10.0f
|
||||
|
||||
enum { PATHFIND_QUEUE_LEN=512};
|
||||
|
||||
struct TCheckMovementInfo;
|
||||
|
||||
/**
|
||||
* This class is a helper class for zone manager. It maintains information regarding the
|
||||
* LocomotorSurfaceTypeMask equivalencies within a ZONE_BLOCK_SIZE x ZONE_BLOCK_SIZE area of
|
||||
* cells. This is used in hierarchical pathfinding to find the best coarse path at the
|
||||
* block level.
|
||||
*/
|
||||
class ZoneBlock
|
||||
{
|
||||
public:
|
||||
ZoneBlock();
|
||||
~ZoneBlock(); // not virtual, please don't override without making virtual. jba.
|
||||
|
||||
void blockCalculateZones( PathfindCell **map, PathfindLayer layers[], const IRegion2D &bounds); ///< Does zone calculations.
|
||||
UnsignedShort getEffectiveZone(LocomotorSurfaceTypeMask acceptableSurfaces, Bool crusher, UnsignedShort zone) const;
|
||||
|
||||
void clearMarkedPassable(void) {m_markedPassable = false;}
|
||||
Bool isPassable(void) {return m_markedPassable;}
|
||||
void setPassable(Bool pass) {m_markedPassable = pass;}
|
||||
|
||||
Bool getInteractsWithBridge(void) const {return m_interactsWithBridge;}
|
||||
void setInteractsWithBridge(Bool interacts) {m_interactsWithBridge = interacts;}
|
||||
|
||||
protected:
|
||||
void allocateZones(void);
|
||||
void freeZones(void);
|
||||
|
||||
protected:
|
||||
ICoord2D m_cellOrigin;
|
||||
|
||||
UnsignedShort m_firstZone; // First zone in this block.
|
||||
UnsignedShort m_numZones; // Number of zones in this block. If == 1, there is only one zone, and
|
||||
// no zone equivalency arrays will be allocated.
|
||||
|
||||
UnsignedShort m_zonesAllocated;
|
||||
UnsignedShort *m_groundCliffZones;
|
||||
UnsignedShort *m_groundWaterZones;
|
||||
UnsignedShort *m_groundRubbleZones;
|
||||
UnsignedShort *m_crusherZones;
|
||||
Bool m_interactsWithBridge;
|
||||
Bool m_markedPassable;
|
||||
};
|
||||
typedef ZoneBlock *ZoneBlockP;
|
||||
|
||||
/**
|
||||
* This class manages the zones in the map. A zone is an area in the map that
|
||||
* is one contiguous type of terrain (clear, cliff, water, building). If
|
||||
* a unit is in a zone, and wants to move to another location, the destination
|
||||
* zone has to be the same, or it can't get there.
|
||||
* There are equivalency tables for meta-zones. For example, an amphibious craft can
|
||||
* travel through water and clear cells.
|
||||
*/
|
||||
class PathfindZoneManager
|
||||
{
|
||||
public:
|
||||
enum {INITIAL_ZONES = 256};
|
||||
enum {ZONE_BLOCK_SIZE = 10}; // Zones are calculated in blocks of 20x20. This way, the raw zone numbers can be used to
|
||||
// compute hierarchically between the 20x20 blocks of cells. jba.
|
||||
PathfindZoneManager();
|
||||
~PathfindZoneManager();
|
||||
|
||||
void reset(void);
|
||||
|
||||
Bool needToCalculateZones(void) const {return m_needToCalculateZones;} ///< Returns true if the zones need to be recalculated.
|
||||
void markZonesDirty(void) ; ///< Called when the zones need to be recalculated.
|
||||
void calculateZones( PathfindCell **map, PathfindLayer layers[], const IRegion2D &bounds); ///< Does zone calculations.
|
||||
UnsignedShort getEffectiveZone(LocomotorSurfaceTypeMask acceptableSurfaces, Bool crusher, UnsignedShort zone) const;
|
||||
UnsignedShort getEffectiveTerrainZone(UnsignedShort zone) const;
|
||||
|
||||
void getExtent(ICoord2D &extent) const {extent = m_zoneBlockExtent;}
|
||||
|
||||
/// return zone relative the the block zone that this cell resides in.
|
||||
UnsignedShort getBlockZone(LocomotorSurfaceTypeMask acceptableSurfaces, Bool crusher, Int cellX, Int cellY, PathfindCell **map) const;
|
||||
void allocateBlocks(const IRegion2D &globalBounds);
|
||||
|
||||
void clearPassableFlags(void);
|
||||
Bool isPassable(Int cellX, Int cellY) const;
|
||||
Bool clipIsPassable(Int cellX, Int cellY) const;
|
||||
void setPassable(Int cellX, Int cellY, Bool passable);
|
||||
|
||||
void setAllPassable(void);
|
||||
|
||||
void setBridge(Int cellX, Int cellY, Bool bridge);
|
||||
Bool interactsWithBridge(Int cellX, Int cellY) const;
|
||||
|
||||
protected:
|
||||
void allocateZones(void);
|
||||
void freeZones(void);
|
||||
void freeBlocks(void);
|
||||
|
||||
protected:
|
||||
ZoneBlock *m_blockOfZoneBlocks; ///< Zone blocks - Info for hierarchical pathfinding at a "blocky" level.
|
||||
ZoneBlock **m_zoneBlocks; ///< Zone blocks as a matrix - contains matrix indexing into the map.
|
||||
ICoord2D m_zoneBlockExtent; ///< Zone block extents. Not the same scale as the pathfind extents.
|
||||
|
||||
UnsignedShort m_maxZone; ///< Max zone used.
|
||||
Bool m_needToCalculateZones; ///< True if terrain has changed.
|
||||
UnsignedShort m_zonesAllocated;
|
||||
UnsignedShort *m_groundCliffZones;
|
||||
UnsignedShort *m_groundWaterZones;
|
||||
UnsignedShort *m_groundRubbleZones;
|
||||
UnsignedShort *m_terrainZones;
|
||||
UnsignedShort *m_crusherZones;
|
||||
UnsignedShort *m_hierarchicalZones;
|
||||
};
|
||||
|
||||
/**
|
||||
* The pathfinding services interface provides access to the 3 expensive path find calls:
|
||||
* findPath, findClosestPath, and findAttackPath.
|
||||
* It is only available to units when their ai interface doPathfind method is called.
|
||||
* This allows the pathfinder to spread out the pathfinding over a number of frames
|
||||
* when a lot of units are trying to pathfind all at the same time.
|
||||
*/
|
||||
class PathfindServicesInterface {
|
||||
public:
|
||||
virtual Path *findPath( Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from,
|
||||
const Coord3D *to )=0; ///< Find a short, valid path between given locations
|
||||
/** Find a short, valid path to a location NEAR the to location.
|
||||
This succeds when the destination is unreachable (like inside a building).
|
||||
If the destination is unreachable, it will adjust the to point. */
|
||||
virtual Path *findClosestPath( Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from,
|
||||
Coord3D *to, Bool blocked, Real pathCostMultiplier, Bool moveAllies )=0;
|
||||
|
||||
/** Find a short, valid path to a location that obj can attack victim from. */
|
||||
virtual Path *findAttackPath( const Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from,
|
||||
const Object *victim, const Coord3D* victimPos, const Weapon *weapon )=0;
|
||||
|
||||
/** Patch to the exiting path from the current position, either because we became blocked,
|
||||
or because we had to move off the path to avoid other units. */
|
||||
virtual Path *patchPath( const Object *obj, const LocomotorSet& locomotorSet,
|
||||
Path *originalPath, Bool blocked ) = 0;
|
||||
|
||||
/** Find a short, valid path to a location that is away from the repulsors. */
|
||||
virtual Path *findSafePath( const Object *obj, const LocomotorSet& locomotorSet,
|
||||
const Coord3D *from, const Coord3D* repulsorPos1, const Coord3D* repulsorPos2, Real repulsorRadius ) = 0;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* The Pathfinding engine itself.
|
||||
*/
|
||||
class Pathfinder : PathfindServicesInterface, public Snapshot
|
||||
{
|
||||
// The following routines are private, but available through the doPathfind callback to aiInterface. jba.
|
||||
private:
|
||||
virtual Path *findPath( Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to); ///< Find a short, valid path between given locations
|
||||
/** Find a short, valid path to a location NEAR the to location.
|
||||
This succeds when the destination is unreachable (like inside a building).
|
||||
If the destination is unreachable, it will adjust the to point. */
|
||||
virtual Path *findClosestPath( Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from,
|
||||
Coord3D *to, Bool blocked, Real pathCostMultiplier, Bool moveAllies );
|
||||
|
||||
/** Find a short, valid path to a location that obj can attack victim from. */
|
||||
virtual Path *findAttackPath( const Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from,
|
||||
const Object *victim, const Coord3D* victimPos, const Weapon *weapon );
|
||||
|
||||
/** Find a short, valid path to a location that is away from the repulsors. */
|
||||
virtual Path *findSafePath( const Object *obj, const LocomotorSet& locomotorSet,
|
||||
const Coord3D *from, const Coord3D* repulsorPos1, const Coord3D* repulsorPos2, Real repulsorRadius );
|
||||
|
||||
/** Patch to the exiting path from the current position, either because we became blocked,
|
||||
or because we had to move off the path to avoid other units. */
|
||||
virtual Path *patchPath( const Object *obj, const LocomotorSet& locomotorSet,
|
||||
Path *originalPath, Bool blocked );
|
||||
|
||||
public:
|
||||
Pathfinder( void );
|
||||
~Pathfinder() ;
|
||||
|
||||
void reset( void ); ///< Reset system in preparation for new map
|
||||
|
||||
// --------------- inherited from Snapshot interface --------------
|
||||
void crc( Xfer *xfer );
|
||||
void xfer( Xfer *xfer );
|
||||
void loadPostProcess( void );
|
||||
|
||||
Bool quickDoesPathExist( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain & buildings check - fast)
|
||||
Bool slowDoesPathExist( Object *obj, const Coord3D *from,
|
||||
const Coord3D *to, ObjectID ignoreObject=INVALID_ID ); ///< Can we build any path at all between the locations (terrain, buildings & units check - slower)
|
||||
|
||||
Bool queueForPath(ObjectID id); ///< The object wants to request a pathfind, so put it on the list to process.
|
||||
void processPathfindQueue(void); ///< Process some or all of the queued pathfinds.
|
||||
void forceMapRecalculation( ); ///< Force pathfind map recomputation. If region is given, only that area is recomputed
|
||||
|
||||
/** Returns an aircraft path to the goal. */
|
||||
Path *getAircraftPath( const Object *obj, const Coord3D *to);
|
||||
Path *findGroundPath( const Coord3D *from, const Coord3D *to, Int pathRadius,
|
||||
Bool crusher); ///< Find a short, valid path of the desired width on the ground.
|
||||
|
||||
void addObjectToPathfindMap( class Object *obj ); ///< Classify the given object's cells in the map
|
||||
void removeObjectFromPathfindMap( class Object *obj ); ///< De-classify the given object's cells in the map
|
||||
|
||||
void removeUnitFromPathfindMap( Object *obj ); ///< De-classify the given mobile unit's cells in the map
|
||||
void updateGoal( Object *obj, const Coord3D *newGoalPos, PathfindLayerEnum layer); ///< Update the given mobile unit's cells in the map
|
||||
void updateAircraftGoal( Object *obj, const Coord3D *newGoalPos); ///< Update the given aircraft unit's cells in the map
|
||||
void removeGoal( Object *obj); ///< Removes the given mobile unit's goal cells in the map
|
||||
void updatePos( Object *obj, const Coord3D *newPos); ///< Update the given mobile unit's cells in the map
|
||||
void removePos( Object *obj); ///< Removes the unit's position cells from the map
|
||||
|
||||
Bool moveAllies(Object *obj, Path *path);
|
||||
|
||||
// NOTE - The object MUST NOT MOVE between the call to createAWall... and removeWall...
|
||||
// or BAD THINGS will happen. jba.
|
||||
void createAWallFromMyFootprint( Object *obj ) {internal_classifyObjectFootprint(obj, true);} // Temporarily treat this object as an obstacle.
|
||||
void removeWallFromMyFootprint( Object *obj ){internal_classifyObjectFootprint(obj, false);} // Undo createAWallFromMyFootprint.
|
||||
|
||||
Path *getMoveAwayFromPath(Object *obj, Object *otherObj, Path *pathToAvoid, Object *otherObj2, Path *pathToAvoid2);
|
||||
|
||||
void changeBridgeState( PathfindLayerEnum layer, Bool repaired );
|
||||
|
||||
Bool findBrokenBridge(const LocomotorSet &locomotorSet, const Coord3D *from, const Coord3D *to, ObjectID *bridgeID);
|
||||
|
||||
void newMap(void);
|
||||
|
||||
PathfindCell *getCell( PathfindLayerEnum layer, Int x, Int y ); ///< Return the cell at grid coords (x,y)
|
||||
PathfindCell *getCell( PathfindLayerEnum layer, const Coord3D *pos ); ///< Given a position, return associated grid cell
|
||||
PathfindCell *getClippedCell( PathfindLayerEnum layer, const Coord3D *pos ); ///< Given a position, return associated grid cell
|
||||
void clip(Coord3D *from, Coord3D *to);
|
||||
Bool worldToCell( const Coord3D *pos, ICoord2D *cell ); ///< Given a world position, return grid cell coordinate
|
||||
|
||||
const ICoord2D *getExtent(void) const {return &m_extent.hi;}
|
||||
|
||||
void setIgnoreObstacleID( ObjectID objID ); ///< if non-zero, the pathfinder will ignore the given obstacle
|
||||
|
||||
Bool validMovementPosition( Bool isCrusher, LocomotorSurfaceTypeMask acceptableSurfaces, PathfindCell *toCell, PathfindCell *fromCell = NULL ); ///< Return true if given position is a valid movement location
|
||||
Bool validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Int x, Int y ); ///< Return true if given position is a valid movement location
|
||||
Bool validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, const Coord3D *pos ); ///< Return true if given position is a valid movement location
|
||||
Bool validMovementTerrain( PathfindLayerEnum layer, const Locomotor* locomotor, const Coord3D *pos ); ///< Return true if given position is a valid movement location
|
||||
|
||||
Locomotor* chooseBestLocomotorForPosition(PathfindLayerEnum layer, LocomotorSet* locomotorSet, const Coord3D* pos );
|
||||
|
||||
Bool isViewBlockedByObstacle(const Object* obj, const Object* objOther); ///< Return true if the straight line between the given points contains any obstacle, and thus blocks vision
|
||||
|
||||
Bool isAttackViewBlockedByObstacle(const Object* obj, const Coord3D& attackerPos, const Object* victim, const Coord3D& victimPos); ///< Return true if the straight line between the given points contains any obstacle, and thus blocks vision
|
||||
|
||||
Bool isLinePassable( const Object *obj, LocomotorSurfaceTypeMask acceptableSurfaces,
|
||||
PathfindLayerEnum layer, const Coord3D& startWorld, const Coord3D& endWorld,
|
||||
Bool blocked, Bool allowPinched ); ///< Return true if the straight line between the given points is passable
|
||||
|
||||
void moveAlliesAwayFromDestination( Object *obj,const Coord3D& destination);
|
||||
|
||||
Bool isGroundPathPassable( Bool isCrusher, const Coord3D& startWorld, PathfindLayerEnum startLayer,
|
||||
const Coord3D& endWorld, Int pathDiameter); ///< Return true if the straight line between the given points is passable
|
||||
|
||||
// for debugging
|
||||
const Coord3D *getDebugPathPosition( void );
|
||||
void setDebugPathPosition( const Coord3D *pos );
|
||||
Path *getDebugPath( void );
|
||||
void setDebugPath( Path *debugpath );
|
||||
|
||||
void cleanOpenAndClosedLists(void);
|
||||
|
||||
// Adjusts the destination to a spot near dest that is not occupied by other units.
|
||||
Bool adjustDestination(Object *obj, const LocomotorSet& locomotorSet,
|
||||
Coord3D *dest, const Coord3D *groupDest=NULL);
|
||||
|
||||
// Adjusts the destination to a spot near dest for landing that is not occupied by other units.
|
||||
Bool adjustToLandingDestination(Object *obj, Coord3D *dest);
|
||||
|
||||
// Adjusts the destination to a spot that can attack target that is not occupied by other units.
|
||||
Bool adjustTargetDestination(const Object *obj, const Object *target, const Coord3D *targetPos,
|
||||
const Weapon *weapon, Coord3D *dest);
|
||||
|
||||
// Adjusts destination to a spot near dest that is possible to path to.
|
||||
Bool adjustToPossibleDestination(Object *obj, const LocomotorSet& locomotorSet, Coord3D *dest);
|
||||
|
||||
void snapPosition(Object *obj, Coord3D *pos); // Snaps the current position to it's grid location.
|
||||
void snapClosestGoalPosition(Object *obj, Coord3D *pos); // Snaps the current position to a good goal position.
|
||||
Bool goalPosition(Object *obj, Coord3D *pos); // Returns the goal position on the grid.
|
||||
|
||||
PathfindLayerEnum addBridge(Bridge *theBridge); // Adds a bridge layer, and returns the layer id.
|
||||
|
||||
void addWallPiece(Object *wallPiece); // Adds a wall piece.
|
||||
void removeWallPiece(Object *wallPiece); // Removes a wall piece.
|
||||
Real getWallHeight(void) {return m_wallHeight;}
|
||||
Bool isPointOnWall(const Coord3D *pos);
|
||||
|
||||
void updateLayer(Object *obj, PathfindLayerEnum layer); ///< Updates object's layer.
|
||||
|
||||
static void classifyMapCell( Int x, Int y, PathfindCell *cell); ///< Classify the given map cell
|
||||
Int clearCellForDiameter( Bool crusher, Int cellX, Int cellY, PathfindLayerEnum layer, Int pathDiameter ); ///< Return true if given position is a valid movement location
|
||||
|
||||
protected:
|
||||
virtual Path *internalFindPath( Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to); ///< Find a short, valid path between given locations
|
||||
Path *findHierarchicalPath( Bool isHuman, const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to, Bool crusher);
|
||||
Path *findClosestHierarchicalPath( Bool isHuman, const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to, Bool crusher);
|
||||
Path *internal_findHierarchicalPath( Bool isHuman, const LocomotorSurfaceTypeMask locomotorSurface, const Coord3D *from, const Coord3D *to, Bool crusher, Bool closestOK);
|
||||
void processHierarchicalCell( const ICoord2D &scanCell, const ICoord2D &deltaPathfindCell,
|
||||
PathfindCell *parentCell,
|
||||
PathfindCell *goalCell, UnsignedShort parentZone,
|
||||
UnsignedShort *examinedZones, Int &numExZones,
|
||||
Bool crusher, Int &cellCount);
|
||||
Bool checkForAdjust(Object *, const LocomotorSet& locomotorSet, Bool isHuman, Int cellX, Int cellY,
|
||||
PathfindLayerEnum layer, Int iRadius, Bool center,Coord3D *dest, const Coord3D *groupDest) ;
|
||||
Bool checkForLanding(Int cellX, Int cellY,
|
||||
PathfindLayerEnum layer, Int iRadius, Bool center,Coord3D *dest) ;
|
||||
Bool checkForTarget(const Object *obj, Int cellX, Int cellY, const Weapon *weapon,
|
||||
const Object *victim, const Coord3D *victimPos,
|
||||
Int iRadius, Bool center,Coord3D *dest) ;
|
||||
Bool checkForPossible(Bool isCrusher, Int fromZone, Bool center, const LocomotorSet& locomotorSet,
|
||||
Int cellX, Int cellY, PathfindLayerEnum layer, Coord3D *dest, Bool startingInObstacle) ;
|
||||
void getRadiusAndCenter(const Object *obj, Int &iRadius, Bool ¢er);
|
||||
void adjustCoordToCell(Int cellX, Int cellY, Bool centerInCell, Coord3D &pos, PathfindLayerEnum layer);
|
||||
Bool checkDestination(const Object *obj, Int cellX, Int cellY, PathfindLayerEnum layer, Int iRadius, Bool centerInCell);
|
||||
Bool checkForMovement(const Object *obj, TCheckMovementInfo &info);
|
||||
Bool segmentIntersectsTallBuilding(const PathNode *curNode, PathNode *nextNode,
|
||||
ObjectID ignoreBuilding, Coord3D *insertPos1, Coord3D *insertPos2, Coord3D *insertPos3); ///< Return true if the straight line between the given points intersects a tall building.
|
||||
Bool circleClipsTallBuilding(const Coord3D *from, const Coord3D *to, Real radius, ObjectID ignoreBuilding, Coord3D *adjustTo); ///< Return true if the circle at the end of the line between the given points intersects a tall building.
|
||||
|
||||
enum {NO_ATTACK=0};
|
||||
Int examineNeighboringCells(PathfindCell *parentCell, PathfindCell *goalCell,
|
||||
const LocomotorSet& locomotorSet, Bool isHumanPlayer,
|
||||
Bool centerInCell, Int radius, const ICoord2D &startCellNdx,
|
||||
const Object *obj, Int attackDistance);
|
||||
|
||||
Bool pathDestination( Object *obj, const LocomotorSet& locomotorSet, Coord3D *dest,
|
||||
PathfindLayerEnum layer, const Coord3D *groupDest); ///< Checks cost between given locations
|
||||
|
||||
Int checkPathCost(Object *obj, const LocomotorSet& locomotorSet, const Coord3D *from,
|
||||
const Coord3D *to);
|
||||
|
||||
void tightenPath(Object *obj, const LocomotorSet& locomotorSet, Coord3D *from,
|
||||
const Coord3D *to);
|
||||
|
||||
/**
|
||||
return 0 to continue iterating the line, nonzero to terminate the iteration.
|
||||
the nonzero result will be returned as the result of iterateCellsAlongLine().
|
||||
iterateCellsAlongLine will return zero if it completes.
|
||||
*/
|
||||
typedef Int (*CellAlongLineProc)(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
Int iterateCellsAlongLine(const Coord3D& startWorld, const Coord3D& endWorld,
|
||||
PathfindLayerEnum layer, CellAlongLineProc proc, void* userData);
|
||||
|
||||
Int iterateCellsAlongLine(const ICoord2D &start, const ICoord2D &end,
|
||||
PathfindLayerEnum layer, CellAlongLineProc proc, void* userData);
|
||||
|
||||
static Int linePassableCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
static Int groundPathPassableCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
static Int lineBlockedByObstacleCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
static Int tightenPathCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
static Int attackBlockedByObstacleCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
static Int examineCellsCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
static Int groundCellsCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
static Int moveAlliesDestinationCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
|
||||
static Int segmentIntersectsBuildingCallback(Pathfinder* pathfinder, PathfindCell* from, PathfindCell* to, Int to_x, Int to_y, void* userData);
|
||||
|
||||
void classifyMap( void ); ///< Classify all cells in grid as obstacles, etc
|
||||
void classifyObjectFootprint( Object *obj, Bool insert ); /** Classify the cells under the given object
|
||||
If 'insert' is true, object is being added
|
||||
If 'insert' is false, object is being removed */
|
||||
void internal_classifyObjectFootprint( Object *obj, Bool insert ); /** Classify the cells under the given object
|
||||
If 'insert' is true, object is being added
|
||||
If 'insert' is false, object is being removed */
|
||||
void classifyFence( Object *obj, Bool insert ); /** Classify the cells under the given fence object. */
|
||||
void classifyUnitFootprint( Object *obj, Bool insert, Bool remove, Bool update ); /** Classify the cells under the given object If 'insert' is true, object is being added */
|
||||
/// Convert world coordinate to array index
|
||||
void worldToGrid( const Coord3D *pos, ICoord2D *cellIndex );
|
||||
|
||||
Bool evaluateCell(PathfindCell* newCell, PathfindCell *parentCell,
|
||||
const LocomotorSet& locomotorSet,
|
||||
Bool centerInCell, Int radius,
|
||||
const Object *obj, Int attackDistance);
|
||||
|
||||
Path *buildActualPath( const Object *obj, LocomotorSurfaceTypeMask acceptableSurfaces,
|
||||
const Coord3D *fromPos, PathfindCell *goalCell, Bool center, Bool blocked ); ///< Work backwards from goal cell to construct final path
|
||||
Path *buildGroundPath( Bool isCrusher,const Coord3D *fromPos, PathfindCell *goalCell,
|
||||
Bool center, Int pathDiameter ); ///< Work backwards from goal cell to construct final path
|
||||
Path *buildHierachicalPath( const Coord3D *fromPos, PathfindCell *goalCell); ///< Work backwards from goal cell to construct final path
|
||||
|
||||
void prependCells( Path *path, const Coord3D *fromPos,
|
||||
PathfindCell *goalCell, Bool center ); ///< Add pathfind cells to a path.
|
||||
|
||||
void debugShowSearch( Bool pathFound ); ///< Show all cells touched in the last search
|
||||
static LocomotorSurfaceTypeMask validLocomotorSurfacesForCellType(PathfindCell::CellType t);
|
||||
|
||||
void checkChangeLayers(PathfindCell *parentCell);
|
||||
|
||||
#if defined _DEBUG || defined _INTERNAL
|
||||
void doDebugIcons(void) ;
|
||||
#endif
|
||||
|
||||
private:
|
||||
/// This uses WAY too much memory. Should at least be array of pointers to cells w/ many fewer cells
|
||||
PathfindCell *m_blockOfMapCells; ///< Pathfinding map - contains iconic representation of the map
|
||||
PathfindCell **m_map; ///< Pathfinding map indexes - contains matrix indexing into the map.
|
||||
IRegion2D m_extent; ///< Grid extent limits
|
||||
IRegion2D m_logicalExtent; ///< Logical grid extent limits
|
||||
|
||||
PathfindCell *m_openList; ///< Cells ready to be explored
|
||||
PathfindCell *m_closedList; ///< Cells already explored
|
||||
|
||||
Bool m_isMapReady; ///< True if all cells of map have been classified
|
||||
Bool m_isTunneling; ///< True if path started in an obstacle
|
||||
|
||||
Int m_frameToShowObstacles; ///< Time to redraw obstacles. For debug output.
|
||||
|
||||
Coord3D debugPathPos; ///< Used for visual debugging
|
||||
Path *debugPath; ///< Used for visual debugging
|
||||
|
||||
ObjectID m_ignoreObstacleID; ///< Ignore the given obstacle
|
||||
|
||||
PathfindZoneManager m_zoneManager; ///< Handles the pathfind zones.
|
||||
|
||||
PathfindLayer m_layers[LAYER_LAST+1];
|
||||
|
||||
ObjectID m_wallPieces[MAX_WALL_PIECES];
|
||||
Int m_numWallPieces;
|
||||
Real m_wallHeight;
|
||||
|
||||
Int m_moveAlliesDepth;
|
||||
|
||||
|
||||
// Pathfind queue
|
||||
ObjectID m_queuedPathfindRequests[PATHFIND_QUEUE_LEN];
|
||||
Int m_queuePRHead;
|
||||
Int m_queuePRTail;
|
||||
Int m_cumulativeCellsAllocated;
|
||||
};
|
||||
|
||||
|
||||
inline void Pathfinder::setIgnoreObstacleID( ObjectID objID )
|
||||
{
|
||||
m_ignoreObstacleID = objID;
|
||||
}
|
||||
|
||||
inline void Pathfinder::worldToGrid( const Coord3D *pos, ICoord2D *cellIndex )
|
||||
{
|
||||
cellIndex->x = REAL_TO_INT(pos->x/PATHFIND_CELL_SIZE);
|
||||
cellIndex->y = REAL_TO_INT(pos->y/PATHFIND_CELL_SIZE);
|
||||
}
|
||||
|
||||
inline Bool Pathfinder::validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, Int x, Int y )
|
||||
{
|
||||
return validMovementPosition( isCrusher, locomotorSet.getValidSurfaces(), getCell( layer, x, y ) );
|
||||
}
|
||||
|
||||
inline Bool Pathfinder::validMovementPosition( Bool isCrusher, PathfindLayerEnum layer, const LocomotorSet& locomotorSet, const Coord3D *pos )
|
||||
{
|
||||
|
||||
Int x = REAL_TO_INT(pos->x/PATHFIND_CELL_SIZE);
|
||||
Int y = REAL_TO_INT(pos->y/PATHFIND_CELL_SIZE);
|
||||
|
||||
return validMovementPosition( isCrusher, layer, locomotorSet, x, y );
|
||||
}
|
||||
|
||||
inline const Coord3D *Pathfinder::getDebugPathPosition( void )
|
||||
{
|
||||
return &debugPathPos;
|
||||
}
|
||||
|
||||
inline void Pathfinder::setDebugPathPosition( const Coord3D *pos )
|
||||
{
|
||||
debugPathPos = *pos;
|
||||
}
|
||||
|
||||
inline Path *Pathfinder::getDebugPath( void )
|
||||
{
|
||||
return debugPath;
|
||||
}
|
||||
|
||||
inline void Pathfinder::addObjectToPathfindMap( class Object *obj )
|
||||
{
|
||||
classifyObjectFootprint( obj, true );
|
||||
}
|
||||
|
||||
inline void Pathfinder::removeObjectFromPathfindMap( class Object *obj )
|
||||
{
|
||||
classifyObjectFootprint( obj, false );
|
||||
}
|
||||
|
||||
inline PathfindCell *Pathfinder::getCell( PathfindLayerEnum layer, Int x, Int y )
|
||||
{
|
||||
if (x >= m_extent.lo.x && x <= m_extent.hi.x &&
|
||||
y >= m_extent.lo.y && y <= m_extent.hi.y)
|
||||
{
|
||||
PathfindCell *cell = NULL;
|
||||
if (layer > LAYER_GROUND && layer <= LAYER_LAST)
|
||||
{
|
||||
cell = m_layers[layer].getCell(x, y);
|
||||
if (cell)
|
||||
return cell;
|
||||
}
|
||||
return &m_map[x][y];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
inline PathfindCell *Pathfinder::getCell( PathfindLayerEnum layer, const Coord3D *pos )
|
||||
{
|
||||
ICoord2D cell;
|
||||
Bool overflow = worldToCell( pos, &cell );
|
||||
if (overflow) return NULL;
|
||||
return getCell( layer, cell.x, cell.y );
|
||||
}
|
||||
|
||||
inline PathfindCell *Pathfinder::getClippedCell( PathfindLayerEnum layer, const Coord3D *pos)
|
||||
{
|
||||
ICoord2D cell;
|
||||
worldToCell( pos, &cell );
|
||||
return getCell( layer, cell.x, cell.y );
|
||||
}
|
||||
|
||||
inline Bool Pathfinder::worldToCell( const Coord3D *pos, ICoord2D *cell )
|
||||
{
|
||||
cell->x = REAL_TO_INT_FLOOR(pos->x/PATHFIND_CELL_SIZE);
|
||||
cell->y = REAL_TO_INT_FLOOR(pos->y/PATHFIND_CELL_SIZE);
|
||||
Bool overflow = false;
|
||||
if (cell->x < m_extent.lo.x) {overflow = true; cell->x = m_extent.lo.x;}
|
||||
if (cell->y < m_extent.lo.y) {overflow = true; cell->y = m_extent.lo.y;}
|
||||
if (cell->x > m_extent.hi.x) {overflow = true; cell->x = m_extent.hi.x;}
|
||||
if (cell->y > m_extent.hi.y) {overflow = true; cell->y = m_extent.hi.y;}
|
||||
return overflow;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the given object ID is registered as an obstacle in this cell
|
||||
*/
|
||||
inline Bool PathfindCell::isObstaclePresent( ObjectID objID ) const
|
||||
{
|
||||
if (objID != INVALID_ID && (getType() == PathfindCell::CELL_OBSTACLE))
|
||||
{
|
||||
DEBUG_ASSERTCRASH(m_info, ("Should have info to be obstacle."));
|
||||
return (m_info && m_info->m_obstacleID == objID);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
#endif // _PATHFIND_H_
|
||||
303
Generals/Code/GameEngine/Include/GameLogic/AIPlayer.h
Normal file
303
Generals/Code/GameEngine/Include/GameLogic/AIPlayer.h
Normal file
@@ -0,0 +1,303 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AIPlayer.h
|
||||
// Computerized opponent
|
||||
// Author: Michael S. Booth, January 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _AI_PLAYER_H_
|
||||
#define _AI_PLAYER_H_
|
||||
|
||||
#include "Common/GameMemory.h"
|
||||
#include "Common/Snapshot.h"
|
||||
|
||||
enum { INVALID_SKILLSET_SELECTION = -1 };
|
||||
|
||||
class BuildListInfo;
|
||||
|
||||
/**
|
||||
* When a team is selected for training, a list of these
|
||||
* "work orders" are created, one for each member of the team.
|
||||
* This pairs team members with production buildings to keep
|
||||
* track of who is building what, and allows us to track if
|
||||
* a building was destroyed while in the process of training a unit.
|
||||
*/
|
||||
class WorkOrder : public MemoryPoolObject,
|
||||
public Snapshot
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( WorkOrder, "WorkOrder" )
|
||||
|
||||
public:
|
||||
|
||||
WorkOrder():m_thing(NULL), m_factoryID(INVALID_ID), m_isResourceGatherer(false), m_numCompleted(0), m_numRequired(1), m_next(NULL) {};
|
||||
|
||||
Bool isWaitingToBuild( void ); ///< return true if nothing is yet building this unit
|
||||
void validateFactory( Player *thisPlayer ); ///< verify factoryID still refers to an active object
|
||||
|
||||
public:
|
||||
|
||||
const ThingTemplate *m_thing; ///< thing to build
|
||||
ObjectID m_factoryID; ///< ID of object that is building this, or zero if no-one is
|
||||
WorkOrder *m_next;
|
||||
Int m_numCompleted; ///< Number built.
|
||||
Int m_numRequired; ///< Number needed.
|
||||
Bool m_required; ///< True if part of minimum requirement.
|
||||
Bool m_isResourceGatherer; ///< True if resource gatherer.
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
};
|
||||
|
||||
inline Bool WorkOrder::isWaitingToBuild( void )
|
||||
{
|
||||
if (m_factoryID!=INVALID_ID)
|
||||
return false;
|
||||
if (m_numCompleted >= m_numRequired)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class TeamInQueue : public MemoryPoolObject,
|
||||
public Snapshot
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( TeamInQueue, "TeamInQueue" )
|
||||
|
||||
private:
|
||||
|
||||
MAKE_DLINK(TeamInQueue, TeamBuildQueue) ///< the instances of our prototype
|
||||
MAKE_DLINK(TeamInQueue, TeamReadyQueue) ///< the instances of our prototype
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
public:
|
||||
|
||||
TeamInQueue() :
|
||||
m_workOrders(NULL),
|
||||
m_team(NULL),
|
||||
m_nextTeamInQueue(NULL),
|
||||
m_sentToStartLocation(false),
|
||||
m_reinforcement(false),
|
||||
m_stopQueueing(false),
|
||||
m_reinforcementID(INVALID_ID),
|
||||
//Added By Sadullah Nader
|
||||
//Initialization(s) inserted
|
||||
m_frameStarted(0),
|
||||
m_priorityBuild(FALSE)
|
||||
//
|
||||
{
|
||||
}
|
||||
|
||||
Bool isAllBuilt( void ); ///< Returns true if the team is finished building.
|
||||
Bool isBuildTimeExpired( void );///< Returns true if the team has run out of build time.
|
||||
Bool isMinimumBuilt( void ); ///< Returns true if the team has started building at least the minimum number of units.
|
||||
Bool includesADozer( void ); ///< Returns true if the team includes a dozer unit.
|
||||
Bool areBuildsComplete( void ); ///< Returns true if all units in factories have finished building.
|
||||
void disband( void ); ///< Disbands the team (moves units into the default team).
|
||||
void stopQueueing(void) {m_stopQueueing=true;} ///< Stops building new units, just finishes current.
|
||||
|
||||
public:
|
||||
|
||||
WorkOrder *m_workOrders; ///< list of work orders
|
||||
Bool m_priorityBuild; ///< True if the team is specifically requested.
|
||||
Team *m_team; ///< the team that units built by the m_workOrders go into
|
||||
TeamInQueue *m_nextTeamInQueue; ///< next
|
||||
Int m_frameStarted; ///< Frame we started building.
|
||||
Bool m_sentToStartLocation; ///< Has it been sent to it's start location?
|
||||
Bool m_stopQueueing; ///< True if we are to quit queueing units (usually because we ran out of build time.)
|
||||
Bool m_reinforcement; ///< True if it is a unit to reinforce an existing team.
|
||||
ObjectID m_reinforcementID; ///< True if it is a unit to reinforce an existing team.
|
||||
|
||||
};
|
||||
|
||||
|
||||
#if !defined(_PLAYTEST)
|
||||
|
||||
/**
|
||||
* The computer-controlled opponent.
|
||||
*/
|
||||
class AIPlayer : public MemoryPoolObject,
|
||||
public Snapshot
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AIPlayer, "AIPlayer" )
|
||||
|
||||
public:
|
||||
|
||||
AIPlayer( Player *p ); ///< constructor
|
||||
|
||||
virtual void computeSuperweaponTarget(const SpecialPowerTemplate *power, Coord3D *pos, Int playerNdx, Real weaponRadius); ///< Calculates best pos for weapon given radius.
|
||||
|
||||
public: // AIPlayer interface, may be overridden by AISkirmishPlayer. jba.
|
||||
|
||||
virtual void update(); ///< simulates the behavior of a player
|
||||
|
||||
virtual void newMap(); ///< New map loaded call.
|
||||
|
||||
/// Invoked when a unit I am training comes into existence
|
||||
virtual void onUnitProduced( Object *factory, Object *unit );
|
||||
|
||||
/// Invoked when a structure I am building comes into existence
|
||||
virtual void onStructureProduced( Object *factory, Object *structure );
|
||||
|
||||
virtual void buildSpecificAITeam(TeamPrototype *teamProto, Bool priorityBuild); ///< Builds this team immediately.
|
||||
|
||||
virtual void buildAIBaseDefense(Bool flank); ///< Builds base defense on front or flank of base.
|
||||
|
||||
virtual void buildAIBaseDefenseStructure(const AsciiString &thingName, Bool flank); ///< Builds base defense on front or flank of base.
|
||||
|
||||
virtual void buildSpecificAIBuilding(const AsciiString &thingName); ///< Builds this building as soon as possible.
|
||||
|
||||
|
||||
virtual void recruitSpecificAITeam(TeamPrototype *teamProto, Real recruitRadius); ///< Builds this team immediately.
|
||||
|
||||
virtual Bool isSkirmishAI(void) {return false;}
|
||||
virtual Player *getAiEnemy(void) {return NULL;} ///< Solo AI attacks based on scripting. Only skirmish auto-acquires an enemy at this point. jba.
|
||||
virtual Bool checkBridges(Object *unit, Waypoint *way) {return false;}
|
||||
virtual void repairStructure(ObjectID structure);
|
||||
|
||||
virtual void selectSkillset(Int skillset);
|
||||
|
||||
public:
|
||||
Bool getBaseCenter(Coord3D *pos) const {*pos = m_baseCenter; return m_baseCenterSet;}
|
||||
/// Difficulty level for this player.
|
||||
GameDifficulty getAIDifficulty(void) const;
|
||||
void setAIDifficulty(GameDifficulty difficulty) {m_difficulty = difficulty;}
|
||||
void buildBySupplies(Int minimumCash, const AsciiString &thingName ); ///< Builds a building by supplies.
|
||||
void buildUpgrade(const AsciiString &upgrade ); ///< Builds an upgrade.
|
||||
/// A team is about to be destroyed.
|
||||
void aiPreTeamDestroy( const Team *team );
|
||||
/// Is the nearest supply source safe?
|
||||
Bool isSupplySourceSafe( Int minSupplies );
|
||||
/// Is a supply source attacked?
|
||||
Bool isSupplySourceAttacked( void );
|
||||
|
||||
Bool isLocationSafe( const Coord3D *pos, const ThingTemplate *tthing);
|
||||
|
||||
/// Have the team guard a supply center.
|
||||
void guardSupplyCenter( Team *team, Int minSupplies );
|
||||
|
||||
void setTeamDelaySeconds(Int delay) {m_teamSeconds = delay;}
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
virtual void doBaseBuilding(void);
|
||||
virtual void checkReadyTeams(void);
|
||||
virtual void checkQueuedTeams(void);
|
||||
virtual void doTeamBuilding(void);
|
||||
virtual void doUpgradesAndSkills(void);
|
||||
virtual Object *findDozer(const Coord3D *pos);
|
||||
virtual void queueDozer(void);
|
||||
virtual Bool selectTeamToBuild( void ); ///< determine the next team to build
|
||||
virtual Bool selectTeamToReinforce( Int minPriority ); ///< determine the next team to reinforce
|
||||
virtual Bool startTraining( WorkOrder *order, Bool busyOK, AsciiString teamName); ///< find a production building that can handle the order, and start building
|
||||
virtual Bool isAGoodIdeaToBuildTeam( TeamPrototype *proto ); ///< return true if team should be built
|
||||
virtual void processBaseBuilding( void ); ///< do base-building behaviors
|
||||
virtual void processTeamBuilding( void ); ///< do team-building behaviors
|
||||
static Int getPlayerSuperweaponValue(Coord3D *center, Int playerNdx, Real radius);
|
||||
// End of aiplayer interface.
|
||||
|
||||
protected:
|
||||
|
||||
MAKE_DLINK_HEAD(TeamInQueue, TeamBuildQueue); ///< List of teams being build
|
||||
MAKE_DLINK_HEAD(TeamInQueue, TeamReadyQueue); ///< List of teams built, waiting to reach rally point.
|
||||
|
||||
protected:
|
||||
Bool isPossibleToBuildTeam( TeamPrototype *proto, Bool requireIdleFactory, Bool &needMoney ); ///< return true if team can be considered for building
|
||||
Object *buildStructureNow(const ThingTemplate *bldgPlan, BuildListInfo *info ); ///< Build a base buiding.
|
||||
Object *buildStructureWithDozer(const ThingTemplate *bldgPlan, BuildListInfo *info ); ///< Build a base buiding.
|
||||
void clearTeamsInQueue( void ); ///< Delete all teams in the build queue.
|
||||
void computeCenterAndRadiusOfBase(Coord3D *center, Real *radius);
|
||||
Object *findFactory(const ThingTemplate *thing, Bool busyOK); ///< Find a factory to build a unit. If force is true, may return a busy factory.
|
||||
void queueUnits( void ); ///< Check the team build list, & queue up units at any idle factories.
|
||||
void checkForSupplyCenter( BuildListInfo *info, Object *bldg);
|
||||
void queueSupplyTruck(void);
|
||||
void updateBridgeRepair(void);
|
||||
Bool dozerInQueue(void);
|
||||
Object *findSupplyCenter(Int minSupplies);
|
||||
static void getPlayerStructureBounds(Region2D *bounds, Int playerNdx);
|
||||
|
||||
protected:
|
||||
|
||||
Player *m_player; ///< the Player we represent
|
||||
|
||||
Bool m_readyToBuildTeam; ///< True if the team select timer has expired.
|
||||
Bool m_readyToBuildStructure; ///< True if the buildDelay timer has expired.
|
||||
Int m_teamTimer; ///< Counts out the time between teams, as specified by ini.
|
||||
Int m_structureTimer; ///< Counts out the time between structures, as specified by ini.
|
||||
Int m_teamSeconds; ///< How many seconds to delay between teams.
|
||||
|
||||
Int m_buildDelay; ///< Delay for building in case we are resource or prereq. limited.
|
||||
Int m_teamDelay; ///< Delay for teams in case we are resource or factory prereq. limited.
|
||||
|
||||
Int m_frameLastBuildingBuilt; ///< When we built the last building.
|
||||
|
||||
GameDifficulty m_difficulty;
|
||||
|
||||
Int m_skillsetSelector;
|
||||
|
||||
Coord3D m_baseCenter; // Center of the initial build list of structures.
|
||||
Bool m_baseCenterSet; // True if baseCenter is valid.
|
||||
Real m_baseRadius; // Radius of the initial build list of structures.
|
||||
|
||||
// Bridge repair info.
|
||||
enum {MAX_STRUCTURES_TO_REPAIR = 2};
|
||||
ObjectID m_structuresToRepair[MAX_STRUCTURES_TO_REPAIR];
|
||||
ObjectID m_repairDozer;
|
||||
Coord3D m_repairDozerOrigin;
|
||||
Int m_structuresInQueue;
|
||||
Bool m_dozerQueuedForRepair;
|
||||
Bool m_dozerIsRepairing; ///< the repair dozer is trying to repair the bridge.
|
||||
Int m_bridgeTimer;
|
||||
|
||||
UnsignedInt m_supplySourceAttackCheckFrame;
|
||||
ObjectID m_attackedSupplyCenter;
|
||||
|
||||
ObjectID m_curWarehouseID;
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif // _AI_PLAYER_H_
|
||||
|
||||
|
||||
|
||||
129
Generals/Code/GameEngine/Include/GameLogic/AISkirmishPlayer.h
Normal file
129
Generals/Code/GameEngine/Include/GameLogic/AISkirmishPlayer.h
Normal file
@@ -0,0 +1,129 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AISkirmishPlayer.h
|
||||
// Computerized opponent
|
||||
// Author: Michael S. Booth, January 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _AI_SKIRMISH_PLAYER_H_
|
||||
#define _AI_SKIRMISH_PLAYER_H_
|
||||
|
||||
#include "Common/GameMemory.h"
|
||||
#include "GameLogic/AIPlayer.h"
|
||||
|
||||
class BuildListInfo;
|
||||
class SpecialPowerTemplate;
|
||||
|
||||
|
||||
#if !defined(_PLAYTEST)
|
||||
|
||||
/**
|
||||
* The computer-controlled opponent.
|
||||
*/
|
||||
class AISkirmishPlayer : public AIPlayer
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AISkirmishPlayer, "AISkirmishPlayer" )
|
||||
|
||||
public: // AISkirmish specific methods.
|
||||
|
||||
AISkirmishPlayer( Player *p ); ///< constructor
|
||||
virtual void computeSuperweaponTarget(const SpecialPowerTemplate *power, Coord3D *pos, Int playerNdx, Real weaponRadius); ///< Calculates best pos for weapon given radius.
|
||||
|
||||
public: // AIPlayer interface methods.
|
||||
|
||||
virtual void update(); ///< simulates the behavior of a player
|
||||
|
||||
virtual void newMap(); ///< New map loaded call.
|
||||
|
||||
/// Invoked when a unit I am training comes into existence
|
||||
virtual void onUnitProduced( Object *factory, Object *unit );
|
||||
|
||||
virtual void buildSpecificAITeam(TeamPrototype *teamProto, Bool priorityBuild); ///< Builds this team immediately.
|
||||
|
||||
virtual void buildSpecificAIBuilding(const AsciiString &thingName); ///< Builds this building as soon as possible.
|
||||
|
||||
virtual void buildAIBaseDefense(Bool flank); ///< Builds base defense on front or flank of base.
|
||||
|
||||
virtual void buildAIBaseDefenseStructure(const AsciiString &thingName, Bool flank); ///< Builds base defense on front or flank of base.
|
||||
|
||||
virtual void recruitSpecificAITeam(TeamPrototype *teamProto, Real recruitRadius); ///< Builds this team immediately.
|
||||
|
||||
virtual Bool isSkirmishAI(void) {return true;}
|
||||
|
||||
virtual Bool checkBridges(Object *unit, Waypoint *way);
|
||||
|
||||
virtual Player *getAiEnemy(void); ///< Solo AI attacks based on scripting. Only skirmish auto-acquires an enemy at this point. jba.
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
virtual void doBaseBuilding(void);
|
||||
virtual void checkReadyTeams(void);
|
||||
virtual void checkQueuedTeams(void);
|
||||
virtual void doTeamBuilding(void);
|
||||
virtual Object *findDozer(const Coord3D *pos);
|
||||
virtual void queueDozer(void);
|
||||
|
||||
protected:
|
||||
|
||||
virtual Bool selectTeamToBuild( void ); ///< determine the next team to build
|
||||
virtual Bool selectTeamToReinforce( Int minPriority ); ///< determine the next team to reinforce
|
||||
virtual Bool startTraining( WorkOrder *order, Bool busyOK, AsciiString teamName); ///< find a production building that can handle the order, and start building
|
||||
|
||||
virtual Bool isAGoodIdeaToBuildTeam( TeamPrototype *proto ); ///< return true if team should be built
|
||||
virtual void processBaseBuilding( void ); ///< do base-building behaviors
|
||||
virtual void processTeamBuilding( void ); ///< do team-building behaviors
|
||||
|
||||
protected:
|
||||
void adjustBuildList(BuildListInfo *list);
|
||||
Int getMyEnemyPlayerIndex(void);
|
||||
void acquireEnemy(void);
|
||||
|
||||
protected:
|
||||
Int m_curFrontBaseDefense; // First is 0.
|
||||
Int m_curFlankBaseDefense; // First is 0.
|
||||
Real m_curFrontLeftDefenseAngle;
|
||||
Real m_curFrontRightDefenseAngle;
|
||||
Real m_curLeftFlankLeftDefenseAngle;
|
||||
Real m_curLeftFlankRightDefenseAngle;
|
||||
Real m_curRightFlankLeftDefenseAngle;
|
||||
Real m_curRightFlankRightDefenseAngle;
|
||||
|
||||
UnsignedInt m_frameToCheckEnemy;
|
||||
Player *m_currentEnemy;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif // _AI_SKIRMISH_PLAYER_H_
|
||||
|
||||
|
||||
|
||||
1269
Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h
Normal file
1269
Generals/Code/GameEngine/Include/GameLogic/AIStateMachine.h
Normal file
File diff suppressed because it is too large
Load Diff
251
Generals/Code/GameEngine/Include/GameLogic/AITNGuard.h
Normal file
251
Generals/Code/GameEngine/Include/GameLogic/AITNGuard.h
Normal file
@@ -0,0 +1,251 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: AITNGuard.h
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* EA Pacific */
|
||||
/* Confidential Information */
|
||||
/* Copyright (C) 2001 - All Rights Reserved */
|
||||
/* DO NOT DISTRIBUTE */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Project: RTS3 */
|
||||
/* File name: AITNGuard.h */
|
||||
/* Created: John K. McDonald, Jr., 3/29/2002 */
|
||||
/* Desc: // Define Guard states for AI */
|
||||
/* Revision History: */
|
||||
/* 3/29/2002 : Initial creation */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#pragma once
|
||||
#ifndef _H_AITNGUARD_
|
||||
#define _H_AITNGUARD_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////
|
||||
#include "Common/GameMemory.h"
|
||||
#include "GameLogic/AIStateMachine.h"
|
||||
#include "GameLogic/GameLogic.h"
|
||||
#include "GameLogic/Object.h"
|
||||
#include "GameLogic/AI.h"
|
||||
|
||||
// DEFINES ////////////////////////////////////////////////////////////////////
|
||||
// TYPE DEFINES ///////////////////////////////////////////////////////////////
|
||||
enum
|
||||
{
|
||||
// prevent collisions with other states that we might use, (namely AI_IDLE)
|
||||
AI_TN_GUARD_INNER = 5000, ///< Attack anything within this area till death
|
||||
AI_TN_GUARD_IDLE, ///< Wait till something shows up to attack.
|
||||
AI_TN_GUARD_OUTER, ///< Attack anything within this area that has been aggressive, until the timer expires
|
||||
AI_TN_GUARD_RETURN, ///< Restore to a position within the inner circle
|
||||
AI_TN_GUARD_GET_CRATE, ///< Pick up a crate from an enemy we killed.
|
||||
AI_TN_GUARD_ATTACK_AGGRESSOR, ///< Attack something that attacked me (that I can attack)
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class TunnelNetworkExitConditions : public AttackExitConditionsInterface
|
||||
{
|
||||
public:
|
||||
|
||||
UnsignedInt m_attackGiveUpFrame; // frame at which we give up (if using)
|
||||
|
||||
TunnelNetworkExitConditions() : m_attackGiveUpFrame(0)
|
||||
{
|
||||
}
|
||||
|
||||
virtual Bool shouldExit(const StateMachine* machine) const;
|
||||
};
|
||||
|
||||
|
||||
// FORWARD DECLARATIONS ///////////////////////////////////////////////////////
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AITNGuardMachine : public StateMachine
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AITNGuardMachine, "AITNGuardMachinePool" );
|
||||
|
||||
private:
|
||||
Coord3D m_positionToGuard;
|
||||
ObjectID m_nemesisToAttack;
|
||||
GuardMode m_guardMode;
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
public:
|
||||
/**
|
||||
* The implementation of this constructor defines the states
|
||||
* used by this machine.
|
||||
*/
|
||||
AITNGuardMachine( Object *owner );
|
||||
|
||||
const Coord3D *getPositionToGuard( void ) const { return &m_positionToGuard; }
|
||||
void setTargetPositionToGuard( const Coord3D *pos) { m_positionToGuard = *pos; }
|
||||
|
||||
void setNemesisID(ObjectID id) { m_nemesisToAttack = id; }
|
||||
ObjectID getNemesisID() const { return m_nemesisToAttack; }
|
||||
|
||||
GuardMode getGuardMode() const { return m_guardMode; }
|
||||
void setGuardMode(GuardMode guardMode) { m_guardMode = guardMode; }
|
||||
|
||||
Bool lookForInnerTarget(void);
|
||||
|
||||
static Real getStdGuardRange(const Object* obj);
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AITNGuardInnerState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AITNGuardInnerState, "AITNGuardInnerState")
|
||||
public:
|
||||
AITNGuardInnerState( StateMachine *machine ) : State( machine, "AITNGuardInner" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AITNGuardMachine* getGuardMachine() { return (AITNGuardMachine*)getMachine(); }
|
||||
|
||||
TunnelNetworkExitConditions m_exitConditions;
|
||||
Bool m_scanForEnemy;
|
||||
AIAttackState *m_attackState;
|
||||
};
|
||||
EMPTY_DTOR(AITNGuardInnerState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AITNGuardIdleState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AITNGuardIdleState, "AITNGuardIdleState")
|
||||
public:
|
||||
AITNGuardIdleState( StateMachine *machine ) : State( machine, "AITNGuardIdleState" ) { }
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AITNGuardMachine* getGuardMachine() { return (AITNGuardMachine*)getMachine(); }
|
||||
|
||||
UnsignedInt m_nextEnemyScanTime;
|
||||
Coord3D m_guardeePos; ///< Where the object we are guarding was last.
|
||||
};
|
||||
EMPTY_DTOR(AITNGuardIdleState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AITNGuardOuterState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AITNGuardOuterState, "AITNGuardOuterState")
|
||||
public:
|
||||
AITNGuardOuterState( StateMachine *machine ) : State( machine, "AITNGuardOuter" )
|
||||
{
|
||||
m_attackState = NULL;
|
||||
}
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AITNGuardMachine* getGuardMachine() { return (AITNGuardMachine*)getMachine(); }
|
||||
|
||||
TunnelNetworkExitConditions m_exitConditions;
|
||||
AIAttackState *m_attackState;
|
||||
};
|
||||
EMPTY_DTOR(AITNGuardOuterState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AITNGuardReturnState : public AIEnterState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AITNGuardReturnState, "AITNGuardReturnState")
|
||||
private:
|
||||
AITNGuardMachine* getGuardMachine() { return (AITNGuardMachine*)getMachine(); }
|
||||
public:
|
||||
AITNGuardReturnState( StateMachine *machine ) : AIEnterState(machine )
|
||||
{
|
||||
m_nextReturnScanTime = 0;
|
||||
}
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
|
||||
protected:
|
||||
UnsignedInt m_nextReturnScanTime;
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
};
|
||||
EMPTY_DTOR(AITNGuardReturnState)
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AITNGuardPickUpCrateState : public AIPickUpCrateState
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AITNGuardPickUpCrateState, "AITNGuardPickUpCrateState")
|
||||
public:
|
||||
AITNGuardPickUpCrateState( StateMachine *machine );
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
};
|
||||
EMPTY_DTOR(AITNGuardPickUpCrateState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
class AITNGuardAttackAggressorState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(AITNGuardAttackAggressorState, "AITNGuardAttackAggressorState")
|
||||
public:
|
||||
AITNGuardAttackAggressorState( StateMachine *machine );
|
||||
virtual StateReturnType onEnter( void );
|
||||
virtual StateReturnType update( void );
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
private:
|
||||
AITNGuardMachine* getGuardMachine() { return (AITNGuardMachine*)getMachine(); }
|
||||
TunnelNetworkExitConditions m_exitConditions;
|
||||
AIAttackState *m_attackState;
|
||||
};
|
||||
|
||||
EMPTY_DTOR(AITNGuardAttackAggressorState)
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
#endif /* _H_AIGUARD_ */
|
||||
134
Generals/Code/GameEngine/Include/GameLogic/Armor.h
Normal file
134
Generals/Code/GameEngine/Include/GameLogic/Armor.h
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: Armor.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Steven Johnson, March 2002
|
||||
// Desc: Damage Multiplier Descriptions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _Armor_H_
|
||||
#define _Armor_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/NameKeyGenerator.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class ArmorStore;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
An Armor encapsulates the a particular type of actual modifier to damage taken, in order
|
||||
to simulate different materials, and to help make game balance easier to adjust.
|
||||
*/
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ArmorTemplate
|
||||
{
|
||||
public:
|
||||
|
||||
ArmorTemplate();
|
||||
|
||||
void clear();
|
||||
|
||||
/**
|
||||
This is the real "meat" of the class: given a damage type and amount, adjust the damage
|
||||
and return the amount that should be dealt.
|
||||
*/
|
||||
Real adjustDamage(DamageType t, Real damage) const;
|
||||
|
||||
static void parseArmorCoefficients( INI* ini, void *instance, void* /* store */, const void* userData );
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
Real m_damageCoefficient[DAMAGE_NUM_TYPES]; ///< modifiers to damage
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class Armor
|
||||
{
|
||||
public:
|
||||
|
||||
inline Armor(const ArmorTemplate* tmpl = NULL) : m_template(tmpl)
|
||||
{
|
||||
}
|
||||
|
||||
inline Real adjustDamage(DamageType t, Real damage) const
|
||||
{
|
||||
return m_template ? m_template->adjustDamage(t, damage) : damage;
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
m_template = NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
const ArmorTemplate* m_template; ///< the kind of armor this is
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
/** Interface class for TheArmorStore, which is just a convenient place for us to
|
||||
* store each Armor we read from INI together in a list, with some access
|
||||
* methods for finding Armors */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ArmorStore : public SubsystemInterface
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
ArmorStore();
|
||||
~ArmorStore();
|
||||
|
||||
void init() { }
|
||||
void reset() { }
|
||||
void update() { }
|
||||
|
||||
/**
|
||||
Find the Armor with the given name. If no such Armor exists, return null.
|
||||
*/
|
||||
const ArmorTemplate* findArmorTemplate(AsciiString name) const;
|
||||
|
||||
inline Armor makeArmor(const ArmorTemplate *tmpl) const
|
||||
{
|
||||
return Armor(tmpl); // my, that was easy
|
||||
}
|
||||
|
||||
static void parseArmorDefinition(INI* ini);
|
||||
|
||||
private:
|
||||
|
||||
typedef std::hash_map< NameKeyType, ArmorTemplate, rts::hash<NameKeyType>, rts::equal_to<NameKeyType> > ArmorTemplateMap;
|
||||
ArmorTemplateMap m_armorTemplates;
|
||||
|
||||
};
|
||||
|
||||
// EXTERNALS //////////////////////////////////////////////////////////////////////////////////////
|
||||
extern ArmorStore *TheArmorStore;
|
||||
|
||||
#endif // _Armor_H_
|
||||
|
||||
100
Generals/Code/GameEngine/Include/GameLogic/ArmorSet.h
Normal file
100
Generals/Code/GameEngine/Include/GameLogic/ArmorSet.h
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ArmorSet.h
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _ArmorSet_H_
|
||||
#define _ArmorSet_H_
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/SparseMatchFinder.h"
|
||||
#include "Common/SparseMatchFinder.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ArmorTemplate;
|
||||
class DamageFX;
|
||||
class INI;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// IMPORTANT NOTE: you should endeavor to set up states such that the most "normal"
|
||||
// state is defined by the bit being off. That is, the typical "normal" condition
|
||||
// has all condition flags set to zero.
|
||||
enum ArmorSetType
|
||||
{
|
||||
// The access and use of this enum has the bit shifting built in, so this is a 0,1,2,3,4,5 enum
|
||||
ARMORSET_VETERAN = 0,
|
||||
ARMORSET_ELITE = 1,
|
||||
ARMORSET_HERO = 2,
|
||||
ARMORSET_PLAYER_UPGRADE = 3,
|
||||
ARMORSET_WEAK_VERSUS_BASEDEFENSES = 4,
|
||||
|
||||
ARMORSET_COUNT ///< keep last, please
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
typedef BitFlags<ARMORSET_COUNT> ArmorSetFlags;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ArmorTemplateSet
|
||||
{
|
||||
private:
|
||||
ArmorSetFlags m_types;
|
||||
const ArmorTemplate* m_template;
|
||||
const DamageFX* m_fx;
|
||||
|
||||
public:
|
||||
inline ArmorTemplateSet()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
inline void clear()
|
||||
{
|
||||
m_types.clear();
|
||||
m_template = NULL;
|
||||
m_fx = NULL;
|
||||
}
|
||||
|
||||
inline const ArmorTemplate* getArmorTemplate() const { return m_template; }
|
||||
inline const DamageFX* getDamageFX() const { return m_fx; }
|
||||
|
||||
inline Int getConditionsYesCount() const { return 1; }
|
||||
inline const ArmorSetFlags& getNthConditionsYes(Int i) const { return m_types; }
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
inline AsciiString getDescription() const { return AsciiString("ArmorTemplateSet"); }
|
||||
#endif
|
||||
|
||||
void parseArmorTemplateSet( INI* ini );
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
typedef std::vector<ArmorTemplateSet> ArmorTemplateSetVector;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
typedef SparseMatchFinder<ArmorTemplateSet, ArmorSetFlags> ArmorTemplateSetFinder;
|
||||
|
||||
#endif // _ArmorSet_H_
|
||||
76
Generals/Code/GameEngine/Include/GameLogic/CaveSystem.h
Normal file
76
Generals/Code/GameEngine/Include/GameLogic/CaveSystem.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CaveSystem.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood July 2002
|
||||
// Desc: System responsible for keeping track of the connectedness of all cave systems on the map
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CAVE_SYSTEM_H
|
||||
#define CAVE_SYSTEM_H
|
||||
|
||||
class Object;
|
||||
class TunnelTracker; // The player owns one such object for his Tunnels, so instead of duplicating
|
||||
// so much code, this SubSystem will manage all of the Cave systems.
|
||||
|
||||
#include "Common/Snapshot.h"
|
||||
#include "Common/SubsystemInterface.h"
|
||||
|
||||
/**
|
||||
System responsible for Crates as code objects - ini, new/delete etc
|
||||
*/
|
||||
class CaveSystem : public SubsystemInterface,
|
||||
public Snapshot
|
||||
{
|
||||
public:
|
||||
CaveSystem();
|
||||
~CaveSystem();
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void update();
|
||||
|
||||
Bool canSwitchIndexToIndex( Int oldIndex, Int newIndex ); // If either Index has guys in it, no, you can't
|
||||
void registerNewCave( Int theIndex ); // All Caves are born with a default index, which could be new
|
||||
void unregisterCave( Int theIndex ); //
|
||||
TunnelTracker *getTunnelTrackerForCaveIndex( Int theIndex );
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer ) { }
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void ) { }
|
||||
|
||||
private:
|
||||
std::vector<TunnelTracker*> m_tunnelTrackerVector;// A vector of pointers where the indexes are known by
|
||||
// others, so it can have NULLs in it to keep position. I've been advised against a map, so don't be a jerk
|
||||
// and use spot 20 first.
|
||||
|
||||
};
|
||||
|
||||
extern CaveSystem *TheCaveSystem;
|
||||
#endif
|
||||
116
Generals/Code/GameEngine/Include/GameLogic/CrateSystem.h
Normal file
116
Generals/Code/GameEngine/Include/GameLogic/CrateSystem.h
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CrateSystem.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood Feb 2002
|
||||
// Desc: System responsible for Crates as code objects - ini, new/delete etc
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CRATE_SYSTEM_H
|
||||
#define CRATE_SYSTEM_H
|
||||
|
||||
#include "Common/Ini.h"
|
||||
#include "Common/Overridable.h"
|
||||
#include "Common/Override.h"
|
||||
|
||||
enum ScienceType;
|
||||
|
||||
struct crateCreationEntry
|
||||
{
|
||||
AsciiString crateName;
|
||||
Real crateChance;
|
||||
};
|
||||
|
||||
typedef std::list< crateCreationEntry > crateCreationEntryList;
|
||||
typedef std::list< crateCreationEntry >::iterator crateCreationEntryIterator;
|
||||
typedef std::list< crateCreationEntry >::const_iterator crateCreationEntryConstIterator;
|
||||
|
||||
/**
|
||||
A CrateTemplate is a ini defined set of conditions plus a ThingTemplate that is the Object
|
||||
containing the correct CrateCollide module.
|
||||
*/
|
||||
class CrateTemplate : public Overridable
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CrateTemplate, "CrateTemplate" )
|
||||
|
||||
public:
|
||||
CrateTemplate();
|
||||
// virtual destructor declared by memory pool
|
||||
|
||||
void setName( AsciiString name ) { m_name = name; }
|
||||
AsciiString getName(){ return m_name; }
|
||||
|
||||
inline const FieldParse *getFieldParse() const { return TheCrateTemplateFieldParseTable; }
|
||||
static const FieldParse TheCrateTemplateFieldParseTable[]; ///< the parse table for INI definition
|
||||
|
||||
static void parseCrateCreationEntry( INI* ini, void *instance, void *store, const void* /*userData*/ );
|
||||
|
||||
AsciiString m_name; ///< name for this CrateTemplate
|
||||
|
||||
Real m_creationChance; ///< Condition for random percentage chance of creating
|
||||
VeterancyLevel m_veterancyLevel; ///< Condition specifing level of killed unit
|
||||
KindOfMaskType m_killedByTypeKindof; ///< Must be killed by something with all these bits set
|
||||
ScienceType m_killerScience; ///< Must be killed by something posessing this science
|
||||
crateCreationEntryList m_possibleCrates; ///< CreationChance is for this CrateData to succeed, this list controls one-of-n crates created on success
|
||||
Bool m_isOwnedByMaker; ///< Design needs crates to be owned sometimes.
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
typedef OVERRIDE<CrateTemplate> CrateTemplateOverride;
|
||||
|
||||
|
||||
/**
|
||||
System responsible for Crates as code objects - ini, new/delete etc
|
||||
*/
|
||||
class CrateSystem : public SubsystemInterface
|
||||
{
|
||||
public:
|
||||
CrateSystem();
|
||||
~CrateSystem();
|
||||
|
||||
void init();
|
||||
void reset();
|
||||
void update(){}
|
||||
|
||||
const CrateTemplate *findCrateTemplate(AsciiString name) const;
|
||||
CrateTemplate *friend_findCrateTemplate(AsciiString name);
|
||||
|
||||
CrateTemplate *newCrateTemplate( AsciiString name );
|
||||
CrateTemplate *newCrateTemplateOverride( CrateTemplate *crateToOverride );
|
||||
|
||||
|
||||
|
||||
static void parseCrateTemplateDefinition(INI* ini);
|
||||
|
||||
private:
|
||||
std::vector<CrateTemplate *> m_crateTemplateVector;
|
||||
|
||||
};
|
||||
|
||||
extern CrateSystem *TheCrateSystem;
|
||||
#endif
|
||||
357
Generals/Code/GameEngine/Include/GameLogic/Damage.h
Normal file
357
Generals/Code/GameEngine/Include/GameLogic/Damage.h
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: Damage.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, November 2001
|
||||
// Desc: Damage description
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DAMAGE_H_
|
||||
#define __DAMAGE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/Snapshot.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Object;
|
||||
class INI;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Damage types, keep this in sync with TheDamageNames[] */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum DamageType
|
||||
{
|
||||
DAMAGE_EXPLOSION = 0,
|
||||
DAMAGE_CRUSH = 1,
|
||||
DAMAGE_ARMOR_PIERCING = 2,
|
||||
DAMAGE_SMALL_ARMS = 3,
|
||||
DAMAGE_GATTLING = 4,
|
||||
DAMAGE_RADIATION = 5,
|
||||
DAMAGE_FLAME = 6,
|
||||
DAMAGE_LASER = 7,
|
||||
DAMAGE_SNIPER = 8,
|
||||
DAMAGE_POISON = 9,
|
||||
DAMAGE_HEALING = 10,
|
||||
DAMAGE_UNRESISTABLE = 11, // this is for scripting to cause 'armorproof' damage
|
||||
DAMAGE_WATER = 12,
|
||||
DAMAGE_DEPLOY = 13, // for transports to deploy units and order them to all attack.
|
||||
// this stays, even if ALLOW_SURRENDER is not defed, since flashbangs still use 'em
|
||||
DAMAGE_SURRENDER = 14, // if something "dies" to surrender damage, they surrender.... duh!
|
||||
DAMAGE_HACK = 15,
|
||||
DAMAGE_KILLPILOT = 16, // special snipe attack that kills the pilot and renders a vehicle unmanned.
|
||||
DAMAGE_PENALTY = 17, // from game penalty (you won't receive radar warnings BTW)
|
||||
DAMAGE_FALLING = 18,
|
||||
DAMAGE_MELEE = 19, // Blades, clubs...
|
||||
DAMAGE_DISARM = 20, // "special" damage type used for disarming mines, bombs, etc (NOT for "disarming" an opponent!)
|
||||
DAMAGE_HAZARD_CLEANUP = 21, // special damage type for cleaning up hazards like radiation or bio-poison.
|
||||
DAMAGE_PARTICLE_BEAM = 22, // Incinerates virtually everything (insanely powerful orbital beam)
|
||||
DAMAGE_TOPPLING = 23, // damage from getting toppled.
|
||||
DAMAGE_INFANTRY_MISSILE = 24,
|
||||
DAMAGE_AURORA_BOMB = 25,
|
||||
DAMAGE_LAND_MINE = 26,
|
||||
DAMAGE_JET_MISSILES = 27,
|
||||
DAMAGE_STEALTHJET_MISSILES = 28,
|
||||
DAMAGE_MOLOTOV_COCKTAIL = 29,
|
||||
DAMAGE_COMANCHE_VULCAN = 30,
|
||||
DAMAGE_FLESHY_SNIPER = 31, // like DAMAGE_SNIPER, but (generally) does no damage to vehicles.
|
||||
|
||||
// Please note: There is a string array below this enum, and when you change them,
|
||||
// you need to search on the array names to find all the stuff that generates names
|
||||
// based on these strings. (eg DamageFX does a strcat to make its array of names so
|
||||
// change DamageFX.ini and its Default)
|
||||
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
//
|
||||
// if you add additional damage types, you will PROBABLY HAVE TO
|
||||
// ENLARGE A BITMASK IN WEAPONSET.
|
||||
//
|
||||
// !!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// !!!!!!!!!!!!!!!!!!!!! NOTE !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
DAMAGE_NUM_TYPES // keep this last
|
||||
};
|
||||
|
||||
#ifdef DEFINE_DAMAGE_NAMES
|
||||
static const char *TheDamageNames[] =
|
||||
{
|
||||
"EXPLOSION",
|
||||
"CRUSH",
|
||||
"ARMOR_PIERCING",
|
||||
"SMALL_ARMS",
|
||||
"GATTLING",
|
||||
"RADIATION",
|
||||
"FLAME",
|
||||
"LASER",
|
||||
"SNIPER",
|
||||
"POISON",
|
||||
"HEALING",
|
||||
"UNRESISTABLE",
|
||||
"WATER",
|
||||
"DEPLOY",
|
||||
"SURRENDER",
|
||||
"HACK",
|
||||
"KILL_PILOT",
|
||||
"PENALTY",
|
||||
"FALLING",
|
||||
"MELEE",
|
||||
"DISARM",
|
||||
"HAZARD_CLEANUP",
|
||||
"PARTICLE_BEAM",
|
||||
"TOPPLING",
|
||||
"INFANTRY_MISSILE",
|
||||
"AURORA_BOMB",
|
||||
"LAND_MINE",
|
||||
"JET_MISSILES",
|
||||
"STEALTHJET_MISSILES",
|
||||
"MOLOTOV_COCKTAIL",
|
||||
"COMANCHE_VULCAN",
|
||||
"FLESHY_SNIPER",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif // end DEFINE_DAMAGE_NAMES
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef UnsignedInt DamageTypeFlags;
|
||||
|
||||
const DamageTypeFlags DAMAGE_TYPE_FLAGS_ALL = 0xffffffff;
|
||||
const DamageTypeFlags DAMAGE_TYPE_FLAGS_NONE = 0x00000000;
|
||||
|
||||
inline Bool getDamageTypeFlag(DamageTypeFlags flags, DamageType dt)
|
||||
{
|
||||
return (flags & (1UL << (dt - 1))) != 0;
|
||||
}
|
||||
|
||||
inline DamageTypeFlags setDamageTypeFlag(DamageTypeFlags flags, DamageType dt)
|
||||
{
|
||||
return (flags | (1UL << (dt - 1)));
|
||||
}
|
||||
|
||||
inline DamageTypeFlags clearDamageTypeFlag(DamageTypeFlags flags, DamageType dt)
|
||||
{
|
||||
return (flags & ~(1UL << (dt - 1)));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Death types, keep this in sync with TheDeathNames[] */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum DeathType
|
||||
{
|
||||
// note that these DELIBERATELY have (slightly) different names from the damage names,
|
||||
// since there isn't necessarily a one-to-one correspondence. e.g., DEATH_BURNED
|
||||
// can come from DAMAGE_FLAME but also from DAMAGE_PARTICLE_BEAM.
|
||||
DEATH_NORMAL = 0,
|
||||
DEATH_NONE = 1, ///< this is a "special case" that can't normally cause death
|
||||
DEATH_CRUSHED = 2,
|
||||
DEATH_BURNED = 3,
|
||||
DEATH_EXPLODED = 4,
|
||||
DEATH_POISONED = 5,
|
||||
DEATH_TOPPLED = 6,
|
||||
DEATH_FLOODED = 7,
|
||||
DEATH_SUICIDED = 8,
|
||||
DEATH_LASERED = 9,
|
||||
DEATH_DETONATED = 10, /**< this is the "death" that occurs when a missile/warhead/etc detonates normally,
|
||||
as opposed to being shot down, etc */
|
||||
DEATH_SPLATTED = 11, /**< the death that results from DAMAGE_FALLING */
|
||||
DEATH_POISONED_BETA = 12,
|
||||
|
||||
// these are the "extra" types for yet-to-be-defined stuff. Don't bother renaming or adding
|
||||
// or removing these; they are reserved for modders :-)
|
||||
DEATH_EXTRA_2 = 13,
|
||||
DEATH_EXTRA_3 = 14,
|
||||
DEATH_EXTRA_4 = 15,
|
||||
DEATH_EXTRA_5 = 16,
|
||||
DEATH_EXTRA_6 = 17,
|
||||
DEATH_EXTRA_7 = 18,
|
||||
DEATH_EXTRA_8 = 19,
|
||||
|
||||
DEATH_NUM_TYPES // keep this last
|
||||
};
|
||||
|
||||
#ifdef DEFINE_DEATH_NAMES
|
||||
static const char *TheDeathNames[] =
|
||||
{
|
||||
"NORMAL",
|
||||
"NONE",
|
||||
"CRUSHED",
|
||||
"BURNED",
|
||||
"EXPLODED",
|
||||
"POISONED",
|
||||
"TOPPLED",
|
||||
"FLOODED",
|
||||
"SUICIDED",
|
||||
"LASERED",
|
||||
"DETONATED",
|
||||
"SPLATTED",
|
||||
"POISONED_BETA",
|
||||
|
||||
"EXTRA_2",
|
||||
"EXTRA_3",
|
||||
"EXTRA_4",
|
||||
"EXTRA_5",
|
||||
"EXTRA_6",
|
||||
"EXTRA_7",
|
||||
"EXTRA_8",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif // end DEFINE_DEATH_NAMES
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef UnsignedInt DeathTypeFlags;
|
||||
|
||||
const DeathTypeFlags DEATH_TYPE_FLAGS_ALL = 0xffffffff;
|
||||
const DeathTypeFlags DEATH_TYPE_FLAGS_NONE = 0x00000000;
|
||||
|
||||
inline Bool getDeathTypeFlag(DeathTypeFlags flags, DeathType dt)
|
||||
{
|
||||
return (flags & (1UL << (dt - 1))) != 0;
|
||||
}
|
||||
|
||||
inline DeathTypeFlags setDeathTypeFlag(DeathTypeFlags flags, DeathType dt)
|
||||
{
|
||||
return (flags | (1UL << (dt - 1)));
|
||||
}
|
||||
|
||||
inline DeathTypeFlags clearDeathTypeFlag(DeathTypeFlags flags, DeathType dt)
|
||||
{
|
||||
return (flags & ~(1UL << (dt - 1)));
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Damage info inputs */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DamageInfoInput : public Snapshot
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DamageInfoInput( void )
|
||||
{
|
||||
m_sourceID = INVALID_ID;
|
||||
m_sourcePlayerMask = 0;
|
||||
m_damageType = DAMAGE_EXPLOSION;
|
||||
m_deathType = DEATH_NORMAL;
|
||||
m_amount = 0;
|
||||
}
|
||||
|
||||
ObjectID m_sourceID; ///< source of the damage
|
||||
PlayerMaskType m_sourcePlayerMask; ///< Player mask of m_sourceID.
|
||||
DamageType m_damageType; ///< type of damage
|
||||
DeathType m_deathType; ///< if this kills us, death type to be used
|
||||
Real m_amount; ///< # value of how much damage to inflict
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer ) { }
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void ) { }
|
||||
|
||||
};
|
||||
|
||||
const Real HUGE_DAMAGE_AMOUNT = 999999.0f;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Damage into outputs */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DamageInfoOutput : public Snapshot
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DamageInfoOutput( void )
|
||||
{
|
||||
m_actualDamageDealt = 0;
|
||||
m_actualDamageClipped = 0;
|
||||
m_noEffect = false;
|
||||
}
|
||||
|
||||
/**
|
||||
m_actualDamageDealt is the damage we tried to apply to object (after multipliers and such).
|
||||
m_actualDamageClipped is the value of m_actualDamageDealt, but clipped to the max health remaining of the obj.
|
||||
example:
|
||||
a mammoth tank fires a round at a small tank, attempting 100 damage.
|
||||
the small tank has a damage multiplier of 50%, meaning that only 50 damage is applied.
|
||||
furthermore, the small tank has only 30 health remaining.
|
||||
so: m_actualDamageDealt = 50, m_actualDamageClipped = 30.
|
||||
|
||||
this distinction is useful, since visual fx really wants to do the fx for "50 damage",
|
||||
even though it was more than necessary to kill this object; game logic, on the other hand,
|
||||
may want to know the "clipped" damage for ai purposes.
|
||||
*/
|
||||
Real m_actualDamageDealt;
|
||||
Real m_actualDamageClipped; ///< (see comment for m_actualDamageDealt)
|
||||
Bool m_noEffect; ///< if true, no damage was done at all (generally due to being InactiveBody)
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer ) { }
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void ) { }
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** DamageInfo is a descriptor of damage we're trying to inflict. The structure
|
||||
* is divided up into two parts, inputs and outputs.
|
||||
*
|
||||
* INPUTS: You must provide valid values for these fields in order for damage
|
||||
* calculation to correctly take place
|
||||
* OUTPUT: Upon returning from damage issuing functions, the output fields
|
||||
* will be filled with the results of the damage occurrence
|
||||
*/
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DamageInfo : public Snapshot
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DamageInfoInput in; ///< inputs for the damage info
|
||||
DamageInfoOutput out; ///< results for the damage occurrence
|
||||
|
||||
protected:
|
||||
|
||||
virtual void crc( Xfer *xfer ) { }
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void ){ }
|
||||
|
||||
};
|
||||
|
||||
#endif // __DAMAGE_H_
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: ExperienceTracker.h //////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, February 2002
|
||||
// Desc: Keeps track of experience points so Veterance levels can be gained
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef EXPERIENCE_TRACKER_H
|
||||
#define EXPERIENCE_TRACKER_H
|
||||
|
||||
#include "Common/GameCommon.h"
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/GameMemory.h"
|
||||
#include "Common/Snapshot.h"
|
||||
|
||||
class Object;
|
||||
|
||||
class ExperienceTracker : public MemoryPoolObject, public Snapshot
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(ExperienceTracker, "ExperienceTrackerPool" )
|
||||
public:
|
||||
ExperienceTracker(Object *parent);
|
||||
|
||||
VeterancyLevel getVeterancyLevel() const { return m_currentLevel; } ///< What level am I?
|
||||
Int getExperienceValue( const Object* killer ) const; ///< How much do give for being killed
|
||||
Int getCurrentExperience( void ) const { return m_currentExperience; }; ///< How much experience do I have at the moment?
|
||||
Bool isTrainable() const; ///< Can I gain experience?
|
||||
Bool isAcceptingExperiencePoints() const; ///< Either I am trainable, or I have a Sink set up
|
||||
|
||||
void setVeterancyLevel( VeterancyLevel newLevel ); ///< Set Level to this
|
||||
void setMinVeterancyLevel( VeterancyLevel newLevel ); ///< Set Level to AT LEAST this... if we are already >= this level, do nothing.
|
||||
void addExperiencePoints( Int experienceGain, Bool canScaleForBonus = TRUE ); ///< Gain this many exp.
|
||||
Bool gainExpForLevel(Int levelsToGain, Bool canScaleForBonus = TRUE ); ///< Gain enough exp to gain a level. return false if can't gain a level.
|
||||
Bool canGainExpForLevel(Int levelsToGain) const; ///< return same value as gainExpForLevel, but don't change anything
|
||||
void setExperienceAndLevel(Int experienceIn);
|
||||
void setExperienceSink( ObjectID sink ); ///< My experience actually goes to this person (loose couple)
|
||||
|
||||
Real getExperienceScalar() const { return m_experienceScalar; }
|
||||
void setExperienceScalar( Real scalar ) { m_experienceScalar = scalar; }
|
||||
|
||||
// --------------- inherited from Snapshot interface --------------
|
||||
void crc( Xfer *xfer );
|
||||
void xfer( Xfer *xfer );
|
||||
void loadPostProcess( void );
|
||||
|
||||
private:
|
||||
Object* m_parent; ///< Object I am owned by
|
||||
VeterancyLevel m_currentLevel; ///< Level of experience
|
||||
Int m_currentExperience; ///< Number of experience points
|
||||
ObjectID m_experienceSink; ///< ID of object I have pledged my experience point gains to
|
||||
Real m_experienceScalar; ///< Scales any experience gained by this multiplier.
|
||||
};
|
||||
|
||||
#endif
|
||||
42
Generals/Code/GameEngine/Include/GameLogic/FPUControl.h
Normal file
42
Generals/Code/GameEngine/Include/GameLogic/FPUControl.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FPUControl.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Matthew D. Campbell, June 2002
|
||||
// Desc: Routines for controlling the FPU state
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FPUCONTROL_H__
|
||||
#define __FPUCONTROL_H__
|
||||
|
||||
/**
|
||||
* setFPMode sets the FPU internal precision and rounding mode. As DirectX is not guaranteed to
|
||||
* leave the FPU in a good state, we must call this at the start of GameLogic::update() and
|
||||
* anywhere that touches DirectX inside GameLogic loops (LoadScreen).
|
||||
*/
|
||||
void setFPMode( void );
|
||||
|
||||
#endif // __FPUCONTROL_H__
|
||||
96
Generals/Code/GameEngine/Include/GameLogic/FiringTracker.h
Normal file
96
Generals/Code/GameEngine/Include/GameLogic/FiringTracker.h
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FiringTracker.h //////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, February 2002
|
||||
// Desc: Keeps track of shots fired and people targeted for weapons that want a history of such a thing
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef FIRING_TRACKER_H
|
||||
#define FIRING_TRACKER_H
|
||||
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/GameMemory.h"
|
||||
#include "Common/AudioEventRTS.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
class Object;
|
||||
class Weapon;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class FiringTrackerModuleData : public ModuleData
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class FiringTracker : public UpdateModule
|
||||
{
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FiringTracker, FiringTrackerModuleData )
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(FiringTracker, "FiringTrackerPool" )
|
||||
public:
|
||||
FiringTracker(Thing *thing, const ModuleData *modData);
|
||||
void shotFired(const Weapon* weaponFired, ObjectID victimID ); ///< Owner just fired this weapon at this Object
|
||||
ObjectID getLastShotVictim() const { return m_victimID; } ///< get the last victim ID that was shot at
|
||||
Int getNumConsecutiveShotsAtVictim( const Object *victim ) const;
|
||||
|
||||
/// this is never disabled, since we want disabled things to continue to slowly "spin down"... (srj)
|
||||
virtual DisabledMaskType getDisabledTypesToProcess() const { return DISABLEDMASK_ALL; }
|
||||
|
||||
virtual UpdateSleepTime update(); ///< See if spin down is needed because we haven't shot in a while
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
The firingtracker needs to have its update run after all "normal"
|
||||
user update modules, so it redefines this. Please don't redefine this
|
||||
for other modules without very careful deliberation. (srj)
|
||||
*/
|
||||
virtual SleepyUpdatePhase getUpdatePhase() const
|
||||
{
|
||||
return PHASE_FINAL;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void speedUp(); ///< I've qualified for an increase in my Object flag status
|
||||
void coolDown(); ///< I need to slow down because it has been too long since I fired.
|
||||
UpdateSleepTime calcTimeToSleep();
|
||||
|
||||
private:
|
||||
Int m_consecutiveShots; ///< How many times I have shot at the same thing
|
||||
ObjectID m_victimID; ///< The thing I have shot so many times
|
||||
UnsignedInt m_frameToStartCooldown; ///< This is the frame I should cool down at, and is pushed back every time a shot is fired
|
||||
UnsignedInt m_frameToForceReload; ///< Even more than AutoReload, this means it will pre-emptively reload instead of event triggering a delay after the last shot
|
||||
|
||||
UnsignedInt m_frameToStopLoopingSound; ///< if sound is looping, frame to stop looping it (or zero if not looping)
|
||||
AudioHandle m_audioHandle;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
412
Generals/Code/GameEngine/Include/GameLogic/GameLogic.h
Normal file
412
Generals/Code/GameEngine/Include/GameLogic/GameLogic.h
Normal file
@@ -0,0 +1,412 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GameLogic.h //////////////////////////////////////////////////////////////////////////////
|
||||
// GameLogic singleton class - defines interface to GameLogic methods and objects
|
||||
// Author: Michael S. Booth, October 2000
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _GAME_LOGIC_H_
|
||||
#define _GAME_LOGIC_H_
|
||||
|
||||
#include "Common/GameCommon.h" // ensure we get DUMP_PERF_STATS, or not
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/Snapshot.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
#include "GameNetwork/NetworkDefs.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
#include "GameLogic/Module/UpdateModule.h" // needed for DIRECT_UPDATEMODULE_ACCESS
|
||||
|
||||
/*
|
||||
At one time, we distinguished between sleepy and nonsleepy
|
||||
update modules, and kept a separate list for each. however,
|
||||
now that the bulk of update modules are sleepy, profiling shows
|
||||
that there is no real advantage to having the separate list,
|
||||
so to simplify the world, I am removing it. If ALLOW_NONSLEEPY_UPDATES
|
||||
is still undefined when we ship, please just nuke all the undefed
|
||||
code. (srj)
|
||||
*/
|
||||
#define NO_ALLOW_NONSLEEPY_UPDATES
|
||||
|
||||
// forward declarations
|
||||
class AudioEventRTS;
|
||||
class Object;
|
||||
class Drawable;
|
||||
class Player;
|
||||
class ThingTemplate;
|
||||
class Team;
|
||||
class CommandList;
|
||||
class GameMessage;
|
||||
class LoadScreen;
|
||||
class WindowLayout;
|
||||
class TerrainLogic;
|
||||
class GhostObjectManager;
|
||||
class CommandButton;
|
||||
enum BuildableStatus;
|
||||
enum ObjectStatusBits;
|
||||
|
||||
typedef const CommandButton* ConstCommandButtonPtr;
|
||||
|
||||
// What kind of game we're in.
|
||||
enum
|
||||
{
|
||||
#if !defined(_PLAYTEST)
|
||||
GAME_SINGLE_PLAYER,
|
||||
GAME_LAN,
|
||||
GAME_SKIRMISH,
|
||||
GAME_REPLAY,
|
||||
#endif
|
||||
GAME_SHELL,
|
||||
GAME_INTERNET,
|
||||
GAME_NONE
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
CRC_CACHED,
|
||||
CRC_RECALC
|
||||
};
|
||||
|
||||
/// Function pointers for use by GameLogic callback functions.
|
||||
typedef void (*GameLogicFuncPtr)( Object *obj, void *userData );
|
||||
typedef std::hash_map<ObjectID, Object *, rts::hash<ObjectID>, rts::equal_to<ObjectID> > ObjectPtrHash;
|
||||
typedef ObjectPtrHash::const_iterator ObjectPtrIter;
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The implementation of GameLogic
|
||||
*/
|
||||
class GameLogic : public SubsystemInterface, public Snapshot
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
GameLogic( void );
|
||||
virtual ~GameLogic();
|
||||
|
||||
// subsytem methods
|
||||
virtual void init( void ); ///< Initialize or re-initialize the instance
|
||||
virtual void reset( void ); ///< Reset the logic system
|
||||
virtual void update( void ); ///< update the world
|
||||
|
||||
void processCommandList( CommandList *list ); ///< process the command list
|
||||
|
||||
void prepareNewGame( Int gameMode, GameDifficulty diff, Int rankPoints ); ///< prepare for new game
|
||||
|
||||
void logicMessageDispatcher( GameMessage *msg,
|
||||
void *userData ); ///< Logic command list processing
|
||||
|
||||
void registerObject( Object *obj ); ///< Given an object, register it with the GameLogic and give it a unique ID
|
||||
|
||||
void addObjectToLookupTable( Object *obj ); ///< add object ID to hash lookup table
|
||||
void removeObjectFromLookupTable( Object *obj );///< remove object ID from hash lookup table
|
||||
|
||||
/// @todo Change this to refer to a Region3D as an extent of the world
|
||||
void setWidth( Real width ); ///< Sets the width of the world
|
||||
Real getWidth( void ); ///< Returns the width of the world
|
||||
void setHeight( Real height ); ///< Sets the height of the world
|
||||
Real getHeight( void ); ///< Returns the height of the world
|
||||
|
||||
Bool isInGameLogicUpdate( void ) const { return m_isInUpdate; }
|
||||
UnsignedInt getFrame( void ); ///< Returns the current simulation frame number
|
||||
UnsignedInt getCRC( Int mode = CRC_CACHED, AsciiString deepCRCFileName = AsciiString::TheEmptyString ); ///< Returns the CRC
|
||||
|
||||
void setObjectIDCounter( ObjectID nextObjID ) { m_nextObjID = nextObjID; }
|
||||
ObjectID getObjectIDCounter( void ) { return m_nextObjID; }
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
void setBuildableStatusOverride(const ThingTemplate* tt, BuildableStatus bs);
|
||||
Bool findBuildableStatusOverride(const ThingTemplate* tt, BuildableStatus& bs) const;
|
||||
|
||||
void setControlBarOverride(const AsciiString& commandSetName, Int slot, ConstCommandButtonPtr commandButton);
|
||||
Bool findControlBarOverride(const AsciiString& commandSetName, Int slot, ConstCommandButtonPtr& commandButton) const;
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
/// create an object given the thing template. (Only for use by ThingFactory.)
|
||||
Object *friend_createObject( const ThingTemplate *thing, ObjectStatusBits statusBits, Team *team );
|
||||
void destroyObject( Object *obj ); ///< Mark object as destroyed for later deletion
|
||||
Object *findObjectByID( ObjectID id ); ///< Given an ObjectID, return a pointer to the object.
|
||||
Object *getFirstObject( void ); ///< Returns the "first" object in the world. When used with the object method "getNextObject()", all objects in the world can be iterated.
|
||||
ObjectID allocateObjectID( void ); ///< Returns a new unique object id
|
||||
|
||||
// super hack
|
||||
void startNewGame( Bool saveGame );
|
||||
void loadMapINI( AsciiString mapName );
|
||||
|
||||
void updateLoadProgress( Int progress );
|
||||
void deleteLoadScreen( void );
|
||||
|
||||
void setGameLoading( Bool loading );
|
||||
void setGameMode( Int mode );
|
||||
Int getGameMode( void );
|
||||
Bool isInGame( void );
|
||||
#if !defined(_PLAYTEST)
|
||||
Bool isInLanGame( void );
|
||||
Bool isInSinglePlayerGame( void );
|
||||
Bool isInSkirmishGame( void );
|
||||
Bool isInReplayGame( void );
|
||||
#endif
|
||||
Bool isInInternetGame( void );
|
||||
Bool isInShellGame( void );
|
||||
Bool isInMultiplayerGame( void );
|
||||
Bool isLoadingGame();
|
||||
void enableScoring(Bool score) { m_isScoringEnabled = score; }
|
||||
Bool isScoringEnabled() const { return m_isScoringEnabled; }
|
||||
|
||||
void setShowBehindBuildingMarkers(Bool b) { m_showBehindBuildingMarkers = b; }
|
||||
Bool getShowBehindBuildingMarkers() const { return m_showBehindBuildingMarkers; }
|
||||
|
||||
void setDrawIconUI(Bool b) { m_drawIconUI = b; }
|
||||
Bool getDrawIconUI() const { return m_drawIconUI; }
|
||||
|
||||
void setShowDynamicLOD(Bool b) { m_showDynamicLOD = b; }
|
||||
Bool getShowDynamicLOD() const { return m_showDynamicLOD; }
|
||||
|
||||
void setHulkMaxLifetimeOverride(Int b) { m_scriptHulkMaxLifetimeOverride = b; }
|
||||
Int getHulkMaxLifetimeOverride() const { return m_scriptHulkMaxLifetimeOverride; }
|
||||
|
||||
Bool isIntroMoviePlaying();
|
||||
|
||||
void updateObjectsChangedTriggerAreas(void) {m_frameObjectsChangedTriggerAreas = m_frame;}
|
||||
UnsignedInt getFrameObjectsChangedTriggerAreas(void) {return m_frameObjectsChangedTriggerAreas;}
|
||||
|
||||
void clearGameData(Bool showScoreScreen = TRUE); ///< Clear the game data
|
||||
void closeWindows( void );
|
||||
|
||||
void sendObjectCreated( Object *obj );
|
||||
void sendObjectDestroyed( Object *obj );
|
||||
|
||||
void bindObjectAndDrawable(Object* obj, Drawable* draw);
|
||||
|
||||
void setGamePaused( Bool paused, Bool pauseMusic = TRUE );
|
||||
Bool isGamePaused( void );
|
||||
Bool getInputEnabledMemory( void ) { return m_inputEnabledMemory; }
|
||||
|
||||
void processProgress(Int playerId, Int percentage);
|
||||
void processProgressComplete(Int playerId);
|
||||
Bool isProgressComplete( void );
|
||||
void timeOutGameStart( void );
|
||||
void initTimeOutValues( void );
|
||||
UnsignedInt getObjectCount( void );
|
||||
|
||||
Int getRankLevelLimit() const { return m_rankLevelLimit; }
|
||||
void setRankLevelLimit(Int limit)
|
||||
{
|
||||
if (limit < 1) limit = 1;
|
||||
m_rankLevelLimit = limit;
|
||||
}
|
||||
|
||||
// We need to allow access to this, because on a restartGame, we need to restart with the settings we started with
|
||||
Int getRankPointsToAddAtGameStart() const { return m_rankPointsToAddAtGameStart; }
|
||||
|
||||
#ifdef DUMP_PERF_STATS
|
||||
void getAIMetricsStatistics( UnsignedInt *numAI, UnsignedInt *numMoving, UnsignedInt *numAttacking, UnsignedInt *numWaitingForPath, UnsignedInt *overallFailedPathfinds );
|
||||
void resetOverallFailedPathfinds() { m_overallFailedPathfinds = 0; }
|
||||
void incrementOverallFailedPathfinds() { m_overallFailedPathfinds++; }
|
||||
UnsignedInt getOverallFailedPathfinds() const { return m_overallFailedPathfinds; }
|
||||
#endif
|
||||
|
||||
// NOTE: selectObject and deselectObject should be called *only* by logical things, NEVER by the
|
||||
// client. These will cause the client to select or deselect the object, if affectClient is true.
|
||||
// If createToSelection is TRUE, this object causes a new group to be selected.
|
||||
void selectObject(Object *obj, Bool createNewSelection, PlayerMaskType playerMask, Bool affectClient = FALSE);
|
||||
void deselectObject(Object *obj, PlayerMaskType playerMask, Bool affectClient = FALSE);
|
||||
|
||||
// this should be called only by UpdateModule, thanks.
|
||||
void friend_awakenUpdateModule(Object* obj, UpdateModulePtr update, UnsignedInt whenToWakeUp);
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
private:
|
||||
|
||||
void pushSleepyUpdate(UpdateModulePtr u);
|
||||
UpdateModulePtr peekSleepyUpdate() const;
|
||||
void popSleepyUpdate();
|
||||
void eraseSleepyUpdate(Int i);
|
||||
void rebalanceSleepyUpdate(Int i);
|
||||
Int rebalanceParentSleepyUpdate(Int i);
|
||||
Int rebalanceChildSleepyUpdate(Int i);
|
||||
void remakeSleepyUpdate();
|
||||
void validateSleepyUpdate() const;
|
||||
|
||||
private:
|
||||
|
||||
/**
|
||||
overrides to thing template buildable status. doesn't really belong here,
|
||||
but has to go somewhere. (srj)
|
||||
*/
|
||||
typedef std::hash_map< AsciiString, BuildableStatus, rts::hash<AsciiString>, rts::equal_to<AsciiString> > BuildableMap;
|
||||
BuildableMap m_thingTemplateBuildableOverrides;
|
||||
|
||||
/**
|
||||
overrides to control bars. doesn't really belong here, but has to go somewhere. (srj)
|
||||
*/
|
||||
typedef std::hash_map< AsciiString, ConstCommandButtonPtr, rts::hash<AsciiString>, rts::equal_to<AsciiString> > ControlBarOverrideMap;
|
||||
ControlBarOverrideMap m_controlBarOverrides;
|
||||
|
||||
Real m_width, m_height; ///< Dimensions of the world
|
||||
UnsignedInt m_frame; ///< Simulation frame number
|
||||
|
||||
// CRC cache system -----------------------------------------------------------------------------
|
||||
UnsignedInt m_CRC; ///< Cache of previous CRC value
|
||||
std::map<Int, UnsignedInt> m_cachedCRCs; ///< CRCs we've seen this frame
|
||||
Bool m_shouldValidateCRCs; ///< Should we validate CRCs this frame?
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
|
||||
//Added By Sadullah Nader
|
||||
//Used to for load scene
|
||||
Bool m_loadingScene;
|
||||
|
||||
Bool m_isInUpdate;
|
||||
|
||||
Int m_rankPointsToAddAtGameStart;
|
||||
|
||||
Bool m_isScoringEnabled;
|
||||
Bool m_showBehindBuildingMarkers; //used by designers to override the user setting for cinematics
|
||||
Bool m_drawIconUI;
|
||||
Bool m_showDynamicLOD; //used by designers to override the user setting for cinematics
|
||||
Int m_scriptHulkMaxLifetimeOverride; ///< Scripts can change the lifetime of a hulk -- defaults to off (-1) in frames.
|
||||
|
||||
/// @todo remove this hack
|
||||
Bool m_startNewGame;
|
||||
WindowLayout *m_background;
|
||||
|
||||
Object* m_objList; ///< All of the objects in the world.
|
||||
ObjectPtrHash m_objHash; ///< Used for ObjectID lookups
|
||||
|
||||
// this is a vector, but is maintained as a priority queue.
|
||||
// never modify it directly; please use the proper access methods.
|
||||
// (for an excellent discussion of priority queues, please see:
|
||||
// http://dogma.net/markn/articles/pq_stl/priority.htm)
|
||||
std::vector<UpdateModulePtr> m_sleepyUpdates;
|
||||
|
||||
#ifdef ALLOW_NONSLEEPY_UPDATES
|
||||
// this is a plain old list, not a pq.
|
||||
std::list<UpdateModulePtr> m_normalUpdates;
|
||||
#endif
|
||||
|
||||
UpdateModulePtr m_curUpdateModule;
|
||||
|
||||
ObjectPointerList m_objectsToDestroy; ///< List of things that need to be destroyed at end of frame
|
||||
|
||||
ObjectID m_nextObjID; ///< For allocating object id's
|
||||
|
||||
void setDefaults( Bool saveGame ); ///< Set default values of class object
|
||||
void processDestroyList( void ); ///< Destroy all pending objects on the destroy list
|
||||
|
||||
void destroyAllObjectsImmediate(); ///< destroy, and process destroy list immediately
|
||||
|
||||
/// factory for TheTerrainLogic, called from init()
|
||||
virtual TerrainLogic *createTerrainLogic( void );
|
||||
virtual GhostObjectManager *createGhostObjectManager(void);
|
||||
|
||||
Int m_gameMode;
|
||||
Int m_rankLevelLimit;
|
||||
|
||||
LoadScreen *getLoadScreen( Bool saveGame );
|
||||
LoadScreen *m_loadScreen;
|
||||
Bool m_gamePaused;
|
||||
Bool m_inputEnabledMemory;// Latches used to remember what to restore to after we unpause
|
||||
Bool m_mouseVisibleMemory;
|
||||
|
||||
Bool m_progressComplete[MAX_SLOTS];
|
||||
enum { PROGRESS_COMPLETE_TIMEOUT = 60000 }; ///< Timeout we wait for when we've completed our Load
|
||||
Int m_progressCompleteTimeout[MAX_SLOTS];
|
||||
void testTimeOut( void );
|
||||
void lastHeardFrom( Int playerId );
|
||||
Bool m_forceGameStartByTimeOut; ///< If we timeout someone we're waiting to load, set this flag to start the game
|
||||
|
||||
#ifdef DUMP_PERF_STATS
|
||||
UnsignedInt m_overallFailedPathfinds;
|
||||
#endif
|
||||
|
||||
UnsignedInt m_frameObjectsChangedTriggerAreas; ///< Last frame objects moved into/outof trigger areas, or were created/destroyed. jba.
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
struct ObjectTOCEntry
|
||||
{
|
||||
AsciiString name;
|
||||
UnsignedShort id;
|
||||
};
|
||||
typedef std::list< ObjectTOCEntry > ObjectTOCList;
|
||||
typedef ObjectTOCList::iterator ObjectTOCListIterator;
|
||||
ObjectTOCList m_objectTOC; ///< the object TOC
|
||||
void addTOCEntry( AsciiString name, UnsignedShort id ); ///< add a new name/id TOC pair
|
||||
ObjectTOCEntry *findTOCEntryByName( AsciiString name ); ///< find ObjectTOC by name
|
||||
ObjectTOCEntry *findTOCEntryById( UnsignedShort id ); ///< find ObjectTOC by id
|
||||
void xferObjectTOC( Xfer *xfer ); ///< save/load object TOC for current state of map
|
||||
void prepareLogicForObjectLoad( void ); ///< prepare engine for object data from game file
|
||||
|
||||
};
|
||||
|
||||
// INLINE /////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline void GameLogic::setWidth( Real width ) { m_width = width; }
|
||||
inline Real GameLogic::getWidth( void ) { return m_width; }
|
||||
inline void GameLogic::setHeight( Real height ) { m_height = height; }
|
||||
inline Real GameLogic::getHeight( void ) { return m_height; }
|
||||
inline UnsignedInt GameLogic::getFrame( void ) { return m_frame; }
|
||||
|
||||
inline Bool GameLogic::isInGame( void ) { return !(m_gameMode == GAME_NONE); }
|
||||
inline void GameLogic::setGameMode( Int mode ) { m_gameMode = mode; }
|
||||
inline Int GameLogic::getGameMode( void ) { return m_gameMode; }
|
||||
#if !defined(_PLAYTEST)
|
||||
inline Bool GameLogic::isInLanGame( void ) { return (m_gameMode == GAME_LAN); }
|
||||
inline Bool GameLogic::isInSkirmishGame( void ) { return (m_gameMode == GAME_SKIRMISH); }
|
||||
inline Bool GameLogic::isInMultiplayerGame( void ) { return ((m_gameMode == GAME_LAN) || (m_gameMode == GAME_INTERNET)) ; }
|
||||
inline Bool GameLogic::isInReplayGame( void ) { return (m_gameMode == GAME_REPLAY); }
|
||||
#else
|
||||
inline Bool GameLogic::isInMultiplayerGame( void ) { return ((m_gameMode == GAME_INTERNET)) ; }
|
||||
#endif
|
||||
inline Bool GameLogic::isInInternetGame( void ) { return (m_gameMode == GAME_INTERNET); }
|
||||
inline Bool GameLogic::isInShellGame( void ) { return (m_gameMode == GAME_SHELL); }
|
||||
//Check for loading scene
|
||||
inline Bool GameLogic::isLoadingGame(){ return m_loadingScene;}
|
||||
|
||||
inline Object* GameLogic::findObjectByID( ObjectID id )
|
||||
{
|
||||
if( id == INVALID_ID )
|
||||
return NULL;
|
||||
|
||||
ObjectPtrHash::iterator it = m_objHash.find(id);
|
||||
if (it == m_objHash.end())
|
||||
return NULL;
|
||||
|
||||
return (*it).second;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the singleton
|
||||
extern GameLogic *TheGameLogic;
|
||||
|
||||
#endif // _GAME_LOGIC_H_
|
||||
|
||||
108
Generals/Code/GameEngine/Include/GameLogic/GhostObject.h
Normal file
108
Generals/Code/GameEngine/Include/GameLogic/GhostObject.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GhostObject.h ////////////////////////////////////////////////////////////
|
||||
// Placeholder for objects that have been deleted but need to be maintained because
|
||||
// a player can see them fogged.
|
||||
// Author: Mark Wilczynski, August 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _GHOSTOBJECT_H_
|
||||
#define _GHOSTOBJECT_H_
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
#include "Common/Snapshot.h"
|
||||
|
||||
// #define DEBUG_FOG_MEMORY ///< this define is used to force object snapshots for all players, not just local player.
|
||||
|
||||
//Magic pointer value which indicates that a drawable pointer is actually invalid
|
||||
//because we're looking at a ghost object.
|
||||
#define GHOST_OBJECT_DRAWABLE 0xFFFFFFFF
|
||||
|
||||
class Object;
|
||||
class PartitionData;
|
||||
enum GeometryType;
|
||||
enum ObjectID;
|
||||
|
||||
class GhostObject : public Snapshot
|
||||
{
|
||||
public:
|
||||
GhostObject();
|
||||
virtual ~GhostObject();
|
||||
virtual void snapShot(int playerIndex)=0;
|
||||
virtual void updateParentObject(Object *object, PartitionData *mod)=0;
|
||||
virtual void freeSnapShot(int playerIndex)=0;
|
||||
inline PartitionData *friend_getPartitionData(void) const {return m_partitionData;}
|
||||
inline GeometryType getGeometryType(void) const {return m_parentGeometryType;}
|
||||
inline Bool getGeometrySmall(void) const {return m_parentGeometryIsSmall;}
|
||||
inline Real getGeometryMajorRadius(void) const {return m_parentGeometryMajorRadius;}
|
||||
inline Real getGeometryMinorRadius(void) const {return m_parentGeometryminorRadius;}
|
||||
inline Real getParentAngle(void) const {return m_parentAngle;}
|
||||
inline const Coord3D *getParentPosition(void) const {return &m_parentPosition;}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
Object *m_parentObject; ///< object which we are ghosting
|
||||
GeometryType m_parentGeometryType;
|
||||
Bool m_parentGeometryIsSmall;
|
||||
Real m_parentGeometryMajorRadius;
|
||||
Real m_parentGeometryminorRadius;
|
||||
Real m_parentAngle;
|
||||
Coord3D m_parentPosition;
|
||||
PartitionData *m_partitionData; ///< our PartitionData
|
||||
};
|
||||
|
||||
class GhostObjectManager : public Snapshot
|
||||
{
|
||||
public:
|
||||
GhostObjectManager();
|
||||
virtual ~GhostObjectManager();
|
||||
virtual void reset(void);
|
||||
virtual GhostObject *addGhostObject(Object *object, PartitionData *pd);
|
||||
virtual void removeGhostObject(GhostObject *mod);
|
||||
virtual inline void setLocalPlayerIndex(int index) { m_localPlayer = index; }
|
||||
inline int getLocalPlayerIndex(void) { return m_localPlayer; }
|
||||
virtual void updateOrphanedObjects(int *playerIndexList, int numNonLocalPlayers);
|
||||
virtual void releasePartitionData(void); ///<saves data needed to later rebuild partition manager data.
|
||||
virtual void restorePartitionData(void); ///<restores ghost objects into the partition manager.
|
||||
inline void lockGhostObjects(Bool enableLock) {m_lockGhostObjects=enableLock;} ///<temporary lock on creating new ghost objects. Only used by map border resizing!
|
||||
inline void saveLockGhostObjects(Bool enableLock) {m_saveLockGhostObjects=enableLock;}
|
||||
protected:
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
Int m_localPlayer;
|
||||
Bool m_lockGhostObjects;
|
||||
Bool m_saveLockGhostObjects; ///< used to lock the ghost object system during a save/load
|
||||
};
|
||||
|
||||
// the singleton
|
||||
extern GhostObjectManager *TheGhostObjectManager;
|
||||
|
||||
#endif // _GAME_DISPLAY_H_
|
||||
492
Generals/Code/GameEngine/Include/GameLogic/Locomotor.h
Normal file
492
Generals/Code/GameEngine/Include/GameLogic/Locomotor.h
Normal file
@@ -0,0 +1,492 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: Locomotor.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Steven Johnson, Feb 2002
|
||||
// Desc: Locomotor Descriptions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __Locomotor_H_
|
||||
#define __Locomotor_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/NameKeyGenerator.h"
|
||||
#include "Common/Override.h"
|
||||
#include "Common/Snapshot.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
#include "GameLogic/LocomotorSet.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Locomotor;
|
||||
class LocomotorTemplate;
|
||||
class INI;
|
||||
class PhysicsBehavior;
|
||||
enum BodyDamageType;
|
||||
enum PhysicsTurningType;
|
||||
|
||||
// if we ever re-enable jets circling for landing, we need this. so keep in around just in case. (srj)
|
||||
#define NO_CIRCLE_FOR_LANDING
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum LocomotorAppearance
|
||||
{
|
||||
LOCO_LEGS_TWO,
|
||||
LOCO_WHEELS_FOUR,
|
||||
LOCO_TREADS,
|
||||
LOCO_HOVER,
|
||||
LOCO_THRUST,
|
||||
LOCO_WINGS,
|
||||
LOCO_CLIMBER, // human climber - backs down cliffs.
|
||||
LOCO_OTHER
|
||||
};
|
||||
|
||||
enum LocomotorPriority
|
||||
{
|
||||
LOCO_MOVES_BACK=0, // In a group, this one moves toward the back
|
||||
LOCO_MOVES_MIDDLE=1, // In a group, this one stays in the middle
|
||||
LOCO_MOVES_FRONT=2 // In a group, this one moves toward the front of the group
|
||||
};
|
||||
|
||||
#ifdef DEFINE_LOCO_APPEARANCE_NAMES
|
||||
static const char *TheLocomotorAppearanceNames[] =
|
||||
{
|
||||
"TWO_LEGS",
|
||||
"FOUR_WHEELS",
|
||||
"TREADS",
|
||||
"HOVER",
|
||||
"THRUST",
|
||||
"WINGS",
|
||||
"CLIMBER",
|
||||
"OTHER",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum LocomotorBehaviorZ
|
||||
{
|
||||
Z_NO_Z_MOTIVE_FORCE, // does whatever physics tells it, but has no z-force of its own.
|
||||
Z_SEA_LEVEL, // keep at surface-of-water level
|
||||
Z_SURFACE_RELATIVE_HEIGHT, // try to follow a specific height relative to terrain/water height
|
||||
Z_ABSOLUTE_HEIGHT, // try follow a specific height regardless of terrain/water height
|
||||
Z_FIXED_SURFACE_RELATIVE_HEIGHT, // stays fixed at surface-rel height, regardless of physics
|
||||
Z_FIXED_ABSOLUTE_HEIGHT, // stays fixed at absolute height, regardless of physics
|
||||
Z_RELATIVE_TO_GROUND_AND_BUILDINGS, // stays fixed at surface-rel height including buildings, regardless of physics
|
||||
Z_SMOOTH_RELATIVE_TO_HIGHEST_LAYER // try to follow a height relative to the highest layer.
|
||||
};
|
||||
|
||||
#ifdef DEFINE_LOCO_Z_NAMES
|
||||
static const char *TheLocomotorBehaviorZNames[] =
|
||||
{
|
||||
"NO_Z_MOTIVE_FORCE",
|
||||
"SEA_LEVEL",
|
||||
"SURFACE_RELATIVE_HEIGHT",
|
||||
"ABSOLUTE_HEIGHT",
|
||||
"FIXED_SURFACE_RELATIVE_HEIGHT",
|
||||
"FIXED_ABSOLUTE_HEIGHT",
|
||||
"FIXED_RELATIVE_TO_GROUND_AND_BUILDINGS",
|
||||
"RELATIVE_TO_HIGHEST_LAYER",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class LocomotorTemplate : public Overridable
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( LocomotorTemplate, "LocomotorTemplate" )
|
||||
friend class Locomotor;
|
||||
|
||||
public:
|
||||
|
||||
LocomotorTemplate();
|
||||
|
||||
/// field table for loading the values from an INI
|
||||
const FieldParse* getFieldParse() const;
|
||||
|
||||
void friend_setName(const AsciiString& n) { m_name = n; }
|
||||
|
||||
void validate();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
private:
|
||||
/**
|
||||
Units check:
|
||||
|
||||
-- Velocity: dist/frame
|
||||
-- Acceleration: dist/(frame*frame)
|
||||
-- Forces: (mass*dist)/(frame*frame)
|
||||
*/
|
||||
AsciiString m_name;
|
||||
LocomotorSurfaceTypeMask m_surfaces; ///< flags indicating the kinds of surfaces we can use
|
||||
Real m_maxSpeed; ///< max speed
|
||||
Real m_maxSpeedDamaged; ///< max speed when "damaged"
|
||||
Real m_minSpeed; ///< we should never brake past this
|
||||
Real m_maxTurnRate; ///< max rate at which we can turn, in rads/frame
|
||||
Real m_maxTurnRateDamaged; ///< max turn rate when "damaged"
|
||||
Real m_acceleration; ///< max acceleration
|
||||
Real m_accelerationDamaged; ///< max acceleration when damaged
|
||||
Real m_lift; ///< max lifting acceleration (flying objects only)
|
||||
Real m_liftDamaged; ///< max lift when damaged
|
||||
Real m_braking; ///< max braking (deceleration)
|
||||
Real m_minTurnSpeed; ///< we must be going >= this speed in order to turn
|
||||
Real m_preferredHeight; ///< our preferred height (if flying)
|
||||
Real m_preferredHeightDamping; ///< how aggressively to adjust to preferred height: 1.0 = very much so, 0.1 = gradually, etc
|
||||
Real m_circlingRadius; ///< for flying things, the radius at which they circle their "maintain" destination. (pos = cw, neg = ccw, 0 = smallest possible)
|
||||
Real m_speedLimitZ; ///< try to avoid going up or down at more than this speed, if possible
|
||||
Real m_extra2DFriction; ///< extra 2dfriction to apply (via Physics)
|
||||
Real m_maxThrustAngle; ///< THRUST locos only: how much we deflect our thrust angle
|
||||
LocomotorBehaviorZ m_behaviorZ; ///< z-axis behavior
|
||||
LocomotorAppearance m_appearance; ///< how we should diddle the Drawable to imitate this motion
|
||||
LocomotorPriority m_movePriority; ///< Where we move - front, middle, back.
|
||||
|
||||
Real m_accelPitchLimit; ///< Maximum amount we will pitch up or down under acceleration (including recoil.)
|
||||
Real m_bounceKick; ///< How much simulating rough terrain "bounces" a wheel up.
|
||||
Real m_pitchStiffness; ///< How stiff the springs are forward & back.
|
||||
Real m_rollStiffness; ///< How stiff the springs are side to side.
|
||||
Real m_pitchDamping; ///< How good the shock absorbers are.
|
||||
Real m_rollDamping; ///< How good the shock absorbers are.
|
||||
Real m_pitchByZVelCoef; ///< How much we pitch in response to z-speed.
|
||||
Real m_thrustRoll; ///< Thrust roll around X axis
|
||||
Real m_wobbleRate; ///< how fast thrust things "wobble"
|
||||
Real m_minWobble; ///< how much thrust things "wobble"
|
||||
Real m_maxWobble; ///< how much thrust things "wobble"
|
||||
Real m_forwardVelCoef; ///< How much we pitch in response to speed.
|
||||
Real m_lateralVelCoef; ///< How much we roll in response to speed.
|
||||
Real m_forwardAccelCoef; ///< How much we pitch in response to acceleration.
|
||||
Real m_lateralAccelCoef; ///< How much we roll in response to acceleration.
|
||||
Real m_uniformAxialDamping; ///< For Attenuating the pitch and roll rates
|
||||
Real m_turnPivotOffset; ///< should we pivot around noncenter? (-1.0 = rear, 0.0 = center, 1.0 = front)
|
||||
Int m_airborneTargetingHeight; ///< The height transition at witch I should mark myself as a AA target.
|
||||
|
||||
Real m_closeEnoughDist; ///< How close we have to approach the end of a path before stopping
|
||||
Bool m_isCloseEnoughDist3D; ///< And is that calculation 3D, for very rare cases that need to move straight down.
|
||||
Real m_ultraAccurateSlideIntoPlaceFactor; ///< how much we can fudge turning when ultra-accurate
|
||||
|
||||
Bool m_locomotorWorksWhenDead; ///< should locomotor continue working even when object is "dead"?
|
||||
Bool m_allowMotiveForceWhileAirborne; ///< can we apply motive when airborne?
|
||||
Bool m_apply2DFrictionWhenAirborne; // apply "2d friction" even when airborne... useful for realistic-looking movement
|
||||
Bool m_downhillOnly; // pinewood derby, moves only by gravity pulling downhill
|
||||
Bool m_stickToGround; // if true, can't leave ground
|
||||
Bool m_canMoveBackward; // if true, can move backwards.
|
||||
Bool m_hasSuspension; ///< If true, calculate 4 wheel independent suspension values.
|
||||
Real m_maximumWheelExtension; ///< Maximum distance wheels can move down. (negative value)
|
||||
Real m_maximumWheelCompression; ///< Maximum distance wheels can move up. (positive value)
|
||||
Real m_wheelTurnAngle; ///< How far the front wheels can turn.
|
||||
|
||||
// Fields for wander locomotor
|
||||
Real m_wanderWidthFactor;
|
||||
Real m_wanderLengthFactor;
|
||||
Real m_wanderAboutPointRadius;
|
||||
};
|
||||
|
||||
typedef OVERRIDE<LocomotorTemplate> LocomotorTemplateOverride;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
class Locomotor : public MemoryPoolObject, public Snapshot
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(Locomotor, "Locomotor" )
|
||||
|
||||
friend class LocomotorStore;
|
||||
|
||||
public:
|
||||
|
||||
void setPhysicsOptions(Object* obj);
|
||||
|
||||
void locoUpdate_moveTowardsPosition(Object* obj, const Coord3D& goalPos,
|
||||
Real onPathDistToGoal, Real desiredSpeed, Bool *blocked);
|
||||
void locoUpdate_moveTowardsAngle(Object* obj, Real angle);
|
||||
/**
|
||||
Kill any current (2D) velocity (but stay at current position, or as close as possible)
|
||||
|
||||
return true if we can maintain the position without being called every frame (eg, we are
|
||||
resting on the ground), false if not (eg, we are hovering or circling)
|
||||
*/
|
||||
Bool locoUpdate_maintainCurrentPosition(Object* obj);
|
||||
|
||||
Real getMaxSpeedForCondition(BodyDamageType condition) const; ///< get max speed given condition
|
||||
Real getMaxTurnRate(BodyDamageType condition) const; ///< get max turning rate given condition
|
||||
Real getMaxAcceleration(BodyDamageType condition) const; ///< get acceleration given condition
|
||||
Real getMaxLift(BodyDamageType condition) const; ///< get acceleration given condition
|
||||
Real getBraking() const; ///< get braking given condition
|
||||
|
||||
inline Real getPreferredHeight() const { return m_preferredHeight;} ///< Just return preferredheight, no damage consideration
|
||||
inline void restorePreferredHeightFromTemplate() { m_preferredHeight = m_template->m_preferredHeight; };
|
||||
inline Real getPreferredHeightDamping() const { return m_preferredHeightDamping;}
|
||||
inline LocomotorAppearance getAppearance() const { return m_template->m_appearance; }
|
||||
inline LocomotorPriority getMovePriority() const { return m_template->m_movePriority; }
|
||||
inline LocomotorSurfaceTypeMask getLegalSurfaces() const { return m_template->m_surfaces; }
|
||||
|
||||
inline AsciiString getTemplateName() const { return m_template->m_name;}
|
||||
inline Real getMinSpeed() const { return m_template->m_minSpeed;}
|
||||
inline Real getAccelPitchLimit() const { return m_template->m_accelPitchLimit;} ///< Maximum amount we will pitch up or down under acceleration (including recoil.)
|
||||
inline Real getBounceKick() const { return m_template->m_bounceKick;} ///< How much simulating rough terrain "bounces" a wheel up.
|
||||
inline Real getPitchStiffness() const { return m_template->m_pitchStiffness;} ///< How stiff the springs are forward & back.
|
||||
inline Real getRollStiffness() const { return m_template->m_rollStiffness;} ///< How stiff the springs are side to side.
|
||||
inline Real getPitchDamping() const { return m_template->m_pitchDamping;} ///< How good the shock absorbers are.
|
||||
inline Real getRollDamping() const { return m_template->m_rollDamping;} ///< How good the shock absorbers are.
|
||||
inline Real getPitchByZVelCoef() const { return m_template->m_pitchByZVelCoef;} ///< How much we pitch in response to speed.
|
||||
inline Real getThrustRoll() const { return m_template->m_thrustRoll; } ///< Thrust roll
|
||||
inline Real getWobbleRate() const { return m_template->m_wobbleRate; } ///< how fast thrust things "wobble"
|
||||
inline Real getMaxWobble() const { return m_template->m_maxWobble; } ///< how much thrust things "wobble"
|
||||
inline Real getMinWobble() const { return m_template->m_minWobble; } ///< how much thrust things "wobble"
|
||||
|
||||
inline Real getForwardVelCoef() const { return m_template->m_forwardVelCoef;} ///< How much we pitch in response to speed.
|
||||
inline Real getLateralVelCoef() const { return m_template->m_lateralVelCoef;} ///< How much we roll in response to speed.
|
||||
inline Real getForwardAccelCoef() const { return m_template->m_forwardAccelCoef;} ///< How much we pitch in response to acceleration.
|
||||
inline Real getLateralAccelCoef() const { return m_template->m_lateralAccelCoef;} ///< How much we roll in response to acceleration.
|
||||
inline Real getUniformAxialDamping() const { return m_template->m_uniformAxialDamping;} ///< How much we roll in response to acceleration.
|
||||
inline Real getTurnPivotOffset() const { return m_template->m_turnPivotOffset;}
|
||||
inline Bool getApply2DFrictionWhenAirborne() const { return m_template->m_apply2DFrictionWhenAirborne; }
|
||||
inline Bool getIsDownhillOnly() const { return m_template->m_downhillOnly; }
|
||||
inline Bool getAllowMotiveForceWhileAirborne() const { return m_template->m_allowMotiveForceWhileAirborne; }
|
||||
inline Int getAirborneTargetingHeight() const { return m_template->m_airborneTargetingHeight; }
|
||||
inline Bool getLocomotorWorksWhenDead() const { return m_template->m_locomotorWorksWhenDead; }
|
||||
inline Bool getStickToGround() const { return m_template->m_stickToGround; }
|
||||
inline Real getCloseEnoughDist() const { return m_closeEnoughDist; }
|
||||
inline Bool isCloseEnoughDist3D() const { return getFlag(IS_CLOSE_ENOUGH_DIST_3D); }
|
||||
inline Bool hasSuspension() const {return m_template->m_hasSuspension;}
|
||||
inline Bool canMoveBackwards() const {return m_template->m_canMoveBackward;}
|
||||
inline Real getMaxWheelExtension() const {return m_template->m_maximumWheelExtension;}
|
||||
inline Real getMaxWheelCompression() const {return m_template->m_maximumWheelCompression;}
|
||||
inline Real getWheelTurnAngle() const {return m_template->m_wheelTurnAngle;}
|
||||
|
||||
inline Real getWanderWidthFactor() const {return m_template->m_wanderWidthFactor;}
|
||||
inline Real getWanderAboutPointRadius() const {return m_template->m_wanderAboutPointRadius;}
|
||||
|
||||
Real calcMinTurnRadius(BodyDamageType condition, Real* timeToTravelThatDist) const;
|
||||
|
||||
/// this is handy for doing things like forcing helicopters to crash realistically: cut their lift.
|
||||
inline void setMaxLift(Real lift) { m_maxLift = lift; }
|
||||
inline void setMaxSpeed(Real speed)
|
||||
{
|
||||
DEBUG_ASSERTCRASH(!(speed <= 0.0f && m_template->m_appearance == LOCO_THRUST), ("THRUST locos may not have zero speeds!\n"));
|
||||
m_maxSpeed = speed;
|
||||
}
|
||||
inline void setMaxAcceleration(Real accel) { m_maxAccel = accel; }
|
||||
inline void setMaxBraking(Real braking) { m_maxBraking = braking; }
|
||||
inline void setMaxTurnRate(Real turn) { m_maxTurnRate = turn; }
|
||||
inline void setAllowInvalidPosition(Bool allow) { setFlag(ALLOW_INVALID_POSITION, allow); }
|
||||
inline void setCloseEnoughDist( Real dist ) { m_closeEnoughDist = dist; }
|
||||
inline void setCloseEnoughDist3D( Bool setting ) { setFlag(IS_CLOSE_ENOUGH_DIST_3D, setting); }
|
||||
|
||||
inline void setPreferredHeight( Real height ) { m_preferredHeight = height; }
|
||||
|
||||
#ifdef CIRCLE_FOR_LANDING
|
||||
/**
|
||||
if we are climbing/diving more than this, circle as needed rather
|
||||
than just diving or climbing directly. (only useful for Winged things)
|
||||
*/
|
||||
inline void setAltitudeChangeThresholdForCircling(Real a) { m_circleThresh = a; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
when off (the default), things get to adjust their z-pos as their
|
||||
loco says (in particular, airborne things tend to try to fly at a preferred height).
|
||||
|
||||
when on, they do their best to reach the specified zpos, even if it's not at their preferred height.
|
||||
this is used mainly for force missiles to swoop in on their target, and to force airplane takeoff/landing
|
||||
to go smoothly.
|
||||
*/
|
||||
inline void setUsePreciseZPos(Bool u) { setFlag(PRECISE_Z_POS, u); }
|
||||
|
||||
/**
|
||||
when off (the default), units slow down as they approach their target.
|
||||
|
||||
when on, units go full speed till the end, and may overshoot their target.
|
||||
this is useful mainly in some weird, temporary situations where we know we are
|
||||
going to follow this move with another one... or for carbombs.
|
||||
*/
|
||||
inline void setNoSlowDownAsApproachingDest(Bool u) { setFlag(NO_SLOW_DOWN_AS_APPROACHING_DEST, u); }
|
||||
|
||||
/**
|
||||
when off (the default), units do their normal stuff.
|
||||
|
||||
when on, we cheat and make very precise motion, regardless of loco settings.
|
||||
this is accomplished by cranking up the unit's turning rate, friction, lift (for airborne things),
|
||||
and possibly other things. This is useful mainly when doing maneuvers where precision
|
||||
is VITAL, such as airplane takeoff/landing.
|
||||
|
||||
For ground units, it also allows units to have a destination off of a pathfing grid.
|
||||
|
||||
*/
|
||||
inline void setUltraAccurate(Bool u) { setFlag(ULTRA_ACCURATE, u); }
|
||||
inline Bool isUltraAccurate() const { return getFlag(ULTRA_ACCURATE); }
|
||||
|
||||
inline Bool isMovingBackwards(void) const {return getFlag(MOVING_BACKWARDS);}
|
||||
|
||||
void startMove(void); ///< Indicates that a move is starting, primarily to reset the donut timer. jba.
|
||||
|
||||
protected:
|
||||
void moveTowardsPositionLegs(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionLegsWander(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionClimb(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionWheels(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionTreads(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionOther(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionHover(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionThrust(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
void moveTowardsPositionWings(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos, Real onPathDistToGoal, Real desiredSpeed);
|
||||
|
||||
void maintainCurrentPositionThrust(Object* obj, PhysicsBehavior *physics);
|
||||
void maintainCurrentPositionOther(Object* obj, PhysicsBehavior *physics);
|
||||
void maintainCurrentPositionLegs(Object* obj, PhysicsBehavior *physics) { maintainCurrentPositionOther(obj, physics); }
|
||||
void maintainCurrentPositionWheels(Object* obj, PhysicsBehavior *physics) { maintainCurrentPositionOther(obj, physics); }
|
||||
void maintainCurrentPositionTreads(Object* obj, PhysicsBehavior *physics) { maintainCurrentPositionOther(obj, physics); }
|
||||
void maintainCurrentPositionHover(Object* obj, PhysicsBehavior *physics);
|
||||
void maintainCurrentPositionWings(Object* obj, PhysicsBehavior *physics);
|
||||
|
||||
PhysicsTurningType rotateTowardsPosition(Object* obj, const Coord3D& goalPos, Real *relAngle=NULL);
|
||||
|
||||
/*
|
||||
return true if we can maintain the position without being called every frame (eg, we are
|
||||
resting on the ground), false if not (eg, we are hovering or circling)
|
||||
*/
|
||||
Bool handleBehaviorZ(Object* obj, PhysicsBehavior *physics, const Coord3D& goalPos);
|
||||
PhysicsTurningType rotateObjAroundLocoPivot(Object* obj, const Coord3D& goalPos, Real maxTurnRate, Real *relAngle = NULL);
|
||||
|
||||
Real getSurfaceHtAtPt(Real x, Real y);
|
||||
Real calcLiftToUseAtPt(Object* obj, PhysicsBehavior *physics, Real curZ, Real surfaceAtPt, Real preferredHeight);
|
||||
|
||||
Bool fixInvalidPosition(Object* obj, PhysicsBehavior *physics);
|
||||
|
||||
protected:
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
protected:
|
||||
|
||||
Locomotor(const LocomotorTemplate* tmpl);
|
||||
|
||||
// Note, "Law of the Big Three" applies here
|
||||
//Locomotor(); -- nope, we don't have a default ctor. (srj)
|
||||
Locomotor(const Locomotor& that);
|
||||
Locomotor& operator=(const Locomotor& that);
|
||||
//~Locomotor();
|
||||
|
||||
private:
|
||||
|
||||
//
|
||||
// Note: these values are saved in save files, so you MUST NOT REMOVE OR CHANGE
|
||||
// existing values!
|
||||
//
|
||||
enum LocoFlag
|
||||
{
|
||||
IS_BRAKING = 0,
|
||||
ALLOW_INVALID_POSITION,
|
||||
MAINTAIN_POS_IS_VALID,
|
||||
PRECISE_Z_POS,
|
||||
NO_SLOW_DOWN_AS_APPROACHING_DEST,
|
||||
OVER_WATER, // To allow things to move slower/faster over water and do special effects
|
||||
ULTRA_ACCURATE,
|
||||
MOVING_BACKWARDS, // If we are moving backwards.
|
||||
DOING_THREE_POINT_TURN, // If we are doing a 3 pt turn.
|
||||
CLIMBING, // If we are in the process of climbing.
|
||||
IS_CLOSE_ENOUGH_DIST_3D,
|
||||
OFFSET_INCREASING
|
||||
};
|
||||
|
||||
inline Bool getFlag(LocoFlag f) const { return (m_flags & (1 << f)) != 0; }
|
||||
inline void setFlag(LocoFlag f, Bool b) { if (b) m_flags |= (1<<f); else m_flags &= ~(1<<f); }
|
||||
|
||||
LocomotorTemplateOverride m_template; ///< the kind of Locomotor this is
|
||||
Coord3D m_maintainPos;
|
||||
Real m_brakingFactor;
|
||||
Real m_maxLift;
|
||||
Real m_maxSpeed;
|
||||
Real m_maxAccel;
|
||||
Real m_maxBraking;
|
||||
Real m_maxTurnRate;
|
||||
Real m_closeEnoughDist;
|
||||
#ifdef CIRCLE_FOR_LANDING
|
||||
Real m_circleThresh;
|
||||
#endif
|
||||
UnsignedInt m_flags;
|
||||
Real m_preferredHeight;
|
||||
Real m_preferredHeightDamping;
|
||||
|
||||
Real m_angleOffset;
|
||||
Real m_offsetIncrement;
|
||||
UnsignedInt m_donutTimer; ///< Frame time to keep units from doing the donut. jba.
|
||||
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
The "store" used to hold all the LocomotorTemplates in existence. This is usually used when creating
|
||||
an Object, but can be used at any time after that. (It is explicitly
|
||||
OK to swap an Object's Locomotor out at any given time.)
|
||||
*/
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class LocomotorStore : public SubsystemInterface
|
||||
{
|
||||
public:
|
||||
|
||||
LocomotorStore();
|
||||
~LocomotorStore();
|
||||
|
||||
void init() { };
|
||||
void reset();
|
||||
void update();
|
||||
|
||||
/**
|
||||
Find the LocomotorTemplate with the given name. If no such LocomotorTemplate exists, return null.
|
||||
*/
|
||||
const LocomotorTemplate* findLocomotorTemplate(NameKeyType namekey) const;
|
||||
LocomotorTemplate* findLocomotorTemplate(NameKeyType namekey);
|
||||
|
||||
inline Locomotor* newLocomotor(const LocomotorTemplate *tmpl) const
|
||||
{
|
||||
return newInstance(Locomotor)(tmpl); // my, that was easy
|
||||
}
|
||||
|
||||
// locoTemplate is who we're overriding
|
||||
LocomotorTemplate *newOverride(LocomotorTemplate *locoTemplate);
|
||||
|
||||
|
||||
static void parseLocomotorTemplateDefinition(INI* ini);
|
||||
|
||||
protected:
|
||||
|
||||
private:
|
||||
|
||||
typedef std::map< NameKeyType, LocomotorTemplate*, std::less<NameKeyType> > LocomotorTemplateMap;
|
||||
|
||||
LocomotorTemplateMap m_locomotorTemplates;
|
||||
|
||||
};
|
||||
|
||||
// EXTERNALS //////////////////////////////////////////////////////////////////////////////////////
|
||||
extern LocomotorStore *TheLocomotorStore;
|
||||
|
||||
#endif // __Locomotor_H_
|
||||
|
||||
114
Generals/Code/GameEngine/Include/GameLogic/LocomotorSet.h
Normal file
114
Generals/Code/GameEngine/Include/GameLogic/LocomotorSet.h
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: LocomotorSet.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Steven Johnson, Feb 2002
|
||||
// Desc: Locomotor Descriptions
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __LocomotorSet_H_
|
||||
#define __LocomotorSet_H_
|
||||
|
||||
// no, please do NOT include this.
|
||||
//#include "GameLogic/Locomotor.h"
|
||||
#include "Common/GameCommon.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
#include "Common/Snapshot.h"
|
||||
|
||||
class Locomotor;
|
||||
class LocomotorTemplate;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Note: these values are saved in save files, so you MUST NOT REMOVE OR CHANGE
|
||||
// existing values!
|
||||
//
|
||||
enum LocomotorSurfaceType
|
||||
{
|
||||
LOCOMOTORSURFACE_GROUND = (1 << 0), ///< clear, unobstructed ground
|
||||
LOCOMOTORSURFACE_WATER = (1 << 1), ///< water area
|
||||
LOCOMOTORSURFACE_CLIFF = (1 << 2), ///< steep altitude change
|
||||
LOCOMOTORSURFACE_AIR = (1 << 3), ///< airborne
|
||||
LOCOMOTORSURFACE_RUBBLE = (1 << 4) ///< building rubble
|
||||
};
|
||||
|
||||
typedef Int LocomotorSurfaceTypeMask;
|
||||
|
||||
const LocomotorSurfaceTypeMask NO_SURFACES = (LocomotorSurfaceTypeMask)0x0000;
|
||||
const LocomotorSurfaceTypeMask ALL_SURFACES = (LocomotorSurfaceTypeMask)0xffff;
|
||||
|
||||
#ifdef DEFINE_SURFACECATEGORY_NAMES
|
||||
static const char *TheLocomotorSurfaceTypeNames[] =
|
||||
{
|
||||
"GROUND",
|
||||
"WATER",
|
||||
"CLIFF",
|
||||
"AIR",
|
||||
"RUBBLE",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
typedef std::vector< Locomotor* > LocomotorVector;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class LocomotorSet : public Snapshot
|
||||
{
|
||||
private:
|
||||
LocomotorVector m_locomotors;
|
||||
LocomotorSurfaceTypeMask m_validLocomotorSurfaces;
|
||||
Bool m_downhillOnly;
|
||||
|
||||
LocomotorSet(const LocomotorSet& that);
|
||||
LocomotorSet& operator=(const LocomotorSet& that);
|
||||
|
||||
protected:
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
public:
|
||||
|
||||
LocomotorSet();
|
||||
~LocomotorSet();
|
||||
|
||||
void clear();
|
||||
|
||||
void addLocomotor(const LocomotorTemplate* lt);
|
||||
|
||||
Locomotor* findLocomotor(LocomotorSurfaceTypeMask t);
|
||||
|
||||
void xferSelfAndCurLocoPtr(Xfer *xfer, Locomotor** loco);
|
||||
|
||||
inline LocomotorSurfaceTypeMask getValidSurfaces() const { return m_validLocomotorSurfaces; }
|
||||
inline Bool isDownhillOnly( void ) const { return m_downhillOnly; };
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// LogicRandomValue.h
|
||||
// Random number generation system
|
||||
// Author: Michael S. Booth, January 1998
|
||||
// Split out into separate Logic/Client/Audio headers by MDC Sept 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _LOGIC_RANDOM_VALUE_H_
|
||||
#define _LOGIC_RANDOM_VALUE_H_
|
||||
|
||||
#include "Lib/BaseType.h"
|
||||
|
||||
// do NOT use these functions directly, rather use the macros below
|
||||
extern Int GetGameLogicRandomValue( int lo, int hi, char *file, int line );
|
||||
extern Real GetGameLogicRandomValueReal( Real lo, Real hi, char *file, int line );
|
||||
|
||||
// use these macros to access the random value functions
|
||||
#define GameLogicRandomValue( lo, hi ) GetGameLogicRandomValue( lo, hi, __FILE__, __LINE__ )
|
||||
#define GameLogicRandomValueReal( lo, hi ) GetGameLogicRandomValueReal( lo, hi, __FILE__, __LINE__ )
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
class CColorAlphaDialog;
|
||||
class DebugWindowDialog;
|
||||
|
||||
/**
|
||||
* A GameLogicRandomVariable represents a distribution of random values
|
||||
* from which discrete values can be retrieved.
|
||||
*/
|
||||
class GameLogicRandomVariable
|
||||
{
|
||||
public:
|
||||
// NOTE: This class cannot have a constructor or destructor due to its use within unions
|
||||
|
||||
/**
|
||||
* CONSTANT represents a single, constant, value.
|
||||
* UNIFORM represents a uniform distribution of random values.
|
||||
* GAUSSIAN represents a normally distributed set of random values.
|
||||
* TRIANGULAR represents a distribution of random values in the shape
|
||||
* of a triangle, with the peak probability midway between low and high.
|
||||
* LOW_BIAS represents a distribution of random values with
|
||||
* maximum probability at low, and zero probability at high.
|
||||
* HIGH_BIAS represents a distribution of random values with
|
||||
* zero probability at low, and maximum probability at high.
|
||||
*/
|
||||
enum DistributionType
|
||||
{
|
||||
CONSTANT, UNIFORM, GAUSSIAN, TRIANGULAR, LOW_BIAS, HIGH_BIAS
|
||||
};
|
||||
|
||||
static const char *DistributionTypeNames[];
|
||||
|
||||
/// define the range of random values, and the distribution of values
|
||||
void setRange( Real low, Real high, DistributionType type = UNIFORM );
|
||||
|
||||
Real getValue( void ) const; ///< return a value from the random distribution
|
||||
inline Real getMinimumValue( void ) const { return m_low; }
|
||||
inline Real getMaximumValue( void ) const { return m_high; }
|
||||
inline DistributionType getDistributionType( void ) const { return m_type; }
|
||||
protected:
|
||||
DistributionType m_type; ///< the kind of random distribution
|
||||
Real m_low, m_high; ///< the range of random values
|
||||
|
||||
// These two friends are for particle editing.
|
||||
friend CColorAlphaDialog;
|
||||
friend DebugWindowDialog;
|
||||
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif // _LOGIC_RANDOM_VALUE_H_
|
||||
788
Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h
Normal file
788
Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h
Normal file
@@ -0,0 +1,788 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AIUpdate.h //
|
||||
// AI interface
|
||||
// Author: Michael S. Booth, 2001-2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _AI_UPDATE_H_
|
||||
#define _AI_UPDATE_H_
|
||||
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameLogic/AI.h"
|
||||
#include "GameLogic/AIStateMachine.h"
|
||||
#include "GameLogic/GameLogic.h"
|
||||
#include "GameLogic/LocomotorSet.h"
|
||||
|
||||
class AIGroup;
|
||||
class AIStateMachine;
|
||||
class AttackPriorityInfo;
|
||||
class DamageInfo;
|
||||
class DozerAIInterface;
|
||||
class Object;
|
||||
class Path;
|
||||
class PathfindServicesInterface;
|
||||
class PathNode;
|
||||
class PhysicsBehavior;
|
||||
#ifdef ALLOW_SURRENDER
|
||||
class POWTruckAIUpdateInterface;
|
||||
#endif
|
||||
class SupplyTruckAIInterface;
|
||||
class TurretAI;
|
||||
class TurretAIData;
|
||||
class Waypoint;
|
||||
class WorkerAIInterface;
|
||||
class HackInternetAIInterface;
|
||||
class AssaultTransportAIInterface;
|
||||
|
||||
enum AIStateType;
|
||||
enum ObjectID;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
const Real FAST_AS_POSSIBLE = 999999.0f;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Note: these values are saved in save files, so you MUST NOT REMOVE OR CHANGE
|
||||
// existing values!
|
||||
//
|
||||
enum LocomotorSetType
|
||||
{
|
||||
LOCOMOTORSET_INVALID = -1,
|
||||
|
||||
LOCOMOTORSET_NORMAL = 0,
|
||||
LOCOMOTORSET_NORMAL_UPGRADED,
|
||||
LOCOMOTORSET_FREEFALL,
|
||||
LOCOMOTORSET_WANDER,
|
||||
LOCOMOTORSET_PANIC,
|
||||
LOCOMOTORSET_TAXIING, // set used for normally-airborne items while taxiing on ground
|
||||
LOCOMOTORSET_SUPERSONIC, // set used for high-speed attacks
|
||||
LOCOMOTORSET_SLUGGISH, // set used for abnormally slow (but not damaged) speeds
|
||||
|
||||
LOCOMOTORSET_COUNT ///< keep last, please
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum GuardTargetType
|
||||
{
|
||||
GUARDTARGET_LOCATION, // Guard a coord3d
|
||||
GUARDTARGET_OBJECT, // Guard an object
|
||||
GUARDTARGET_AREA, // Guard a Polygon trigger
|
||||
GUARDTARGET_NONE // Currently not guarding
|
||||
};
|
||||
|
||||
#ifdef DEFINE_LOCOMOTORSET_NAMES
|
||||
static const char *TheLocomotorSetNames[] =
|
||||
{
|
||||
"SET_NORMAL",
|
||||
"SET_NORMAL_UPGRADED",
|
||||
"SET_FREEFALL",
|
||||
"SET_WANDER",
|
||||
"SET_PANIC",
|
||||
"SET_TAXIING",
|
||||
"SET_SUPERSONIC",
|
||||
"SET_SLUGGISH",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
enum AutoAcquireStates
|
||||
{
|
||||
AAS_Idle = 0x01,
|
||||
AAS_Idle_Stealthed = 0x02,
|
||||
AAS_Idle_No = 0x04,
|
||||
AAS_Idle_Not_While_Attacking = 0x08,
|
||||
AAS_Idle_Attack_Buildings = 0x10,
|
||||
};
|
||||
|
||||
#ifdef DEFINE_AUTOACQUIRE_NAMES
|
||||
static const char *TheAutoAcquireEnemiesNames[] =
|
||||
{
|
||||
"YES",
|
||||
"STEALTHED",
|
||||
"NO",
|
||||
"NOTWHILEATTACKING",
|
||||
"ATTACK_BUILDINGS",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum MoodMatrixParameters
|
||||
{
|
||||
// Controller_Player and Controller_AI are mutually exclusive
|
||||
MM_Controller_Player = 0x00000001,
|
||||
MM_Controller_AI = 0x00000002,
|
||||
MM_Controller_Bitmask = (MM_Controller_Player | MM_Controller_AI),
|
||||
|
||||
// UnitTypes are mutually exclusive, ie: you cannot be turreted and air at the same time (we do
|
||||
// not make such a distinction, so air takes precedence over turretedness)
|
||||
MM_UnitType_NonTurreted = 0x00000010,
|
||||
MM_UnitType_Turreted = 0x00000020,
|
||||
MM_UnitType_Air = 0x00000040,
|
||||
MM_UnitType_Bitmask = (MM_UnitType_NonTurreted | MM_UnitType_Turreted | MM_UnitType_Air),
|
||||
|
||||
// A unit can be in only one mood at a time.
|
||||
MM_Mood_Sleep = 0x00000100,
|
||||
MM_Mood_Passive = 0x00000200,
|
||||
MM_Mood_Normal = 0x00000400,
|
||||
MM_Mood_Alert = 0x00000800,
|
||||
MM_Mood_Aggressive = 0x00001000,
|
||||
MM_Mood_Bitmask = (MM_Mood_Sleep | MM_Mood_Passive | MM_Mood_Normal | MM_Mood_Alert | MM_Mood_Aggressive)
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum MoodMatrixAction
|
||||
{
|
||||
MM_Action_Idle,
|
||||
MM_Action_Move,
|
||||
MM_Action_Attack,
|
||||
MM_Action_AttackMove
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum MoodActionAdjustment
|
||||
{
|
||||
MAA_Action_Ok = 0x00000001,
|
||||
MAA_Action_To_Idle = 0x00000002,
|
||||
MAA_Action_To_AttackMove = 0x00000004,
|
||||
MAA_Action_To_Bitmask = (MAA_Action_Ok | MAA_Action_To_Idle | MAA_Action_To_AttackMove),
|
||||
|
||||
MAA_Affect_Range_IgnoreAll = 0x00000010,
|
||||
MAA_Affect_Range_WaitForAttack = 0x00000020,
|
||||
// Normal doesn't affect ranges.
|
||||
MAA_Affect_Range_Alert = 0x00000040,
|
||||
MAA_Affect_Range_Aggressive = 0x00000080,
|
||||
MAA_Affect_Range_Bitmask = (MAA_Affect_Range_IgnoreAll | MAA_Affect_Range_WaitForAttack | MAA_Affect_Range_Alert | MAA_Affect_Range_Aggressive)
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
typedef std::vector< const LocomotorTemplate* > LocomotorTemplateVector;
|
||||
typedef std::map< LocomotorSetType, LocomotorTemplateVector, std::less<LocomotorSetType> > LocomotorTemplateMap;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AIUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
LocomotorTemplateMap m_locomotorTemplates; ///< locomotors for object
|
||||
const TurretAIData* m_turretData[MAX_TURRETS];
|
||||
UnsignedInt m_moodAttackCheckRate; ///< how frequently we should recheck for enemies due to moods, when idle
|
||||
UnsignedInt m_autoAcquireEnemiesWhenIdle;
|
||||
#ifdef ALLOW_SURRENDER
|
||||
UnsignedInt m_surrenderDuration; ///< when we surrender, how long we stay surrendered.
|
||||
#endif
|
||||
|
||||
AIUpdateModuleData();
|
||||
virtual ~AIUpdateModuleData();
|
||||
|
||||
virtual Bool isAiModuleData() const { return true; }
|
||||
|
||||
const LocomotorTemplateVector* findLocomotorTemplateVector(LocomotorSetType t) const;
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
static void parseLocomotorSet( INI* ini, void *instance, void *store, const void* /*userData*/ );
|
||||
|
||||
private:
|
||||
static void parseTurret( INI* ini, void *instance, void *store, const void* /*userData*/ );
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum AIFreeToExitType // Note - written out in save/load xfer, don't change these numbers. jba.
|
||||
{
|
||||
FREE_TO_EXIT=0,
|
||||
NOT_FREE_TO_EXIT=1,
|
||||
WAIT_TO_EXIT=2
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/**
|
||||
* The AIUpdateInterface module contains the interface to the AI system,
|
||||
* and performs the actual AI behaviors.
|
||||
*/
|
||||
class AIUpdateInterface : public UpdateModule, public AICommandInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AIUpdateInterface, "AIUpdateInterface" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AIUpdateInterface, AIUpdateModuleData )
|
||||
|
||||
protected:
|
||||
|
||||
// yes, protected, NOT public.
|
||||
virtual void privateMoveToPosition( const Coord3D *pos, CommandSourceType cmdSource ); ///< move to given position(s) tightening the formation.
|
||||
virtual void privateMoveToObject( Object *obj, CommandSourceType cmdSource ); ///< move to given object
|
||||
virtual void privateMoveToAndEvacuate( const Coord3D *pos, CommandSourceType cmdSource ); ///< move to given position(s)
|
||||
virtual void privateMoveToAndEvacuateAndExit( const Coord3D *pos, CommandSourceType cmdSource ); ///< move to given position & unload transport.
|
||||
virtual void privateIdle(CommandSourceType cmdSource); ///< Enter idle state.
|
||||
virtual void privateTightenToPosition( const Coord3D *pos, CommandSourceType cmdSource ); ///< move to given position(s) tightening the formation.
|
||||
virtual void privateFollowWaypointPath( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
virtual void privateFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
virtual void privateFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
virtual void privateFollowWaypointPathAsTeamExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
|
||||
virtual void privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
|
||||
virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource );
|
||||
virtual void privateAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
|
||||
virtual void privateForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
|
||||
virtual void privateAttackTeam( const Team *team, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack the given team
|
||||
virtual void privateAttackPosition( const Coord3D *pos, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given spot
|
||||
virtual void privateAttackMoveToPosition( const Coord3D *pos, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack move to the given location
|
||||
virtual void privateAttackFollowWaypointPath( const Waypoint *way, Int maxShotsToFire, Bool asTeam, CommandSourceType cmdSource ); ///< attack move along the following waypoint path, potentially as a team
|
||||
virtual void privateHunt( CommandSourceType cmdSource ); ///< begin "seek and destroy"
|
||||
virtual void privateRepair( Object *obj, CommandSourceType cmdSource ); ///< repair the given object
|
||||
#ifdef ALLOW_SURRENDER
|
||||
virtual void privatePickUpPrisoner( Object *prisoner, CommandSourceType cmdSource ); ///< pick up prisoner
|
||||
virtual void privateReturnPrisoners( Object *prison, CommandSourceType cmdSource ); ///< return picked up prisoners to the 'prison'
|
||||
#endif
|
||||
virtual void privateResumeConstruction( Object *obj, CommandSourceType cmdSource ); ///< resume construction of object
|
||||
virtual void privateGetHealed( Object *healDepot, CommandSourceType cmdSource ); ///< get healed at heal depot
|
||||
virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot
|
||||
virtual void privateEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object
|
||||
virtual void privateDock( Object *obj, CommandSourceType cmdSource ); ///< get near given object and wait for enter clearance
|
||||
virtual void privateExit( Object *objectToExit, CommandSourceType cmdSource ); ///< get out of this Object
|
||||
virtual void privateEvacuate( Int exposeStealthUnits, CommandSourceType cmdSource ); ///< empty its contents
|
||||
virtual void privateExecuteRailedTransport( CommandSourceType cmdSource ); ///< execute next leg in railed transport sequence
|
||||
virtual void privateGoProne( const DamageInfo *damageInfo, CommandSourceType cmdSource ); ///< life altering state change, if this AI can do it
|
||||
virtual void privateGuardTunnelNetwork( GuardMode guardMode, CommandSourceType cmdSource ); ///< guard the given spot
|
||||
virtual void privateGuardPosition( const Coord3D *pos, GuardMode guardMode, CommandSourceType cmdSource ); ///< guard the given spot
|
||||
virtual void privateGuardObject( Object *objectToGuard, GuardMode guardMode, CommandSourceType cmdSource ); ///< guard the given object
|
||||
virtual void privateGuardArea( const PolygonTrigger *areaToGuard, GuardMode guardMode, CommandSourceType cmdSource ); ///< guard the given area
|
||||
virtual void privateAttackArea( const PolygonTrigger *areaToGuard, CommandSourceType cmdSource ); ///< guard the given area
|
||||
virtual void privateHackInternet( CommandSourceType cmdSource ); ///< Hack money from the heavens (free money)
|
||||
virtual void privateFaceObject( Object *target, CommandSourceType cmdSource );
|
||||
virtual void privateFacePosition( const Coord3D *pos, CommandSourceType cmdSource );
|
||||
virtual void privateRappelInto( Object *target, const Coord3D& pos, CommandSourceType cmdSource );
|
||||
virtual void privateCombatDrop( Object *target, const Coord3D& pos, CommandSourceType cmdSource );
|
||||
virtual void privateCommandButton( const CommandButton *commandButton, CommandSourceType cmdSource );
|
||||
virtual void privateCommandButtonPosition( const CommandButton *commandButton, const Coord3D *pos, CommandSourceType cmdSource );
|
||||
virtual void privateCommandButtonObject( const CommandButton *commandButton, Object *obj, CommandSourceType cmdSource );
|
||||
virtual void privateWander( const Waypoint *way, CommandSourceType cmdSource ); ///< Wander around the waypoint path.
|
||||
virtual void privateWanderInPlace( CommandSourceType cmdSource ); ///< Wander around the current position.
|
||||
virtual void privatePanic( const Waypoint *way, CommandSourceType cmdSource ); ///< Run screaming down the waypoint path.
|
||||
virtual void privateBusy( CommandSourceType cmdSource ); ///< Transition to the busy state
|
||||
virtual void privateMoveAwayFromUnit( Object *unit, CommandSourceType cmdSource ); ///< Move out of the way of a unit.
|
||||
|
||||
|
||||
public:
|
||||
AIUpdateInterface( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual AIUpdateInterface* getAIUpdateInterface() { return this; }
|
||||
|
||||
// Disabled conditions to process (AI will still process held status)
|
||||
virtual DisabledMaskType getDisabledTypesToProcess() const { return MAKE_DISABLED_MASK( DISABLED_HELD ); }
|
||||
|
||||
// Some very specific, complex behaviors are used by more than one AIUpdate. Here are their interfaces.
|
||||
virtual DozerAIInterface* getDozerAIInterface() {return NULL;}
|
||||
virtual SupplyTruckAIInterface* getSupplyTruckAIInterface() {return NULL;}
|
||||
virtual const DozerAIInterface* getDozerAIInterface() const {return NULL;}
|
||||
virtual const SupplyTruckAIInterface* getSupplyTruckAIInterface() const {return NULL;}
|
||||
#ifdef ALLOW_SURRENDER
|
||||
virtual POWTruckAIUpdateInterface *getPOWTruckAIUpdateInterface( void ) { return NULL; }
|
||||
#endif
|
||||
virtual WorkerAIInterface* getWorkerAIInterface( void ) { return NULL; }
|
||||
virtual const WorkerAIInterface* getWorkerAIInterface( void ) const { return NULL; }
|
||||
virtual HackInternetAIInterface* getHackInternetAIInterface() { return NULL; }
|
||||
virtual const HackInternetAIInterface* getHackInternetAIInterface() const { return NULL; }
|
||||
virtual AssaultTransportAIInterface* getAssaultTransportAIInterface() { return NULL; }
|
||||
virtual const AssaultTransportAIInterface* getAssaultTransportAIInterface() const { return NULL; }
|
||||
|
||||
#ifdef ALLOW_SURRENDER
|
||||
void setSurrendered( const Object *objWeSurrenderedTo, Bool surrendered );
|
||||
inline Bool isSurrendered( void ) const { return m_surrenderedFramesLeft > 0; }
|
||||
inline Int getSurrenderedPlayerIndex() const { return m_surrenderedPlayerIndex; }
|
||||
#endif
|
||||
|
||||
virtual void joinTeam( void ); ///< This unit just got added to a team & needs to catch up.
|
||||
|
||||
|
||||
// this is present solely for some transports to override, so that they can land before
|
||||
// allowing people to exit...
|
||||
virtual AIFreeToExitType getAiFreeToExit(const Object* exiter) const { return FREE_TO_EXIT; }
|
||||
|
||||
// this is present solely to allow some special-case things to override, like landed choppers.
|
||||
virtual Bool isAllowedToAdjustDestination() const { return true; }
|
||||
virtual Bool isAllowedToMoveAwayFromUnit() const { return true; }
|
||||
// this is used for Chinooks, so the pathfinder doesn't make 'em avoid 'em... for combat drops!
|
||||
virtual ObjectID getBuildingToNotPathAround() const { return INVALID_ID; }
|
||||
|
||||
// AI Interface implementation -----------------------------------------------------------------------
|
||||
virtual Bool isIdle() const;
|
||||
virtual Bool isAttacking() const;
|
||||
virtual Bool isClearingMines() const;
|
||||
//Definition of busy -- when explicitly in the busy state. Moving or attacking is not considered busy!
|
||||
virtual Bool isBusy() const;
|
||||
|
||||
virtual void onObjectCreated();
|
||||
virtual void doQuickExit( const std::vector<Coord3D>* path ); ///< get out of this Object
|
||||
|
||||
virtual void aiDoCommand(const AICommandParms* parms);
|
||||
|
||||
virtual const Coord3D *getGuardLocation( void ) const { return &m_locationToGuard; }
|
||||
virtual const ObjectID getGuardObject( void ) const { return m_objectToGuard; }
|
||||
virtual const PolygonTrigger *getAreaToGuard( void ) const { return m_areaToGuard; }
|
||||
virtual GuardTargetType getGuardTargetType() const { return m_guardTargetType[1]; }
|
||||
virtual void clearGuardTargetType() { m_guardTargetType[1] = m_guardTargetType[0]; m_guardTargetType[0] = GUARDTARGET_NONE; }
|
||||
virtual GuardMode getGuardMode() const { return m_guardMode; }
|
||||
|
||||
virtual Object* construct( const ThingTemplate *what,
|
||||
const Coord3D *pos, Real angle,
|
||||
Player *owningPlayer,
|
||||
Bool isRebuild ) { return NULL; }///< construct a building
|
||||
|
||||
|
||||
void ignoreObstacle( const Object *obj ); ///< tell the pathfinder to ignore the given object as an obstacle
|
||||
void ignoreObstacleID( ObjectID id ); ///< tell the pathfinder to ignore the given object as an obstacle
|
||||
|
||||
AIStateType getAIStateType() const; ///< What general state is the AIState Machine in?
|
||||
|
||||
AsciiString getCurrentStateName(void) const { return m_stateMachine->getCurrentStateName(); }
|
||||
|
||||
virtual Object* getEnterTarget(); ///< if we are trying to enter something (see enter() above), what is the thing in question? (or null)
|
||||
|
||||
/**
|
||||
This exists solely to be overridden by children... the idea is that when a unit is targeted by someone else, it
|
||||
asks for an offset to add to its targeting position... if this returns true, the offset should be added to the
|
||||
true target pos. This is primarily for the Aurora Bomber, which uses this technique to make itself "unhittable"
|
||||
when in Supersonic Attack Mode -- things still target it, they just aim "behind" it!
|
||||
*/
|
||||
virtual Bool getSneakyTargetingOffset(Coord3D* offset) const { return false; }
|
||||
|
||||
/**
|
||||
Exists solely to be overridden by JetAIUpdate...
|
||||
*/
|
||||
virtual void addTargeter(ObjectID id, Bool add) { return; }
|
||||
virtual Bool isTemporarilyPreventingAimSuccess() const { return false; }
|
||||
|
||||
|
||||
void setPriorWaypointID( UnsignedInt id ) { m_priorWaypointID = id; };
|
||||
void setCurrentWaypointID( UnsignedInt id ) { m_currentWaypointID = id; };
|
||||
|
||||
// Group ----------------------------------------------------------------------------------------------
|
||||
// these three methods allow a group leader's path to be communicated to the other group members
|
||||
|
||||
AIGroup *getGroup(void);
|
||||
|
||||
// it's VERY RARE you want to call this function; you should normally use Object::isEffectivelyDead()
|
||||
// instead. the exception would be for things that need to know whether to call markIsDead or not.
|
||||
Bool isAiInDeadState( void ) const { return m_isAiDead; } ///< return true if we are dead
|
||||
void markAsDead( void );
|
||||
|
||||
Bool isRecruitable(void) const {return m_isRecruitable;}
|
||||
void setIsRecruitable(Bool isRecruitable) {m_isRecruitable = isRecruitable;}
|
||||
|
||||
Real getDesiredSpeed() const { return m_desiredSpeed; }
|
||||
void setDesiredSpeed( Real speed ) { m_desiredSpeed = speed; } ///< how fast we want to go
|
||||
|
||||
// these are virtual because subclasses might need to override them. (srj)
|
||||
virtual void setLocomotorGoalPositionOnPath();
|
||||
virtual void setLocomotorGoalPositionExplicit(const Coord3D& newPos);
|
||||
virtual void setLocomotorGoalOrientation(Real angle);
|
||||
virtual void setLocomotorGoalNone();
|
||||
virtual Bool isDoingGroundMovement(void) const; ///< True if moving along ground.
|
||||
|
||||
Bool isValidLocomotorPosition(const Coord3D* pos) const;
|
||||
Bool isAircraftThatAdjustsDestination(void) const; ///< True if is aircraft that doesn't stack destinations (missles for example do stack destinations.)
|
||||
Real getCurLocomotorSpeed() const;
|
||||
Real getLocomotorDistanceToGoal();
|
||||
const Locomotor *getCurLocomotor() const {return m_curLocomotor;}
|
||||
Locomotor *getCurLocomotor() { return m_curLocomotor; }
|
||||
|
||||
// turret stuff.
|
||||
WhichTurretType getWhichTurretForWeaponSlot(WeaponSlotType wslot, Real* turretAngle, Real* turretPitch = NULL) const;
|
||||
WhichTurretType getWhichTurretForCurWeapon() const;
|
||||
/**
|
||||
return true iff the weapon is on a turret, that turret is trying to aim at the victim,
|
||||
BUT is not yet pointing in the right dir.
|
||||
*/
|
||||
Bool isWeaponSlotOnTurretAndAimingAtTarget(WeaponSlotType wslot, const Object* victim) const;
|
||||
Bool getTurretRotAndPitch(WhichTurretType tur, Real* turretAngle, Real* turretPitch) const;
|
||||
Real getTurretTurnRate(WhichTurretType tur) const;
|
||||
void setTurretTargetObject(WhichTurretType tur, Object* o, Bool isForceAttacking = FALSE);
|
||||
Object *getTurretTargetObject( WhichTurretType tur );
|
||||
void setTurretTargetPosition(WhichTurretType tur, const Coord3D* pos);
|
||||
void setTurretEnabled(WhichTurretType tur, Bool enabled);
|
||||
void recenterTurret(WhichTurretType tur);
|
||||
Bool isTurretEnabled( WhichTurretType tur ) const;
|
||||
Bool isTurretInNaturalPosition(WhichTurretType tur) const;
|
||||
|
||||
// "Planning Mode" -----------------------------------------------------------------------------------
|
||||
Bool queueWaypoint( const Coord3D *pos ); ///< add waypoint to end of move list. return true if success, false if queue was full and those the waypoint not added
|
||||
void clearWaypointQueue( void ); ///< reset the waypoint queue to empty
|
||||
void executeWaypointQueue( void ); ///< start moving along queued waypoints
|
||||
|
||||
// Pathfinding ---------------------------------------------------------------------------------------
|
||||
private:
|
||||
Bool computePath( PathfindServicesInterface *pathfinder, Coord3D *destination ); ///< computes path to destination, returns false if no path
|
||||
Bool computeAttackPath(PathfindServicesInterface *pathfinder, const Object *victim, const Coord3D* victimPos ); ///< computes path to attack the current target, returns false if no path
|
||||
#ifdef ALLOW_SURRENDER
|
||||
void doSurrenderUpdateStuff();
|
||||
#endif
|
||||
|
||||
public:
|
||||
void doPathfind( PathfindServicesInterface *pathfinder );
|
||||
void requestPath( Coord3D *destination, Bool isGoalDestination ); ///< Queues a request to pathfind to destination.
|
||||
void requestAttackPath( ObjectID victimID, const Coord3D* victimPos ); ///< computes path to attack the current target, returns false if no path
|
||||
void requestApproachPath( Coord3D *destination ); ///< computes path to attack the current target, returns false if no path
|
||||
void requestSafePath( ObjectID repulsor1 ); ///< computes path to attack the current target, returns false if no path
|
||||
|
||||
Bool isWaitingForPath(void) const {return m_waitingForPath;}
|
||||
Bool isAttackPath(void) const {return m_isAttackPath;} ///< True if we have a path to an attack location.
|
||||
void cancelPath(void); ///< Called if we no longer need the path.
|
||||
Path* getPath( void ) { return m_path; } ///< return the agent's current path
|
||||
const Path* getPath( void ) const { return m_path; } ///< return the agent's current path
|
||||
void destroyPath( void ); ///< destroy the current path, setting it to NULL
|
||||
UnsignedInt getPathAge( void ) const { return TheGameLogic->getFrame() - m_pathTimestamp; } ///< return the "age" of the path
|
||||
Bool isPathAvailable( const Coord3D *destination ) const; ///< does a path exist between us and the destination
|
||||
Bool isQuickPathAvailable( const Coord3D *destination ) const; ///< does a path (using quick pathfind) exist between us and the destination
|
||||
Int getNumFramesBlocked(void) const {return m_blockedFrames;}
|
||||
Bool isBlockedAndStuck(void) const {return m_isBlockedAndStuck;}
|
||||
Bool canComputeQuickPath(void); ///< Returns true if we can quickly comput a path. Usually missiles & the like that just move straight to the destination.
|
||||
Bool computeQuickPath(const Coord3D *destination); ///< Computes a quick path to the destination.
|
||||
|
||||
Bool isMoving() const;
|
||||
Bool isMovingAwayFrom(Object *obj) const;
|
||||
|
||||
// the following routines should only be called by the AIInternalMoveToState.
|
||||
// They are used to determine when we are really through moving. Due to the nature of the beast,
|
||||
// we often exit one move state & immediately enter another. This should not cause a "stop start".
|
||||
// jba.
|
||||
void friend_startingMove(void);
|
||||
void friend_endingMove(void);
|
||||
|
||||
void friend_setPath(Path *newPath);
|
||||
|
||||
void friend_setGoalObject(Object *obj);
|
||||
|
||||
virtual Bool processCollision(PhysicsBehavior *physics, Object *other); ///< Returns true if the physics collide should apply the force. Normally not. jba.
|
||||
ObjectID getIgnoredObstacleID( void ) const;
|
||||
|
||||
// "Waypoint Mode" -----------------------------------------------------------------------------------
|
||||
const Waypoint *getCompletedWaypoint(void) const {return m_completedWaypoint;}
|
||||
void setCompletedWaypoint(const Waypoint *pWay) {m_completedWaypoint = pWay;}
|
||||
|
||||
const LocomotorSet& getLocomotorSet(void) const {return m_locomotorSet;}
|
||||
void setPathExtraDistance(Real dist) {m_pathExtraDistance = dist;}
|
||||
inline Real getPathExtraDistance() const { return m_pathExtraDistance; }
|
||||
|
||||
virtual Bool chooseLocomotorSet(LocomotorSetType wst);
|
||||
|
||||
virtual CommandSourceType getLastCommandSource() const { return m_lastCommandSource; }
|
||||
|
||||
const AttackPriorityInfo *getAttackInfo(void) {return m_attackInfo;}
|
||||
void setAttackInfo(const AttackPriorityInfo *info) {m_attackInfo = info;}
|
||||
|
||||
void setCurPathfindCell(const ICoord2D &cell) {m_pathfindCurCell = cell;}
|
||||
void setPathfindGoalCell(const ICoord2D &cell) {m_pathfindGoalCell = cell;}
|
||||
|
||||
void setPathFromWaypoint(const Waypoint *way, const Coord2D *offset);
|
||||
|
||||
const ICoord2D *getCurPathfindCell(void) const {return &m_pathfindCurCell;}
|
||||
const ICoord2D *getPathfindGoalCell(void) const {return &m_pathfindGoalCell;}
|
||||
|
||||
/// Return true if our path has higher priority.
|
||||
Bool hasHigherPathPriority(AIUpdateInterface *otherAI) const;
|
||||
void setFinalPosition(const Coord3D *pos) { m_finalPosition = *pos; m_doFinalPosition = false;}
|
||||
|
||||
virtual UpdateSleepTime update( void ); ///< update this object's AI
|
||||
|
||||
/// if we are attacking "fromID", stop that and attack "toID" instead
|
||||
void transferAttack(ObjectID fromID, ObjectID toID);
|
||||
|
||||
void setCurrentVictim( const Object *nemesis ); ///< Current victim.
|
||||
Object *getCurrentVictim( void ) const;
|
||||
virtual void notifyVictimIsDead() { }
|
||||
|
||||
// if we are attacking a position (and NOT an object), return it. otherwise return null.
|
||||
const Coord3D *getCurrentVictimPos( void ) const;
|
||||
|
||||
void setLocomotorUpgrade(Bool set);
|
||||
|
||||
// This function is used to notify the unit that it may have a target of opportunity to attack.
|
||||
void wakeUpAndAttemptToTarget( void );
|
||||
|
||||
void resetNextMoodCheckTime( void );
|
||||
|
||||
//Specifically set a frame to check next mood time -- added for the purpose of ordering a stealth combat unit that can't
|
||||
//autoacquire while stealthed, but isn't stealthed and can stealth and is not detected, and the player specifically orders
|
||||
//that unit to stop. In this case, instead of the unit autoacquiring another unit, and preventing him from stealthing,
|
||||
//we will instead delay the autoacquire until later to give him enough time to stealth properly.
|
||||
void setNextMoodCheckTime( UnsignedInt frame );
|
||||
|
||||
///< States should call this with calledByAI set true to prevent them from checking every frame
|
||||
///< States that are doing idle checks should call with calledDuringIdle set true so that they check their
|
||||
|
||||
Object *getNextMoodTarget( Bool calledByAI, Bool calledDuringIdle );
|
||||
UnsignedInt getNextMoodCheckTime() const { return m_nextMoodCheckTime; }
|
||||
|
||||
// This function will return a combination of MoodMatrixParameter flags.
|
||||
UnsignedInt getMoodMatrixValue( void ) const;
|
||||
UnsignedInt getMoodMatrixActionAdjustment( MoodMatrixAction action ) const;
|
||||
void setAttitude( AttitudeType tude ); ///< set the behavior modifier for this agent
|
||||
|
||||
// Common AI "status" effects -------------------------------------------------------------------
|
||||
void evaluateMoraleBonus( void );
|
||||
|
||||
#ifdef ALLOW_DEMORALIZE
|
||||
// demoralization ... what a nifty word to write.
|
||||
Bool isDemoralized( void ) const { return m_demoralizedFramesLeft > 0; }
|
||||
void setDemoralized( UnsignedInt durationInFrames );
|
||||
#endif
|
||||
|
||||
Bool canPathThroughUnits( void ) const { return m_canPathThroughUnits; }
|
||||
void setCanPathThroughUnits( Bool canPath ) { m_canPathThroughUnits = canPath; if (canPath) m_isBlockedAndStuck=false;}
|
||||
|
||||
// Notify the ai that it has caused a crate to be created (usually by killing something.)
|
||||
void notifyCrate(ObjectID id) { m_crateCreated = id; }
|
||||
ObjectID getCrateID(void) const { return m_crateCreated; }
|
||||
Object* checkForCrateToPickup();
|
||||
|
||||
void setIgnoreCollisionTime(Int frames) { m_ignoreCollisionsUntil = TheGameLogic->getFrame() + frames; }
|
||||
|
||||
void setQueueForPathTime(Int frames);
|
||||
|
||||
// For the attack move, that switches from move to attack, and the attack is CMD_FROM_AI,
|
||||
// while the move is the original command source. John A.
|
||||
void friend_setLastCommandSource( CommandSourceType source ) {m_lastCommandSource = source;}
|
||||
|
||||
Bool canAutoAcquire() const { return getAIUpdateModuleData()->m_autoAcquireEnemiesWhenIdle; }
|
||||
Bool canAutoAcquireWhileStealthed() const { return getAIUpdateModuleData()->m_autoAcquireEnemiesWhenIdle & AAS_Idle_Stealthed; }
|
||||
|
||||
protected:
|
||||
|
||||
/*
|
||||
AIUpdates run in the initial phase.
|
||||
|
||||
It's actually quite important that AI (the thing that drives Locomotors) and Physics
|
||||
run in the same order, relative to each other, for a given object; otherwise,
|
||||
interesting oscillations can occur in some situations, with friction being applied
|
||||
either before or after the locomotive force, making for huge stuttery messes. (srj)
|
||||
*/
|
||||
virtual SleepyUpdatePhase getUpdatePhase() const { return PHASE_INITIAL; }
|
||||
|
||||
void setGoalPositionClipped(const Coord3D* in, CommandSourceType cmdSource);
|
||||
|
||||
virtual Bool isAllowedToRespondToAiCommands(const AICommandParms* parms) const;
|
||||
|
||||
// getAttitude is protected because other places should call getMoodMatrixValue to get all the facts they need to consider.
|
||||
AttitudeType getAttitude( void ) const; ///< get the current behavior modifier state.
|
||||
|
||||
Bool blockedBy(Object *other); ///< Returns true if we are blocked by "other"
|
||||
Bool needToRotate(void); ///< Returns true if we are not pointing in the right direction for movement.
|
||||
Real calculateMaxBlockedSpeed(Object *other) const;
|
||||
|
||||
virtual UpdateSleepTime doLocomotor(); // virtual so subclasses can override
|
||||
void chooseGoodLocomotorFromCurrentSet();
|
||||
|
||||
void setLastCommandSource( CommandSourceType source );
|
||||
|
||||
// subclasses may want to override this, to use a subclass of AIStateMachine.
|
||||
virtual AIStateMachine* makeStateMachine();
|
||||
|
||||
virtual Bool getTreatAsAircraftForLocoDistToGoal() const;
|
||||
|
||||
// yes, protected, NOT public... try to avoid exposing the state machine directly, please
|
||||
inline AIStateMachine* getStateMachine() { return m_stateMachine; }
|
||||
inline const AIStateMachine* getStateMachine() const { return m_stateMachine; }
|
||||
|
||||
void wakeUpNow();
|
||||
|
||||
public:
|
||||
|
||||
inline StateID getCurrentStateID() const { return getStateMachine()->getCurrentStateID(); } ///< return the id of the current state of the machine
|
||||
/// @ todo -- srj sez: JBA NUKE THIS CODE, IT IS EVIL
|
||||
inline void friend_addToWaypointGoalPath( const Coord3D *pathPoint ) { getStateMachine()->addToGoalPath(pathPoint); }
|
||||
|
||||
// this is intended for use ONLY by W3dWaypointBuffer and AIFollowPathState.
|
||||
inline const Coord3D* friend_getGoalPathPosition( Int index ) const { return getStateMachine()->getGoalPathPosition( index ); }
|
||||
|
||||
// this is intended for use ONLY by W3dWaypointBuffer.
|
||||
Int friend_getWaypointGoalPathSize() const;
|
||||
|
||||
// this is intended for use ONLY by W3dWaypointBuffer.
|
||||
inline Int friend_getCurrentGoalPathIndex() const { return m_nextGoalPathIndex; }
|
||||
|
||||
// this is intended for use ONLY by AIFollowPathState.
|
||||
inline void friend_setCurrentGoalPathIndex( Int index ) { m_nextGoalPathIndex = index; }
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
inline const Coord3D *friend_getRequestedDestination() const { return &m_requestedDestination; }
|
||||
inline const Coord3D *friend_getRequestedDestination2() const { return &m_requestedDestination2; }
|
||||
#endif
|
||||
|
||||
inline Object* getGoalObject() { return getStateMachine()->getGoalObject(); } ///< return the id of the current state of the machine
|
||||
inline const Coord3D* getGoalPosition() const { return getStateMachine()->getGoalPosition(); } ///< return the id of the current state of the machine
|
||||
|
||||
inline WhichTurretType friend_getTurretSync() const { return m_turretSyncFlag; }
|
||||
inline void friend_setTurretSync(WhichTurretType t) { m_turretSyncFlag = t; }
|
||||
|
||||
inline UnsignedInt getPriorWaypointID ( void ) { return m_priorWaypointID; };
|
||||
inline UnsignedInt getCurrentWaypointID ( void ) { return m_currentWaypointID; };
|
||||
|
||||
inline void clearMoveOutOfWay(void) {m_moveOutOfWay1 = INVALID_ID; m_moveOutOfWay2 = INVALID_ID;}
|
||||
|
||||
inline void setTmpValue(Int val) {m_tmpInt = val;}
|
||||
inline Int getTmpValue(void) {return m_tmpInt;}
|
||||
|
||||
inline Bool getRetryPath(void) {return m_retryPath;}
|
||||
|
||||
inline void setAllowedToChase( Bool allow ) { m_allowedToChase = allow; }
|
||||
inline Bool isAllowedToChase() const { return m_allowedToChase; }
|
||||
|
||||
// only for AIStateMachine.
|
||||
virtual void friend_notifyStateMachineChanged();
|
||||
|
||||
private:
|
||||
// this should only be called by load/save, or by chooseLocomotorSet.
|
||||
// it does no sanity checking; it just jams it in.
|
||||
Bool chooseLocomotorSetExplicit(LocomotorSetType wst);
|
||||
|
||||
private:
|
||||
UnsignedInt m_priorWaypointID; ///< ID of the path we follwed to before the most recent one
|
||||
UnsignedInt m_currentWaypointID; ///< ID of the most recent one...
|
||||
|
||||
AIStateMachine* m_stateMachine; ///< the state machine
|
||||
UnsignedInt m_nextEnemyScanTime; ///< how long until the next enemy scan
|
||||
ObjectID m_currentVictimID; ///< if not INVALID_ID, this agent's current victim.
|
||||
Real m_desiredSpeed; ///< the desired speed of the tank
|
||||
CommandSourceType m_lastCommandSource; /**< Keep track of the source of the last command we got.
|
||||
This is set immediately before the SetState that goes
|
||||
to the state machine, so onEnter in there can know where
|
||||
the command came from.
|
||||
*/
|
||||
|
||||
GuardMode m_guardMode;
|
||||
GuardTargetType m_guardTargetType[2];
|
||||
Coord3D m_locationToGuard;
|
||||
ObjectID m_objectToGuard;
|
||||
const PolygonTrigger* m_areaToGuard;
|
||||
|
||||
// Attack Info --------------------------------------------------------------------------------------------
|
||||
const AttackPriorityInfo* m_attackInfo;
|
||||
|
||||
// "Planning Mode" -----------------------------------------------------------------------------------------
|
||||
enum { MAX_WAYPOINTS = 16 };
|
||||
Coord3D m_waypointQueue[ MAX_WAYPOINTS ]; ///< the waypoint queue
|
||||
Int m_waypointCount; ///< number of waypoints in the queue
|
||||
Int m_waypointIndex; ///< current waypoint we are moving to
|
||||
const Waypoint* m_completedWaypoint; ///< Set to the last waypoint in a path when the FollowWaypointPath is complete.
|
||||
|
||||
// Pathfinding ---------------------------------------------------------------------------------------------
|
||||
Path* m_path; ///< current path to follow (for moving)
|
||||
ObjectID m_requestedVictimID;
|
||||
Coord3D m_requestedDestination;
|
||||
Coord3D m_requestedDestination2;
|
||||
UnsignedInt m_pathTimestamp; ///< time of path construction
|
||||
ObjectID m_ignoreObstacleID; ///< ignore this obstacle when pathfinding
|
||||
Real m_pathExtraDistance; ///< If we are following a waypoint path, there will be extra distance beyond the current path.
|
||||
ICoord2D m_pathfindGoalCell; ///< Cell we are moving towards.
|
||||
ICoord2D m_pathfindCurCell; ///< Cell we are currently occupying.
|
||||
Int m_blockedFrames; ///< Number of frames we've been blocked.
|
||||
Real m_curMaxBlockedSpeed; ///< Max speed we can have and not run into blocking things.
|
||||
Real m_bumpSpeedLimit; ///< Max speed after bumping a unit.
|
||||
UnsignedInt m_ignoreCollisionsUntil; ///< Timer to cheat if we get stuck.
|
||||
/**
|
||||
If nonzero and >= now, frame when we should queueForPath.
|
||||
|
||||
NEVER EVER EVER set this directly. you must call setQueueForPathTime() in ALL CASES.
|
||||
NEVER EVER EVER set this directly. you must call setQueueForPathTime() in ALL CASES.
|
||||
NEVER EVER EVER set this directly. you must call setQueueForPathTime() in ALL CASES.
|
||||
NEVER EVER EVER set this directly. you must call setQueueForPathTime() in ALL CASES.
|
||||
*/
|
||||
UnsignedInt m_queueForPathFrame;
|
||||
Coord3D m_finalPosition; ///< Final position for the moveto states.
|
||||
ObjectID m_repulsor1; ///< First object we are running away from.
|
||||
ObjectID m_repulsor2; ///< Second object we are running away from.
|
||||
Int m_nextGoalPathIndex; ///< The simple goal path index we are moving to next.
|
||||
ObjectID m_moveOutOfWay1;
|
||||
ObjectID m_moveOutOfWay2;
|
||||
|
||||
// Locomotors -------------------------------------------------------------------------------------------------
|
||||
enum LocoGoalType // Note - written out in save/load xfer, don't change these numbers. jba.
|
||||
{
|
||||
NONE = 0,
|
||||
POSITION_ON_PATH = 1,
|
||||
POSITION_EXPLICIT = 2,
|
||||
ANGLE = 3
|
||||
};
|
||||
LocomotorSet m_locomotorSet;
|
||||
Locomotor* m_curLocomotor;
|
||||
LocomotorSetType m_curLocomotorSet;
|
||||
LocoGoalType m_locomotorGoalType;
|
||||
Coord3D m_locomotorGoalData;
|
||||
|
||||
// Turrets -------------------------------------------------------------------------------------------------
|
||||
TurretAI* m_turretAI[MAX_TURRETS]; // ai for our turret (or null if no turret)
|
||||
WhichTurretType m_turretSyncFlag; ///< for private use by multiturreted units where the turrets must sync with each other
|
||||
|
||||
// AI -------------------------------------------------------------------------------------------
|
||||
AttitudeType m_attitude;
|
||||
UnsignedInt m_nextMoodCheckTime;
|
||||
|
||||
// Common AI "status" effects -------------------------------------------------------------------
|
||||
#ifdef ALLOW_DEMORALIZE
|
||||
UnsignedInt m_demoralizedFramesLeft;
|
||||
#endif
|
||||
#ifdef ALLOW_SURRENDER
|
||||
UnsignedInt m_surrenderedFramesLeft; ///< Non-zero when in a surrendered state
|
||||
Int m_surrenderedPlayerIndex; ///< if surrendered, the playerindex to whom we are surrendered, or -1 if available for everyone
|
||||
#endif
|
||||
|
||||
// Note the id of a crate we caused to be created.
|
||||
ObjectID m_crateCreated;
|
||||
|
||||
Int m_tmpInt;
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
Bool m_doFinalPosition; ///< True if we are moving towards final position in a non-physics kind of way.
|
||||
Bool m_waitingForPath; ///< True if we have a pathfind request outstanding.
|
||||
Bool m_isAttackPath; ///< True if we have an attack path.
|
||||
Bool m_isFinalGoal; ///< True if this path ends at our destination (as opposed to an intermediate point on a waypoint path).
|
||||
Bool m_isApproachPath; ///< True if we are just approaching to tighten.
|
||||
Bool m_isSafePath; ///< True if we are just approaching to tighten.
|
||||
Bool m_movementComplete; ///< True if we finished an AIInternalMoveToState.
|
||||
Bool m_isMoving; ///< True if we are in an AIInternalMoveToState.
|
||||
Bool m_isBlocked;
|
||||
Bool m_isBlockedAndStuck; ///< True if we are stuck & need to recompute path.
|
||||
Bool m_upgradedLocomotors;
|
||||
Bool m_canPathThroughUnits; ///< Can path through units.
|
||||
Bool m_randomlyOffsetMoodCheck; ///< If true, randomly offset the mood check rate next time, to avoid "spiking" of ai checks
|
||||
Bool m_isAiDead; ///< TRUE if dead
|
||||
Bool m_isRecruitable; ///< TRUE if recruitable by the ai.
|
||||
Bool m_executingWaypointQueue; ///< if true, we are moving thru the waypoints
|
||||
Bool m_retryPath; ///< If true, we need to try the path a second time. jba.
|
||||
Bool m_allowedToChase; ///< Allowed to pursue targets.
|
||||
Bool m_isInUpdate; ///< If true, we are inside our update method.
|
||||
Bool m_fixLocoInPostProcess;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------------------------------
|
||||
// Inlines
|
||||
//
|
||||
|
||||
#endif // _AI_UPDATE_H_
|
||||
|
||||
157
Generals/Code/GameEngine/Include/GameLogic/Module/ActiveBody.h
Normal file
157
Generals/Code/GameEngine/Include/GameLogic/Module/ActiveBody.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: ActiveBody.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, November 2001
|
||||
// Desc: Active bodies have health, they can die and are affected by health
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ACTIVEBODY_H_
|
||||
#define __ACTIVEBODY_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/DamageFX.h"
|
||||
#include "GameLogic/Module/BodyModule.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
#include "GameLogic/Armor.h"
|
||||
#include "GameLogic/ArmorSet.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class BodyParticleSystem;
|
||||
class ParticleSystemTemplate;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Active body module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ActiveBodyModuleData : public BodyModuleData
|
||||
{
|
||||
public:
|
||||
Real m_maxHealth;
|
||||
Real m_initialHealth;
|
||||
|
||||
ActiveBodyModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ActiveBody : public BodyModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ActiveBody, "ActiveBody" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( ActiveBody, ActiveBodyModuleData )
|
||||
|
||||
public:
|
||||
|
||||
ActiveBody( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onDelete( void );
|
||||
|
||||
virtual void attemptDamage( DamageInfo *damageInfo ); ///< try to damage this object
|
||||
virtual Real estimateDamage( DamageInfoInput& damageInfo ) const;
|
||||
virtual void attemptHealing( DamageInfo *damageInfo ); ///< try to heal this object
|
||||
virtual Real getHealth() const; ///< get current health
|
||||
virtual BodyDamageType getDamageState() const;
|
||||
virtual void setDamageState( BodyDamageType newState ); ///< control damage state directly. Will adjust hitpoints.
|
||||
virtual void setAflame( Bool setting );///< This is a major change like a damage state.
|
||||
|
||||
virtual const DamageInfo *getLastDamageInfo() const { return &m_lastDamageInfo; } ///< return info on last damage dealt to this object
|
||||
virtual UnsignedInt getLastDamageTimestamp() const { return m_lastDamageTimestamp; } ///< return frame of last damage dealt
|
||||
virtual UnsignedInt getLastHealingTimestamp() const { return m_lastHealingTimestamp; } ///< return frame of last damage dealt
|
||||
virtual ObjectID getClearableLastAttacker() const { return (m_lastDamageCleared ? INVALID_ID : m_lastDamageInfo.in.m_sourceID); }
|
||||
virtual void clearLastAttacker() { m_lastDamageCleared = true; }
|
||||
|
||||
void onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel newLevel );
|
||||
|
||||
virtual void setArmorSetFlag(ArmorSetType ast) { m_curArmorSetFlags.set(ast, 1); }
|
||||
virtual void clearArmorSetFlag(ArmorSetType ast) { m_curArmorSetFlags.set(ast, 0); }
|
||||
|
||||
virtual void setInitialHealth(Int initialPercent); ///< Sets the inital load health %.
|
||||
virtual void setMaxHealth( Real maxHealth, MaxHealthChangeType healthChangeType = SAME_CURRENTHEALTH ); ///< Sets the inital max health
|
||||
|
||||
virtual Bool getFrontCrushed() const { return m_frontCrushed; }
|
||||
virtual Bool getBackCrushed() const { return m_backCrushed; }
|
||||
|
||||
virtual void setFrontCrushed(Bool v) { m_frontCrushed = v; }
|
||||
virtual void setBackCrushed(Bool v) { m_backCrushed = v; }
|
||||
|
||||
virtual Real getMaxHealth() const; ///< return max health
|
||||
virtual Real getInitialHealth() const; // return initial health
|
||||
|
||||
virtual void setIndestructible( Bool indestructible );
|
||||
virtual Bool isIndestructible( void ) const { return m_indestructible; }
|
||||
|
||||
virtual void internalChangeHealth( Real delta ); ///< change health
|
||||
|
||||
virtual void evaluateVisualCondition();
|
||||
virtual void updateBodyParticleSystems( void );// made public for topple anf building collapse updates -ML
|
||||
|
||||
protected:
|
||||
|
||||
void validateArmorAndDamageFX() const;
|
||||
void doDamageFX( const DamageInfo *damageInfo );
|
||||
|
||||
void createParticleSystems( const AsciiString &boneBaseName,
|
||||
const ParticleSystemTemplate *systemTemplate,
|
||||
Int maxSystems );
|
||||
void deleteAllParticleSystems( void );
|
||||
void setCorrectDamageState();
|
||||
|
||||
private:
|
||||
|
||||
Real m_currentHealth; ///< health of the object
|
||||
Real m_prevHealth; ///< previous health value before current health change op
|
||||
Real m_maxHealth; ///< max health this object can have
|
||||
Real m_initialHealth; ///< starting health for this object
|
||||
|
||||
BodyDamageType m_curDamageState; ///< last known damage state
|
||||
UnsignedInt m_nextDamageFXTime;
|
||||
DamageType m_lastDamageFXDone;
|
||||
DamageInfo m_lastDamageInfo; ///< store the last DamageInfo object that we received
|
||||
UnsignedInt m_lastDamageTimestamp; ///< frame of last damage dealt
|
||||
UnsignedInt m_lastHealingTimestamp; ///< frame of last healing dealt
|
||||
Bool m_frontCrushed;
|
||||
Bool m_backCrushed;
|
||||
Bool m_lastDamageCleared;
|
||||
Bool m_indestructible; ///< is this object indestructible?
|
||||
|
||||
BodyParticleSystem *m_particleSystems; ///< particle systems created and attached to this object
|
||||
|
||||
/*
|
||||
Note, you MUST call validateArmorAndDamageFX() before accessing these fields.
|
||||
*/
|
||||
ArmorSetFlags m_curArmorSetFlags;
|
||||
mutable const ArmorTemplateSet* m_curArmorSet;
|
||||
mutable Armor m_curArmor;
|
||||
mutable const DamageFX* m_curDamageFX;
|
||||
|
||||
};
|
||||
|
||||
#endif // __ACTIVEBODY_H_
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: ActiveShroudUpgrade.h ///////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, July 2002
|
||||
// Desc: An upgrade that modifies the object's ShroudRange.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ACTIVE_SHROUD_UPGRADE_H_
|
||||
#define __ACTIVE_SHROUD_UPGRADE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
class Player;
|
||||
class ObjectCreationList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ActiveShroudUpgradeModuleData : public UpgradeModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
ActiveShroudUpgradeModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
Real m_newShroudRange;
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** An upgrade that modifies the object's ShroudRange */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ActiveShroudUpgrade : public UpgradeModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ActiveShroudUpgrade, "ActiveShroudUpgrade" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( ActiveShroudUpgrade, ActiveShroudUpgradeModuleData );
|
||||
|
||||
public:
|
||||
|
||||
ActiveShroudUpgrade( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation( void ); ///< Here's the actual work of Upgrading
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
};
|
||||
|
||||
#endif // __ACTIVE_SHROUD_UPGRADE_H_
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: ArmorUpgrade.h /////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Electronic Arts Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2002 - All Rights Reserved
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// created: July 2002
|
||||
//
|
||||
// Filename: ArmorUpgrade.h
|
||||
//
|
||||
// author: Chris Brue
|
||||
//
|
||||
// purpose:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ARMOR_UPGRADE_H_
|
||||
#define __ARMOR_UPGRADE_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
class Thing;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TYPE DEFINES ///////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class ArmorUpgrade : public UpgradeModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ArmorUpgrade, "ArmorUpgrade" )
|
||||
MAKE_STANDARD_MODULE_MACRO( ArmorUpgrade );
|
||||
|
||||
public:
|
||||
|
||||
ArmorUpgrade( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
protected:
|
||||
virtual void upgradeImplementation( ); ///< Here's the actual work of Upgrading
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// INLINING ///////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// EXTERNALS //////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __ARMOR_UPGRADE_H_
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// AssaultTransportAIUpdate.h ////////////
|
||||
// Author: Kris Morness, December 2002
|
||||
// Desc: State machine that allows assault transports (troop crawler) to deploy
|
||||
// troops, order them to attack, then return. Can do extra things like ordering
|
||||
// injured troops to return to the transport for healing purposes.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ASSAULT_TRANSPORT_AI_UPDATE_H
|
||||
#define __ASSAULT_TRANSPORT_AI_UPDATE_H
|
||||
|
||||
#include "Common/StateMachine.h"
|
||||
#include "GameLogic/Module/AIUpdate.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum AssaultStateTypes
|
||||
{
|
||||
IDLE, ///< Not doing anything.
|
||||
ASSAULTING, ///< Transport is waiting while troops do fighting.
|
||||
};
|
||||
|
||||
#define MAX_TRANSPORT_SLOTS 10
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AssaultTransportAIUpdateModuleData : public AIUpdateModuleData
|
||||
{
|
||||
public:
|
||||
Real m_membersGetHealedAtLifeRatio;
|
||||
Real m_clearRangeRequiredToContinueAttackMove;
|
||||
|
||||
AssaultTransportAIUpdateModuleData()
|
||||
{
|
||||
m_membersGetHealedAtLifeRatio = 0.0f;
|
||||
m_clearRangeRequiredToContinueAttackMove = 50.0f;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
AIUpdateModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "MembersGetHealedAtLifeRatio", INI::parseReal, NULL, offsetof( AssaultTransportAIUpdateModuleData, m_membersGetHealedAtLifeRatio ) },
|
||||
{ "ClearRangeRequiredToContinueAttackMove", INI::parseReal, NULL, offsetof( AssaultTransportAIUpdateModuleData, m_clearRangeRequiredToContinueAttackMove ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
class AssaultTransportAIInterface
|
||||
{
|
||||
public:
|
||||
virtual void beginAssault( const Object *designatedTarget ) const = 0;
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AssaultTransportAIUpdate : public AIUpdateInterface, public AssaultTransportAIInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AssaultTransportAIUpdate, "AssaultTransportAIUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AssaultTransportAIUpdate, AssaultTransportAIUpdateModuleData )
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
AssaultTransportAIUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void aiDoCommand(const AICommandParms* parms);
|
||||
virtual Bool isIdle() const;
|
||||
virtual UpdateSleepTime update();
|
||||
virtual AssaultTransportAIInterface* getAssaultTransportAIInterface() { return this; }
|
||||
virtual const AssaultTransportAIInterface* getAssaultTransportAIInterface() const { return this; }
|
||||
virtual void beginAssault( const Object *designatedTarget ) const;
|
||||
|
||||
UpdateSleepTime calcSleepTime();
|
||||
|
||||
void reset();
|
||||
Bool isMemberWounded( const Object *member ) const; //Member requires medical attention?
|
||||
Bool isMemberHealthy( const Object *member ) const; //Member has full health?
|
||||
void retrieveMembers();
|
||||
void giveFinalOrders();
|
||||
Bool isAttackPointless() const;
|
||||
|
||||
protected:
|
||||
|
||||
ObjectID m_memberIDs[ MAX_TRANSPORT_SLOTS ];
|
||||
Bool m_memberHealing[ MAX_TRANSPORT_SLOTS ];
|
||||
Bool m_newMember[ MAX_TRANSPORT_SLOTS ];
|
||||
Coord3D m_attackMoveGoalPos;
|
||||
mutable ObjectID m_designatedTarget;
|
||||
AssaultStateTypes m_state;
|
||||
UnsignedInt m_framesRemaining;
|
||||
Int m_currentMembers;
|
||||
Bool m_isAttackMove;
|
||||
Bool m_isAttackObject;
|
||||
Bool m_newOccupantsAreNewMembers;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: AssistedTargetingUpdate.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, September 2002
|
||||
// Desc: Outside influences can tell me to attack something out of my normal targeting range
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _ASSISTED_TARGETING_UPDATE_H
|
||||
#define _ASSISTED_TARGETING_UPDATE_H
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AssistedTargetingUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
Int m_clipSize;
|
||||
WeaponSlotType m_weaponSlot;
|
||||
ThingTemplate *m_laserFromAssisted;
|
||||
ThingTemplate *m_laserToTarget;
|
||||
|
||||
AssistedTargetingUpdateModuleData()
|
||||
{
|
||||
m_clipSize = 1;
|
||||
m_weaponSlot = PRIMARY_WEAPON;
|
||||
m_laserFromAssisted = NULL;
|
||||
m_laserToTarget = NULL;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AssistedTargetingUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AssistedTargetingUpdate, "AssistedTargetingUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AssistedTargetingUpdate, AssistedTargetingUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
AssistedTargetingUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update( void );
|
||||
|
||||
Bool isFreeToAssist() const;
|
||||
void assistAttack( const Object *requestingObject, Object *victimObject );
|
||||
|
||||
private:
|
||||
void makeFeedbackLaser( const ThingTemplate *laserTemplate, const Object *from, const Object *to );
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: AutoDepositUpdate.h /////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Electronic Arts Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2002 - All Rights Reserved
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// created: Aug 2002
|
||||
//
|
||||
// Filename: AutoDepositUpdate.h
|
||||
//
|
||||
// author: Chris Huybregts
|
||||
//
|
||||
// purpose: Auto Deposit Update Module
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AUTO_DEPOSIT_UPDATE_H_
|
||||
#define __AUTO_DEPOSIT_UPDATE_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
class Player;
|
||||
class Thing;
|
||||
//-----------------------------------------------------------------------------
|
||||
// TYPE DEFINES ///////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
class AutoDepositUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_depositFrame;
|
||||
Int m_depositAmount;
|
||||
Int m_initialCaptureBonus;
|
||||
|
||||
AutoDepositUpdateModuleData()
|
||||
{
|
||||
m_depositFrame = 0;
|
||||
m_depositAmount = 0;
|
||||
m_initialCaptureBonus = 0;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "DepositTiming", INI::parseDurationUnsignedInt, NULL, offsetof( AutoDepositUpdateModuleData, m_depositFrame ) },
|
||||
{ "DepositAmount", INI::parseInt, NULL, offsetof( AutoDepositUpdateModuleData, m_depositAmount ) },
|
||||
{ "InitialCaptureBonus", INI::parseInt, NULL, offsetof( AutoDepositUpdateModuleData, m_initialCaptureBonus ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AutoDepositUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AutoDepositUpdate, "AutoDepositUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AutoDepositUpdate, AutoDepositUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
AutoDepositUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
void awardInitialCaptureBonus( Player *player ); // Test and award the initial capture bonus
|
||||
virtual UpdateSleepTime update( void );
|
||||
|
||||
protected:
|
||||
|
||||
UnsignedInt m_depositOnFrame;
|
||||
Bool m_awardInitialCaptureBonus;
|
||||
Bool m_initialized;
|
||||
|
||||
};
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// INLINING ///////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// EXTERNALS //////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#endif // __AUTO_DEPOSIT_UPDATE_H_
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: AutoFindHealingUpdate.cpp //////////////////////////////////////////////////////////////////////////
|
||||
// Author: John Ahlquist, Sept. 2002
|
||||
// Desc: Update module to handle wounded idle infantry finding a heal unit or structure.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AUTO_FIND_HEALING_UPDATE_H_
|
||||
#define __AUTO_FIND_HEALING_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/KindOf.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class ThingTemplate;
|
||||
class WeaponTemplate;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AutoFindHealingUpdateModuleData : public ModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_scanFrames;
|
||||
Real m_scanRange;
|
||||
Real m_neverHeal;
|
||||
Real m_alwaysHeal;
|
||||
|
||||
AutoFindHealingUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The default update module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AutoFindHealingUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AutoFindHealingUpdate, "AutoFindHealingUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AutoFindHealingUpdate, AutoFindHealingUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
AutoFindHealingUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onObjectCreated();
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
Object* scanClosestTarget();
|
||||
|
||||
protected:
|
||||
Int m_nextScanFrames;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: AutoHealBehavior.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, December 2001
|
||||
// Desc: Update that heals itself
|
||||
//------------------------------------------
|
||||
// Modified by Kris Morness, September 2002
|
||||
// Kris: Added the ability to add effects, radius healing, and restricting the type of objects
|
||||
// subjected to the heal (or repair).
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __AutoHealBehavior_H_
|
||||
#define __AutoHealBehavior_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameClient/ParticleSys.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameLogic/Module/DamageModule.h"
|
||||
#include "Common/BitFlagsIO.h"
|
||||
|
||||
class ParticleSystem;
|
||||
class ParticleSystemTemplate;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AutoHealBehaviorModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UpgradeMuxData m_upgradeMuxData;
|
||||
Bool m_initiallyActive;
|
||||
Bool m_singleBurst;
|
||||
Int m_healingAmount;
|
||||
UnsignedInt m_healingDelay;
|
||||
UnsignedInt m_startHealingDelay; ///< how long since our last damage till autoheal starts.
|
||||
Real m_radius; //If non-zero, then it becomes a area effect.
|
||||
Bool m_affectsWholePlayer; ///< I have more than a range, I try to affect everything the player owns
|
||||
KindOfMaskType m_kindOf; //Only these types can heal -- defaults to everything.
|
||||
const ParticleSystemTemplate* m_radiusParticleSystemTmpl; //Optional particle system meant to apply to entire effect for entire duration.
|
||||
const ParticleSystemTemplate* m_unitHealPulseParticleSystemTmpl; //Optional particle system applying to each object getting healed each heal pulse.
|
||||
|
||||
AutoHealBehaviorModuleData()
|
||||
{
|
||||
m_initiallyActive = false;
|
||||
m_singleBurst = FALSE;
|
||||
m_healingAmount = 0;
|
||||
m_healingDelay = UINT_MAX;
|
||||
m_startHealingDelay = 0;
|
||||
m_radius = 0.0f;
|
||||
m_radiusParticleSystemTmpl = NULL;
|
||||
m_unitHealPulseParticleSystemTmpl = NULL;
|
||||
m_affectsWholePlayer = FALSE;
|
||||
SET_ALL_KINDOFMASK_BITS( m_kindOf );
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "StartsActive", INI::parseBool, NULL, offsetof( AutoHealBehaviorModuleData, m_initiallyActive ) },
|
||||
{ "SingleBurst", INI::parseBool, NULL, offsetof( AutoHealBehaviorModuleData, m_singleBurst ) },
|
||||
{ "HealingAmount", INI::parseInt, NULL, offsetof( AutoHealBehaviorModuleData, m_healingAmount ) },
|
||||
{ "HealingDelay", INI::parseDurationUnsignedInt, NULL, offsetof( AutoHealBehaviorModuleData, m_healingDelay ) },
|
||||
{ "Radius", INI::parseReal, NULL, offsetof( AutoHealBehaviorModuleData, m_radius ) },
|
||||
{ "KindOf", KindOfMaskType::parseFromINI, NULL, offsetof( AutoHealBehaviorModuleData, m_kindOf ) },
|
||||
{ "RadiusParticleSystemName", INI::parseParticleSystemTemplate, NULL, offsetof( AutoHealBehaviorModuleData, m_radiusParticleSystemTmpl ) },
|
||||
{ "UnitHealPulseParticleSystemName", INI::parseParticleSystemTemplate, NULL, offsetof( AutoHealBehaviorModuleData, m_unitHealPulseParticleSystemTmpl ) },
|
||||
{ "StartHealingDelay", INI::parseDurationUnsignedInt, NULL, offsetof( AutoHealBehaviorModuleData, m_startHealingDelay ) },
|
||||
{ "AffectsWholePlayer", INI::parseBool, NULL, offsetof( AutoHealBehaviorModuleData, m_affectsWholePlayer ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
p.add(dataFieldParse);
|
||||
p.add(UpgradeMuxData::getFieldParse(), offsetof( AutoHealBehaviorModuleData, m_upgradeMuxData ));
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class AutoHealBehavior : public UpdateModule,
|
||||
public UpgradeMux,
|
||||
public DamageModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( AutoHealBehavior, "AutoHealBehavior" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( AutoHealBehavior, AutoHealBehaviorModuleData )
|
||||
|
||||
public:
|
||||
|
||||
AutoHealBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// module methods
|
||||
static Int getInterfaceMask() { return UpdateModule::getInterfaceMask() | MODULEINTERFACE_UPGRADE | MODULEINTERFACE_DAMAGE; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual UpgradeModuleInterface* getUpgrade() { return this; }
|
||||
virtual DamageModuleInterface* getDamage() { return this; }
|
||||
|
||||
// DamageModuleInterface
|
||||
virtual void onDamage( DamageInfo *damageInfo );
|
||||
virtual void onHealing( DamageInfo *damageInfo ) { }
|
||||
virtual void onBodyDamageStateChange(const DamageInfo* damageInfo, BodyDamageType oldState, BodyDamageType newState) { }
|
||||
|
||||
// UpdateModuleInterface
|
||||
virtual UpdateSleepTime update();
|
||||
virtual DisabledMaskType getDisabledTypesToProcess() const { return MAKE_DISABLED_MASK( DISABLED_HELD ); }
|
||||
|
||||
void stopHealing();
|
||||
void undoUpgrade(); ///<pretend like we have not been activated yet, so we can be reactivated later
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation()
|
||||
{
|
||||
setWakeFrame(getObject(), UPDATE_SLEEP_NONE);
|
||||
}
|
||||
|
||||
virtual void getUpgradeActivationMasks(Int64& activation, Int64& conflicting) const
|
||||
{
|
||||
getAutoHealBehaviorModuleData()->m_upgradeMuxData.getUpgradeActivationMasks(activation, conflicting);
|
||||
}
|
||||
|
||||
virtual void performUpgradeFX()
|
||||
{
|
||||
getAutoHealBehaviorModuleData()->m_upgradeMuxData.performUpgradeFX(getObject());
|
||||
}
|
||||
|
||||
virtual Bool requiresAllActivationUpgrades() const
|
||||
{
|
||||
return getAutoHealBehaviorModuleData()->m_upgradeMuxData.m_requiresAllTriggers;
|
||||
}
|
||||
|
||||
inline Bool isUpgradeActive() const { return isAlreadyUpgraded(); }
|
||||
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
void pulseHealObject( Object *obj );
|
||||
|
||||
ParticleSystemID m_radiusParticleSystemID;
|
||||
|
||||
UnsignedInt m_soonestHealFrame;/** I need to record this, because with multiple wake up sources,
|
||||
I can't rely solely on my sleeping. So this will guard onDamage's wake up.
|
||||
I could guard the act of healing, but that would defeat the gain of being
|
||||
a sleepy module. I never want to run update unless I am going to heal.
|
||||
*/
|
||||
|
||||
Bool m_stopped;
|
||||
|
||||
};
|
||||
|
||||
#endif // __AutoHealBehavior_H_
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BaikonurLaunchPower.h /////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Electronic Arts Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2002 - All Rights Reserved
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Created: November 2002
|
||||
//
|
||||
// Filename: BaikonurLaunchPower.h
|
||||
//
|
||||
// Author: Kris Morness
|
||||
//
|
||||
// Purpose: Triggers the beginning of the launch for the baikonur launch tower.
|
||||
// This is used only by script to trigger the GLA end game.
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BAIKONUR_LAUNCH_POWER_H_
|
||||
#define __BAIKONUR_LAUNCH_POWER_H_
|
||||
|
||||
#include "GameLogic/Module/SpecialPowerModule.h"
|
||||
|
||||
class Object;
|
||||
class SpecialPowerTemplate;
|
||||
struct FieldParse;
|
||||
enum ScienceType;
|
||||
|
||||
class BaikonurLaunchPowerModuleData : public SpecialPowerModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
BaikonurLaunchPowerModuleData( void );
|
||||
|
||||
static void buildFieldParse( MultiIniFieldParse& p );
|
||||
|
||||
AsciiString m_detonationObject;
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BaikonurLaunchPower : public SpecialPowerModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BaikonurLaunchPower, "BaikonurLaunchPower" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( BaikonurLaunchPower, BaikonurLaunchPowerModuleData )
|
||||
|
||||
public:
|
||||
|
||||
BaikonurLaunchPower( Thing *thing, const ModuleData *moduleData );
|
||||
|
||||
virtual void doSpecialPower( UnsignedInt commandOptions );
|
||||
virtual void doSpecialPowerAtLocation( const Coord3D *loc, UnsignedInt commandOptions );
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif // __BAIKONUR_LAUNCH_POWER_H_
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BaseRegenerateUpdate.h ///////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, July 2002
|
||||
// Desc: Update module for base objects automatically regenerating health
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BASE_REGENERATE_UPDATE_H_
|
||||
#define __BASE_REGENERATE_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameLogic/Module/DamageModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BaseRegenerateUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
BaseRegenerateUpdateModuleData( void );
|
||||
static void buildFieldParse( MultiIniFieldParse &p );
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BaseRegenerateUpdate : public UpdateModule,
|
||||
public DamageModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BaseRegenerateUpdate, "BaseRegenerateUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( BaseRegenerateUpdate, BaseRegenerateUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
BaseRegenerateUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
static Int getInterfaceMask() { return UpdateModule::getInterfaceMask() | MODULEINTERFACE_DAMAGE; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual DamageModuleInterface* getDamage() { return this; }
|
||||
|
||||
// UpdateModuleInterface
|
||||
virtual UpdateSleepTime update( void );
|
||||
|
||||
// DamageModuleInterface
|
||||
virtual void onDamage( DamageInfo *damageInfo );
|
||||
virtual void onHealing( DamageInfo *damageInfo ) { }
|
||||
virtual void onBodyDamageStateChange(const DamageInfo* damageInfo, BodyDamageType oldState, BodyDamageType newState) { }
|
||||
virtual DisabledMaskType getDisabledTypesToProcess() const { return MAKE_DISABLED_MASK( DISABLED_UNDERPOWERED ); }
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
#endif // end __BASE_REGENERATE_UPDATE_H_
|
||||
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BattlePlanUpdate.h //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Kris Morness, September 2002
|
||||
// Desc: Update module to handle building states and battle plan execution & changes
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BATTLE_PLAN_UPDATE_H_
|
||||
#define __BATTLE_PLAN_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/KindOf.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class SpecialPowerModule;
|
||||
class ParticleSystem;
|
||||
class FXList;
|
||||
class AudioEventRTS;
|
||||
enum MaxHealthChangeType;
|
||||
enum CommandOption;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BattlePlanUpdateModuleData : public ModuleData
|
||||
{
|
||||
public:
|
||||
SpecialPowerTemplate *m_specialPowerTemplate;
|
||||
|
||||
UnsignedInt m_bombardmentPlanAnimationFrames;
|
||||
UnsignedInt m_holdTheLinePlanAnimationFrames;
|
||||
UnsignedInt m_searchAndDestroyPlanAnimationFrames;
|
||||
UnsignedInt m_transitionIdleFrames;
|
||||
|
||||
AsciiString m_bombardmentUnpackName;
|
||||
AsciiString m_bombardmentPackName;
|
||||
AsciiString m_bombardmentMessageLabel;
|
||||
AsciiString m_bombardmentAnnouncementName;
|
||||
AsciiString m_searchAndDestroyUnpackName;
|
||||
AsciiString m_searchAndDestroyIdleName;
|
||||
AsciiString m_searchAndDestroyPackName;
|
||||
AsciiString m_searchAndDestroyMessageLabel;
|
||||
AsciiString m_searchAndDestroyAnnouncementName;
|
||||
AsciiString m_holdTheLineUnpackName;
|
||||
AsciiString m_holdTheLinePackName;
|
||||
AsciiString m_holdTheLineMessageLabel;
|
||||
AsciiString m_holdTheLineAnnouncementName;
|
||||
|
||||
UnsignedInt m_battlePlanParalyzeFrames;
|
||||
KindOfMaskType m_validMemberKindOf;
|
||||
KindOfMaskType m_invalidMemberKindOf;
|
||||
|
||||
Real m_holdTheLineArmorDamageScalar;
|
||||
Real m_searchAndDestroySightRangeScalar;
|
||||
Real m_strategyCenterSearchAndDestroySightRangeScalar;
|
||||
Bool m_strategyCenterSearchAndDestroyDetectsStealth;
|
||||
Real m_strategyCenterHoldTheLineMaxHealthScalar;
|
||||
MaxHealthChangeType m_strategyCenterHoldTheLineMaxHealthChangeType;
|
||||
|
||||
AsciiString m_visionObjectName; ///< name of object to create to reveal shroud to all players
|
||||
|
||||
BattlePlanUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
enum TransitionStatus
|
||||
{
|
||||
TRANSITIONSTATUS_IDLE,
|
||||
TRANSITIONSTATUS_UNPACKING,
|
||||
TRANSITIONSTATUS_ACTIVE,
|
||||
TRANSITIONSTATUS_PACKING,
|
||||
};
|
||||
|
||||
enum BattlePlanStatus
|
||||
{
|
||||
PLANSTATUS_NONE,
|
||||
PLANSTATUS_BOMBARDMENT,
|
||||
PLANSTATUS_HOLDTHELINE,
|
||||
PLANSTATUS_SEARCHANDDESTROY,
|
||||
};
|
||||
|
||||
class BattlePlanBonuses : public MemoryPoolObject
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(BattlePlanBonuses, "BattlePlanBonuses")
|
||||
public:
|
||||
Real m_armorScalar;
|
||||
Int m_bombardment; //Represents having weapon bonuses for bombardment plan
|
||||
Int m_searchAndDestroy; //Represents having weapon bonuses for searchAndDestroy plan
|
||||
Int m_holdTheLine; //Represents having weapon bonuses for holdTheLine plan
|
||||
Real m_sightRangeScalar;
|
||||
KindOfMaskType m_validKindOf;
|
||||
KindOfMaskType m_invalidKindOf;
|
||||
};
|
||||
EMPTY_DTOR(BattlePlanBonuses)
|
||||
|
||||
#define ALL_PLANS 1000000 //Used when stacking or removing plans -- we only remove the bonuses when it's 0 or negative.
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The default update module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BattlePlanUpdate : public UpdateModule, public SpecialPowerUpdateInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BattlePlanUpdate, "BattlePlanUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( BattlePlanUpdate, BattlePlanUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
BattlePlanUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// SpecialPowerUpdateInterface
|
||||
virtual void initiateIntentToDoSpecialPower(const SpecialPowerTemplate *specialPowerTemplate, const Object *targetObj, const Coord3D *targetPos, UnsignedInt commandOptions, Int locationCount );
|
||||
virtual Bool isSpecialAbility() const { return false; }
|
||||
virtual Bool isSpecialPower() const { return true; }
|
||||
virtual Bool isActive() const {return m_status != TRANSITIONSTATUS_IDLE;}
|
||||
virtual SpecialPowerUpdateInterface* getSpecialPowerUpdateInterface() { return this; }
|
||||
virtual Bool doesSpecialPowerHaveOverridableDestinationActive() const { return false; }
|
||||
virtual void setSpecialPowerOverridableDestination( const Coord3D *loc ) {}
|
||||
virtual Bool isPowerCurrentlyInUse( const CommandButton *command = NULL ) const;
|
||||
|
||||
//Returns the currently active battle plan -- unpacked and ready... returns PLANSTATUS_NONE if in transition!
|
||||
BattlePlanStatus getActiveBattlePlan() const;
|
||||
|
||||
virtual void onObjectCreated();
|
||||
virtual void onDelete();
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
virtual CommandOption getCommandOption() const;
|
||||
protected:
|
||||
|
||||
void setStatus( TransitionStatus status );
|
||||
void enableTurret( Bool enable );
|
||||
void recenterTurret();
|
||||
Bool isTurretInNaturalPosition();
|
||||
void setBattlePlan( BattlePlanStatus plan );
|
||||
void createVisionObject();
|
||||
|
||||
BattlePlanStatus m_currentPlan; //The current battle plan displayed by the building (includes packing & unpacking)
|
||||
BattlePlanStatus m_desiredPlan; //The user desired battle plan
|
||||
BattlePlanStatus m_planAffectingArmy; //The current battle plan that is affecting troops!
|
||||
TransitionStatus m_status;
|
||||
|
||||
UnsignedInt m_nextReadyFrame;
|
||||
SpecialPowerModuleInterface *m_specialPowerModule;
|
||||
Bool m_invalidSettings;
|
||||
Bool m_centeringTurret;
|
||||
BattlePlanBonuses* m_bonuses;
|
||||
|
||||
AudioEventRTS m_bombardmentUnpack;
|
||||
AudioEventRTS m_bombardmentPack;
|
||||
AudioEventRTS m_bombardmentAnnouncement;
|
||||
AudioEventRTS m_searchAndDestroyUnpack;
|
||||
AudioEventRTS m_searchAndDestroyIdle;
|
||||
AudioEventRTS m_searchAndDestroyPack;
|
||||
AudioEventRTS m_searchAndDestroyAnnouncement;
|
||||
AudioEventRTS m_holdTheLineUnpack;
|
||||
AudioEventRTS m_holdTheLinePack;
|
||||
AudioEventRTS m_holdTheLineAnnouncement;
|
||||
|
||||
// vision object - hang on to this so we can delete it on destruction
|
||||
ObjectID m_visionObjectID;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BehaviorModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Steven Johnson
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BehaviorModule_H_
|
||||
#define __BehaviorModule_H_
|
||||
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/Module.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class Team;
|
||||
class ThingTemplate;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BodyModuleInterface;
|
||||
class CollideModuleInterface;
|
||||
class ContainModuleInterface;
|
||||
class CreateModuleInterface;
|
||||
class DamageModuleInterface;
|
||||
class DestroyModuleInterface;
|
||||
class DieModuleInterface;
|
||||
class SpecialPowerModuleInterface;
|
||||
class UpdateModuleInterface;
|
||||
class UpgradeModuleInterface;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ParkingPlaceBehaviorInterface;
|
||||
class RebuildHoleBehaviorInterface;
|
||||
class BridgeBehaviorInterface;
|
||||
class BridgeTowerBehaviorInterface;
|
||||
class BridgeScaffoldBehaviorInterface;
|
||||
class OverchargeBehaviorInterface;
|
||||
class TransportPassengerInterface;
|
||||
class CaveInterface;
|
||||
class LandMineInterface;
|
||||
|
||||
class ProjectileUpdateInterface;
|
||||
class AIUpdateInterface;
|
||||
class ExitInterface;
|
||||
class DelayedUpgradeUpdateInterface;
|
||||
class DockUpdateInterface;
|
||||
class RailedTransportDockUpdateInterface;
|
||||
class SpecialPowerUpdateInterface;
|
||||
class SlavedUpdateInterface;
|
||||
class SpawnBehaviorInterface;
|
||||
class SlowDeathBehaviorInterface;
|
||||
class PowerPlantUpdateInterface;
|
||||
class ProductionUpdateInterface;
|
||||
class HordeUpdateInterface;
|
||||
class SpecialPowerTemplate;
|
||||
class WeaponTemplate;
|
||||
class DamageInfo;
|
||||
class ParticleSystemTemplate;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BehaviorModuleData : public ModuleData
|
||||
{
|
||||
public:
|
||||
BehaviorModuleData()
|
||||
{
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
ModuleData::buildFieldParse(p);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BehaviorModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual BodyModuleInterface* getBody() = 0;
|
||||
virtual CollideModuleInterface* getCollide() = 0;
|
||||
virtual ContainModuleInterface* getContain() = 0;
|
||||
virtual CreateModuleInterface* getCreate() = 0;
|
||||
virtual DamageModuleInterface* getDamage() = 0;
|
||||
virtual DestroyModuleInterface* getDestroy() = 0;
|
||||
virtual DieModuleInterface* getDie() = 0;
|
||||
virtual SpecialPowerModuleInterface* getSpecialPower() = 0;
|
||||
virtual UpdateModuleInterface* getUpdate() = 0;
|
||||
virtual UpgradeModuleInterface* getUpgrade() = 0;
|
||||
|
||||
// interface acquisition
|
||||
virtual ParkingPlaceBehaviorInterface* getParkingPlaceBehaviorInterface() = 0;
|
||||
virtual RebuildHoleBehaviorInterface* getRebuildHoleBehaviorInterface() = 0;
|
||||
virtual BridgeBehaviorInterface* getBridgeBehaviorInterface() = 0;
|
||||
virtual BridgeTowerBehaviorInterface* getBridgeTowerBehaviorInterface() = 0;
|
||||
virtual BridgeScaffoldBehaviorInterface* getBridgeScaffoldBehaviorInterface() = 0;
|
||||
virtual OverchargeBehaviorInterface* getOverchargeBehaviorInterface() = 0;
|
||||
virtual TransportPassengerInterface* getTransportPassengerInterface() = 0;
|
||||
virtual CaveInterface* getCaveInterface() = 0;
|
||||
virtual LandMineInterface* getLandMineInterface() = 0;
|
||||
virtual DieModuleInterface* getEjectPilotDieInterface() = 0;
|
||||
// move from UpdateModuleInterface (srj)
|
||||
virtual ProjectileUpdateInterface* getProjectileUpdateInterface() = 0;
|
||||
virtual AIUpdateInterface* getAIUpdateInterface() = 0;
|
||||
virtual ExitInterface* getUpdateExitInterface() = 0;
|
||||
virtual DelayedUpgradeUpdateInterface* getDelayedUpgradeUpdateInterface() = 0;
|
||||
virtual DockUpdateInterface* getDockUpdateInterface() = 0;
|
||||
virtual RailedTransportDockUpdateInterface *getRailedTransportDockUpdateInterface( void ) = 0;
|
||||
virtual SlowDeathBehaviorInterface* getSlowDeathBehaviorInterface() = 0;
|
||||
virtual SpecialPowerUpdateInterface* getSpecialPowerUpdateInterface() = 0;
|
||||
virtual SlavedUpdateInterface* getSlavedUpdateInterface() = 0;
|
||||
virtual ProductionUpdateInterface* getProductionUpdateInterface() = 0;
|
||||
virtual HordeUpdateInterface* getHordeUpdateInterface() = 0;
|
||||
virtual PowerPlantUpdateInterface* getPowerPlantUpdateInterface() = 0;
|
||||
virtual SpawnBehaviorInterface* getSpawnBehaviorInterface() = 0;
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BehaviorModule : public ObjectModule, public BehaviorModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( BehaviorModule )
|
||||
|
||||
public:
|
||||
|
||||
BehaviorModule( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
static Int getInterfaceMask() { return 0; }
|
||||
static ModuleType getModuleType() { return MODULETYPE_BEHAVIOR; }
|
||||
|
||||
virtual BodyModuleInterface* getBody() { return NULL; }
|
||||
virtual CollideModuleInterface* getCollide() { return NULL; }
|
||||
virtual ContainModuleInterface* getContain() { return NULL; }
|
||||
virtual CreateModuleInterface* getCreate() { return NULL; }
|
||||
virtual DamageModuleInterface* getDamage() { return NULL; }
|
||||
virtual DestroyModuleInterface* getDestroy() { return NULL; }
|
||||
virtual DieModuleInterface* getDie() { return NULL; }
|
||||
virtual SpecialPowerModuleInterface* getSpecialPower() { return NULL; }
|
||||
virtual UpdateModuleInterface* getUpdate() { return NULL; }
|
||||
virtual UpgradeModuleInterface* getUpgrade() { return NULL; }
|
||||
|
||||
virtual ParkingPlaceBehaviorInterface* getParkingPlaceBehaviorInterface() { return NULL; }
|
||||
virtual RebuildHoleBehaviorInterface* getRebuildHoleBehaviorInterface() { return NULL; }
|
||||
virtual BridgeBehaviorInterface* getBridgeBehaviorInterface() { return NULL; }
|
||||
virtual BridgeTowerBehaviorInterface* getBridgeTowerBehaviorInterface() { return NULL; }
|
||||
virtual BridgeScaffoldBehaviorInterface* getBridgeScaffoldBehaviorInterface() { return NULL; }
|
||||
virtual OverchargeBehaviorInterface* getOverchargeBehaviorInterface() { return NULL; }
|
||||
virtual TransportPassengerInterface* getTransportPassengerInterface() { return NULL; }
|
||||
virtual CaveInterface* getCaveInterface() { return NULL; }
|
||||
virtual LandMineInterface* getLandMineInterface() { return NULL; }
|
||||
virtual DieModuleInterface* getEjectPilotDieInterface() { return NULL; }
|
||||
// interface acquisition (moved from UpdateModule)
|
||||
virtual ProjectileUpdateInterface* getProjectileUpdateInterface() { return NULL; }
|
||||
virtual AIUpdateInterface* getAIUpdateInterface() { return NULL; }
|
||||
virtual ExitInterface* getUpdateExitInterface() { return NULL; }
|
||||
virtual DelayedUpgradeUpdateInterface* getDelayedUpgradeUpdateInterface() { return NULL; }
|
||||
virtual DockUpdateInterface* getDockUpdateInterface() { return NULL; }
|
||||
virtual RailedTransportDockUpdateInterface *getRailedTransportDockUpdateInterface( void ) { return NULL; }
|
||||
virtual SlowDeathBehaviorInterface* getSlowDeathBehaviorInterface() { return NULL; }
|
||||
virtual SpecialPowerUpdateInterface* getSpecialPowerUpdateInterface() { return NULL; }
|
||||
virtual SlavedUpdateInterface* getSlavedUpdateInterface() { return NULL; }
|
||||
virtual ProductionUpdateInterface* getProductionUpdateInterface() { return NULL; }
|
||||
virtual HordeUpdateInterface* getHordeUpdateInterface() { return NULL; }
|
||||
virtual PowerPlantUpdateInterface* getPowerPlantUpdateInterface() { return NULL; }
|
||||
virtual SpawnBehaviorInterface* getSpawnBehaviorInterface() { return NULL; }
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
};
|
||||
inline BehaviorModule::BehaviorModule( Thing *thing, const ModuleData* moduleData ) : ObjectModule( thing, moduleData ) { }
|
||||
inline BehaviorModule::~BehaviorModule() { }
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ParkingPlaceBehaviorInterface
|
||||
{
|
||||
public:
|
||||
struct PPInfo
|
||||
{
|
||||
Coord3D parkingSpace;
|
||||
Real parkingOrientation;
|
||||
Coord3D runwayPrep;
|
||||
Coord3D runwayStart;
|
||||
Coord3D runwayEnd;
|
||||
Coord3D runwayApproach;
|
||||
Coord3D hangarInternal;
|
||||
Real hangarInternalOrient;
|
||||
};
|
||||
virtual Bool shouldReserveDoorWhenQueued(const ThingTemplate* thing) const = 0;
|
||||
virtual Bool hasAvailableSpaceFor(const ThingTemplate* thing) const = 0;
|
||||
virtual Bool hasReservedSpace(ObjectID id) const = 0;
|
||||
virtual Bool reserveSpace(ObjectID id, Real parkingOffset, PPInfo* info) = 0;
|
||||
virtual void releaseSpace(ObjectID id) = 0;
|
||||
virtual Bool reserveRunway(ObjectID id, Bool forLanding) = 0;
|
||||
virtual void releaseRunway(ObjectID id) = 0;
|
||||
virtual Int getRunwayCount() const = 0;
|
||||
virtual ObjectID getRunwayReservation(Int r) = 0;
|
||||
virtual void transferRunwayReservationToNextInLineForTakeoff(ObjectID id) = 0;
|
||||
virtual Real getApproachHeight() const = 0;
|
||||
virtual void setHealee(Object* healee, Bool add) = 0;
|
||||
virtual void killAllParkedUnits() = 0;
|
||||
virtual void defectAllParkedUnits(Team* newTeam, UnsignedInt detectionTime) = 0;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class TransportPassengerInterface
|
||||
{
|
||||
public:
|
||||
virtual Bool tryToEvacuate( Bool exposeStealthedUnits ) = 0; ///< Will try to kick everybody out with game checks, and will return whether anyone made it
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CaveInterface
|
||||
{
|
||||
public:
|
||||
virtual void tryToSetCaveIndex( Int newIndex ) = 0; ///< Called by script as an alternative to instancing separate objects. 'Try', because can fail.
|
||||
virtual void setOriginalTeam( Team *oldTeam ) = 0; ///< This is a distributed Garrison in terms of capturing, so when one node triggers the change, he needs to tell everyone, so anyone can do the un-change.
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class LandMineInterface
|
||||
{
|
||||
public:
|
||||
virtual void setScootParms(const Coord3D& start, const Coord3D& end) = 0;
|
||||
virtual void disarm() = 0;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
292
Generals/Code/GameEngine/Include/GameLogic/Module/BodyModule.h
Normal file
292
Generals/Code/GameEngine/Include/GameLogic/Module/BodyModule.h
Normal file
@@ -0,0 +1,292 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BodyModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2001
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BODYMODULE_H_
|
||||
#define __BODYMODULE_H_
|
||||
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
#include "GameLogic/ArmorSet.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** OBJECT BODY MODULE base class */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
class WeaponTemplate;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Damage states for structures
|
||||
*
|
||||
* NOTE: the macros below for IS_CONDITION_WORSE and IS_CONDITION_BETTER depend on this
|
||||
* enumeration being in sequential order
|
||||
*/
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum BodyDamageType
|
||||
{
|
||||
BODY_PRISTINE, ///< unit should appear in pristine condition
|
||||
BODY_DAMAGED, ///< unit has been damaged
|
||||
BODY_REALLYDAMAGED, ///< unit is extremely damaged / nearly destroyed
|
||||
BODY_RUBBLE, ///< unit has been reduced to rubble/corpse/exploded-hulk, etc
|
||||
|
||||
BODYDAMAGETYPE_COUNT
|
||||
};
|
||||
|
||||
#ifdef DEFINE_BODYDAMAGETYPE_NAMES
|
||||
static const char* TheBodyDamageTypeNames[] =
|
||||
{
|
||||
"PRISTINE",
|
||||
"DAMAGED",
|
||||
"REALLYDAMAGED",
|
||||
"RUBBLE",
|
||||
|
||||
NULL
|
||||
};
|
||||
#endif
|
||||
|
||||
enum MaxHealthChangeType
|
||||
{
|
||||
SAME_CURRENTHEALTH,
|
||||
PRESERVE_RATIO,
|
||||
ADD_CURRENT_HEALTH_TOO,
|
||||
};
|
||||
|
||||
#ifdef DEFINE_MAXHEALTHCHANGETYPE_NAMES
|
||||
static const char* TheMaxHealthChangeTypeNames[] =
|
||||
{
|
||||
"SAME_CURRENTHEALTH",
|
||||
"PRESERVE_RATIO",
|
||||
"ADD_CURRENT_HEALTH_TOO",
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// is condition A worse than condition B ... NOTE: this assumes the conditions
|
||||
// in BodyDamageType are in sequential order
|
||||
//
|
||||
// is a worse than b
|
||||
#define IS_CONDITION_WORSE( a, b ) ( a > b )
|
||||
// is a better than b
|
||||
#define IS_CONDITION_BETTER( a, b ) ( a < b )
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BodyModuleData : public BehaviorModuleData
|
||||
{
|
||||
public:
|
||||
BodyModuleData()
|
||||
{
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
BehaviorModuleData::buildFieldParse(p);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BodyModuleInterface
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Try to damage this Object. The module's Armor
|
||||
will be taken into account, so the actual damage done may vary
|
||||
considerably from what you requested. Also note that (if damage is done)
|
||||
the DamageFX will be invoked to provide a/v fx as appropriate.
|
||||
*/
|
||||
virtual void attemptDamage( DamageInfo *damageInfo ) = 0;
|
||||
|
||||
/**
|
||||
Instead of having negative damage count as healing, or allowing access to the private
|
||||
changeHealth Method, we will use this parallel to attemptDamage to do healing without hack.
|
||||
*/
|
||||
virtual void attemptHealing( DamageInfo *healingInfo ) = 0;
|
||||
|
||||
/**
|
||||
Estimate the (unclipped) damage that would be done to this object
|
||||
by the given damage (taking bonuses, armor, etc into account),
|
||||
but DO NOT alter the body in any way. (This is used by the AI system
|
||||
to choose weapons.)
|
||||
*/
|
||||
virtual Real estimateDamage( DamageInfoInput& damageInfo ) const = 0;
|
||||
|
||||
virtual Real getHealth() const = 0; ///< get current health
|
||||
|
||||
virtual Real getMaxHealth() const = 0;
|
||||
|
||||
virtual Real getInitialHealth() const = 0;
|
||||
|
||||
virtual BodyDamageType getDamageState() const = 0;
|
||||
virtual void setDamageState( BodyDamageType newState ) = 0; ///< control damage state directly. Will adjust hitpoints.
|
||||
virtual void setAflame( Bool setting ) = 0;///< This is a major change like a damage state.
|
||||
|
||||
virtual void onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel newLevel ) = 0; ///< I just achieved this level right this moment
|
||||
|
||||
virtual void setArmorSetFlag(ArmorSetType ast) = 0;
|
||||
virtual void clearArmorSetFlag(ArmorSetType ast) = 0;
|
||||
|
||||
virtual const DamageInfo *getLastDamageInfo() const = 0;
|
||||
virtual UnsignedInt getLastDamageTimestamp() const = 0;
|
||||
virtual UnsignedInt getLastHealingTimestamp() const = 0;
|
||||
virtual ObjectID getClearableLastAttacker() const = 0;
|
||||
virtual void clearLastAttacker() = 0;
|
||||
virtual Bool getFrontCrushed() const = 0;
|
||||
virtual Bool getBackCrushed() const = 0;
|
||||
|
||||
virtual void setInitialHealth(Int initialPercent) = 0;
|
||||
virtual void setMaxHealth( Real maxHealth, MaxHealthChangeType healthChangeType = SAME_CURRENTHEALTH ) = 0;
|
||||
|
||||
virtual void setFrontCrushed(Bool v) = 0;
|
||||
virtual void setBackCrushed(Bool v) = 0;
|
||||
|
||||
virtual void applyDamageScalar( Real scalar ) = 0;
|
||||
virtual Real getDamageScalar() const = 0;
|
||||
|
||||
/**
|
||||
Change the module's health by the given delta. Note that
|
||||
the module's DamageFX and Armor are NOT taken into
|
||||
account, so you should think about what you're bypassing when you
|
||||
call this directly (especially when when decreasing health, since
|
||||
you probably want "attemptDamage" or "attemptHealing")
|
||||
*/
|
||||
virtual void internalChangeHealth( Real delta ) = 0;
|
||||
|
||||
virtual void setIndestructible( Bool indestructible ) = 0;
|
||||
virtual Bool isIndestructible( void ) const = 0;
|
||||
|
||||
virtual void evaluateVisualCondition() = 0;
|
||||
virtual void updateBodyParticleSystems() = 0; // made public for topple and building collapse updates -ML
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BodyModule : public BehaviorModule, public BodyModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( BodyModule )
|
||||
|
||||
public:
|
||||
|
||||
BodyModule( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
static Int getInterfaceMask() { return MODULEINTERFACE_BODY; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual BodyModuleInterface* getBody() { return this; }
|
||||
|
||||
/**
|
||||
Try to damage this Object. The module's Armor
|
||||
will be taken into account, so the actual damage done may vary
|
||||
considerably from what you requested. Also note that (if damage is done)
|
||||
the DamageFX will be invoked to provide a/v fx as appropriate.
|
||||
*/
|
||||
virtual void attemptDamage( DamageInfo *damageInfo ) = 0;
|
||||
|
||||
/**
|
||||
Instead of having negative damage count as healing, or allowing access to the private
|
||||
changeHealth Method, we will use this parallel to attemptDamage to do healing without hack.
|
||||
*/
|
||||
virtual void attemptHealing( DamageInfo *healingInfo ) = 0;
|
||||
|
||||
/**
|
||||
Estimate the (unclipped) damage that would be done to this object
|
||||
by the given damage (taking bonuses, armor, etc into account),
|
||||
but DO NOT alter the body in any way. (This is used by the AI system
|
||||
to choose weapons.)
|
||||
*/
|
||||
virtual Real estimateDamage( DamageInfoInput& damageInfo ) const = 0;
|
||||
|
||||
virtual Real getHealth() const = 0; ///< get current health
|
||||
|
||||
virtual Real getMaxHealth() const {return 0.0f;} ///< return max health
|
||||
|
||||
virtual Real getInitialHealth() const {return 0.0f;} // return initial health
|
||||
|
||||
virtual BodyDamageType getDamageState() const = 0;
|
||||
virtual void setDamageState( BodyDamageType newState ) = 0; ///< control damage state directly. Will adjust hitpoints.
|
||||
virtual void setAflame( Bool setting ) = 0;///< This is a major change like a damage state.
|
||||
|
||||
virtual void onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel newLevel ) = 0; ///< I just achieved this level right this moment
|
||||
|
||||
virtual void setArmorSetFlag(ArmorSetType ast) = 0;
|
||||
virtual void clearArmorSetFlag(ArmorSetType ast) = 0;
|
||||
|
||||
virtual const DamageInfo *getLastDamageInfo() const { return NULL; } ///< return info on last damage dealt to this object
|
||||
virtual UnsignedInt getLastDamageTimestamp() const { return 0; } ///< return frame of last damage dealt
|
||||
virtual UnsignedInt getLastHealingTimestamp() const { return 0; } ///< return frame of last healing dealt
|
||||
virtual ObjectID getClearableLastAttacker() const { return INVALID_ID; }
|
||||
virtual void clearLastAttacker() { }
|
||||
virtual Bool getFrontCrushed() const { return false; }
|
||||
virtual Bool getBackCrushed() const { return false; }
|
||||
|
||||
virtual void setInitialHealth(Int initialPercent) { } ///< Sets the inital load health %.
|
||||
virtual void setMaxHealth(Real maxHealth, MaxHealthChangeType healthChangeType = SAME_CURRENTHEALTH ) { } ///< Sets the max health.
|
||||
|
||||
virtual void setFrontCrushed(Bool v) { DEBUG_CRASH(("you should never call this for generic Bodys")); }
|
||||
virtual void setBackCrushed(Bool v) { DEBUG_CRASH(("you should never call this for generic Bodys")); }
|
||||
|
||||
|
||||
virtual void setIndestructible( Bool indestructible ) { }
|
||||
virtual Bool isIndestructible( void ) const { return TRUE; }
|
||||
|
||||
//Allows outside systems to apply defensive bonuses or penalties (they all stack as a multiplier!)
|
||||
virtual void applyDamageScalar( Real scalar ) { m_damageScalar *= scalar; }
|
||||
virtual Real getDamageScalar() const { return m_damageScalar; }
|
||||
|
||||
/**
|
||||
Change the module's health by the given delta. Note that
|
||||
the module's DamageFX and Armor are NOT taken into
|
||||
account, so you should think about what you're bypassing when you
|
||||
call this directly (especially when when decreasing health, since
|
||||
you probably want "attemptDamage" or "attemptHealing")
|
||||
*/
|
||||
virtual void internalChangeHealth( Real delta ) = 0;
|
||||
|
||||
virtual void evaluateVisualCondition() { }
|
||||
virtual void updateBodyParticleSystems() { };// made public for topple anf building collapse updates -ML
|
||||
|
||||
protected:
|
||||
|
||||
// snapshot methods
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess( void );
|
||||
|
||||
Real m_damageScalar;
|
||||
|
||||
};
|
||||
inline BodyModule::BodyModule( Thing *thing, const ModuleData* moduleData ) : BehaviorModule( thing, moduleData ), m_damageScalar(1.0f) { }
|
||||
inline BodyModule::~BodyModule() { }
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BoneFXDamage.h /////////////////////////////////////////////////////////////////////
|
||||
// Author: Bryan Cleveland, April 2002
|
||||
// Desc: Damage module for the boneFX update module
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BONEFXDAMAGE_H_
|
||||
#define __BONEFXDAMAGE_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "GameLogic/Module/DamageModule.h"
|
||||
|
||||
//#include "GameLogic/Module/BodyModule.h" -- Yikes... not necessary to include this! (KM)
|
||||
enum BodyDamageType; //Ahhhh much better!
|
||||
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BoneFXDamage : public DamageModule
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO( BoneFXDamage );
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BoneFXDamage, "BoneFXDamage" )
|
||||
|
||||
public:
|
||||
|
||||
BoneFXDamage( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// damage module methods
|
||||
virtual void onDamage( DamageInfo *damageInfo ) { }
|
||||
virtual void onHealing( DamageInfo *damageInfo ) { }
|
||||
virtual void onBodyDamageStateChange( const DamageInfo* damageInfo,
|
||||
BodyDamageType oldState,
|
||||
BodyDamageType newState );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onObjectCreated();
|
||||
|
||||
};
|
||||
|
||||
#endif // end __BONEFXDAMAGE_H_
|
||||
281
Generals/Code/GameEngine/Include/GameLogic/Module/BoneFXUpdate.h
Normal file
281
Generals/Code/GameEngine/Include/GameLogic/Module/BoneFXUpdate.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BoneFXUpdate.h /////////////////////////////////////////////////////////////////////
|
||||
// Author: Bryan Cleveland, April 2002
|
||||
// Desc: Update module that will fire off FX lists at bone locations at random intervals
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BONEFXUPDATE_H_
|
||||
#define __BONEFXUPDATE_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameClient/ParticleSys.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
//#include "GameLogic/Module/DamageModule.h" -- Yikes... not necessary to include this! (KM)
|
||||
class DamageInfo; //Ahhhh much better!
|
||||
|
||||
#include "GameLogic/Module/BodyModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
class FXList;
|
||||
class ObjectCreationList;
|
||||
class ParticleSystemTemplate;
|
||||
|
||||
// we can have this many effects of each type per body state
|
||||
// NOTE: If you change this you should update the dataFieldParse[] table in the FXDamageModuleData
|
||||
// to allow for the new indices into the effect arrays
|
||||
enum { BONE_FX_MAX_BONES = 8 };
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
struct BoneLocInfo
|
||||
{
|
||||
AsciiString boneName; // bone name to use for effect pos
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
struct BaseBoneListInfo
|
||||
{
|
||||
BoneLocInfo locInfo;
|
||||
GameClientRandomVariable gameClientDelay;
|
||||
GameLogicRandomVariable gameLogicDelay;
|
||||
Bool onlyOnce;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
struct BoneFXListInfo : public BaseBoneListInfo
|
||||
{
|
||||
const FXList *fx;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
struct BoneOCLInfo : public BaseBoneListInfo
|
||||
{
|
||||
const ObjectCreationList *ocl;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
struct BoneParticleSystemInfo : public BaseBoneListInfo
|
||||
{
|
||||
const ParticleSystemTemplate *particleSysTemplate;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BoneFXUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
BoneFXUpdateModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
|
||||
{ "DamageFXTypes", INI::parseDamageTypeFlags, NULL, offsetof( BoneFXUpdateModuleData, m_damageFXTypes ) },
|
||||
{ "DamageOCLTypes", INI::parseDamageTypeFlags, NULL, offsetof( BoneFXUpdateModuleData, m_damageOCLTypes ) },
|
||||
{ "DamageParticleTypes", INI::parseDamageTypeFlags, NULL, offsetof( BoneFXUpdateModuleData, m_damageParticleTypes ) },
|
||||
|
||||
{ "PristineFXList1", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 0 ] ) },
|
||||
{ "PristineFXList2", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 1 ] ) },
|
||||
{ "PristineFXList3", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 2 ] ) },
|
||||
{ "PristineFXList4", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 3 ] ) },
|
||||
{ "PristineFXList5", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 4 ] ) },
|
||||
{ "PristineFXList6", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 5 ] ) },
|
||||
{ "PristineFXList7", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 6 ] ) },
|
||||
{ "PristineFXList8", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_PRISTINE ][ 7 ] ) },
|
||||
{ "DamagedFXList1", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 0 ] ) },
|
||||
{ "DamagedFXList2", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 1 ] ) },
|
||||
{ "DamagedFXList3", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 2 ] ) },
|
||||
{ "DamagedFXList4", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 3 ] ) },
|
||||
{ "DamagedFXList5", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 4 ] ) },
|
||||
{ "DamagedFXList6", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 5 ] ) },
|
||||
{ "DamagedFXList7", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 6 ] ) },
|
||||
{ "DamagedFXList8", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_DAMAGED ][ 7 ] ) },
|
||||
{ "ReallyDamagedFXList1", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 0 ] ) },
|
||||
{ "ReallyDamagedFXList2", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 1 ] ) },
|
||||
{ "ReallyDamagedFXList3", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 2 ] ) },
|
||||
{ "ReallyDamagedFXList4", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 3 ] ) },
|
||||
{ "ReallyDamagedFXList5", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 4 ] ) },
|
||||
{ "ReallyDamagedFXList6", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 5 ] ) },
|
||||
{ "ReallyDamagedFXList7", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 6 ] ) },
|
||||
{ "ReallyDamagedFXList8", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_REALLYDAMAGED ][ 7 ] ) },
|
||||
{ "RubbleFXList1", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 0 ] ) },
|
||||
{ "RubbleFXList2", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 1 ] ) },
|
||||
{ "RubbleFXList3", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 2 ] ) },
|
||||
{ "RubbleFXList4", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 3 ] ) },
|
||||
{ "RubbleFXList5", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 4 ] ) },
|
||||
{ "RubbleFXList6", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 5 ] ) },
|
||||
{ "RubbleFXList7", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 6 ] ) },
|
||||
{ "RubbleFXList8", BoneFXUpdateModuleData::parseFXList, NULL, offsetof( BoneFXUpdateModuleData, m_fxList[ BODY_RUBBLE ][ 7 ] ) },
|
||||
|
||||
{ "PristineOCL1", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 0 ] ) },
|
||||
{ "PristineOCL2", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 1 ] ) },
|
||||
{ "PristineOCL3", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 2 ] ) },
|
||||
{ "PristineOCL4", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 3 ] ) },
|
||||
{ "PristineOCL5", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 4 ] ) },
|
||||
{ "PristineOCL6", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 5 ] ) },
|
||||
{ "PristineOCL7", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 6 ] ) },
|
||||
{ "PristineOCL8", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_PRISTINE ][ 7 ] ) },
|
||||
{ "DamagedOCL1", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 0 ] ) },
|
||||
{ "DamagedOCL2", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 1 ] ) },
|
||||
{ "DamagedOCL3", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 2 ] ) },
|
||||
{ "DamagedOCL4", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 3 ] ) },
|
||||
{ "DamagedOCL5", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 4 ] ) },
|
||||
{ "DamagedOCL6", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 5 ] ) },
|
||||
{ "DamagedOCL7", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 6 ] ) },
|
||||
{ "DamagedOCL8", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_DAMAGED ][ 7 ] ) },
|
||||
{ "ReallyDamagedOCL1", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 0 ] ) },
|
||||
{ "ReallyDamagedOCL2", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 1 ] ) },
|
||||
{ "ReallyDamagedOCL3", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 2 ] ) },
|
||||
{ "ReallyDamagedOCL4", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 3 ] ) },
|
||||
{ "ReallyDamagedOCL5", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 4 ] ) },
|
||||
{ "ReallyDamagedOCL6", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 5 ] ) },
|
||||
{ "ReallyDamagedOCL7", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 6 ] ) },
|
||||
{ "ReallyDamagedOCL8", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_REALLYDAMAGED ][ 7 ] ) },
|
||||
{ "RubbleOCL1", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 0 ] ) },
|
||||
{ "RubbleOCL2", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 1 ] ) },
|
||||
{ "RubbleOCL3", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 2 ] ) },
|
||||
{ "RubbleOCL4", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 3 ] ) },
|
||||
{ "RubbleOCL5", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 4 ] ) },
|
||||
{ "RubbleOCL6", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 5 ] ) },
|
||||
{ "RubbleOCL7", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 6 ] ) },
|
||||
{ "RubbleOCL8", BoneFXUpdateModuleData::parseObjectCreationList, NULL, offsetof( BoneFXUpdateModuleData, m_OCL[ BODY_RUBBLE ][ 7 ] ) },
|
||||
|
||||
{ "PristineParticleSystem1", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 0 ] ) },
|
||||
{ "PristineParticleSystem2", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 1 ] ) },
|
||||
{ "PristineParticleSystem3", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 2 ] ) },
|
||||
{ "PristineParticleSystem4", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 3 ] ) },
|
||||
{ "PristineParticleSystem5", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 4 ] ) },
|
||||
{ "PristineParticleSystem6", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 5 ] ) },
|
||||
{ "PristineParticleSystem7", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 6 ] ) },
|
||||
{ "PristineParticleSystem8", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_PRISTINE ][ 7 ] ) },
|
||||
{ "DamagedParticleSystem1", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 0 ] ) },
|
||||
{ "DamagedParticleSystem2", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 1 ] ) },
|
||||
{ "DamagedParticleSystem3", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 2 ] ) },
|
||||
{ "DamagedParticleSystem4", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 3 ] ) },
|
||||
{ "DamagedParticleSystem5", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 4 ] ) },
|
||||
{ "DamagedParticleSystem6", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 5 ] ) },
|
||||
{ "DamagedParticleSystem7", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 6 ] ) },
|
||||
{ "DamagedParticleSystem8", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_DAMAGED ][ 7 ] ) },
|
||||
{ "ReallyDamagedParticleSystem1", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 0 ] ) },
|
||||
{ "ReallyDamagedParticleSystem2", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 1 ] ) },
|
||||
{ "ReallyDamagedParticleSystem3", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 2 ] ) },
|
||||
{ "ReallyDamagedParticleSystem4", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 3 ] ) },
|
||||
{ "ReallyDamagedParticleSystem5", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 4 ] ) },
|
||||
{ "ReallyDamagedParticleSystem6", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 5 ] ) },
|
||||
{ "ReallyDamagedParticleSystem7", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 6 ] ) },
|
||||
{ "ReallyDamagedParticleSystem8", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_REALLYDAMAGED ][ 7 ] ) },
|
||||
{ "RubbleParticleSystem1", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 0 ] ) },
|
||||
{ "RubbleParticleSystem2", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 1 ] ) },
|
||||
{ "RubbleParticleSystem3", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 2 ] ) },
|
||||
{ "RubbleParticleSystem4", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 3 ] ) },
|
||||
{ "RubbleParticleSystem5", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 4 ] ) },
|
||||
{ "RubbleParticleSystem6", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 5 ] ) },
|
||||
{ "RubbleParticleSystem7", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 6 ] ) },
|
||||
{ "RubbleParticleSystem8", BoneFXUpdateModuleData::parseParticleSystem, NULL, offsetof( BoneFXUpdateModuleData, m_particleSystem[ BODY_RUBBLE ][ 7 ] ) },
|
||||
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
|
||||
}
|
||||
|
||||
static void parseFXList( INI *ini, void *instance, void *store, const void *userData );
|
||||
static void parseObjectCreationList( INI *ini, void *instance, void *store, const void *userData );
|
||||
static void parseParticleSystem( INI *ini, void *instance, void *store, const void *userData );
|
||||
|
||||
DamageTypeFlags m_damageFXTypes; ///< flags used to play or not play the effects
|
||||
BoneFXListInfo m_fxList[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
DamageTypeFlags m_damageOCLTypes; ///< flags used to play or not play the effects
|
||||
BoneOCLInfo m_OCL[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
DamageTypeFlags m_damageParticleTypes; ///< flags used to play or not play the effects
|
||||
BoneParticleSystemInfo m_particleSystem[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class BoneFXUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( BoneFXUpdate, BoneFXUpdateModuleData );
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BoneFXUpdate, "BoneFXUpdate" )
|
||||
|
||||
public:
|
||||
|
||||
BoneFXUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
void changeBodyDamageState( BodyDamageType oldState, BodyDamageType newState);
|
||||
void stopAllBoneFX();
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onObjectCreated();
|
||||
|
||||
virtual void resolveBoneLocations();
|
||||
|
||||
void doFXListAtBone(const FXList *fxList, const Coord3D *bonePosition);
|
||||
void doOCLAtBone(const ObjectCreationList *ocl, const Coord3D *bonePosition);
|
||||
void doParticleSystemAtBone(const ParticleSystemTemplate *particleSystemTemplate, const Coord3D *bonePosition);
|
||||
void killRunningParticleSystems();
|
||||
|
||||
void computeNextClientFXTime(const BaseBoneListInfo *info, Int &nextFrame);
|
||||
void computeNextLogicFXTime(const BaseBoneListInfo *info, Int &nextFrame);
|
||||
void initTimes();
|
||||
|
||||
|
||||
|
||||
typedef std::vector<ParticleSystemID> ParticleSystemIDVec;
|
||||
|
||||
/// we keep a record of attached particle system so we can detach and kill them when we want to
|
||||
ParticleSystemIDVec m_particleSystemIDs;
|
||||
Int m_nextFXFrame[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
Int m_nextOCLFrame[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
Int m_nextParticleSystemFrame[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
Coord3D m_FXBonePositions[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
Coord3D m_OCLBonePositions[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
Coord3D m_PSBonePositions[ BODYDAMAGETYPE_COUNT ][ BONE_FX_MAX_BONES ];
|
||||
BodyDamageType m_curBodyState;
|
||||
Bool m_bonesResolved[BODYDAMAGETYPE_COUNT];
|
||||
Bool m_active;
|
||||
};
|
||||
|
||||
#endif // end __BONEFXUPDATE_H_
|
||||
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BridgeBehavior.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, July 2002
|
||||
// Desc: Behavior module for bridges
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BRIDGE_BEHAVIOR_H_
|
||||
#define __BRIDGE_BEHAVIOR_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/AudioEventRTS.h"
|
||||
#include "GameClient/TerrainRoads.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/DamageModule.h"
|
||||
#include "GameLogic/Module/Diemodule.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
enum BridgeTowerType;
|
||||
class FXList;
|
||||
class ObjectCreationList;
|
||||
class Bridge;
|
||||
class BridgeInfo;
|
||||
|
||||
// TYPES //////////////////////////////////////////////////////////////////////////////////////////
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
struct TimeAndLocationInfo
|
||||
{
|
||||
UnsignedInt delay; ///< how long to wait to execute this
|
||||
AsciiString boneName; ///< which bone to execute at
|
||||
};
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
struct BridgeFXInfo
|
||||
{
|
||||
const FXList *fx;
|
||||
TimeAndLocationInfo timeAndLocationInfo;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
struct BridgeOCLInfo
|
||||
{
|
||||
const ObjectCreationList *ocl;
|
||||
TimeAndLocationInfo timeAndLocationInfo;
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
typedef std::list< BridgeFXInfo > BridgeFXList;
|
||||
typedef std::list< BridgeOCLInfo > BridgeOCLList;
|
||||
typedef std::list< ObjectID > ObjectIDList;
|
||||
typedef ObjectIDList::iterator ObjectIDListIterator;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BridgeBehaviorInterface
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual void setTower( BridgeTowerType towerType, Object *tower ) = 0;
|
||||
virtual ObjectID getTowerID( BridgeTowerType towerType ) = 0;
|
||||
virtual void createScaffolding( void ) = 0;
|
||||
virtual void removeScaffolding( void ) = 0;
|
||||
virtual Bool isScaffoldInMotion( void ) = 0;
|
||||
virtual Bool isScaffoldPresent( void ) = 0;
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BridgeBehaviorModuleData : public BehaviorModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
BridgeBehaviorModuleData( void );
|
||||
~BridgeBehaviorModuleData( void );
|
||||
|
||||
static void buildFieldParse( MultiIniFieldParse &p );
|
||||
|
||||
Real m_lateralScaffoldSpeed;
|
||||
Real m_verticalScaffoldSpeed;
|
||||
BridgeFXList m_fx; ///< list of FX lists to execute
|
||||
BridgeOCLList m_ocl; ///< list of OCL to execute
|
||||
|
||||
static void parseFX( INI *ini, void *instance, void *store, const void* userData );
|
||||
static void parseOCL( INI *ini, void *instance, void *store, const void* userData );
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BridgeBehavior : public UpdateModule,
|
||||
public BridgeBehaviorInterface,
|
||||
public DamageModuleInterface,
|
||||
public DieModuleInterface
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( BridgeBehavior, BridgeBehaviorModuleData );
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BridgeBehavior, "BridgeBehavior" )
|
||||
|
||||
public:
|
||||
|
||||
BridgeBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// module methods
|
||||
static Int getInterfaceMask( void ) { return (MODULEINTERFACE_DAMAGE) |
|
||||
(MODULEINTERFACE_DIE) |
|
||||
(MODULEINTERFACE_UPDATE); }
|
||||
virtual BridgeBehaviorInterface* getBridgeBehaviorInterface( void ) { return this; }
|
||||
virtual void onDelete( void );
|
||||
|
||||
// Damage methods
|
||||
virtual DamageModuleInterface* getDamage( void ) { return this; }
|
||||
virtual void onDamage( DamageInfo *damageInfo );
|
||||
virtual void onHealing( DamageInfo *damageInfo );
|
||||
virtual void onBodyDamageStateChange( const DamageInfo* damageInfo,
|
||||
BodyDamageType oldState,
|
||||
BodyDamageType newState );
|
||||
|
||||
// Die methods
|
||||
virtual DieModuleInterface* getDie( void ) { return this; }
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
// Update methods
|
||||
virtual UpdateModuleInterface *getUpdate( void ) { return this; }
|
||||
virtual UpdateSleepTime update( void );
|
||||
|
||||
// our own methods
|
||||
static BridgeBehaviorInterface *getBridgeBehaviorInterfaceFromObject( Object *obj );
|
||||
virtual void setTower( BridgeTowerType towerType, Object *tower ); ///< connect tower to us
|
||||
virtual ObjectID getTowerID( BridgeTowerType towerType ); ///< retrive one of our towers
|
||||
virtual void createScaffolding( void ); ///< create scaffolding around bridge
|
||||
virtual void removeScaffolding( void ); ///< remove scaffolding around bridge
|
||||
virtual Bool isScaffoldInMotion( void ); ///< is scaffold in motion
|
||||
virtual Bool isScaffoldPresent( void ) { return m_scaffoldPresent; }
|
||||
|
||||
protected:
|
||||
|
||||
void resolveFX( void );
|
||||
void handleObjectsOnBridgeOnDie( void );
|
||||
void doAreaEffects( TerrainRoadType *bridgeTemplate, Bridge *bridge,
|
||||
const ObjectCreationList *ocl, const FXList *fx );
|
||||
void setScaffoldData( Object *obj,
|
||||
Real *angle,
|
||||
Real *sunkenHeight,
|
||||
const Coord3D *riseToPos,
|
||||
const Coord3D *buildPos,
|
||||
const Coord3D *bridgeCenter );
|
||||
|
||||
void getRandomSurfacePosition( TerrainRoadType *bridgeTemplate,
|
||||
const BridgeInfo *bridgeInfo,
|
||||
Coord3D *pos );
|
||||
|
||||
ObjectID m_towerID[ BRIDGE_MAX_TOWERS ]; ///< the towers that are a part of us
|
||||
|
||||
// got damaged fx stuff
|
||||
const ObjectCreationList *m_damageToOCL[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ];
|
||||
const FXList *m_damageToFX[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ];
|
||||
AudioEventRTS m_damageToSound[ BODYDAMAGETYPE_COUNT ];
|
||||
|
||||
// got repaired fx stuff
|
||||
const ObjectCreationList *m_repairToOCL[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ];
|
||||
const FXList *m_repairToFX[ BODYDAMAGETYPE_COUNT ][ MAX_BRIDGE_BODY_FX ];
|
||||
AudioEventRTS m_repairToSound[ BODYDAMAGETYPE_COUNT ];
|
||||
|
||||
Bool m_fxResolved; ///< TRUE until we've loaded our fx pointers and sounds
|
||||
|
||||
Bool m_scaffoldPresent; ///< TRUE when we have repair scaffolding visible
|
||||
ObjectIDList m_scaffoldObjectIDList; ///< list of scaffold object IDs
|
||||
|
||||
UnsignedInt m_deathFrame; ///< frame we died on
|
||||
|
||||
};
|
||||
|
||||
#endif // end __BRIDGE_DAMAGE_H_
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BridgeScaffoldBehavior.h /////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2002
|
||||
// Desc: Bridge scaffold
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BRIDGE_SCAFFOLD_BEHAVIOR_H_
|
||||
#define __BRIDGE_SCAFFOLD_BEHAVIOR_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
enum ScaffoldTargetMotion
|
||||
{
|
||||
STM_STILL,
|
||||
STM_RISE,
|
||||
STM_BUILD_ACROSS,
|
||||
STM_TEAR_DOWN_ACROSS,
|
||||
STM_SINK,
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BridgeScaffoldBehaviorInterface
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual void setPositions( const Coord3D *createPos,
|
||||
const Coord3D *riseToPos,
|
||||
const Coord3D *buildPos ) = 0;
|
||||
virtual void setMotion( ScaffoldTargetMotion targetMotion ) = 0;
|
||||
virtual ScaffoldTargetMotion getCurrentMotion( void ) = 0;
|
||||
virtual void reverseMotion( void ) = 0;
|
||||
virtual void setLateralSpeed( Real lateralSpeed ) = 0;
|
||||
virtual void setVerticalSpeed( Real verticalSpeed ) = 0;
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BridgeScaffoldBehavior : public UpdateModule,
|
||||
public BridgeScaffoldBehaviorInterface
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO( BridgeScaffoldBehavior );
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BridgeScaffoldBehavior, "BridgeScaffoldBehavior" )
|
||||
|
||||
public:
|
||||
|
||||
BridgeScaffoldBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// behavior module methods
|
||||
virtual BridgeScaffoldBehaviorInterface* getBridgeScaffoldBehaviorInterface() { return this; }
|
||||
|
||||
// update methods
|
||||
virtual UpdateSleepTime update( void );
|
||||
|
||||
// bridge scaffold interface methods
|
||||
virtual void setPositions( const Coord3D *createPos,
|
||||
const Coord3D *riseToPos,
|
||||
const Coord3D *buildPos );
|
||||
virtual void setMotion( ScaffoldTargetMotion targetMotion );
|
||||
virtual ScaffoldTargetMotion getCurrentMotion( void ) { return m_targetMotion; }
|
||||
virtual void reverseMotion( void );
|
||||
virtual void setLateralSpeed( Real lateralSpeed ) { m_lateralSpeed = lateralSpeed; }
|
||||
virtual void setVerticalSpeed( Real verticalSpeed ) { m_verticalSpeed = verticalSpeed; }
|
||||
|
||||
// public interface acquisition
|
||||
static BridgeScaffoldBehaviorInterface *getBridgeScaffoldBehaviorInterfaceFromObject( Object *obj );
|
||||
|
||||
protected:
|
||||
|
||||
void doVerticalMotion( void ); ///< do rise/sink vertical motion
|
||||
void doLateralmotion( void ); ///< do lateral motion
|
||||
|
||||
ScaffoldTargetMotion m_targetMotion; ///< which way our motion should be going (build up, still, tear down etc)
|
||||
Coord3D m_createPos; ///< initial position of object creation (in ground)
|
||||
Coord3D m_riseToPos; ///< position we "rise to" out of the ground
|
||||
Coord3D m_buildPos; ///< position we move to and stop at on the bridge surface
|
||||
Real m_lateralSpeed; ///< speed for lateral motions
|
||||
Real m_verticalSpeed; ///< speed for vertical motions
|
||||
Coord3D m_targetPos; ///< current target position for our motion type
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // end __BRIDGE_SCAFFOLD_BEHAVIOR_H_
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: BridgeTowerBehavior.h ////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, July 2002
|
||||
// Desc: Behavior module for the towers attached to bridges that can be targeted
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __BRIDGE_TOWER_BEHAVIOR_H_
|
||||
#define __BRIDGE_TOWER_BEHAVIOR_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/DamageModule.h"
|
||||
#include "GameLogic/Module/Diemodule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BridgeTowerBehaviorInterface
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual void setBridge( Object *bridge ) = 0;
|
||||
virtual ObjectID getBridgeID( void ) = 0;
|
||||
virtual void setTowerType( BridgeTowerType type ) = 0;
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class BridgeTowerBehavior : public BehaviorModule,
|
||||
public BridgeTowerBehaviorInterface,
|
||||
public DieModuleInterface,
|
||||
public DamageModuleInterface
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO( BridgeTowerBehavior );
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( BridgeTowerBehavior, "BridgeTowerBehavior" )
|
||||
|
||||
public:
|
||||
|
||||
BridgeTowerBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
static Int getInterfaceMask() { return (MODULEINTERFACE_DAMAGE) | (MODULEINTERFACE_DIE); }
|
||||
BridgeTowerBehaviorInterface* getBridgeTowerBehaviorInterface( void ) { return this; }
|
||||
|
||||
virtual void setBridge( Object *bridge );
|
||||
virtual ObjectID getBridgeID( void );
|
||||
virtual void setTowerType( BridgeTowerType type );
|
||||
|
||||
static BridgeTowerBehaviorInterface *getBridgeTowerBehaviorInterfaceFromObject( Object *obj );
|
||||
|
||||
// Damage methods
|
||||
virtual DamageModuleInterface* getDamage() { return this; }
|
||||
virtual void onDamage( DamageInfo *damageInfo );
|
||||
virtual void onHealing( DamageInfo *damageInfo );
|
||||
virtual void onBodyDamageStateChange( const DamageInfo* damageInfo,
|
||||
BodyDamageType oldState,
|
||||
BodyDamageType newState );
|
||||
|
||||
// Die methods
|
||||
virtual DieModuleInterface* getDie() { return this; }
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
protected:
|
||||
|
||||
ObjectID m_bridgeID; ///< the bridge we're a part of
|
||||
BridgeTowerType m_type; ///< type of tower (positioning) we are
|
||||
|
||||
};
|
||||
|
||||
#endif // end __BRIDGE_TOWER_DAMAGE_H_
|
||||
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CashBountyPower.h /////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Electronic Arts Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2002 - All Rights Reserved
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// created: Aug 2002
|
||||
//
|
||||
// Filename: CashBountyPower.h
|
||||
//
|
||||
//
|
||||
// purpose:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CashBountyPower_H_
|
||||
#define __CashBountyPower_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "GameLogic/Module/SpecialPowerModule.h"
|
||||
#include "Common/Science.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
class Thing;
|
||||
class Player;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TYPE DEFINES ///////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// INLINING ///////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// EXTERNALS //////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CashBountyPowerModuleData : public SpecialPowerModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
#ifdef NOT_IN_USE
|
||||
struct Upgrades
|
||||
{
|
||||
ScienceType m_science;
|
||||
Real m_bounty;
|
||||
|
||||
Upgrades() : m_science(SCIENCE_INVALID), m_bounty(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
std::vector<Upgrades> m_upgrades;
|
||||
#endif
|
||||
Real m_defaultBounty;
|
||||
|
||||
CashBountyPowerModuleData( void );
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The OCL upgrade module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CashBountyPower : public SpecialPowerModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CashBountyPower, "CashBountyPower" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CashBountyPower, CashBountyPowerModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CashBountyPower( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
virtual void onObjectCreated();
|
||||
|
||||
//virtual void onBuildComplete(); ///< This is called when you are a finished game object
|
||||
virtual void onSpecialPowerCreation(); ///< This is called when you are a finished game object
|
||||
virtual void doSpecialPower( UnsignedInt commandOptions ) { return; }
|
||||
|
||||
protected:
|
||||
|
||||
Real findBounty() const;
|
||||
|
||||
};
|
||||
|
||||
#endif // __CashBountyPower_H_
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CashHackSpecialPower.h ///////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, June 2002
|
||||
// Desc: The Spy Satellite will reveal shrouded areas of the map that the player chooses
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CASHHACKSPECIALPOWER_H_
|
||||
#define __CASHHACKSPECIALPOWER_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/SpecialPowerModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Object;
|
||||
class SpecialPowerTemplate;
|
||||
struct FieldParse;
|
||||
enum ScienceType;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CashHackSpecialPowerModuleData : public SpecialPowerModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
struct Upgrades
|
||||
{
|
||||
ScienceType m_science;
|
||||
Int m_amountToSteal;
|
||||
|
||||
Upgrades() : m_science(SCIENCE_INVALID), m_amountToSteal(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
std::vector<Upgrades> m_upgrades;
|
||||
Int m_defaultAmountToSteal; ///< the amount of money that we will steal
|
||||
|
||||
CashHackSpecialPowerModuleData( void );
|
||||
static void buildFieldParse( MultiIniFieldParse& p );
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CashHackSpecialPower : public SpecialPowerModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CashHackSpecialPower, "CashHackSpecialPower" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CashHackSpecialPower, CashHackSpecialPowerModuleData )
|
||||
|
||||
public:
|
||||
|
||||
CashHackSpecialPower( Thing *thing, const ModuleData *moduleData );
|
||||
// virtual destructor provided by memory pool object
|
||||
|
||||
virtual void doSpecialPowerAtObject( Object *obj, UnsignedInt commandOptions );
|
||||
virtual void doSpecialPowerAtLocation( const Coord3D *loc, UnsignedInt commandOptions );
|
||||
|
||||
protected:
|
||||
|
||||
Int findAmountToSteal() const;
|
||||
|
||||
};
|
||||
|
||||
#endif // end __CASHHACKSPECIALPOWER_H_
|
||||
|
||||
130
Generals/Code/GameEngine/Include/GameLogic/Module/CaveContain.h
Normal file
130
Generals/Code/GameEngine/Include/GameLogic/Module/CaveContain.h
Normal file
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CaveContain.h ////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, July 2002
|
||||
// Desc: A version of OpenContain that overrides where the passengers are stored: one of CaveManager's
|
||||
// entries. Changing entry is a script or ini command. All queries about capacity and
|
||||
// contents are also redirected.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CAVE_CONTAIN_H_
|
||||
#define __CAVE_CONTAIN_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/CreateModule.h"
|
||||
#include "GameLogic/Module/OpenContain.h"
|
||||
|
||||
struct Sound;
|
||||
class Team;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CaveContainModuleData : public OpenContainModuleData
|
||||
{
|
||||
public:
|
||||
Int m_caveIndexData;
|
||||
|
||||
CaveContainModuleData()
|
||||
{
|
||||
m_caveIndexData = 0;// By default, all Caves will be grouped together as number 0
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
OpenContainModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "CaveIndex", INI::parseInt, NULL, offsetof( CaveContainModuleData, m_caveIndexData ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CaveContain : public OpenContain, public CreateModuleInterface, public CaveInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CaveContain, "CaveContain" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CaveContain, CaveContainModuleData )
|
||||
|
||||
public:
|
||||
|
||||
CaveContain( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual CreateModuleInterface* getCreate() { return this; }
|
||||
virtual CaveInterface* getCaveInterface() { return this; }
|
||||
static Int getInterfaceMask() { return OpenContain::getInterfaceMask() | (MODULEINTERFACE_CREATE); }
|
||||
|
||||
virtual OpenContain *asOpenContain() { return this; } ///< treat as open container
|
||||
virtual Bool isGarrisonable() const { return false; } ///< can this unit be Garrisoned? (ick)
|
||||
virtual Bool isHealContain() const { return false; } ///< true when container only contains units while healing (not a transport!)
|
||||
|
||||
virtual void onContaining( Object *obj ); ///< object now contains 'obj'
|
||||
virtual void onRemoving( Object *obj ); ///< object no longer contains 'obj'
|
||||
|
||||
virtual Bool isValidContainerFor(const Object* obj, Bool checkCapacity) const;
|
||||
virtual void addToContainList( Object *obj ); ///< The part of AddToContain that inheritors can override (Can't do whole thing because of all the private stuff involved)
|
||||
virtual void removeFromContain( Object *obj, Bool exposeStealthUnits = FALSE ); ///< remove 'obj' from contain list
|
||||
virtual void removeAllContained( Bool exposeStealthUnits = FALSE ); ///< remove all objects on contain list
|
||||
|
||||
/**
|
||||
return the player that *appears* to control this unit. if null, use getObject()->getControllingPlayer() instead.
|
||||
*/
|
||||
virtual void recalcApparentControllingPlayer( void );
|
||||
|
||||
// contain list access
|
||||
virtual void iterateContained( ContainIterateFunc func, void *userData, Bool reverse );
|
||||
virtual UnsignedInt getContainCount() const;
|
||||
virtual Int getContainMax( void ) const;
|
||||
virtual const ContainedItemsList* getContainedItemsList() const;
|
||||
virtual Bool isKickOutOnCapture(){ return FALSE; }///< Caves and Tunnels don't kick out on capture.
|
||||
|
||||
// override the onDie we inherit from OpenContain
|
||||
virtual void onDie( const DamageInfo *damageInfo ); ///< the die callback
|
||||
|
||||
virtual void onCreate( void );
|
||||
virtual void onBuildComplete(); ///< This is called when you are a finished game object
|
||||
virtual Bool shouldDoOnBuildComplete() const { return m_needToRunOnBuildComplete; }
|
||||
|
||||
// Unique to Cave Contain
|
||||
virtual void tryToSetCaveIndex( Int newIndex ); ///< Called by script as an alternative to instancing separate objects. 'Try', because can fail.
|
||||
virtual void setOriginalTeam( Team *oldTeam ); ///< This is a distributed Garrison in terms of capturing, so when one node triggers the change, he needs to tell everyone, so anyone can do the un-change.
|
||||
|
||||
protected:
|
||||
|
||||
void changeTeamOnAllConnectedCaves( Team *newTeam, Bool setOriginalTeams ); ///< When one gets captured, all connected ones get captured. DistributedGarrison.
|
||||
|
||||
Bool m_needToRunOnBuildComplete;
|
||||
Int m_caveIndex;
|
||||
|
||||
Team *m_originalTeam; ///< our original team before we were garrisoned
|
||||
|
||||
};
|
||||
|
||||
#endif // end __CAVE_CONTAIN_H_
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CheckpointUpdate.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Matthew D. Campbell, April 2002
|
||||
// Desc: Reacts when an enemy is within range
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CHECKPOINT_UPDATE_H
|
||||
#define CHECKPOINT_UPDATE_H
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "Common/KindOf.h"
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Checkpoint update */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CheckpointUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_enemyScanDelayTime;
|
||||
|
||||
CheckpointUpdateModuleData()
|
||||
{
|
||||
m_enemyScanDelayTime = LOGICFRAMES_PER_SECOND;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "ScanDelayTime", INI::parseDurationUnsignedInt, NULL, offsetof( CheckpointUpdateModuleData, m_enemyScanDelayTime ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class CheckpointUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CheckpointUpdate, "CheckpointUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CheckpointUpdate, CheckpointUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
CheckpointUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
Bool m_enemyNear;
|
||||
Bool m_allyNear;
|
||||
Real m_maxMinorRadius;
|
||||
|
||||
UnsignedInt m_enemyScanDelay;
|
||||
void checkForAlliesAndEnemies( void );
|
||||
|
||||
};
|
||||
|
||||
#endif // end CHECKPOINT_UPDATE_H
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ChinookAIUpdate.h //////////
|
||||
// Author: Steven Johnson, June 2002
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _ChinookAIUpdate_H_
|
||||
#define _ChinookAIUpdate_H_
|
||||
|
||||
#include "GameLogic/AIStateMachine.h"
|
||||
#include "GameLogic/Module/SupplyTruckAIUpdate.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ChinookAIUpdateModuleData : public SupplyTruckAIUpdateModuleData
|
||||
{
|
||||
public:
|
||||
AsciiString m_ropeName;
|
||||
Real m_rappelSpeed;
|
||||
Real m_ropeDropSpeed;
|
||||
Real m_ropeWidth;
|
||||
Real m_ropeFinalHeight;
|
||||
Real m_ropeWobbleLen;
|
||||
Real m_ropeWobbleAmp;
|
||||
Real m_ropeWobbleRate;
|
||||
RGBColor m_ropeColor;
|
||||
UnsignedInt m_numRopes;
|
||||
UnsignedInt m_perRopeDelayMin;
|
||||
UnsignedInt m_perRopeDelayMax;
|
||||
Real m_minDropHeight;
|
||||
Bool m_waitForRopesToDrop;
|
||||
|
||||
ChinookAIUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum ChinookFlightStatus // Stored in save file, don't renumber. jba.
|
||||
{
|
||||
CHINOOK_TAKING_OFF = 0,
|
||||
CHINOOK_FLYING = 1,
|
||||
CHINOOK_DOING_COMBAT_DROP = 2,
|
||||
CHINOOK_LANDING = 3,
|
||||
CHINOOK_LANDED = 4
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ChinookAIUpdate : public SupplyTruckAIUpdate
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ChinookAIUpdate, "ChinookAIUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( ChinookAIUpdate, ChinookAIUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
ChinookAIUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
virtual void aiDoCommand(const AICommandParms* parms);
|
||||
virtual Bool chooseLocomotorSet(LocomotorSetType wst);
|
||||
// this is present solely for some transports to override, so that they can land before
|
||||
// allowing people to exit...
|
||||
virtual AIFreeToExitType getAiFreeToExit(const Object* exiter) const;
|
||||
virtual Bool isAllowedToAdjustDestination() const;
|
||||
virtual ObjectID getBuildingToNotPathAround() const;
|
||||
|
||||
// this is present for subclasses (eg, Chinook) to override, to
|
||||
// prevent supply-ferry behavior in some cases (eg, when toting passengers)
|
||||
virtual Bool isAvailableForSupplying() const;
|
||||
virtual Bool isCurrentlyFerryingSupplies() const;
|
||||
|
||||
virtual Bool isIdle() const;
|
||||
|
||||
const ChinookAIUpdateModuleData* friend_getData() const { return getChinookAIUpdateModuleData(); }
|
||||
void friend_setFlightStatus(ChinookFlightStatus a) { m_flightStatus = a; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual AIStateMachine* makeStateMachine();
|
||||
|
||||
virtual void privateCombatDrop( Object *target, const Coord3D& pos, CommandSourceType cmdSource );
|
||||
virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot
|
||||
|
||||
private:
|
||||
|
||||
void setMyState( StateID cmd, Object* target, const Coord3D* pos, CommandSourceType cmdSource );
|
||||
void setAirfieldForHealing(ObjectID id);
|
||||
|
||||
AICommandParmsStorage m_pendingCommand;
|
||||
ChinookFlightStatus m_flightStatus;
|
||||
ObjectID m_airfieldForHealing;
|
||||
Bool m_hasPendingCommand;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CleanupAreaPower.h /////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Electronic Arts Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2002 - All Rights Reserved
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Created: September 2002
|
||||
//
|
||||
// Author: Kris Morness
|
||||
//
|
||||
// Makes use of the cleanup hazard update by augmenting the cleanup range
|
||||
// until there is nothing left to cleanup at which time it goes idle.
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CLEANUP_AREA_POWER_H_
|
||||
#define __CLEANUP_AREA_POWER_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "GameLogic/Module/SpecialPowerModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CleanupAreaPowerModuleData : public SpecialPowerModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
Real m_cleanupMoveRange;
|
||||
|
||||
CleanupAreaPowerModuleData( void );
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CleanupAreaPower : public SpecialPowerModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CleanupAreaPower, "CleanupAreaPower" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CleanupAreaPower, CleanupAreaPowerModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CleanupAreaPower( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
virtual void doSpecialPowerAtLocation( const Coord3D *loc, UnsignedInt commandOptions );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CleanupHazardUpdate.cpp //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Kris Morness, August 2002
|
||||
// Desc: Update module to handle independent targeting of hazards to cleanup.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CLEANUP_HAZARD_UPDATE_H_
|
||||
#define __CLEANUP_HAZARD_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/KindOf.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class ThingTemplate;
|
||||
class WeaponTemplate;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CleanupHazardUpdateModuleData : public ModuleData
|
||||
{
|
||||
public:
|
||||
WeaponSlotType m_weaponSlot;
|
||||
UnsignedInt m_scanFrames;
|
||||
Real m_scanRange;
|
||||
|
||||
CleanupHazardUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The default update module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CleanupHazardUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CleanupHazardUpdate, "CleanupHazardUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CleanupHazardUpdate, CleanupHazardUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CleanupHazardUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onObjectCreated();
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
Object* scanClosestTarget();
|
||||
void fireWhenReady();
|
||||
|
||||
void setCleanupAreaParameters( const Coord3D *pos, Real range ); //This allows the unit to cleanup an area until clean, then the AI goes idle.
|
||||
|
||||
protected:
|
||||
|
||||
ObjectID m_bestTargetID;
|
||||
Bool m_inRange;
|
||||
Int m_nextScanFrames;
|
||||
Int m_nextShotAvailableInFrames;
|
||||
const WeaponTemplate *m_weaponTemplate;
|
||||
|
||||
//Cleanup area (temporary values).
|
||||
Coord3D m_pos;
|
||||
Real m_moveRange;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CollideModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2001
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CollideModule_H_
|
||||
#define __CollideModule_H_
|
||||
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** OBJECT COLLIDE MODULE
|
||||
- Called when two objects collide (or when object collides with ground)
|
||||
- Note in the 'collide' method that 'other' can be NULL, this indicates a
|
||||
collision with the ground
|
||||
- Also note the 'collide' method is the response for the object that THIS module
|
||||
belongs to, we do not need to worry about the collision moudle of 'other',
|
||||
it will have its own collide action called separately */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CollideModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal ) = 0;
|
||||
virtual Bool wouldLikeToCollideWith(const Object* other) const = 0;
|
||||
virtual Bool isHijackedVehicleCrateCollide() const = 0;
|
||||
virtual Bool isCarBombCrateCollide() const = 0;
|
||||
virtual Bool isRailroad() const = 0;
|
||||
virtual Bool isSalvageCrateCollide() const = 0;
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CollideModuleData : public BehaviorModuleData
|
||||
{
|
||||
public:
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
BehaviorModuleData::buildFieldParse(p);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CollideModule : public BehaviorModule,
|
||||
public CollideModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( CollideModule )
|
||||
MAKE_STANDARD_MODULE_MACRO_ABC( CollideModule )
|
||||
MAKE_STANDARD_MODULE_DATA_MACRO_ABC(CollideModule, CollideModuleData)
|
||||
|
||||
public:
|
||||
|
||||
CollideModule( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
static Int getInterfaceMask() { return MODULEINTERFACE_COLLIDE; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual CollideModuleInterface* getCollide() { return this; }
|
||||
|
||||
virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal ) = 0;
|
||||
|
||||
/// this is used for things like pilots, to determine if they can "enter" something
|
||||
virtual Bool wouldLikeToCollideWith(const Object* other) const { return false; }
|
||||
virtual Bool isHijackedVehicleCrateCollide() const { return false; }
|
||||
virtual Bool isCarBombCrateCollide() const { return false; }
|
||||
virtual Bool isRailroad() const { return false;}
|
||||
virtual Bool isSalvageCrateCollide() const { return false; }
|
||||
|
||||
};
|
||||
inline CollideModule::CollideModule( Thing *thing, const ModuleData* moduleData ) : BehaviorModule( thing, moduleData ) { }
|
||||
inline CollideModule::~CollideModule() { }
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CommandButtonHuntUpdate.cpp //////////////////////////////////////////////////////////////////////////
|
||||
// Author: John Ahlquist, Sept. 2002
|
||||
// Desc: Update module to handle wounded idle infantry finding a heal unit or structure.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COMMAND_BUTTON_HUNT_UPDATE_H_
|
||||
#define __COMMAND_BUTTON_HUNT_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/KindOf.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class ThingTemplate;
|
||||
class WeaponTemplate;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CommandButtonHuntUpdateModuleData : public ModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_scanFrames;
|
||||
Real m_scanRange;
|
||||
|
||||
CommandButtonHuntUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The default update module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CommandButtonHuntUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CommandButtonHuntUpdate, "CommandButtonHuntUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CommandButtonHuntUpdate, CommandButtonHuntUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CommandButtonHuntUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onObjectCreated();
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
void setCommandButton(const AsciiString& buttonName);
|
||||
|
||||
protected:
|
||||
Object* scanClosestTarget(void);
|
||||
UpdateSleepTime huntSpecialPower(AIUpdateInterface *ai);
|
||||
UpdateSleepTime huntWeapon(AIUpdateInterface *ai);
|
||||
|
||||
|
||||
protected:
|
||||
AsciiString m_commandButtonName;
|
||||
const CommandButton *m_commandButton;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CommandSetUpgrade.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, September 2002
|
||||
// Desc: UpgradeModule that sets a new override string for Command Set look ups
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _COMMAND_SET_UPGRADE_H
|
||||
#define _COMMAND_SET_UPGRADE_H
|
||||
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CommandSetUpgradeModuleData : public UpgradeModuleData
|
||||
{
|
||||
public:
|
||||
AsciiString m_newCommandSet;
|
||||
|
||||
CommandSetUpgradeModuleData()
|
||||
{
|
||||
m_newCommandSet = AsciiString::TheEmptyString;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
class CommandSetUpgrade : public UpgradeModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CommandSetUpgrade, "CommandSetUpgrade" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CommandSetUpgrade, CommandSetUpgradeModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CommandSetUpgrade( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
protected:
|
||||
virtual void upgradeImplementation( ); ///< Here's the actual work of Upgrading
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
};
|
||||
#endif // _COMMAND_SET_UPGRADE_H
|
||||
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: ContainModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2001
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __ContainModule_H_
|
||||
#define __ContainModule_H_
|
||||
|
||||
#include "Common/Module.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class OpenContain;
|
||||
class Player;
|
||||
class ExitInterface;
|
||||
class Matrix3D;
|
||||
class Weapon;
|
||||
enum CommandSourceType;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum ObjectEnterExitType
|
||||
{
|
||||
WANTS_TO_ENTER,
|
||||
WANTS_TO_EXIT,
|
||||
WANTS_NEITHER
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef std::list<Object*> ContainedItemsList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
typedef ModuleData ContainModuleData;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
typedef void (*ContainIterateFunc)( Object *obj, void *userData ); ///< callback type for contain iterate
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ContainModuleInterface
|
||||
{
|
||||
public:
|
||||
|
||||
// we have a two basic container types that it is convenient to query and use
|
||||
virtual OpenContain *asOpenContain() = 0;
|
||||
|
||||
// our object changed position... react as appropriate.
|
||||
virtual void containReactToTransformChange() = 0;
|
||||
|
||||
|
||||
// containment is the basis for many complex systems, it helps us to have a formal
|
||||
// place where we can monitor the outside world if we need to
|
||||
|
||||
//===============================================================================================
|
||||
// Containment ==================================================================================
|
||||
//===============================================================================================
|
||||
|
||||
virtual Bool isGarrisonable() const = 0;
|
||||
virtual Bool isSpecialZeroSlotContainer() const = 0;
|
||||
virtual Bool isHealContain() const = 0;
|
||||
virtual Bool isImmuneToClearBuildingAttacks() const = 0;
|
||||
|
||||
|
||||
///< if my object gets selected, then my visible passengers should, too
|
||||
///< this gets called from
|
||||
virtual void clientVisibleContainedFlashAsSelected() = 0;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
this is used for containers that must do something to allow people to enter or exit...
|
||||
eg, land (for Chinook), open door (whatever)... it's called with wants=WANTS_TO_ENTER
|
||||
when something is in the enter state, and wants=ENTS_NOTHING when the unit has
|
||||
either entered, or given up...
|
||||
*/
|
||||
virtual void onObjectWantsToEnterOrExit(Object* obj, ObjectEnterExitType wants) = 0;
|
||||
|
||||
// returns true iff there are objects currently waiting to enter.
|
||||
virtual Bool hasObjectsWantingToEnterOrExit() const = 0;
|
||||
|
||||
/**
|
||||
return the player that *appears* to control this unit, given an observing player.
|
||||
if null, use getObject()->getControllingPlayer() instead.
|
||||
*/
|
||||
virtual const Player* getApparentControllingPlayer(const Player* observingPlayer) const = 0;
|
||||
|
||||
virtual void recalcApparentControllingPlayer() = 0;
|
||||
|
||||
//
|
||||
// you will want to override onContaining() and onRemoving() if you need to
|
||||
// do special actions at those event times for your module
|
||||
//
|
||||
virtual void onContaining( Object *obj ) = 0; ///< object now contains 'obj'
|
||||
virtual void onRemoving( Object *obj ) = 0; ///< object no longer contains 'obj'
|
||||
virtual void onCapture( Player *oldOwner, Player *newOwner ) = 0; // Very important to handle capture of container, don't want to differ in teams from passenger to us.
|
||||
virtual void onSelling() = 0;///< Container is being sold. Most people respond by kicking everyone out, but not all.
|
||||
|
||||
virtual Int getContainMax() const = 0; ///< The max needs to be virtual, but only two inheritors care. -1 means "I don't care".
|
||||
|
||||
virtual ExitInterface* getContainExitInterface() = 0;
|
||||
|
||||
virtual void orderAllPassengersToExit( CommandSourceType ) = 0; ///< All of the smarts of exiting are in the passenger's AIExit. removeAllFrommContain is a last ditch system call, this is the game Evacuate
|
||||
virtual void markAllPassengersDetected() = 0; ///< Cool game stuff got added to the system calls since this layer didn't exist, so this regains that functionality
|
||||
|
||||
//
|
||||
// interface for containing objects inside of objects. Objects that are
|
||||
// contained remove their drawable representations entirely from the client
|
||||
//
|
||||
/**
|
||||
can this container contain this kind of object?
|
||||
and, if checkCapacity is TRUE, does this container have enough space left to hold the given unit?
|
||||
*/
|
||||
virtual Bool isValidContainerFor(const Object* obj, Bool checkCapacity) const = 0;
|
||||
virtual void addToContain( Object *obj ) = 0; ///< add 'obj' to contain list
|
||||
virtual void addToContainList( Object *obj ) = 0; ///< The part of AddToContain that inheritors can override (Can't do whole thing because of all the private stuff involved)
|
||||
virtual void removeFromContain( Object *obj, Bool exposeStealthUnits = FALSE ) = 0; ///< remove 'obj' from contain list
|
||||
virtual void removeAllContained( Bool exposeStealthUnits = FALSE ) = 0; ///< remove all objects on contain list
|
||||
virtual Bool isEnclosingContainerFor( const Object *obj ) const = 0; ///< Does this type of Contain Visibly enclose its contents?
|
||||
virtual Bool isPassengerAllowedToFire() const = 0; ///< Hey, can I shoot out of this container?
|
||||
virtual void setOverrideDestination( const Coord3D * ) = 0; ///< Instead of falling peacefully towards a clear spot, I will now aim here
|
||||
virtual Bool isDisplayedOnControlBar() const = 0;///< Does this container display its contents on the ControlBar?
|
||||
virtual Int getExtraSlotsInUse( void ) = 0;
|
||||
virtual Bool isKickOutOnCapture() = 0;///< Does this contain module kick people out when captured?
|
||||
|
||||
// list access
|
||||
virtual void iterateContained( ContainIterateFunc func, void *userData, Bool reverse ) = 0; ///< iterate the contain list
|
||||
virtual UnsignedInt getContainCount() const = 0; ///< contained count
|
||||
virtual const ContainedItemsList* getContainedItemsList() const = 0;
|
||||
virtual const Object *friend_getRider() const = 0; ///< Damn. The draw order dependency bug for riders means that our draw module needs to cheat to get around it.
|
||||
virtual Real getContainedItemsMass() const = 0;
|
||||
virtual UnsignedInt getStealthUnitsContained() const = 0;
|
||||
|
||||
virtual Bool calcBestGarrisonPosition( Coord3D *sourcePos, const Coord3D *targetPos ) = 0;
|
||||
virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, Object *victim ) = 0;
|
||||
virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, const Coord3D *targetPos ) = 0;
|
||||
|
||||
// Player Occupancy.
|
||||
virtual PlayerMaskType getPlayerWhoEntered(void) const = 0;
|
||||
|
||||
virtual void processDamageToContained() = 0; ///< Do our % damage to units now.
|
||||
|
||||
virtual void enableLoadSounds( Bool enable ) = 0;
|
||||
|
||||
// this exists really just so someone can override it to prevent pip showings...
|
||||
virtual Bool getContainerPipsToShow(Int& numTotal, Int& numFull)
|
||||
{
|
||||
numTotal = getContainMax();
|
||||
numFull = getContainCount() + getExtraSlotsInUse();
|
||||
// srj sez: this makes the pips display in the same manner as the inventory control bar...
|
||||
// numTotal = getContainMax() - getExtraSlotsInUse();
|
||||
// numFull = getContainCount();
|
||||
|
||||
return true;
|
||||
}
|
||||
};
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: VeterancyCrateCollide.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Kris Morness, April 2002
|
||||
// Desc: A crate (actually a terrorist - mobile crate) that converts a car into a carbomb, activating
|
||||
// it's weapon and then activating it's AI.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CONVERT_TO_CAR_BOMB_CRATE_COLLIDE_H_
|
||||
#define CONVERT_TO_CAR_BOMB_CRATE_COLLIDE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Module/CrateCollide.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
class FXList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ConvertToCarBombCrateCollideModuleData : public CrateCollideModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_rangeOfEffect;
|
||||
const FXList *m_fxList;
|
||||
|
||||
ConvertToCarBombCrateCollideModuleData()
|
||||
{
|
||||
m_rangeOfEffect = 0;
|
||||
m_fxList = NULL;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
CrateCollideModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "FXList", INI::parseFXList, NULL, offsetof( ConvertToCarBombCrateCollideModuleData, m_fxList ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ConvertToCarBombCrateCollide : public CrateCollide
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ConvertToCarBombCrateCollide, "ConvertToCarBombCrateCollide" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( ConvertToCarBombCrateCollide, ConvertToCarBombCrateCollideModuleData );
|
||||
|
||||
public:
|
||||
|
||||
ConvertToCarBombCrateCollide( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
protected:
|
||||
|
||||
/// This allows specific vetoes to certain types of crates and their data
|
||||
virtual Bool isValidToExecute( const Object *other ) const;
|
||||
|
||||
/// This is the game logic execution function that all real CrateCollides will implement
|
||||
virtual Bool executeCrateBehavior( Object *other );
|
||||
virtual Bool isRailroad() const { return FALSE;};
|
||||
virtual Bool isCarBombCrateCollide() const { return TRUE; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FILE: ConvertToHijackedVehicleCrateCollide.h
|
||||
// Author: Mark Lorenzen, July 2002
|
||||
// Desc: A crate (actually a terrorist - mobile crate) that makes the target vehicle switch
|
||||
// sides, and kills its driver
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CONVERT_TO_HIJACKED_VEHICLE_CRATE_COLLIDE_H_
|
||||
#define CONVERT_TO_HIJACKED_VEHICLE_CRATE_COLLIDE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Module/CrateCollide.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ConvertToHijackedVehicleCrateCollideModuleData : public CrateCollideModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_rangeOfEffect;
|
||||
|
||||
ConvertToHijackedVehicleCrateCollideModuleData()
|
||||
{
|
||||
m_rangeOfEffect = 0;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
CrateCollideModuleData::buildFieldParse(p);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ConvertToHijackedVehicleCrateCollide : public CrateCollide
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ConvertToHijackedVehicleCrateCollide, "ConvertToHijackedVehicleCrateCollide" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( ConvertToHijackedVehicleCrateCollide, ConvertToHijackedVehicleCrateCollideModuleData );
|
||||
|
||||
public:
|
||||
|
||||
ConvertToHijackedVehicleCrateCollide( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
protected:
|
||||
|
||||
/// This allows specific vetoes to certain types of crates and their data
|
||||
virtual Bool isValidToExecute( const Object *other ) const;
|
||||
|
||||
/// This is the game logic execution function that all real CrateCollides will implement
|
||||
virtual Bool executeCrateBehavior( Object *other );
|
||||
|
||||
virtual Bool isHijackedVehicleCrateCollide() const { return TRUE; }
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CostModifierUpgrade.h /////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// Electronic Arts Pacific.
|
||||
//
|
||||
// Confidential Information
|
||||
// Copyright (C) 2002 - All Rights Reserved
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
// created: Aug 2002
|
||||
//
|
||||
// Filename: CostModifierUpgrade.h
|
||||
//
|
||||
// author: Chris Huybregts
|
||||
//
|
||||
// purpose:
|
||||
//
|
||||
//-----------------------------------------------------------------------------
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __COST_MODIFIER_UPGRADE_H_
|
||||
#define __COST_MODIFIER_UPGRADE_H_
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// SYSTEM INCLUDES ////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
#include "Common/KindOf.h"
|
||||
//-----------------------------------------------------------------------------
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
class Thing;
|
||||
class Player;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// TYPE DEFINES ///////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// INLINING ///////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// EXTERNALS //////////////////////////////////////////////////////////////////
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CostModifierUpgradeModuleData : public UpgradeModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
CostModifierUpgradeModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
Real m_percentage;
|
||||
KindOfMaskType m_kindOf;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The OCL upgrade module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CostModifierUpgrade : public UpgradeModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CostModifierUpgrade, "CostModifierUpgrade" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CostModifierUpgrade, CostModifierUpgradeModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CostModifierUpgrade( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
virtual void onDelete( void ); ///< we have some work to do when this module goes away
|
||||
virtual void onCapture( Player *oldOwner, Player *newOwner );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation( void ); ///< Here's the actual work of Upgrading
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
};
|
||||
|
||||
#endif // __COST_MODIFIER_UPGRADE_H_
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CrateCollide.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, March 2002
|
||||
// Desc: Abstract base Class Crate Collide
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef CRATE_COLLIDE_H_
|
||||
#define CRATE_COLLIDE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/CollideModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
class Anim2DTemplate;
|
||||
class FXList;
|
||||
enum ScienceType;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CrateCollideModuleData : public CollideModuleData
|
||||
{
|
||||
public:
|
||||
KindOfMaskType m_kindof; ///< the kind(s) of units that can be collided with
|
||||
KindOfMaskType m_kindofnot; ///< the kind(s) of units that CANNOT be collided with
|
||||
Bool m_isForbidOwnerPlayer; ///< This crate cannot be picked up by the player of the dead thing that made it.
|
||||
Bool m_isBuildingPickup; ///< This crate can be picked up by a Building (bypassing AI requirement)
|
||||
Bool m_isHumanOnlyPickup; ///< Can this crate only be picked up by a human player? (Mission thing)
|
||||
ScienceType m_pickupScience; ///< Can only be picked up by a unit whose player has this science
|
||||
FXList *m_executeFX; ///< FXList to play when activated
|
||||
|
||||
AsciiString m_executionAnimationTemplate; ///< Anim2D to play at crate location
|
||||
Real m_executeAnimationDisplayTimeInSeconds; ///< time to play animation for
|
||||
Real m_executeAnimationZRisePerSecond; ///< rise animation up while playing
|
||||
Bool m_executeAnimationFades; ///< animation fades out
|
||||
|
||||
CrateCollideModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CrateCollide : public CollideModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( CrateCollide )
|
||||
MAKE_STANDARD_MODULE_MACRO_ABC( CrateCollide )
|
||||
MAKE_STANDARD_MODULE_DATA_MACRO_ABC( CrateCollide, CrateCollideModuleData )
|
||||
|
||||
public:
|
||||
|
||||
CrateCollide( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
/// This collide method gets called when collision occur
|
||||
virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal );
|
||||
|
||||
virtual Bool wouldLikeToCollideWith(const Object* other) const { return isValidToExecute(other); }
|
||||
|
||||
virtual Bool isRailroad() const { return FALSE;};
|
||||
virtual Bool isCarBombCrateCollide() const { return FALSE; }
|
||||
virtual Bool isHijackedVehicleCrateCollide() const { return FALSE; }
|
||||
|
||||
protected:
|
||||
|
||||
/// This is the game logic execution function that all real CrateCollides will implement
|
||||
virtual Bool executeCrateBehavior( Object *other ) = 0;
|
||||
|
||||
/// This allows specific vetoes to certain types of crates and their data
|
||||
virtual Bool isValidToExecute( const Object *other ) const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CreateCrateDie.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, February 2002
|
||||
// Desc: A chance to create a crate on death according to certain condition checks
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _CREATE_CRATE_DIE_H_
|
||||
#define _CREATE_CRATE_DIE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/INI.h"
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class CrateTemplate;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class CreateCrateDieModuleData : public DieModuleData
|
||||
{
|
||||
public:
|
||||
AsciiStringList m_crateNameList;
|
||||
|
||||
CreateCrateDieModuleData()
|
||||
{
|
||||
// Added By Sadullah Nader
|
||||
// Initializations missing and needed
|
||||
m_crateNameList.clear();
|
||||
}
|
||||
~CreateCrateDieModuleData()
|
||||
{
|
||||
m_crateNameList.clear();
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
DieModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "CrateData", CreateCrateDieModuleData::parseCrateData, NULL, NULL },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
|
||||
static void parseCrateData( INI* ini, void *instance, void * /*store*/, const void* /*userData*/ );
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class CreateCrateDie : public DieModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CreateCrateDie, "CreateCrateDie" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CreateCrateDie, CreateCrateDieModuleData )
|
||||
|
||||
public:
|
||||
|
||||
CreateCrateDie( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
private:
|
||||
Bool testCreationChance( CrateTemplate const *currentCrateData );
|
||||
Bool testVeterancyLevel( CrateTemplate const *currentCrateData );
|
||||
Bool testKillerType( CrateTemplate const *currentCrateData, Object *killer );
|
||||
Bool testKillerScience( CrateTemplate const *currentCrateData, Object *killer );
|
||||
|
||||
Object *createCrate( CrateTemplate const *currentCrateData );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CreateModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2001
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CreateModule_H_
|
||||
#define __CreateModule_H_
|
||||
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** OBJECT CREATE MODULE base class */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CreateModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void onCreate() = 0; ///< This is called when you become a code Object
|
||||
virtual void onBuildComplete() = 0; ///< This is called when you are a finished game object
|
||||
virtual Bool shouldDoOnBuildComplete() const = 0;
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CreateModuleData : public BehaviorModuleData
|
||||
{
|
||||
public:
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
BehaviorModuleData::buildFieldParse(p);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CreateModule : public BehaviorModule, public CreateModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( CreateModule )
|
||||
MAKE_STANDARD_MODULE_MACRO_ABC( CreateModule )
|
||||
//MAKE_STANDARD_MODULE_DATA_MACRO_ABC(CreateModule, CreateModuleData)
|
||||
|
||||
public:
|
||||
|
||||
CreateModule( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
static Int getInterfaceMask() { return MODULEINTERFACE_CREATE; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual CreateModuleInterface* getCreate() { return this; }
|
||||
|
||||
virtual void onCreate() = 0; ///< This is called when you become a code Object
|
||||
virtual void onBuildComplete(){ m_needToRunOnBuildComplete = FALSE; } ///< This is called when you are a finished game object
|
||||
virtual Bool shouldDoOnBuildComplete() const { return m_needToRunOnBuildComplete; }
|
||||
|
||||
private:
|
||||
|
||||
Bool m_needToRunOnBuildComplete; ///< Prevent the multiple calling of onBuildComplete
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CreateObjectDie.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Michael S. Booth, January 2002
|
||||
// Desc: Create object at current object's death
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _CREATE_OBJECT_DIE_H_
|
||||
#define _CREATE_OBJECT_DIE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/INI.h"
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
class ObjectCreationList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CreateObjectDieModuleData : public DieModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
const ObjectCreationList* m_ocl; ///< object creaton list to make
|
||||
|
||||
CreateObjectDieModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** When this object dies, create another object in its place */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CreateObjectDie : public DieModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CreateObjectDie, "CreateObjectDie" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CreateObjectDie, CreateObjectDieModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CreateObjectDie( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
};
|
||||
|
||||
#endif // _CREATE_OBJECT_DIE_H_
|
||||
|
||||
106
Generals/Code/GameEngine/Include/GameLogic/Module/CrushDie.h
Normal file
106
Generals/Code/GameEngine/Include/GameLogic/Module/CrushDie.h
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: CrushDie.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, November 2001
|
||||
// Desc: Default die module
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __CrushDie_H_
|
||||
#define __CrushDie_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/AudioEventRTS.h"
|
||||
#include "Common/INI.h"
|
||||
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
enum CrushEnum
|
||||
{
|
||||
TOTAL_CRUSH,
|
||||
BACK_END_CRUSH,
|
||||
FRONT_END_CRUSH,
|
||||
NO_CRUSH,
|
||||
|
||||
CRUSH_COUNT
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CrushDieModuleData : public DieModuleData
|
||||
{
|
||||
public:
|
||||
AudioEventRTS m_crushSounds[CRUSH_COUNT];
|
||||
Int m_crushSoundPercent[CRUSH_COUNT];
|
||||
|
||||
CrushDieModuleData()
|
||||
{
|
||||
for (int i = 0; i < CRUSH_COUNT; i++)
|
||||
{
|
||||
m_crushSoundPercent[i] = 100;
|
||||
}
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
DieModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "TotalCrushSound", INI::parseAudioEventRTS, NULL, offsetof( CrushDieModuleData, m_crushSounds[TOTAL_CRUSH] ) },
|
||||
{ "BackEndCrushSound", INI::parseAudioEventRTS, NULL, offsetof( CrushDieModuleData, m_crushSounds[BACK_END_CRUSH] ) },
|
||||
{ "FrontEndCrushSound", INI::parseAudioEventRTS, NULL, offsetof( CrushDieModuleData, m_crushSounds[FRONT_END_CRUSH] ) },
|
||||
{ "TotalCrushSoundPercent", INI::parseInt, NULL, offsetof( CrushDieModuleData, m_crushSoundPercent[TOTAL_CRUSH] ) },
|
||||
{ "BackEndCrushSoundPercent", INI::parseInt, NULL, offsetof( CrushDieModuleData, m_crushSoundPercent[BACK_END_CRUSH] ) },
|
||||
{ "FrontEndCrushSoundPercent",INI::parseInt, NULL, offsetof( CrushDieModuleData, m_crushSoundPercent[FRONT_END_CRUSH] ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CrushDie : public DieModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( CrushDie, "CrushDie" )
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( CrushDie, CrushDieModuleData );
|
||||
|
||||
public:
|
||||
|
||||
CrushDie( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
};
|
||||
|
||||
#endif // __CrushDie_H_
|
||||
|
||||
68
Generals/Code/GameEngine/Include/GameLogic/Module/DamDie.h
Normal file
68
Generals/Code/GameEngine/Include/GameLogic/Module/DamDie.h
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DamDie.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, April 2002
|
||||
// Desc: The big water dam dying
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DAMDIE_H_
|
||||
#define __DAMDIE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class DamDieModuleData : public DieModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DamDieModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class DamDie : public DieModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DamDie, "DamDie" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DamDie, DamDieModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DamDie( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prorotype provided by MemoryPoolObject
|
||||
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
};
|
||||
|
||||
#endif // end __DAMDIE_H_
|
||||
117
Generals/Code/GameEngine/Include/GameLogic/Module/DamageModule.h
Normal file
117
Generals/Code/GameEngine/Include/GameLogic/Module/DamageModule.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DamageModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2001
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DamageModule_H_
|
||||
#define __DamageModule_H_
|
||||
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
|
||||
enum BodyDamageType;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** OBJECT DAMAGE MODULE base class */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DamageModuleInterface
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
virtual void onDamage( DamageInfo *damageInfo ) = 0; ///< damage callback
|
||||
virtual void onHealing( DamageInfo *damageInfo ) = 0; ///< healing callback
|
||||
virtual void onBodyDamageStateChange( const DamageInfo* damageInfo,
|
||||
BodyDamageType oldState,
|
||||
BodyDamageType newState) = 0; ///< state change callback
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DamageModuleData : public BehaviorModuleData
|
||||
{
|
||||
public:
|
||||
// DamageTypeFlags m_damageTypes;
|
||||
|
||||
DamageModuleData()
|
||||
// : m_damageTypes(DAMAGE_TYPE_FLAGS_ALL)
|
||||
{
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
BehaviorModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
// { "DamageTypes", INI::parseDamageTypeFlags, NULL, offsetof( DamageModuleData, m_damageTypes ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DamageModule : public BehaviorModule, public DamageModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( DamageModule )
|
||||
MAKE_STANDARD_MODULE_MACRO_ABC( DamageModule )
|
||||
MAKE_STANDARD_MODULE_DATA_MACRO_ABC( DamageModule, DamageModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DamageModule( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
// module methods
|
||||
static Int getInterfaceMask() { return MODULEINTERFACE_DAMAGE; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual DamageModuleInterface* getDamage() { return this; }
|
||||
|
||||
// damage module callbacks
|
||||
virtual void onDamage( DamageInfo *damageInfo ) = 0; ///< damage callback
|
||||
virtual void onHealing( DamageInfo *damageInfo ) = 0; ///< healing callback
|
||||
virtual void onBodyDamageStateChange( const DamageInfo* damageInfo,
|
||||
BodyDamageType oldState,
|
||||
BodyDamageType newState) = 0; ///< state change callback
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
inline DamageModule::DamageModule( Thing *thing, const ModuleData* moduleData ) : BehaviorModule( thing, moduleData ) { }
|
||||
inline DamageModule::~DamageModule() { }
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DefaultProductionExitUpdate.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, January, 2002
|
||||
// Desc: Hand off produced Units to me so I can Exit them into the world with my specific style
|
||||
// This instance simply spits the guy out at a point.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _DEFAULT_PRODUCTION_EXIT_UPDATE_H
|
||||
#define _DEFAULT_PRODUCTION_EXIT_UPDATE_H
|
||||
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "Common/INI.h"
|
||||
#include "Lib/BaseType.h"
|
||||
|
||||
class Object;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DefaultProductionExitUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
Coord3D m_unitCreatePoint;
|
||||
Coord3D m_naturalRallyPoint;
|
||||
|
||||
DefaultProductionExitUpdateModuleData()
|
||||
{
|
||||
m_unitCreatePoint.zero();
|
||||
m_naturalRallyPoint.zero();
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "UnitCreatePoint", INI::parseCoord3D, NULL, offsetof( DefaultProductionExitUpdateModuleData, m_unitCreatePoint ) },
|
||||
{ "NaturalRallyPoint", INI::parseCoord3D, NULL, offsetof( DefaultProductionExitUpdateModuleData, m_naturalRallyPoint ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DefaultProductionExitUpdate : public UpdateModule, public ExitInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DefaultProductionExitUpdate, "DefaultProductionExitUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DefaultProductionExitUpdate, DefaultProductionExitUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
virtual ExitInterface* getUpdateExitInterface() { return this; }
|
||||
|
||||
DefaultProductionExitUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// Required funcs to fufill interface requirements
|
||||
virtual Bool isExitBusy() const {return FALSE;} ///< Contain style exiters are getting the ability to space out exits, so ask this before reserveDoor as a kind of no-commitment check.
|
||||
virtual ExitDoorType reserveDoorForExit( const ThingTemplate* objType, Object *specificObject ) { return DOOR_1; }
|
||||
virtual void exitObjectViaDoor( Object *newObj, ExitDoorType exitDoor );
|
||||
virtual void unreserveDoorForExit( ExitDoorType exitDoor ) { /* nothing */ }
|
||||
virtual void exitObjectByBudding( Object *newObj, Object *budHost ) { return; }
|
||||
|
||||
virtual void setRallyPoint( const Coord3D *pos ); ///< define a "rally point" for units to move towards
|
||||
virtual const Coord3D *getRallyPoint( void ) const; ///< define a "rally point" for units to move towards
|
||||
virtual Bool getNaturalRallyPoint( Coord3D& rallyPoint, Bool offset = TRUE ) const; ///< get the natural "rally point" for units to move towards
|
||||
virtual Bool getExitPosition( Coord3D& exitPosition ) const; ///< access to the "Door" position of the production object
|
||||
virtual UpdateSleepTime update() { return UPDATE_SLEEP_FOREVER; }
|
||||
|
||||
protected:
|
||||
|
||||
Coord3D m_rallyPoint; ///< Where units should move to after they have reached the "natural" rally point
|
||||
Bool m_rallyPointExists; ///< Only move to the rally point if this is true
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
inline void DefaultProductionExitUpdate::setRallyPoint( const Coord3D *pos )
|
||||
{
|
||||
m_rallyPoint = *pos;
|
||||
m_rallyPointExists = true;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
inline const Coord3D *DefaultProductionExitUpdate::getRallyPoint( void ) const
|
||||
{
|
||||
if (m_rallyPointExists)
|
||||
return &m_rallyPoint;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// FILE: DefectorSpecialPower.h
|
||||
// Author: Mark Lorenzen, JULY 2002
|
||||
// Desc: General can click command cursor on any enemy, and it becomes his
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEFECTORSPECIALPOWER_H_
|
||||
#define __DEFECTORSPECIALPOWER_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/SpecialPowerModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Object;
|
||||
class SpecialPowerTemplate;
|
||||
struct FieldParse;
|
||||
enum ScienceType;
|
||||
|
||||
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DefectorSpecialPowerModuleData : public SpecialPowerModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DefectorSpecialPowerModuleData( void );
|
||||
|
||||
static void buildFieldParse( MultiIniFieldParse& p );
|
||||
|
||||
Real m_fatCursorRadius; ///< the distance around the target we will reveal
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DefectorSpecialPower : public SpecialPowerModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DefectorSpecialPower, "DefectorSpecialPower" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DefectorSpecialPower, DefectorSpecialPowerModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DefectorSpecialPower( Thing *thing, const ModuleData *moduleData );
|
||||
// virtual destructor prototype provided by memory pool object
|
||||
|
||||
virtual void doSpecialPowerAtObject( Object *obj, UnsignedInt commandOptions );
|
||||
virtual void doSpecialPowerAtLocation( const Coord3D *loc, UnsignedInt commandOptions );
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
#endif // end DefectorSpecialPower
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DelayedUpgrade.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, April 2002
|
||||
// Desc: An Upgrade that broadcasts to all DelayedUpgradeUpdates that maybe they should start
|
||||
// counting down to execution
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DELAYED_UPGRADE_H_
|
||||
#define __DELAYED_UPGRADE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DelayedUpgradeModuleData : public UpgradeModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_delayTime;
|
||||
|
||||
DelayedUpgradeModuleData()
|
||||
{
|
||||
m_delayTime = 0;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpgradeModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "DelayTime", INI::parseDurationUnsignedInt, NULL, offsetof( DelayedUpgradeModuleData, m_delayTime ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class DelayedUpgrade : public UpgradeModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DelayedUpgrade, "DelayedUpgrade" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DelayedUpgrade, DelayedUpgradeModuleData );
|
||||
|
||||
public:
|
||||
|
||||
DelayedUpgrade( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation( ); ///< Here's the actual work of Upgrading
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DelayedWeaponSetUpgradeUpdate.h ////////////////////////////////////////////////////////////////////////
|
||||
// Author: Will act like an WeaponSet UpgradeModule, but after a delay.
|
||||
// Desc: Graham Smallwood, April 2002
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DELAYED_WEAPON_SET_UPGRADE_UPDATE_H_
|
||||
#define __DELAYED_WEAPON_SET_UPGRADE_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DelayedWeaponSetUpgradeUpdateModuleData: public UpdateModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DelayedWeaponSetUpgradeUpdateModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DelayedWeaponSetUpgradeUpdate : public UpdateModule, public DelayedUpgradeUpdateInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DelayedWeaponSetUpgradeUpdate, "DelayedWeaponSetUpgradeUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DelayedWeaponSetUpgradeUpdate, DelayedWeaponSetUpgradeUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DelayedWeaponSetUpgradeUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual Bool isTriggeredBy( Int64 potentialMask ); ///< If you were an upgrade, would you trigger for this?
|
||||
virtual void setDelay( UnsignedInt startingDelay ); ///< Start the upgrade doing countdown
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DeletionUpdate.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, August 2002
|
||||
// Desc: Update that will count down a lifetime and destroy object when it reaches zero
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DELETION_UPDATE_H_
|
||||
#define __DELETION_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeletionUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_minFrames;
|
||||
UnsignedInt m_maxFrames;
|
||||
|
||||
DeletionUpdateModuleData()
|
||||
{
|
||||
m_minFrames = 0.0f;
|
||||
m_maxFrames = 0.0f;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "MinLifetime", INI::parseDurationUnsignedInt, NULL, offsetof( DeletionUpdateModuleData, m_minFrames ) },
|
||||
{ "MaxLifetime", INI::parseDurationUnsignedInt, NULL, offsetof( DeletionUpdateModuleData, m_maxFrames ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeletionUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DeletionUpdate, "DeletionUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DeletionUpdate, DeletionUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DeletionUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
void setLifetimeRange( UnsignedInt minFrames, UnsignedInt maxFrames );
|
||||
UnsignedInt getDieFrame() { return m_dieFrame; }
|
||||
|
||||
virtual UpdateSleepTime update( void );
|
||||
|
||||
protected:
|
||||
|
||||
UnsignedInt calcSleepDelay(UnsignedInt minFrames, UnsignedInt maxFrames);
|
||||
|
||||
UnsignedInt m_dieFrame; ///< frame we die on
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,386 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// DeliverPayloadAIUpdate.h ////////////
|
||||
// Author: Graham Smallwood, March 2002
|
||||
// Desc: State machine that controls the approach and deployment of airborne cargo
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _DELIVER_PAYLOAD_AI_UPDATE_H_
|
||||
#define _DELIVER_PAYLOAD_AI_UPDATE_H_
|
||||
|
||||
#include "Common/StateMachine.h"
|
||||
#include "GameLogic/Module/AIUpdate.h"
|
||||
#include "GameClient/RadiusDecal.h"
|
||||
|
||||
class DeliverPayloadData;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeliverPayloadStateMachine : public StateMachine
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DeliverPayloadStateMachine, "DeliverPayloadStateMachine" );
|
||||
public:
|
||||
DeliverPayloadStateMachine( Object *owner );
|
||||
|
||||
static Bool isOffMap( State *thisState, void* userData );
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ApproachState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(ApproachState, "ApproachState")
|
||||
//Approaching the drop zone
|
||||
public:
|
||||
ApproachState( StateMachine *machine ) :State( machine, "ApproachState" ) {}
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
protected:
|
||||
// snapshot interface STUBBED - no member vars to save. jba.
|
||||
virtual void crc( Xfer *xfer ){};
|
||||
virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
|
||||
virtual void loadPostProcess(){};
|
||||
};
|
||||
EMPTY_DTOR(ApproachState)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeliveringState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(DeliveringState, "DeliveringState")
|
||||
// Kickin' stuff out the door
|
||||
public:
|
||||
DeliveringState( StateMachine *machine ) :State( machine, "DeliveringState" )
|
||||
{
|
||||
m_dropDelayLeft = 0;
|
||||
m_didOpen = false;
|
||||
}
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
private:
|
||||
UnsignedInt m_dropDelayLeft;
|
||||
Bool m_didOpen;
|
||||
};
|
||||
EMPTY_DTOR(DeliveringState)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class ConsiderNewApproachState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(ConsiderNewApproachState, "ConsiderNewApproachState")
|
||||
//Should I try again? Has own data to keep track.
|
||||
public:
|
||||
ConsiderNewApproachState( StateMachine *machine ) : State( machine, "ConsiderNewApproachState" ), m_numberEntriesToState(0) { }
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
private:
|
||||
Int m_numberEntriesToState;
|
||||
};
|
||||
EMPTY_DTOR(ConsiderNewApproachState)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class RecoverFromOffMapState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(RecoverFromOffMapState, "RecoverFromOffMapState")
|
||||
public:
|
||||
RecoverFromOffMapState( StateMachine *machine ) : State( machine, "RecoverFromOffMapState" ), m_reEntryFrame(0) { }
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
private:
|
||||
UnsignedInt m_reEntryFrame;
|
||||
};
|
||||
EMPTY_DTOR(RecoverFromOffMapState)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HeadOffMapState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(HeadOffMapState, "HeadOffMapState")
|
||||
//I'm outta here
|
||||
public:
|
||||
HeadOffMapState( StateMachine *machine ) :State( machine, "HeadOffMapState" ) {}
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
protected:
|
||||
// snapshot interface STUBBED - no member vars to save. jba.
|
||||
virtual void crc( Xfer *xfer ){};
|
||||
virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
|
||||
virtual void loadPostProcess(){};
|
||||
};
|
||||
EMPTY_DTOR(HeadOffMapState)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class CleanUpState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(CleanUpState, "CleanUpState")
|
||||
//Made it off map, delete ourselves
|
||||
public:
|
||||
CleanUpState( StateMachine *machine ) :State( machine, "CleanUpState" ) {}
|
||||
virtual StateReturnType update(){return STATE_CONTINUE;}
|
||||
virtual StateReturnType onEnter();
|
||||
protected:
|
||||
// snapshot interface STUBBED - no member vars to save. jba.
|
||||
virtual void crc( Xfer *xfer ){};
|
||||
virtual void xfer( Xfer *xfer ){XferVersion cv = 1; XferVersion v = cv; xfer->xferVersion( &v, cv );}
|
||||
virtual void loadPostProcess(){};
|
||||
};
|
||||
EMPTY_DTOR(CleanUpState)
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
APPROACH, ///< Flying towards target
|
||||
DELIVERING, ///< Delivering the payload to the target
|
||||
CONSIDER_NEW_APPROACH, ///< Deciding if I should reapproach to deliver more payload or go home
|
||||
RECOVER_FROM_OFF_MAP, ///< oops, went off the map, special recovery needed
|
||||
HEAD_OFF_MAP, ///< We're all done here, take off into the sunset
|
||||
CLEAN_UP, ///< Made it to the sunset. Delete peacefully, don't kill
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeliverPayloadAIUpdateModuleData : public AIUpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_doorDelay;
|
||||
Real m_maxDistanceToTarget; ///< How far away from target I can unload, plus how far after target I need to turn around at
|
||||
Int m_maxNumberAttempts; ///< How many times I can re-approach
|
||||
UnsignedInt m_dropDelay; ///< How long to wait after entering Deliver state (to allow for doors opening)
|
||||
Coord3D m_dropOffset; ///< where to disgorge the guys, relative to me
|
||||
Coord3D m_dropVariance; ///< variance in dropping position among guys that I am dropping
|
||||
AsciiString m_putInContainerName;
|
||||
RadiusDecalTemplate m_deliveryDecalTemplate;
|
||||
Real m_deliveryDecalRadius;
|
||||
|
||||
DeliverPayloadAIUpdateModuleData()
|
||||
{
|
||||
m_doorDelay = 0;
|
||||
m_maxDistanceToTarget = 0.0f;
|
||||
m_maxNumberAttempts = 0;
|
||||
m_dropDelay = 0;
|
||||
m_dropOffset.zero();
|
||||
m_dropVariance.zero();
|
||||
m_deliveryDecalRadius = 0;
|
||||
// Added By Sadullah Nader
|
||||
// Initialization missing and needed
|
||||
|
||||
m_putInContainerName.clear();
|
||||
// End Add
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
AIUpdateModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
//These values represent script only reinforcements using deliverPayloadViaModuleData()!
|
||||
//***********************************************************************************
|
||||
//DO NOT ADD DATA HERE UNLESS YOU ARE SUPPORTING SCRIPTED TEAM REINFORCEMENT DELIVERY
|
||||
//THESE DATA VALUES ARE SPECIFIED ONLY BY FACTIONUNIT.INI
|
||||
//***********************************************************************************
|
||||
{ "DoorDelay", INI::parseDurationUnsignedInt, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_doorDelay ) },
|
||||
{ "PutInContainer", INI::parseAsciiString, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_putInContainerName ) },
|
||||
{ "DeliveryDistance", INI::parseReal, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_maxDistanceToTarget ) },
|
||||
{ "MaxAttempts", INI::parseInt, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_maxNumberAttempts ) },
|
||||
{ "DropDelay", INI::parseDurationUnsignedInt, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_dropDelay ) },
|
||||
{ "DropOffset", INI::parseCoord3D, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_dropOffset ) },
|
||||
{ "DropVariance", INI::parseCoord3D, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_dropVariance ) },
|
||||
{ "DeliveryDecal", RadiusDecalTemplate::parseRadiusDecalTemplate, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_deliveryDecalTemplate ) },
|
||||
{ "DeliveryDecalRadius", INI::parseReal, NULL, offsetof( DeliverPayloadAIUpdateModuleData, m_deliveryDecalRadius ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
//This data is set by DeliverPayloadNugget in ObjectCreationList. This struct contains
|
||||
//all the necessary information for DeliverPayloadAIUpdate to perform it's necessary
|
||||
//functions. If you add something here, make sure you add the parsing function inside
|
||||
//DeliverPayloadNugget.
|
||||
//***********************************************************************************
|
||||
//THESE DATA VALUES ARE SPECIFIED ONLY BY OBJECTCREATIONLIST.INI
|
||||
//***********************************************************************************
|
||||
class DeliverPayloadData
|
||||
{
|
||||
public:
|
||||
AsciiString m_visibleDropBoneName; ///< Where the payload is created (offset by current bone number 01-xx)
|
||||
AsciiString m_visibleSubObjectName; ///< Visible subobject to show or hide (offset by current drop number 01-xx)
|
||||
AsciiString m_visiblePayloadTemplateName;
|
||||
Real m_distToTarget;
|
||||
Real m_preOpenDistance;
|
||||
Int m_maxAttempts;
|
||||
Coord3D m_dropOffset;
|
||||
Coord3D m_dropVariance;
|
||||
UnsignedInt m_dropDelay;
|
||||
Bool m_fireWeapon;
|
||||
Bool m_selfDestructObject;
|
||||
Int m_visibleNumBones; ///< The number of visible bones to process.
|
||||
Real m_diveStartDistance;
|
||||
Real m_diveEndDistance;
|
||||
WeaponSlotType m_strafingWeaponSlot;
|
||||
Int m_visibleItemsDroppedPerInterval;
|
||||
Bool m_inheritTransportVelocity;
|
||||
Bool m_isParachuteDirectly; ///< Instead of parachuting to below the point of exit, go ahead and bunch up on the target
|
||||
Real m_exitPitchRate;
|
||||
const FXList *m_strafeFX;
|
||||
Real m_strafeLength;
|
||||
const WeaponTemplate *m_visiblePayloadWeaponTemplate;
|
||||
RadiusDecalTemplate m_deliveryDecalTemplate;
|
||||
Real m_deliveryDecalRadius;
|
||||
|
||||
DeliverPayloadData()
|
||||
{
|
||||
m_distToTarget = 0.0f;
|
||||
m_preOpenDistance = 0.0f;
|
||||
m_maxAttempts = 1;
|
||||
m_dropOffset.zero();
|
||||
m_dropVariance.zero();
|
||||
m_dropDelay = 0;
|
||||
m_fireWeapon = false;
|
||||
m_visibleNumBones = 0;
|
||||
m_diveStartDistance = 0.0f;
|
||||
m_diveEndDistance = 0.0f;
|
||||
m_strafingWeaponSlot = (WeaponSlotType)-1;
|
||||
m_visibleItemsDroppedPerInterval = 0;
|
||||
m_inheritTransportVelocity = false;
|
||||
m_isParachuteDirectly = FALSE;
|
||||
m_exitPitchRate = 0.0f;
|
||||
m_strafeFX = NULL;
|
||||
m_strafeLength = 0.0f;
|
||||
m_visiblePayloadWeaponTemplate = NULL;
|
||||
m_selfDestructObject = FALSE;
|
||||
m_deliveryDecalRadius = 0;
|
||||
// Added By Sadullah Nader
|
||||
// Initialization missing and needed
|
||||
|
||||
m_visibleDropBoneName.clear();
|
||||
m_visiblePayloadTemplateName.clear();
|
||||
m_visibleSubObjectName.clear();
|
||||
|
||||
// End Add
|
||||
}
|
||||
|
||||
static const FieldParse* getFieldParse();
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeliverPayloadAIUpdate : public AIUpdateInterface
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DeliverPayloadAIUpdate, "DeliverPayloadAIUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DeliverPayloadAIUpdate, DeliverPayloadAIUpdateModuleData )
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
DeliverPayloadAIUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual AIFreeToExitType getAiFreeToExit(const Object* exiter) const;
|
||||
|
||||
const Coord3D* getTargetPos() const { return &m_targetPos; }
|
||||
const Coord3D* getMoveToPos() const { return &m_moveToPos; }
|
||||
UnsignedInt getDoorDelay() const { return getDeliverPayloadAIUpdateModuleData()->m_doorDelay; }
|
||||
Bool isDeliveringPayload() const { return m_deliverPayloadStateMachine != NULL; }
|
||||
const ThingTemplate* getPutInContainerTemplateViaModuleData() const;
|
||||
|
||||
Real getAllowedDistanceToTarget() const { return m_data.m_distToTarget; }
|
||||
Real getPreOpenDistance() const { return m_data.m_preOpenDistance; }
|
||||
Int getMaxNumberAttempts() const { return m_data.m_maxAttempts; }
|
||||
UnsignedInt getDropDelay() const { return m_data.m_dropDelay; }
|
||||
const Coord3D& getDropOffset() const { return m_data.m_dropOffset; }
|
||||
const Coord3D& getDropVariance() const { return m_data.m_dropVariance; }
|
||||
Bool isFireWeapon() const { return m_data.m_fireWeapon; }
|
||||
Int getVisibleItemsDelivered() const { return m_visibleItemsDelivered; }
|
||||
void setVisibleItemsDelivered( Int num ) { m_visibleItemsDelivered = num; }
|
||||
|
||||
Bool isCloseEnoughToTarget();
|
||||
Bool isOffMap() const;
|
||||
Real calcMinTurnRadius(Real* timeToTravelThatDist) const;
|
||||
|
||||
void deliverPayload( const Coord3D *moveToPos, const Coord3D *targetPos, const DeliverPayloadData *data );
|
||||
void deliverPayloadViaModuleData( const Coord3D *moveToPos );
|
||||
|
||||
const DeliverPayloadData* getData() { return &m_data; }
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
void killDeliveryDecal();
|
||||
|
||||
void friend_setFreeToExit(Bool f) { m_freeToExit = f; }
|
||||
void friend_setAcceptingCommands(Bool f) { m_acceptingCommands = f; }
|
||||
|
||||
protected:
|
||||
|
||||
virtual AIStateMachine* makeStateMachine();
|
||||
virtual Bool isAllowedToRespondToAiCommands(const AICommandParms* parms) const;
|
||||
|
||||
DeliverPayloadStateMachine* m_deliverPayloadStateMachine; ///< Controls my special logic
|
||||
Coord3D m_targetPos; ///< Where I plan to deliver my little friends, if obj is null
|
||||
Coord3D m_moveToPos; ///< Where I am moving to.
|
||||
DeliverPayloadData m_data;
|
||||
Int m_visibleItemsDelivered;
|
||||
RadiusDecal m_deliveryDecal;
|
||||
Real m_previousDistanceSqr;
|
||||
Bool m_freeToExit;
|
||||
Bool m_acceptingCommands;
|
||||
|
||||
enum DiveState // Stored in save file as int, don't renumber! jba.
|
||||
{
|
||||
DIVESTATE_PREDIVE=0,
|
||||
DIVESTATE_DIVING=1,
|
||||
DIVESTATE_POSTDIVE=2,
|
||||
};
|
||||
DiveState m_diveState;
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DemoTrapUpdate.cpp //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Kris Morness, August 2002
|
||||
// Desc: Update module to handle demo trap proximity triggering.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEMO_TRAP_UPDATE_H_
|
||||
#define __DEMO_TRAP_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/KindOf.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DemoTrapUpdateModuleData : public ModuleData
|
||||
{
|
||||
public:
|
||||
WeaponTemplate *m_detonationWeaponTemplate;
|
||||
KindOfMaskType m_ignoreKindOf;
|
||||
WeaponSlotType m_manualModeWeaponSlot;
|
||||
WeaponSlotType m_detonationWeaponSlot;
|
||||
WeaponSlotType m_proximityModeWeaponSlot;
|
||||
Real m_triggerDetonationRange;
|
||||
UnsignedInt m_scanFrames;
|
||||
Bool m_defaultsToProximityMode;
|
||||
Bool m_friendlyDetonation;
|
||||
Bool m_detonateWhenKilled;
|
||||
|
||||
DemoTrapUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The default update module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DemoTrapUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DemoTrapUpdate, "DemoTrapUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DemoTrapUpdate, DemoTrapUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
DemoTrapUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onObjectCreated();
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
void detonate();
|
||||
|
||||
protected:
|
||||
|
||||
Int m_nextScanFrames;
|
||||
Bool m_detonated;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DemoralizeSpecialPower.h /////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, July 2002
|
||||
// Desc: Demoralize
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEMORALIZE_SPECIAL_POWER_H_
|
||||
#define __DEMORALIZE_SPECIAL_POWER_H_
|
||||
|
||||
#ifdef ALLOW_DEMORALIZE
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/SpecialPowerModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class FXList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DemoralizeSpecialPowerModuleData : public SpecialPowerModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DemoralizeSpecialPowerModuleData( void );
|
||||
|
||||
static void buildFieldParse( MultiIniFieldParse& p );
|
||||
|
||||
Real m_baseRange; ///< base range for this special power
|
||||
Real m_bonusRangePerCaptured; ///< additional range we get for each prisoner
|
||||
Real m_maxRange; ///< no matter how many prisoners we have, this is max
|
||||
UnsignedInt m_baseDurationInFrames; ///< duration of the demoralization (in frames)
|
||||
UnsignedInt m_bonusDurationPerCapturedInFrames; ///< additional duration added for each prisoner we have
|
||||
UnsignedInt m_maxDurationInFrames; ///< no matter how many prisoners we have, this is max
|
||||
const FXList *m_fxList; ///< fx list to play
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DemoralizeSpecialPower : public SpecialPowerModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DemoralizeSpecialPower, "DemoralizeSpecialPower" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DemoralizeSpecialPower, DemoralizeSpecialPowerModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DemoralizeSpecialPower( Thing *thing, const ModuleData *moduleData );
|
||||
// virtual destructor prototype provided by memory pool object
|
||||
|
||||
virtual void doSpecialPowerAtObject( const Object *obj, UnsignedInt commandOptions );
|
||||
virtual void doSpecialPowerAtLocation( const Coord3D *loc, UnsignedInt commandOptions );
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif // ALLOW_DEMORALIZE
|
||||
|
||||
|
||||
#endif // end __DEMORALIZE_SPECIAL_POWER_H_
|
||||
@@ -0,0 +1,130 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// DeployStyleAIUpdate.h ////////////
|
||||
// Author: Kris Morness, August 2002
|
||||
// Desc: State machine that allows deploying/undeploying to control the AI.
|
||||
// When deployed, you can't move, when undeployed, you can't attack.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DEPLOY_STYLE_AI_UPDATE_H
|
||||
#define __DEPLOY_STYLE_AI_UPDATE_H
|
||||
|
||||
#include "Common/StateMachine.h"
|
||||
#include "GameLogic/Module/AIUpdate.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum DeployStateTypes
|
||||
{
|
||||
READY_TO_MOVE, ///< Mobile, can't attack.
|
||||
DEPLOY, ///< Not mobile, can't attack, currently unpacking to attack
|
||||
READY_TO_ATTACK, ///< Not mobile, can attack
|
||||
UNDEPLOY, ///< Not mobile, can't attack, currently packing to move
|
||||
ALIGNING_TURRETS, ///< While deployed, we must wait for the turret to go back to natural position prior to undeploying.
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeployStyleAIUpdateModuleData : public AIUpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_unpackTime;
|
||||
UnsignedInt m_packTime;
|
||||
Bool m_resetTurretBeforePacking;
|
||||
Bool m_turretsFunctionOnlyWhenDeployed;
|
||||
Bool m_turretsMustCenterBeforePacking;
|
||||
|
||||
DeployStyleAIUpdateModuleData()
|
||||
{
|
||||
m_unpackTime = 0;
|
||||
m_packTime = 0;
|
||||
m_resetTurretBeforePacking = false;
|
||||
m_turretsFunctionOnlyWhenDeployed = false;
|
||||
// Added By Sadullah Nader
|
||||
// Initialization necessary
|
||||
m_turretsMustCenterBeforePacking = FALSE;
|
||||
// End Add
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
AIUpdateModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "UnpackTime", INI::parseDurationUnsignedInt, NULL, offsetof( DeployStyleAIUpdateModuleData, m_unpackTime ) },
|
||||
{ "PackTime", INI::parseDurationUnsignedInt, NULL, offsetof( DeployStyleAIUpdateModuleData, m_packTime ) },
|
||||
{ "ResetTurretBeforePacking", INI::parseBool, NULL, offsetof( DeployStyleAIUpdateModuleData, m_resetTurretBeforePacking ) },
|
||||
{ "TurretsFunctionOnlyWhenDeployed", INI::parseBool, NULL, offsetof( DeployStyleAIUpdateModuleData, m_turretsFunctionOnlyWhenDeployed ) },
|
||||
{ "TurretsMustCenterBeforePacking", INI::parseBool, NULL, offsetof( DeployStyleAIUpdateModuleData, m_turretsMustCenterBeforePacking ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DeployStyleAIUpdate : public AIUpdateInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DeployStyleAIUpdate, "DeployStyleAIUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DeployStyleAIUpdate, DeployStyleAIUpdateModuleData )
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
|
||||
DeployStyleAIUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void aiDoCommand(const AICommandParms* parms);
|
||||
virtual Bool isIdle() const;
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
UnsignedInt getUnpackTime() const { return getDeployStyleAIUpdateModuleData()->m_unpackTime; }
|
||||
UnsignedInt getPackTime() const { return getDeployStyleAIUpdateModuleData()->m_packTime; }
|
||||
Bool doTurretsFunctionOnlyWhenDeployed() const { return getDeployStyleAIUpdateModuleData()->m_turretsFunctionOnlyWhenDeployed; }
|
||||
Bool doTurretsHaveToCenterBeforePacking() const { return getDeployStyleAIUpdateModuleData()->m_turretsMustCenterBeforePacking; }
|
||||
void setMyState( DeployStateTypes StateID );
|
||||
void reset();
|
||||
|
||||
protected:
|
||||
|
||||
AICommandParmsStorage m_lastOutsideCommand;
|
||||
Bool m_hasOutsideCommand;
|
||||
DeployStateTypes m_state;
|
||||
UnsignedInt m_frameToWakeForDeploy;
|
||||
|
||||
ObjectID m_designatedTargetID;
|
||||
ObjectID m_attackObjectID;
|
||||
Coord3D m_position; //Used for attack position and guard position.
|
||||
Bool m_isAttackMultiple;
|
||||
Bool m_isAttackObject;
|
||||
Bool m_isAttackPosition;
|
||||
Bool m_isGuardingPosition;
|
||||
Bool m_overriddenAttack;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DestroyDie.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, November 2001
|
||||
// Desc: Default die module
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DestroyDie_H_
|
||||
#define __DestroyDie_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
#include "Common/INI.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
class DestroyDie : public DieModule
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO( DestroyDie );
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DestroyDie, "DestroyDie" )
|
||||
|
||||
public:
|
||||
|
||||
DestroyDie( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
};
|
||||
|
||||
#endif // __DestroyDie_H_
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DestroyModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2001
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DestroyModule_H_
|
||||
#define __DestroyModule_H_
|
||||
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** OBJECT DESTROY MODULE base class */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DestroyModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void onDestroy() = 0;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DestroyModule : public BehaviorModule, public DestroyModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( DestroyModule )
|
||||
MAKE_STANDARD_MODULE_MACRO_ABC( DestroyModule )
|
||||
|
||||
public:
|
||||
|
||||
DestroyModule( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
static Int getInterfaceMask() { return MODULEINTERFACE_DESTROY; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual DestroyModuleInterface* getDestroy() { return this; }
|
||||
|
||||
virtual void onDestroy() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
111
Generals/Code/GameEngine/Include/GameLogic/Module/DieModule.h
Normal file
111
Generals/Code/GameEngine/Include/GameLogic/Module/DieModule.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DieModule.h /////////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, September 2001
|
||||
// Desc:
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DieModule_H_
|
||||
#define __DieModule_H_
|
||||
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** OBJECT DIE MODULE base class */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DieModuleInterface
|
||||
{
|
||||
public:
|
||||
virtual void onDie( const DamageInfo *damageInfo ) = 0;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DieMuxData // does NOT inherit from ModuleData.
|
||||
{
|
||||
public:
|
||||
DeathTypeFlags m_deathTypes;
|
||||
VeterancyLevelFlags m_veterancyLevels;
|
||||
UnsignedInt m_exemptStatus; ///< die module is ignored if any of these status bits are set
|
||||
UnsignedInt m_requiredStatus; ///< die module is ignored if any of these status bits are clear
|
||||
|
||||
DieMuxData();
|
||||
static const FieldParse* getFieldParse();
|
||||
|
||||
Bool isDieApplicable(const Object* obj, const DamageInfo *damageInfo) const;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DieModuleData : public BehaviorModuleData
|
||||
{
|
||||
public:
|
||||
DieMuxData m_dieMuxData;
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
BehaviorModuleData::buildFieldParse(p);
|
||||
p.add(DieMuxData::getFieldParse(), offsetof( DieModuleData, m_dieMuxData ));
|
||||
}
|
||||
|
||||
inline Bool isDieApplicable(const Object* obj, const DamageInfo *damageInfo) const { return m_dieMuxData.isDieApplicable(obj, damageInfo); }
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DieModule : public BehaviorModule, public DieModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( DieModule )
|
||||
MAKE_STANDARD_MODULE_MACRO_ABC( DieModule )
|
||||
MAKE_STANDARD_MODULE_DATA_MACRO_ABC(DieModule, DieModuleData)
|
||||
|
||||
public:
|
||||
|
||||
DieModule( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
static Int getInterfaceMask() { return MODULEINTERFACE_DIE; }
|
||||
|
||||
// BehaviorModule
|
||||
virtual DieModuleInterface* getDie() { return this; }
|
||||
|
||||
void onDie( const DamageInfo *damageInfo ) = 0;
|
||||
|
||||
protected:
|
||||
Bool isDieApplicable(const DamageInfo *damageInfo) const { return getDieModuleData()->isDieApplicable(getObject(), damageInfo); }
|
||||
|
||||
};
|
||||
inline DieModule::DieModule( Thing *thing, const ModuleData* moduleData ) : BehaviorModule( thing, moduleData ) { }
|
||||
inline DieModule::~DieModule() { }
|
||||
|
||||
#endif
|
||||
160
Generals/Code/GameEngine/Include/GameLogic/Module/DockUpdate.h
Normal file
160
Generals/Code/GameEngine/Include/GameLogic/Module/DockUpdate.h
Normal file
@@ -0,0 +1,160 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DockUpdate.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood Feb 2002
|
||||
// Desc: Behavior common to all DockUpdates is here. Everything but action()
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _DOCK_UPDATE_H_
|
||||
#define _DOCK_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/INI.h"
|
||||
#include "Common/GameMemory.h"
|
||||
#include "Common/STLTypedefs.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
enum
|
||||
{
|
||||
DEFAULT_APPROACH_VECTOR_SIZE = 10
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DYNAMIC_APPROACH_VECTOR_FLAG = -1
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DockUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
Int m_numberApproachPositionsData; // A positive number is an absolute, DYNAMIC_APPROACH_VECTOR_FLAG means dynamic vector
|
||||
Bool m_isAllowPassthrough;
|
||||
|
||||
DockUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DockUpdate : public UpdateModule , public DockUpdateInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_ABC( DockUpdate )
|
||||
MAKE_STANDARD_MODULE_MACRO_ABC( DockUpdate )
|
||||
MAKE_STANDARD_MODULE_DATA_MACRO_ABC( DockUpdate, DockUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DockUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor provided by memory pool object
|
||||
|
||||
/** Returns true if it is okay for the docker to approach and prepare to dock.
|
||||
False could mean the queue is full, for example.
|
||||
*/
|
||||
virtual Bool isClearToApproach( Object const* docker ) const;
|
||||
|
||||
/** Give me a Queue point to drive to, and record that that point is taken.
|
||||
Returning NULL means there are none free
|
||||
*/
|
||||
virtual Bool reserveApproachPosition( Object* docker, Coord3D *position, Int *index );
|
||||
|
||||
/** Give me the next Queue point to drive to, and record that that point is taken.
|
||||
*/
|
||||
virtual Bool advanceApproachPosition( Object* docker, Coord3D *position, Int *index );
|
||||
|
||||
/** Return true when it is OK for docker to begin entering the dock
|
||||
The Dock will lift the restriction on one particular docker on its own,
|
||||
so you must continually ask.
|
||||
*/
|
||||
virtual Bool isClearToEnter( Object const* docker ) const;
|
||||
|
||||
/** Return true when it is OK for docker to request a new Approach position. The dock is in
|
||||
charge of keeping track of holes in the line, but the docker will remind us of their spot.
|
||||
*/
|
||||
virtual Bool isClearToAdvance( Object const* docker, Int dockerIndex ) const;
|
||||
|
||||
/** Give me the point that is the start of your docking path
|
||||
Returning NULL means there is none free
|
||||
All functions take docker as arg so we could have multiple docks on a building.
|
||||
Docker is not assumed, it is recorded and checked.
|
||||
*/
|
||||
virtual void getEnterPosition( Object* docker, Coord3D *position );
|
||||
|
||||
/** Give me the middle point of the dock process where the action() happens */
|
||||
virtual void getDockPosition( Object* docker, Coord3D *position );
|
||||
|
||||
/** Give me the point to drive to when I am done */
|
||||
virtual void getExitPosition( Object* docker, Coord3D *position );
|
||||
|
||||
virtual void onApproachReached( Object* docker ); ///< I have reached the Approach Point.
|
||||
virtual void onEnterReached( Object* docker ); ///< I have reached the Enter Point.
|
||||
virtual void onDockReached( Object* docker ); ///< I have reached the Dock point
|
||||
virtual void onExitReached( Object* docker ); ///< I have reached the exit. You are no longer busy
|
||||
|
||||
//The fact that action() is not here is intentional. This object cannot exist. You must
|
||||
//derive off it and implement action().
|
||||
|
||||
virtual void cancelDock( Object* docker ); ///< Clear me from any reserved points, and if I was the reason you were Busy, you aren't anymore.
|
||||
|
||||
virtual Bool isDockOpen( void ) { return m_dockOpen; } ///< Is the dock open to accepting dockers
|
||||
virtual void setDockOpen( Bool open ) { m_dockOpen = open; } ///< Open/Close the dock
|
||||
|
||||
virtual Bool isAllowPassthroughType(); ///< Not all docks allow you to path through them in your AIDock machine
|
||||
|
||||
virtual Bool isRallyPointAfterDockType(){return FALSE;} ///< A minority of docks want to give you a final command to their rally point
|
||||
|
||||
virtual void setDockCrippled( Bool setting ); ///< Game Logic can set me as inoperative. I get to decide what that means.
|
||||
|
||||
virtual UpdateSleepTime update(); ///< In charge of lifting dock restriction for one registered as Approached if all is ready
|
||||
|
||||
protected:
|
||||
|
||||
// These are const data read from the drawable when first asked for them
|
||||
Coord3D m_enterPosition;
|
||||
Coord3D m_dockPosition;
|
||||
Coord3D m_exitPosition;
|
||||
Int m_numberApproachPositions;
|
||||
Int m_numberApproachPositionBones;
|
||||
|
||||
// These are real variables local to my specific needs here in DockUpdate
|
||||
Bool m_positionsLoaded; ///< FALSE until we have loaded all the docking positions
|
||||
|
||||
VecCoord3D m_approachPositions;
|
||||
ObjectIDVector m_approachPositionOwners; ///< Who is in or at least reserved each spot
|
||||
BoolVector m_approachPositionReached; ///< Which positions have actually been reached
|
||||
|
||||
ObjectID m_activeDocker; ///< we could expand this to multiple dock paths since we always get docker in our methods
|
||||
Bool m_dockerInside; ///< This is true while our active docker is between Enter and Exit. This is shorter than activeDocker's lifetime as it doesn't include approach to enter
|
||||
Bool m_dockCrippled; ///< Has game logic set me as crippled?
|
||||
|
||||
Bool m_dockOpen; ///< Is the dock open for dockers
|
||||
|
||||
void loadDockPositions(); ///< load all the dock positions
|
||||
Coord3D computeApproachPosition( Int positionIndex, Object *forWhom ); ///< Do a smart lookup of this bone position
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,309 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DozerAIUpdate.h //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, February 2002
|
||||
// Desc: Dozer AI behavior
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DOZERAIUPDATE_H_
|
||||
#define __DOZERAIUPDATE_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/AIUpdate.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class AudioEventRTS;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The Dozer primary state machine */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DozerPrimaryStateMachine : public StateMachine
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DozerPrimaryStateMachine, "DozerPrimaryStateMachine" );
|
||||
|
||||
public:
|
||||
|
||||
DozerPrimaryStateMachine( Object *owner );
|
||||
// virtual destructor prototypes provided by memory pool object
|
||||
|
||||
//-----------------------------------------------------------------------------------------------
|
||||
// state transition conditions
|
||||
static Bool isBuildMostImportant( State *thisState, void* userData );
|
||||
static Bool isRepairMostImportant( State *thisState, void* userData );
|
||||
static Bool isFortifyMostImportant( State *thisState, void* userData );
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
};
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** Dozer behaviors that use action sub state machines */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum DozerTask // These enums are saved in the game save file, so DO NOT renumber them. jba.
|
||||
{
|
||||
DOZER_TASK_INVALID = -1,
|
||||
DOZER_TASK_FIRST = 0,
|
||||
DOZER_TASK_BUILD = DOZER_TASK_FIRST, ///< go build something
|
||||
DOZER_TASK_REPAIR = 1, ///< go repair something
|
||||
DOZER_TASK_FORTIFY = 2, ///< go fortify something
|
||||
|
||||
DOZER_NUM_TASKS // keep this last
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
enum DozerDockPoint // These enums are saved in the game save file, so DO NOT renumber them. jba.
|
||||
{
|
||||
DOZER_DOCK_POINT_START = 0,
|
||||
DOZER_DOCK_POINT_ACTION = 1,
|
||||
DOZER_DOCK_POINT_END = 2,
|
||||
DOZER_NUM_DOCK_POINTS // keep this one last
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
enum DozerBuildSubTask // These enums are saved in the game save file, so DO NOT renumber them. jba.
|
||||
{
|
||||
DOZER_SELECT_BUILD_DOCK_LOCATION = 0,
|
||||
DOZER_MOVING_TO_BUILD_DOCK_LOCATION = 1,
|
||||
DOZER_DO_BUILD_AT_DOCK = 2
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** This is no longer a leaf behavior. Someone else needs to combine this
|
||||
* with another major AIUpdate. So provide an interface to satisfy the people
|
||||
* who look this up by name. */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class DozerAIInterface
|
||||
{
|
||||
|
||||
// This is no longer a leaf behavior. Someone else needs to combine this
|
||||
// with another major AIUpdate. So provide an interface to satisfy the people
|
||||
// who look this up by name.
|
||||
|
||||
public:
|
||||
|
||||
virtual void onDelete( void ) = 0;
|
||||
|
||||
virtual Real getRepairHealthPerSecond( void ) const = 0; ///< get health to repair per second
|
||||
virtual Real getBoredTime( void ) const = 0; ///< how long till we're bored
|
||||
virtual Real getBoredRange( void ) const = 0; ///< when we're bored, we look this far away to do things
|
||||
|
||||
// methods to override for the dozer behaviors
|
||||
virtual Object *construct( const ThingTemplate *what,
|
||||
const Coord3D *pos, Real angle,
|
||||
Player *owningPlayer,
|
||||
Bool isRebuild ) = 0;
|
||||
|
||||
|
||||
// get task information
|
||||
virtual DozerTask getMostRecentCommand( void ) = 0; ///< return task that was most recently issued
|
||||
virtual Bool isTaskPending( DozerTask task ) = 0; ///< is there a desire to do the requested task
|
||||
virtual ObjectID getTaskTarget( DozerTask task ) = 0; ///< get target of task
|
||||
virtual Bool isAnyTaskPending( void ) = 0; ///< is there any dozer task pending
|
||||
|
||||
virtual DozerTask getCurrentTask( void ) const = 0; ///< return the current task we're doing
|
||||
// the following should only be used from inside the Dozer state machine!
|
||||
// !!! *DO NOT CALL THIS AND SET THE TASK DIRECTLY TO AFFECT BEHAVIOR* !!! ///
|
||||
virtual void setCurrentTask( DozerTask task ) = 0; ///< set the current task of the dozer
|
||||
|
||||
virtual Bool getIsRebuild( void ) = 0; ///< get whether or not this is a rebuild.
|
||||
|
||||
// task actions
|
||||
virtual void newTask( DozerTask task, Object *target ) = 0; ///< set a desire to do the requrested task
|
||||
virtual void cancelTask( DozerTask task ) = 0; ///< cancel this task from the queue, if it's the current task the dozer will stop working on it
|
||||
|
||||
// internal methods to manage behavior from within the dozer state machine
|
||||
virtual void internalTaskComplete( DozerTask task ) = 0; ///< set a dozer task as successfully completed
|
||||
virtual void internalCancelTask( DozerTask task ) = 0; ///< cancel this task from the dozer
|
||||
virtual void internalTaskCompleteOrCancelled( DozerTask task ) = 0; ///< this is called when tasks are cancelled or completed
|
||||
|
||||
/** return a dock point for the action and task (if valid) ... note it can return NULL
|
||||
if no point has been set for the combination of task and point */
|
||||
virtual const Coord3D* getDockPoint( DozerTask task, DozerDockPoint point ) = 0;
|
||||
|
||||
virtual void setBuildSubTask( DozerBuildSubTask subTask ) = 0;
|
||||
virtual DozerBuildSubTask getBuildSubTask( void ) = 0;
|
||||
|
||||
// repairing
|
||||
virtual Bool canAcceptNewRepair( Object *obj ) = 0;
|
||||
virtual void createBridgeScaffolding( Object *bridgeTower ) = 0;
|
||||
virtual void removeBridgeScaffolding( Object *bridgeTower ) = 0;
|
||||
|
||||
virtual void startBuildingSound( const AudioEventRTS *sound, ObjectID constructionSiteID ) = 0;
|
||||
virtual void finishBuildingSound() = 0;
|
||||
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker */
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class DozerAIUpdateModuleData : public AIUpdateModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
DozerAIUpdateModuleData( void );
|
||||
|
||||
// !!!
|
||||
// !!! NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker !!!
|
||||
// !!!
|
||||
|
||||
Real m_repairHealthPercentPerSecond; ///< how many health points per second the dozer repairs at
|
||||
Real m_boredTime; ///< after this many frames, a dozer will try to find something to do on its own
|
||||
Real m_boredRange; ///< range the dozers try to auto repair when they're bored
|
||||
|
||||
static void buildFieldParse( MultiIniFieldParse &p );
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The Dozer AI Update interface. Dozers are workers that are capable of building all the
|
||||
* structures available to a player, as well as repairing building, and fortifying
|
||||
* civilian structures */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DozerAIUpdate : public AIUpdateInterface, public DozerAIInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DozerAIUpdate, "DozerAIUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DozerAIUpdate, DozerAIUpdateModuleData )
|
||||
|
||||
public:
|
||||
static Bool findGoodBuildOrRepairPosition(const Object* me, const Object* target, Coord3D& positionOut);
|
||||
static Object* findGoodBuildOrRepairPositionAndTarget(Object* me, Object* target, Coord3D& positionOut);
|
||||
|
||||
public:
|
||||
|
||||
DozerAIUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual DozerAIInterface* getDozerAIInterface() {return this;}
|
||||
virtual const DozerAIInterface* getDozerAIInterface() const {return this;}
|
||||
|
||||
virtual void onDelete( void );
|
||||
|
||||
//
|
||||
// module data methods ... this is LAME, multiple inheritance off an interface with replicated
|
||||
// data and code, ick!
|
||||
// NOTE: If you edit module data you must do it in both the Dozer *AND* the Worker
|
||||
//
|
||||
virtual Real getRepairHealthPerSecond( void ) const; ///< get health to repair per second
|
||||
virtual Real getBoredTime( void ) const; ///< how long till we're bored
|
||||
virtual Real getBoredRange( void ) const; ///< when we're bored, we look this far away to do things
|
||||
|
||||
// methods to override for the dozer behaviors
|
||||
virtual Object* construct( const ThingTemplate *what,
|
||||
const Coord3D *pos, Real angle,
|
||||
Player *owningPlayer,
|
||||
Bool isRebuild ); ///< construct an object
|
||||
|
||||
|
||||
// get task information
|
||||
virtual DozerTask getMostRecentCommand( void ); ///< return task that was most recently issued
|
||||
virtual Bool isTaskPending( DozerTask task ); ///< is there a desire to do the requested task
|
||||
virtual ObjectID getTaskTarget( DozerTask task ); ///< get target of task
|
||||
virtual Bool isAnyTaskPending( void ); ///< is there any dozer task pending
|
||||
virtual DozerTask getCurrentTask( void ) const { return m_currentTask; } ///< return the current task we're doing
|
||||
virtual void setCurrentTask( DozerTask task ) { m_currentTask = task; } ///< set the current task of the dozer
|
||||
|
||||
virtual Bool getIsRebuild( void ) { return m_isRebuild; } ///< get whether or not this building is a rebuild.
|
||||
|
||||
// task actions
|
||||
virtual void newTask( DozerTask task, Object *target ); ///< set a desire to do the requrested task
|
||||
virtual void cancelTask( DozerTask task ); ///< cancel this task from the queue, if it's the current task the dozer will stop working on it
|
||||
|
||||
// internal methods to manage behavior from within the dozer state machine
|
||||
virtual void internalTaskComplete( DozerTask task ); ///< set a dozer task as successfully completed
|
||||
virtual void internalCancelTask( DozerTask task ); ///< cancel this task from the dozer
|
||||
virtual void internalTaskCompleteOrCancelled( DozerTask task ); ///< this is called when tasks are cancelled or completed
|
||||
|
||||
/** return a dock point for the action and task (if valid) ... note it can return NULL
|
||||
if no point has been set for the combination of task and point */
|
||||
virtual const Coord3D* getDockPoint( DozerTask task, DozerDockPoint point );
|
||||
|
||||
virtual void setBuildSubTask( DozerBuildSubTask subTask ) { m_buildSubTask = subTask; };
|
||||
virtual DozerBuildSubTask getBuildSubTask( void ) { return m_buildSubTask; }
|
||||
|
||||
virtual UpdateSleepTime update( void ); ///< the update entry point
|
||||
|
||||
// repairing
|
||||
virtual Bool canAcceptNewRepair( Object *obj );
|
||||
virtual void createBridgeScaffolding( Object *bridgeTower );
|
||||
virtual void removeBridgeScaffolding( Object *bridgeTower );
|
||||
|
||||
virtual void startBuildingSound( const AudioEventRTS *sound, ObjectID constructionSiteID );
|
||||
virtual void finishBuildingSound();
|
||||
|
||||
//
|
||||
// the following methods must be overridden so that if a player issues a command the dozer
|
||||
// can exit the internal state machine and do whatever the player says
|
||||
//
|
||||
virtual void aiDoCommand(const AICommandParms* parms);
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
virtual void privateRepair( Object *obj, CommandSourceType cmdSource ); ///< repair the target
|
||||
virtual void privateResumeConstruction( Object *obj, CommandSourceType cmdSource ); ///< resume construction on obj
|
||||
|
||||
struct DozerTaskInfo
|
||||
{
|
||||
ObjectID m_targetObjectID; ///< target object ID of task
|
||||
UnsignedInt m_taskOrderFrame; ///< logic frame we decided we wanted to do this task
|
||||
} m_task[ DOZER_NUM_TASKS ]; ///< tasks we want to do indexed by DozerTask
|
||||
|
||||
DozerPrimaryStateMachine *m_dozerMachine; ///< the custom state machine for Dozer behavior
|
||||
DozerTask m_currentTask; ///< current task the dozer is attending to (if any)
|
||||
AudioEventRTS m_buildingSound; ///< sound is pulled from the object we are building!
|
||||
Bool m_isRebuild; ///< is this a rebuild of a previous building?
|
||||
|
||||
//
|
||||
// the following info array can be used if we want to have more complicated approaches
|
||||
// to our target depending on our task
|
||||
//
|
||||
struct DozerDockPointInfo
|
||||
{
|
||||
Bool valid; ///< this point has been set and is valid
|
||||
Coord3D location; ///< WORLD location
|
||||
} m_dockPoint[ DOZER_NUM_TASKS ][ DOZER_NUM_DOCK_POINTS ];
|
||||
|
||||
DozerBuildSubTask m_buildSubTask; ///< for building and actually docking for the build
|
||||
|
||||
private:
|
||||
|
||||
void createMachines( void ); ///< create our behavior machines we need
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __DOZERAIUPDATE_H_
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DumbProjectileBehavior.h
|
||||
// Author: Steven Johnson, July 2002
|
||||
// Desc:
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _DumbProjectileBehavior_H_
|
||||
#define _DumbProjectileBehavior_H_
|
||||
|
||||
#include "Common/GameType.h"
|
||||
#include "Common/GlobalData.h"
|
||||
#include "Common/STLTypeDefs.h"
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/CollideModule.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameLogic/WeaponBonusConditionFlags.h"
|
||||
#include "Common/INI.h"
|
||||
#include "WWMath/Matrix3D.h"
|
||||
|
||||
class ParticleSystem;
|
||||
class FXList;
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DumbProjectileBehaviorModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
These four data define a Bezier curve. The first and last control points are the firer and victim.
|
||||
*/
|
||||
Real m_firstHeight; ///< The first airborne control point will be this high above the highest intervening terrain
|
||||
Real m_secondHeight; ///< And the second, this.
|
||||
Real m_firstPercentIndent; ///< The first point will be this percent along the target line
|
||||
Real m_secondPercentIndent; ///< And the second, this.
|
||||
UnsignedInt m_maxLifespan;
|
||||
Bool m_tumbleRandomly;
|
||||
Bool m_orientToFlightPath;
|
||||
Bool m_detonateCallsKill;
|
||||
Int m_garrisonHitKillCount;
|
||||
KindOfMaskType m_garrisonHitKillKindof; ///< the kind(s) of units that can be collided with
|
||||
KindOfMaskType m_garrisonHitKillKindofNot; ///< the kind(s) of units that CANNOT be collided with
|
||||
const FXList* m_garrisonHitKillFX;
|
||||
Real m_flightPathAdjustDistPerFrame;
|
||||
|
||||
|
||||
DumbProjectileBehaviorModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DumbProjectileBehavior : public UpdateModule, public ProjectileUpdateInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DumbProjectileBehavior, "DumbProjectileBehavior" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DumbProjectileBehavior, DumbProjectileBehaviorModuleData );
|
||||
|
||||
public:
|
||||
|
||||
DumbProjectileBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor provided by memory pool object
|
||||
|
||||
// UpdateModuleInterface
|
||||
virtual UpdateSleepTime update();
|
||||
virtual ProjectileUpdateInterface* getProjectileUpdateInterface() { return this; }
|
||||
|
||||
// ProjectileUpdateInterface
|
||||
virtual void projectileLaunchAtObjectOrPosition(const Object *victim, const Coord3D* victimPos, const Object *launcher, WeaponSlotType wslot, Int specificBarrelToUse, const WeaponTemplate* detWeap, const ParticleSystemTemplate* exhaustSysOverride);
|
||||
virtual void projectileFireAtObjectOrPosition( const Object *victim, const Coord3D *victimPos, const WeaponTemplate *detWeap, const ParticleSystemTemplate* exhaustSysOverride );
|
||||
virtual Bool projectileHandleCollision( Object *other );
|
||||
virtual Bool projectileIsArmed() const { return true; }
|
||||
virtual ObjectID projectileGetLauncherID() const { return m_launcherID; }
|
||||
|
||||
protected:
|
||||
|
||||
void positionForLaunch(const Object *launcher, WeaponSlotType wslot, Int specificBarrelToUse);
|
||||
void detonate();
|
||||
|
||||
private:
|
||||
|
||||
ObjectID m_launcherID; ///< ID of object that launched us (zero if not yet launched)
|
||||
ObjectID m_victimID; ///< ID of object we are targeting (zero if not yet launched)
|
||||
const WeaponTemplate* m_detonationWeaponTmpl; ///< weapon to fire at end (or null)
|
||||
UnsignedInt m_lifespanFrame; ///< if we haven't collided by this frame, blow up anyway
|
||||
VecCoord3D m_flightPath; ///< The frame by frame flight path in a Bezier curve
|
||||
Coord3D m_flightPathStart; ///< where flight path started (in case we must regen it)
|
||||
Coord3D m_flightPathEnd; ///< where flight path ends (in case we must regen it)
|
||||
Real m_flightPathSpeed; ///< flight path speed (in case we must regen it)
|
||||
Int m_flightPathSegments; ///< number of segments in the flightpath (in case we must regen it)
|
||||
Int m_currentFlightPathStep; ///< Our current index in the flight path vector. Quicker than popping off.
|
||||
WeaponBonusConditionFlags m_extraBonusFlags;
|
||||
|
||||
Bool calcFlightPath(Bool recalcNumSegments);
|
||||
#if defined(_DEBUG) || defined(_INTERNAL)
|
||||
void displayFlightPath(); ///< Uses little debug icons in worldspace to show the path chosen when it is decided upon
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#endif // _DumbProjectileBehavior_H_
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DynamicGeometryInfoUpdate.h //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, April 2002
|
||||
// Desc: Update module that changes the object's GeometryInfo
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DYNAMIC_GEOMETRY_INFO_UPDATE_H_
|
||||
#define __DYNAMIC_GEOMETRY_INFO_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/Geometry.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class DynamicGeometryInfoUpdateModuleData : public ModuleData
|
||||
{
|
||||
public:
|
||||
|
||||
UnsignedInt m_initialDelay;
|
||||
|
||||
Real m_initialHeight;
|
||||
Real m_initialMajorRadius;
|
||||
Real m_initialMinorRadius;
|
||||
|
||||
Real m_finalHeight;
|
||||
Real m_finalMajorRadius;
|
||||
Real m_finalMinorRadius;
|
||||
|
||||
UnsignedInt m_transitionTime;
|
||||
|
||||
Bool m_reverseAtTransitionTime; ///< reverse directions once transition time is reached
|
||||
|
||||
// I will go from initial to final in transitionTime frames, smoothly.
|
||||
// I won't change type until that is actually needed as a task.
|
||||
|
||||
DynamicGeometryInfoUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The default update module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DynamicGeometryInfoUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DynamicGeometryInfoUpdate, "DynamicGeometryInfoUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DynamicGeometryInfoUpdate, DynamicGeometryInfoUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
DynamicGeometryInfoUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
UnsignedInt m_startingDelayCountdown;
|
||||
UnsignedInt m_timeActive;
|
||||
|
||||
Bool m_started;
|
||||
Bool m_finished;
|
||||
|
||||
Bool m_reverseAtTransitionTime; ///< do a reverse at transition time
|
||||
enum DynamicGeometryDirection { FORWARD = 1, BACKWARD = -1 };
|
||||
DynamicGeometryDirection m_direction; ///< direction we're growing/shrinking
|
||||
Bool m_switchedDirections; ///< TRUE once we've switched directions
|
||||
|
||||
Real m_initialHeight;
|
||||
Real m_initialMajorRadius;
|
||||
Real m_initialMinorRadius;
|
||||
Real m_finalHeight;
|
||||
Real m_finalMajorRadius;
|
||||
Real m_finalMinorRadius;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: DynamicShroudClearingRangeUpdate.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, August 2002
|
||||
// Desc: Changes the Objects shroud clearing range
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __DYNAMIC_SHROUD_RANGE_UPDATE_H_
|
||||
#define __DYNAMIC_SHROUD_RANGE_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameClient/RadiusDecal.h"///< For the pseudo-wireframe decal effect
|
||||
|
||||
|
||||
#define GRID_FX_DECAL_COUNT (30)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DynamicShroudClearingRangeUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_shrinkDelay; ///< wait until
|
||||
UnsignedInt m_shrinkTime; ///< then shrink this fast
|
||||
UnsignedInt m_growDelay; ///< wait until
|
||||
UnsignedInt m_growTime; ///< then grow this fast
|
||||
|
||||
Real m_finalVision; ///< Then change to this
|
||||
UnsignedInt m_changeInterval; ///< And update my Object every this long
|
||||
UnsignedInt m_growInterval; ///< Update evey this long while growing
|
||||
Bool m_doSpySatFX; ///< Do I do the pseudo-wireframe decal and blip effects?
|
||||
RadiusDecalTemplate m_gridDecalTemplate;///< For the pseudo-wireframe decal effect
|
||||
|
||||
|
||||
DynamicShroudClearingRangeUpdateModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class DynamicShroudClearingRangeUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( DynamicShroudClearingRangeUpdate, "DynamicShroudClearingRangeUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( DynamicShroudClearingRangeUpdate, DynamicShroudClearingRangeUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
DynamicShroudClearingRangeUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
void createGridDecals( const RadiusDecalTemplate& tmpl, Real radius, const Coord3D& pos );
|
||||
void killGridDecals( void );
|
||||
void animateGridDecals( void );
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
|
||||
enum DSCRU_STATE
|
||||
{
|
||||
DSCRU_NOT_STARTED_YET,
|
||||
DSCRU_GROWING,
|
||||
DSCRU_SUSTAINING,
|
||||
DSCRU_SHRINKING,
|
||||
DSCRU_DONE_FOREVER,
|
||||
DSCRU_SLEEPING
|
||||
};
|
||||
|
||||
DSCRU_STATE m_state;
|
||||
|
||||
// Bool m_shrinkFinished; ///< Nothing left to do
|
||||
// Bool m_shrinkStarted; ///< Working it
|
||||
|
||||
|
||||
// UnsignedInt m_shrinkStartCountdown; ///< When I start to shrink
|
||||
// UnsignedInt m_shrinkDeadline; ///< When I am done
|
||||
|
||||
//New Timer Parameters
|
||||
|
||||
Int m_stateCountDown;
|
||||
Int m_totalFrames;
|
||||
UnsignedInt m_growStartDeadline;
|
||||
UnsignedInt m_sustainDeadline;
|
||||
UnsignedInt m_shrinkStartDeadline;
|
||||
UnsignedInt m_doneForeverFrame; ///< Just in case interval and state timing goes awry
|
||||
///< This supercedes and makes us quit
|
||||
|
||||
|
||||
UnsignedInt m_changeIntervalCountdown;///< How long till I change my vision range again
|
||||
|
||||
|
||||
|
||||
Bool m_decalsCreated; ///< Have I created the fx decals yet?
|
||||
Real m_visionChangePerInterval; ///< How much I change each time.
|
||||
Real m_nativeClearingRange; ///< What is my objects native vision range?
|
||||
Real m_currentClearingRange; ///<ToKeepTrackOfWhere We are at
|
||||
|
||||
RadiusDecal m_gridDecal[GRID_FX_DECAL_COUNT];///< For the pseudo-wireframe decal effect
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
128
Generals/Code/GameEngine/Include/GameLogic/Module/EMPUpdate.h
Normal file
128
Generals/Code/GameEngine/Include/GameLogic/Module/EMPUpdate.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: EMPUpdate.h ///////////////////////////////////////////////////////////////////////
|
||||
// Author: Mark Lorenzen Sept. 2002
|
||||
// Desc: Update that makes the electromagnetic pulse field grow, fade and disable junk
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __EMPUPDATE_H_
|
||||
#define __EMPUPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class EMPUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_lifeFrames;
|
||||
UnsignedInt m_startFadeFrame;
|
||||
UnsignedInt m_disabledDuration;
|
||||
Real m_startScale; ///< how big I start drawing
|
||||
Real m_targetScaleMin; ///< how big I change to by the time I'm done
|
||||
Real m_targetScaleMax; ///< how big I change to by the time I'm done
|
||||
//Real m_spinRateMax; ///< how fast may I spin?
|
||||
RGBColor m_startColor;
|
||||
RGBColor m_endColor;
|
||||
const ParticleSystemTemplate *m_disableFXParticleSystem;
|
||||
Real m_sparksPerCubicFoot; //<just like it sounds
|
||||
|
||||
EMPUpdateModuleData()
|
||||
{
|
||||
m_lifeFrames = 1;
|
||||
m_startFadeFrame = 0;
|
||||
m_startScale = 1.0f;
|
||||
m_targetScaleMax = 1.0f;
|
||||
m_targetScaleMin = 1.0f;
|
||||
m_startColor.setFromInt(0xffffffff);
|
||||
m_endColor.setFromInt (0x00000000);
|
||||
//m_spinRateMax = 0.0f;
|
||||
m_disabledDuration = 0;
|
||||
m_disableFXParticleSystem = NULL;
|
||||
m_sparksPerCubicFoot = 0.001f;
|
||||
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "Lifetime", INI::parseDurationUnsignedInt, NULL, offsetof( EMPUpdateModuleData, m_lifeFrames ) },
|
||||
{ "StartFadeTime", INI::parseDurationUnsignedInt, NULL, offsetof( EMPUpdateModuleData, m_startFadeFrame ) },
|
||||
{ "StartScale", INI::parseReal, NULL, offsetof( EMPUpdateModuleData, m_startScale ) },
|
||||
{ "DisabledDuration", INI::parseDurationUnsignedInt, NULL, offsetof( EMPUpdateModuleData, m_disabledDuration ) },
|
||||
//{ "SpinRateMax", INI::parseReal, NULL, offsetof( EMPUpdateModuleData, m_spinRateMax ) },
|
||||
{ "TargetScaleMax", INI::parseReal, NULL, offsetof( EMPUpdateModuleData, m_targetScaleMax ) },
|
||||
{ "TargetScaleMin", INI::parseReal, NULL, offsetof( EMPUpdateModuleData, m_targetScaleMin ) },
|
||||
{ "StartColor", INI::parseRGBColor, NULL, offsetof( EMPUpdateModuleData, m_startColor ) },
|
||||
{ "EndColor", INI::parseRGBColor, NULL, offsetof( EMPUpdateModuleData, m_endColor ) },
|
||||
{ "DisableFXParticleSystem", INI::parseParticleSystemTemplate, NULL, offsetof( EMPUpdateModuleData, m_disableFXParticleSystem ) },
|
||||
{ "SparksPerCubicFoot", INI::parseReal, NULL, offsetof( EMPUpdateModuleData, m_sparksPerCubicFoot ) },
|
||||
|
||||
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class EMPUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( EMPUpdate, "EMPUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( EMPUpdate, EMPUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
EMPUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
UnsignedInt getDieFrame() { return m_dieFrame; }
|
||||
|
||||
virtual UpdateSleepTime update( void );
|
||||
void doDisableAttack( void );
|
||||
|
||||
protected:
|
||||
|
||||
UnsignedInt m_dieFrame; ///< frame we die on
|
||||
UnsignedInt m_tintEnvFadeFrames;///< param for tint envelope
|
||||
UnsignedInt m_tintEnvPlayFrame;///< which frame to trigger the tint envelope
|
||||
|
||||
Real m_targetScale; ///How big will I get
|
||||
//Real m_spinRate; ///HowMuch To Spin each frame;
|
||||
Real m_currentScale; ///< how big I am drawing this frame
|
||||
|
||||
//static Bool s_lastInstanceSpunPositive;/// so that only every other instance spins positive direction
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif // __EMPUPDATE_H_
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: EjectPilotDie.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Steven Johnson, April 2002
|
||||
// Desc: Create object at current object's death
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef _EjectPilotDie_H_
|
||||
#define _EjectPilotDie_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
#include "Common/INI.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
class ObjectCreationList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class EjectPilotDieModuleData : public DieModuleData
|
||||
{
|
||||
public:
|
||||
const ObjectCreationList* m_oclInAir;
|
||||
const ObjectCreationList* m_oclOnGround;
|
||||
UnsignedInt m_invulnerableTime;
|
||||
|
||||
EjectPilotDieModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** When this object dies, create another object in its place */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class EjectPilotDie : public DieModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( EjectPilotDie, "EjectPilotDie" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( EjectPilotDie, EjectPilotDieModuleData );
|
||||
|
||||
public:
|
||||
|
||||
EjectPilotDie( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
static void ejectPilot(const ObjectCreationList* ocl, const Object* dyingObject, const Object* damageDealer);
|
||||
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
virtual DieModuleInterface* getEjectPilotDieInterface( void ) {return this; }
|
||||
|
||||
};
|
||||
|
||||
#endif // _EjectPilotDie_H_
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: EnemyNearUpdate.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Matthew D. Campbell, April 2002
|
||||
// Desc: Reacts when an enemy is within range
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __EnemyNearUpdate_H_
|
||||
#define __EnemyNearUpdate_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "Common/KindOf.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class EnemyNearUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_enemyScanDelayTime;
|
||||
|
||||
EnemyNearUpdateModuleData()
|
||||
{
|
||||
m_enemyScanDelayTime = LOGICFRAMES_PER_SECOND;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "ScanDelayTime", INI::parseDurationUnsignedInt, NULL, offsetof( EnemyNearUpdateModuleData, m_enemyScanDelayTime ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** EnemyNear update */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class EnemyNearUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( EnemyNearUpdate, "EnemyNearUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( EnemyNearUpdate, EnemyNearUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
EnemyNearUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
UnsignedInt m_enemyScanDelay;
|
||||
Bool m_enemyNear;
|
||||
|
||||
void checkForEnemies( void );
|
||||
|
||||
};
|
||||
|
||||
#endif // end __EnemyNearUpdate_H_
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: ExperienceScalarUpgrade.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Kris Morness, September 2002
|
||||
// Desc: UpgradeModule that adds a scalar to the object's experience gain.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __EXPERIENCE_SCALAR_UPGRADE_H_
|
||||
#define __EXPERIENCE_SCALAR_UPGRADE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class ExperienceScalarUpgradeModuleData: public UpgradeModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
ExperienceScalarUpgradeModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
Real m_addXPScalar;
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class ExperienceScalarUpgrade : public UpgradeModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ExperienceScalarUpgrade, "ExperienceScalarUpgrade" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( ExperienceScalarUpgrade, ExperienceScalarUpgradeModuleData );
|
||||
|
||||
public:
|
||||
|
||||
ExperienceScalarUpgrade( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype defined by MemoryPoolObject
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation( ); ///< Here's the actual work of Upgrading
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __DEFAULTDIE_H_
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FXListDie.h /////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Steven Johnson, Jan 2002
|
||||
// Desc: Simple die module
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FXListDie_H_
|
||||
#define __FXListDie_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/INI.h"
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
#include "GameLogic/Weapon.h"
|
||||
#include "GameLogic/Damage.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
class FXList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FXListDieModuleData : public DieModuleData
|
||||
{
|
||||
public:
|
||||
const FXList *m_defaultDeathFX; ///< default fx to make
|
||||
Bool m_orientToObject;
|
||||
|
||||
FXListDieModuleData()
|
||||
{
|
||||
m_defaultDeathFX = NULL;
|
||||
m_orientToObject = true;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
DieModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "DeathFX", INI::parseFXList, NULL, offsetof( FXListDieModuleData, m_defaultDeathFX ) },
|
||||
{ "OrientToObject", INI::parseBool, NULL, offsetof( FXListDieModuleData, m_orientToObject ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FXListDie : public DieModule
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FXListDie, FXListDieModuleData );
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FXListDie, "FXListDie" )
|
||||
|
||||
public:
|
||||
|
||||
FXListDie( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // __FXListDie_H_
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FireOCLAfterWeaponCooldownUpdate.h ////////////////////////////////////////////////////////////////////////
|
||||
// Author: Kris Morness, September 2002
|
||||
// Desc: This system tracks the objects status with regards to firing, and whenever the object stops
|
||||
// firing, and all the conditions are met, then it'll create the specified OCL.
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FIRE_OCL_AFTER_WEAPON_COOLDOWN_UPDATE_H
|
||||
#define __FIRE_OCL_AFTER_WEAPON_COOLDOWN_UPDATE_H
|
||||
|
||||
class UpgradeMuxData;
|
||||
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireOCLAfterWeaponCooldownUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UpgradeMuxData m_upgradeMuxData;
|
||||
ObjectCreationList *m_ocl;
|
||||
WeaponSlotType m_weaponSlot;
|
||||
UnsignedInt m_minShotsRequired;
|
||||
UnsignedInt m_oclLifetimePerSecond;
|
||||
UnsignedInt m_oclMaxFrames;
|
||||
|
||||
FireOCLAfterWeaponCooldownUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireOCLAfterWeaponCooldownUpdate : public UpdateModule, public UpgradeMux
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FireOCLAfterWeaponCooldownUpdate, "FireOCLAfterWeaponCooldownUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FireOCLAfterWeaponCooldownUpdate, FireOCLAfterWeaponCooldownUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
FireOCLAfterWeaponCooldownUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// update methods
|
||||
virtual UpdateSleepTime update(); ///< called once per frame
|
||||
|
||||
protected:
|
||||
virtual void upgradeImplementation()
|
||||
{
|
||||
// nothing!
|
||||
}
|
||||
|
||||
virtual void getUpgradeActivationMasks(Int64& activation, Int64& conflicting) const
|
||||
{
|
||||
getFireOCLAfterWeaponCooldownUpdateModuleData()->m_upgradeMuxData.getUpgradeActivationMasks(activation, conflicting);
|
||||
}
|
||||
|
||||
virtual void performUpgradeFX()
|
||||
{
|
||||
getFireOCLAfterWeaponCooldownUpdateModuleData()->m_upgradeMuxData.performUpgradeFX(getObject());
|
||||
}
|
||||
|
||||
virtual Bool requiresAllActivationUpgrades() const
|
||||
{
|
||||
return getFireOCLAfterWeaponCooldownUpdateModuleData()->m_upgradeMuxData.m_requiresAllTriggers;
|
||||
}
|
||||
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
void resetStats();
|
||||
void fireOCL();
|
||||
|
||||
private:
|
||||
|
||||
Bool m_valid;
|
||||
UnsignedInt m_consecutiveShots;
|
||||
UnsignedInt m_startFrame;
|
||||
|
||||
};
|
||||
|
||||
#endif // __FIRE_OCL_AFTER_WEAPON_COOLDOWN_UPDATE_H
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FireSpreadUpdate.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, April 2002
|
||||
// Desc: Update looks for ::Aflame and explicitly ignites someone nearby if set
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FIRE_SPREAD_UPDATE_H_
|
||||
#define __FIRE_SPREAD_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
class ObjectCreationList;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireSpreadUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
const ObjectCreationList *m_oclEmbers;
|
||||
UnsignedInt m_minSpreadTryDelayData;
|
||||
UnsignedInt m_maxSpreadTryDelayData;
|
||||
Real m_spreadTryRange;
|
||||
|
||||
FireSpreadUpdateModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireSpreadUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FireSpreadUpdate, "FireSpreadUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FireSpreadUpdate, FireSpreadUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
FireSpreadUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
void startFireSpreading();
|
||||
|
||||
protected:
|
||||
|
||||
UnsignedInt calcNextSpreadDelay();
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FireWeaponCollide.h ///////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood April 2002
|
||||
// Desc: Shoot something that collides with me every frame with my weapon
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FireWeaponCollide_H_
|
||||
#define __FireWeaponCollide_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/CollideModule.h"
|
||||
#include "GameLogic/Weapon.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Object;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponCollideModuleData : public CollideModuleData
|
||||
{
|
||||
public:
|
||||
const WeaponTemplate* m_collideWeaponTemplate;
|
||||
UnsignedInt m_requiredStatus;
|
||||
UnsignedInt m_forbiddenStatus;
|
||||
Bool m_fireOnce;
|
||||
|
||||
FireWeaponCollideModuleData()
|
||||
{
|
||||
m_collideWeaponTemplate = NULL;
|
||||
m_requiredStatus = 0; // nothing required
|
||||
m_forbiddenStatus = 0; // nothing forbidden
|
||||
m_fireOnce = FALSE;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponCollide : public CollideModule
|
||||
{
|
||||
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FireWeaponCollide, FireWeaponCollideModuleData );
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FireWeaponCollide, "FireWeaponCollide" )
|
||||
|
||||
public:
|
||||
|
||||
FireWeaponCollide( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
protected:
|
||||
|
||||
virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal );
|
||||
|
||||
virtual Bool shouldFireWeapon();
|
||||
|
||||
private:
|
||||
Weapon* m_collideWeapon;
|
||||
Bool m_everFired;
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FireWeaponUpdate.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, August 2002
|
||||
// Desc: Update fires a weapon at its own feet as quickly as the weapon allows
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FIRE_WEAPON_UPDATE_H_
|
||||
#define __FIRE_WEAPON_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameLogic/Weapon.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
const WeaponTemplate* m_weaponTemplate;
|
||||
FireWeaponUpdateModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FireWeaponUpdate, "FireWeaponUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FireWeaponUpdate, FireWeaponUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
FireWeaponUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
Weapon* m_weapon;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,172 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FireWeaponWhenDamagedBehavior.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Steven Johnson, June 2002
|
||||
// Desc: Update that will count down a lifetime and destroy object when it reaches zero
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FireWeaponWhenDamagedBehavior_H_
|
||||
#define __FireWeaponWhenDamagedBehavior_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
#include "GameLogic/Module/DamageModule.h"
|
||||
#include "GameLogic/Weapon.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponWhenDamagedBehaviorModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UpgradeMuxData m_upgradeMuxData;
|
||||
Bool m_initiallyActive;
|
||||
DamageTypeFlags m_damageTypes;
|
||||
Real m_damageAmount;
|
||||
const WeaponTemplate* m_reactionWeaponPristine;///< fire these weapons only when damage is received
|
||||
const WeaponTemplate* m_reactionWeaponDamaged;
|
||||
const WeaponTemplate* m_reactionWeaponReallyDamaged;
|
||||
const WeaponTemplate* m_reactionWeaponRubble;
|
||||
const WeaponTemplate* m_continuousWeaponPristine;///< fire these weapons continuously, versus just onDamage
|
||||
const WeaponTemplate* m_continuousWeaponDamaged;
|
||||
const WeaponTemplate* m_continuousWeaponReallyDamaged;
|
||||
const WeaponTemplate* m_continuousWeaponRubble;
|
||||
|
||||
FireWeaponWhenDamagedBehaviorModuleData()
|
||||
{
|
||||
m_initiallyActive = false;
|
||||
m_reactionWeaponPristine = NULL;
|
||||
m_reactionWeaponDamaged = NULL;
|
||||
m_reactionWeaponReallyDamaged = NULL;
|
||||
m_reactionWeaponRubble = NULL;
|
||||
m_continuousWeaponPristine = NULL;
|
||||
m_continuousWeaponDamaged = NULL;
|
||||
m_continuousWeaponReallyDamaged = NULL;
|
||||
m_continuousWeaponRubble = NULL;
|
||||
m_damageTypes = DAMAGE_TYPE_FLAGS_ALL;
|
||||
m_damageAmount = 0;
|
||||
}
|
||||
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "StartsActive", INI::parseBool, NULL, offsetof( FireWeaponWhenDamagedBehaviorModuleData, m_initiallyActive ) },
|
||||
{ "ReactionWeaponPristine", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData, m_reactionWeaponPristine) },
|
||||
{ "ReactionWeaponDamaged", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData, m_reactionWeaponDamaged) },
|
||||
{ "ReactionWeaponReallyDamaged", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData, m_reactionWeaponReallyDamaged) },
|
||||
{ "ReactionWeaponRubble", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData, m_reactionWeaponRubble) },
|
||||
{ "ContinuousWeaponPristine", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData, m_continuousWeaponPristine) },
|
||||
{ "ContinuousWeaponDamaged", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData, m_continuousWeaponDamaged) },
|
||||
{ "ContinuousWeaponReallyDamaged", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData,m_continuousWeaponReallyDamaged) },
|
||||
{ "ContinuousWeaponRubble", INI::parseWeaponTemplate, NULL, offsetof(FireWeaponWhenDamagedBehaviorModuleData, m_continuousWeaponRubble) },
|
||||
{ "DamageTypes", INI::parseDamageTypeFlags, NULL, offsetof( FireWeaponWhenDamagedBehaviorModuleData, m_damageTypes ) },
|
||||
{ "DamageAmount", INI::parseReal, NULL, offsetof( FireWeaponWhenDamagedBehaviorModuleData, m_damageAmount ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
UpdateModuleData::buildFieldParse(p);
|
||||
p.add(dataFieldParse);
|
||||
p.add(UpgradeMuxData::getFieldParse(), offsetof( FireWeaponWhenDamagedBehaviorModuleData, m_upgradeMuxData ));
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponWhenDamagedBehavior : public UpdateModule,
|
||||
public UpgradeMux,
|
||||
public DamageModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FireWeaponWhenDamagedBehavior, "FireWeaponWhenDamagedBehavior" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FireWeaponWhenDamagedBehavior, FireWeaponWhenDamagedBehaviorModuleData )
|
||||
|
||||
public:
|
||||
|
||||
FireWeaponWhenDamagedBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// module methids
|
||||
static Int getInterfaceMask() { return UpdateModule::getInterfaceMask() | (MODULEINTERFACE_UPGRADE) | (MODULEINTERFACE_DAMAGE); }
|
||||
|
||||
// BehaviorModule
|
||||
virtual UpgradeModuleInterface* getUpgrade() { return this; }
|
||||
virtual DamageModuleInterface* getDamage() { return this; }
|
||||
|
||||
// DamageModuleInterface
|
||||
virtual void onDamage( DamageInfo *damageInfo );
|
||||
virtual void onHealing( DamageInfo *damageInfo ) { }
|
||||
virtual void onBodyDamageStateChange(const DamageInfo* damageInfo, BodyDamageType oldState, BodyDamageType newState) { }
|
||||
|
||||
// UpdateModuleInterface
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation()
|
||||
{
|
||||
setWakeFrame(getObject(), UPDATE_SLEEP_NONE);
|
||||
}
|
||||
|
||||
virtual void getUpgradeActivationMasks(Int64& activation, Int64& conflicting) const
|
||||
{
|
||||
getFireWeaponWhenDamagedBehaviorModuleData()->m_upgradeMuxData.getUpgradeActivationMasks(activation, conflicting);
|
||||
}
|
||||
|
||||
virtual void performUpgradeFX()
|
||||
{
|
||||
getFireWeaponWhenDamagedBehaviorModuleData()->m_upgradeMuxData.performUpgradeFX(getObject());
|
||||
}
|
||||
|
||||
virtual Bool requiresAllActivationUpgrades() const
|
||||
{
|
||||
return getFireWeaponWhenDamagedBehaviorModuleData()->m_upgradeMuxData.m_requiresAllTriggers;
|
||||
}
|
||||
|
||||
inline Bool isUpgradeActive() const { return isAlreadyUpgraded(); }
|
||||
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
private:
|
||||
Weapon *m_reactionWeaponPristine;
|
||||
Weapon *m_reactionWeaponDamaged;
|
||||
Weapon *m_reactionWeaponReallyDamaged;
|
||||
Weapon *m_reactionWeaponRubble;
|
||||
Weapon *m_continuousWeaponPristine;
|
||||
Weapon *m_continuousWeaponDamaged;
|
||||
Weapon *m_continuousWeaponReallyDamaged;
|
||||
Weapon *m_continuousWeaponRubble;
|
||||
|
||||
};
|
||||
|
||||
#endif // __FireWeaponWhenDamagedBehavior_H_
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FireWeaponWhenDeadBehavior.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, December 2001
|
||||
// Desc: Update that will count down a lifetime and destroy object when it reaches zero
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FireWeaponWhenDeadBehavior_H_
|
||||
#define __FireWeaponWhenDeadBehavior_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponWhenDeadBehaviorModuleData : public BehaviorModuleData
|
||||
{
|
||||
public:
|
||||
UpgradeMuxData m_upgradeMuxData;
|
||||
Bool m_initiallyActive;
|
||||
DieMuxData m_dieMuxData;
|
||||
const WeaponTemplate* m_deathWeapon; ///< fire this weapon when we are damaged
|
||||
|
||||
FireWeaponWhenDeadBehaviorModuleData()
|
||||
{
|
||||
m_initiallyActive = false;
|
||||
m_deathWeapon = NULL;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "StartsActive", INI::parseBool, NULL, offsetof( FireWeaponWhenDeadBehaviorModuleData, m_initiallyActive ) },
|
||||
{ "DeathWeapon", INI::parseWeaponTemplate, NULL, offsetof( FireWeaponWhenDeadBehaviorModuleData, m_deathWeapon ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
BehaviorModuleData::buildFieldParse(p);
|
||||
p.add(dataFieldParse);
|
||||
p.add(UpgradeMuxData::getFieldParse(), offsetof( FireWeaponWhenDeadBehaviorModuleData, m_upgradeMuxData ));
|
||||
p.add(DieMuxData::getFieldParse(), offsetof( FireWeaponWhenDeadBehaviorModuleData, m_dieMuxData ));
|
||||
}
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FireWeaponWhenDeadBehavior : public BehaviorModule,
|
||||
public UpgradeMux,
|
||||
public DieModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FireWeaponWhenDeadBehavior, "FireWeaponWhenDeadBehavior" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FireWeaponWhenDeadBehavior, FireWeaponWhenDeadBehaviorModuleData )
|
||||
|
||||
public:
|
||||
|
||||
FireWeaponWhenDeadBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// module methods
|
||||
static Int getInterfaceMask() { return BehaviorModule::getInterfaceMask() | (MODULEINTERFACE_UPGRADE) | (MODULEINTERFACE_DIE); }
|
||||
|
||||
// BehaviorModule
|
||||
virtual UpgradeModuleInterface* getUpgrade() { return this; }
|
||||
virtual DieModuleInterface* getDie() { return this; }
|
||||
|
||||
// DamageModuleInterface
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation()
|
||||
{
|
||||
// nothing!
|
||||
}
|
||||
|
||||
virtual void getUpgradeActivationMasks(Int64& activation, Int64& conflicting) const
|
||||
{
|
||||
getFireWeaponWhenDeadBehaviorModuleData()->m_upgradeMuxData.getUpgradeActivationMasks(activation, conflicting);
|
||||
}
|
||||
|
||||
virtual void performUpgradeFX()
|
||||
{
|
||||
getFireWeaponWhenDeadBehaviorModuleData()->m_upgradeMuxData.performUpgradeFX(getObject());
|
||||
}
|
||||
|
||||
virtual Bool requiresAllActivationUpgrades() const
|
||||
{
|
||||
return getFireWeaponWhenDeadBehaviorModuleData()->m_upgradeMuxData.m_requiresAllTriggers;
|
||||
}
|
||||
|
||||
inline Bool isUpgradeActive() const { return isAlreadyUpgraded(); }
|
||||
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
};
|
||||
|
||||
#endif // __FireWeaponWhenDeadBehavior_H_
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FirestormDynamicGeometryInfoUpdate.h //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, April 2002
|
||||
// Desc: Update module adds the molestation of a particle system to Geometry changing
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FIRESTORM_DYNAMIC_GEOMETRY_INFO_UPDATE_H_
|
||||
#define __FIRESTORM_DYNAMIC_GEOMETRY_INFO_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/Geometry.h"
|
||||
#include "GameLogic/Module/DynamicGeometryInfoUpdate.h"
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
enum { MAX_FIRESTORM_SYSTEMS = 16 };
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class ParticleSystemTemplate;
|
||||
|
||||
class FirestormDynamicGeometryInfoUpdateModuleData : public DynamicGeometryInfoUpdateModuleData
|
||||
{
|
||||
public:
|
||||
|
||||
FirestormDynamicGeometryInfoUpdateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
const FXList *m_fxList;
|
||||
const ParticleSystemTemplate *m_particleSystem[ MAX_FIRESTORM_SYSTEMS ];
|
||||
Real m_particleOffsetZ;
|
||||
Real m_scorchSize;
|
||||
Real m_delayBetweenDamageFrames;
|
||||
Real m_damageAmount;
|
||||
Real m_maxHeightForDamage; // things higher than this above us take no damage
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The default update module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FirestormDynamicGeometryInfoUpdate : public DynamicGeometryInfoUpdate
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FirestormDynamicGeometryInfoUpdate, "FirestormDynamicGeometryInfoUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FirestormDynamicGeometryInfoUpdate, FirestormDynamicGeometryInfoUpdateModuleData );
|
||||
|
||||
public:
|
||||
|
||||
FirestormDynamicGeometryInfoUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
void doDamageScan( void );
|
||||
|
||||
ParticleSystemID m_myParticleSystemID[ MAX_FIRESTORM_SYSTEMS ];
|
||||
Bool m_effectsFired; ///< TRUE once the effects have been fired off
|
||||
Bool m_scorchPlaced; ///< TRUE once we have placed the scorch mark
|
||||
UnsignedInt m_lastDamageFrame; ///< frame we last did damage on
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FlammableUpdate.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, April 2002
|
||||
// Desc: Update that manages Aflame and Burned statuses and their effects
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FLAMMABLE_UPDATE_H_
|
||||
#define __FLAMMABLE_UPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/AudioEventRTS.h"
|
||||
#include "GameLogic/Module/DamageModule.h"
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum FlammabilityStatusType
|
||||
{
|
||||
// These show the state I last noticed my object was in.
|
||||
FS_NORMAL = 0,
|
||||
FS_AFLAME,
|
||||
FS_BURNED,
|
||||
|
||||
FS_NORMAL_COUNT // keep last
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FlammableUpdateModuleData : public UpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_burnedDelay; ///< How long before I am ::Burned. 0 means never
|
||||
UnsignedInt m_aflameDuration; ///< How long I stay ::Aflame. Independent of Burned.
|
||||
// When aflame wears out is when I check to be normal or burned, So my model can
|
||||
// change to burned while I am still aflame.
|
||||
UnsignedInt m_aflameDamageDelay; ///< While ::Aflame, I take damage this often. If 0, never.
|
||||
Int m_aflameDamageAmount; ///< And this is how much I take.
|
||||
AsciiString m_burningSoundName; ///< Sound to loop-play while burning (Not an AudioEventRTS here, since that belongs to the module)
|
||||
Real m_flameDamageLimitData;
|
||||
UnsignedInt m_flameDamageExpirationDelay;
|
||||
|
||||
FlammableUpdateModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FlammableUpdate : public UpdateModule, public DamageModuleInterface
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FlammableUpdate, "FlammableUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FlammableUpdate, FlammableUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
FlammableUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
static Int getInterfaceMask() { return UpdateModule::getInterfaceMask() | (MODULEINTERFACE_DAMAGE); }
|
||||
virtual DamageModuleInterface* getDamage() { return this; }
|
||||
|
||||
void tryToIgnite(); ///< FlammabeDamage uses this. It is up to me to decide if I am burnable
|
||||
Bool wouldIgnite(); ///< Since we need to cheat sometimes and light something directly, ask if this would light
|
||||
|
||||
//UpdateModuleInterface
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
//DamageModuleInterface
|
||||
virtual void onDamage( DamageInfo *damageInfo );
|
||||
virtual void onHealing( DamageInfo *damageInfo ) { }
|
||||
virtual void onBodyDamageStateChange( const DamageInfo *damageInfo,
|
||||
BodyDamageType oldState,
|
||||
BodyDamageType newState ) { }
|
||||
|
||||
protected:
|
||||
|
||||
UpdateSleepTime calcSleepTime();
|
||||
void doAflameDamage();
|
||||
void startBurningSound();
|
||||
void stopBurningSound();
|
||||
|
||||
FlammabilityStatusType m_status;
|
||||
UnsignedInt m_aflameEndFrame;
|
||||
UnsignedInt m_burnedEndFrame;
|
||||
UnsignedInt m_damageEndFrame;
|
||||
AudioHandle m_audioHandle;
|
||||
Real m_flameDamageLimit;
|
||||
UnsignedInt m_lastFlameDamageDealt;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: FloatUpdate.h ////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, May 2002
|
||||
// Desc: Floting on water update
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __FLOATUPDATE_H_
|
||||
#define __FLOATUPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
struct FieldParse;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FloatUpdateModuleData: public UpdateModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
FloatUpdateModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
Bool m_enabled; ///< enabled
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class FloatUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( FloatUpdate, "FloatUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( FloatUpdate, FloatUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
FloatUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
void setEnabled( Bool enabled ) { m_enabled = enabled; } ///< enable/disable floating
|
||||
|
||||
virtual UpdateSleepTime update(); ///< Deciding whether or not to make new guys
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
Bool m_enabled; ///< enabled
|
||||
|
||||
};
|
||||
|
||||
#endif // end __FLOATUPDATE_H_
|
||||
@@ -0,0 +1,216 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GarrisonContain.h ////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, February 2002
|
||||
// Desc: Contain module for structures that can be garrisoned
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GARRISONCONTAIN_H_
|
||||
#define __GARRISONCONTAIN_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/OpenContain.h"
|
||||
#include "Common/ModelState.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class GarrisonContainModuleData : public OpenContainModuleData
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
struct InitialRoster
|
||||
{
|
||||
AsciiString templateName;
|
||||
Int count;
|
||||
};
|
||||
|
||||
|
||||
Bool m_doIHealObjects;
|
||||
Real m_framesForFullHeal;
|
||||
Bool m_mobileGarrison;
|
||||
Bool m_immuneToClearBuildingAttacks;
|
||||
InitialRoster m_initialRoster;
|
||||
|
||||
GarrisonContainModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
OpenContainModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "MobileGarrison", INI::parseBool, NULL, offsetof( GarrisonContainModuleData, m_mobileGarrison ) },
|
||||
{ "HealObjects", INI::parseBool, NULL, offsetof( GarrisonContainModuleData, m_doIHealObjects ) },
|
||||
{ "TimeForFullHeal", INI::parseDurationReal, NULL, offsetof( GarrisonContainModuleData, m_framesForFullHeal ) },
|
||||
{ "InitialRoster", parseInitialRoster, NULL, 0 },
|
||||
{ "ImmuneToClearBuildingAttacks", INI::parseBool, NULL, offsetof( GarrisonContainModuleData, m_immuneToClearBuildingAttacks ) },
|
||||
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
};
|
||||
|
||||
static void parseInitialRoster( INI* ini, void *instance, void *store, const void* )
|
||||
{
|
||||
GarrisonContainModuleData* self = (GarrisonContainModuleData*)instance;
|
||||
const char* name = ini->getNextToken();
|
||||
const char* countStr = ini->getNextTokenOrNull();
|
||||
Int count = countStr ? INI::scanInt(countStr) : 1;
|
||||
|
||||
self->m_initialRoster.templateName.set(name);
|
||||
self->m_initialRoster.count = count;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** A GarrisonContain is used for objects that can be garrisoned, heh, go figure */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class GarrisonContain : public OpenContain
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( GarrisonContain, "GarrisonContain" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( GarrisonContain, GarrisonContainModuleData )
|
||||
|
||||
public:
|
||||
|
||||
GarrisonContain( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update( void ); ///< called once per frame
|
||||
|
||||
virtual Bool isValidContainerFor( const Object* obj, Bool checkCapacity) const; // Garrison has an extra check forbidding any containment if ReallyDamaged
|
||||
virtual Bool isGarrisonable() const { return true; } ///< can this unit be Garrisoned? (ick)
|
||||
virtual Bool isImmuneToClearBuildingAttacks() const { return getGarrisonContainModuleData()->m_immuneToClearBuildingAttacks; }
|
||||
virtual Bool isHealContain() const { return false; } ///< true when container only contains units while healing (not a transport!)
|
||||
virtual Bool isPassengerAllowedToFire( void ) const; ///< Hey, can I shoot out of this container?
|
||||
|
||||
virtual void removeAllContained( Bool exposeStealthUnits ); ///< remove all contents of this open container
|
||||
|
||||
virtual void exitObjectViaDoor( Object *exitObj, ExitDoorType exitDoor ); ///< exit one of our content items from us
|
||||
virtual void exitObjectByBudding( Object *newObj, Object *budHost ) { return; };
|
||||
virtual void onContaining( Object *obj ); ///< object now contains 'obj'
|
||||
virtual void onRemoving( Object *obj ); ///< object no longer contains 'obj'
|
||||
|
||||
// A Garrison Contain must eject all passengers when it crosses the ReallyDamaged threshold.
|
||||
virtual void onBodyDamageStateChange( const DamageInfo* damageInfo,
|
||||
BodyDamageType oldState,
|
||||
BodyDamageType newState); ///< Die Interface state change callback
|
||||
|
||||
|
||||
/**
|
||||
return the player that *appears* to control this unit, given an observing player.
|
||||
if null, use getObject()->getControllingPlayer() instead.
|
||||
*/
|
||||
virtual const Player* getApparentControllingPlayer( const Player* observingPlayer ) const;
|
||||
virtual void recalcApparentControllingPlayer( void );
|
||||
virtual Bool isDisplayedOnControlBar() const {return TRUE;}///< Does this container display its contents on the ControlBar?
|
||||
|
||||
protected:
|
||||
|
||||
virtual void redeployOccupants( void ); ///< redeploy the occupants of us at all available garrison points
|
||||
virtual void onObjectCreated();
|
||||
|
||||
void validateRallyPoint( void ); ///< validate (if necessary) and pick (if possible) an exit rally point
|
||||
|
||||
virtual Bool calcBestGarrisonPosition( Coord3D *sourcePos, const Coord3D *targetPos );
|
||||
virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, Object *victim );
|
||||
virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, const Coord3D *targetPos );
|
||||
|
||||
void updateEffects( void ); ///< do any effects needed per frame
|
||||
void loadGarrisonPoints( void ); ///< load garrison point position data and save for later
|
||||
void putObjectAtBestGarrisonPoint( Object *obj, Object *target, const Coord3D *targetPos ); ///< place object at position of the best garrison point to use for its target
|
||||
void putObjectAtGarrisonPoint( Object *obj, ObjectID targetID, Int conditionIndex, Int index ); ///< place object at the specified garrison point index
|
||||
enum { SEARCH_FOR_REMOVE = -1 };
|
||||
void removeObjectFromGarrisonPoint( Object *obj, Int index = SEARCH_FOR_REMOVE );///< remove object from the garrison point placement
|
||||
void addValidObjectsToGarrisonPoints( void ); ///< add any objects with targets to a garrison point
|
||||
void removeInvalidObjectsFromGarrisonPoints( void ); ///< remove objects with invalid targets from valid points
|
||||
void trackTargets( void ); ///< keep attackers at the closest garrison point to their active target
|
||||
|
||||
enum { GARRISON_INDEX_INVALID = -1 };
|
||||
Int findConditionIndex( void ); ///< find the condition index to use given the current object body state
|
||||
Int getObjectGarrisonPointIndex( Object *obj ); ///< get the garrison point index object is at (if present)
|
||||
Int findClosestFreeGarrisonPointIndex( Int conditionIndex,
|
||||
const Coord3D *targetPos ); ///< find closest free garrison point to the target location
|
||||
|
||||
void healObjects( void ); ///< heal all the objects within me
|
||||
void healSingleObject( Object *obj, Real frames ); ///< heal just one of the objects within me
|
||||
void moveObjectsWithMe( void ); ///< translates all the garrisoned object to this->getObject()->getPosition()
|
||||
|
||||
private:
|
||||
|
||||
enum { MAX_GARRISON_POINTS = 40 };
|
||||
|
||||
//
|
||||
// The max units inside any garrisoned structure is 10. Since the units will "move around"
|
||||
// the inside of the structure to be close to their targets, we need a max of 10 garrison points
|
||||
// on each side of the building to accomodate everybody inside
|
||||
//
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
struct GarrisonPointData
|
||||
{
|
||||
union
|
||||
{
|
||||
Object * object; ///< object at this garrison point
|
||||
ObjectID objectID; ///< for loading
|
||||
};
|
||||
ObjectID targetID; ///< object ID that is our current target
|
||||
UnsignedInt placeFrame; ///< frame we were placed at this garrison point
|
||||
UnsignedInt lastEffectFrame; ///< last frame we fired our effects on
|
||||
union
|
||||
{
|
||||
Drawable * effect; ///< effect object for showing gun barrels and muzzle flash fire
|
||||
DrawableID effectID; ///< for loading
|
||||
};
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
GARRISON_POINT_PRISTINE,
|
||||
GARRISON_POINT_DAMAGED,
|
||||
GARRISON_POINT_REALLY_DAMAGED,
|
||||
|
||||
MAX_GARRISON_POINT_CONDITIONS ///< leave this last
|
||||
};
|
||||
|
||||
Team * m_originalTeam; ///< our original team before we were garrisoned
|
||||
GarrisonPointData m_garrisonPointData[ MAX_GARRISON_POINTS ]; ///< the garrison point placement data
|
||||
Int m_garrisonPointsInUse;
|
||||
Coord3D m_garrisonPoint[ MAX_GARRISON_POINT_CONDITIONS ][ MAX_GARRISON_POINTS ]; ///< the garrison point positions (in world coords) for pristine, damaged, and really damaged
|
||||
Coord3D m_exitRallyPoint; ///< Point to rally at when exiting structure (if possible)
|
||||
|
||||
Bool m_garrisonPointsInitialized; ///< TRUE once we have loaded the garrison point positions from the art
|
||||
Bool m_hideGarrisonedStateFromNonallies; ///< if T, don't appear to be garrisoned (all stealthy)
|
||||
Bool m_rallyValid; ///< TRUE when m_exitRallyPoint is valid
|
||||
|
||||
};
|
||||
|
||||
#endif // __GARRISONCONTAIN_H_
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GenerateMinefieldBehavior.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, December 2001
|
||||
// Desc: Update that will count down a lifetime and destroy object when it reaches zero
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GenerateMinefieldBehavior_H_
|
||||
#define __GenerateMinefieldBehavior_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/BehaviorModule.h"
|
||||
#include "GameLogic/Module/DieModule.h"
|
||||
#include "GameLogic/Module/UpgradeModule.h"
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class GenerateMinefieldBehaviorModuleData : public BehaviorModuleData
|
||||
{
|
||||
public:
|
||||
UpgradeMuxData m_upgradeMuxData;
|
||||
AsciiString m_mineName;
|
||||
const FXList* m_genFX;
|
||||
Real m_distanceAroundObject;
|
||||
Real m_minesPerSquareFoot;
|
||||
Real m_randomJitter;
|
||||
Real m_skipIfThisMuchUnderStructure;
|
||||
Bool m_onDeath;
|
||||
Bool m_borderOnly;
|
||||
Bool m_alwaysCircular;
|
||||
Bool m_smartBorder;
|
||||
Bool m_smartBorderSkipInterior;
|
||||
|
||||
GenerateMinefieldBehaviorModuleData();
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
private:
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class GenerateMinefieldBehavior : public BehaviorModule,
|
||||
public DieModuleInterface,
|
||||
public UpgradeMux
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( GenerateMinefieldBehavior, "GenerateMinefieldBehavior" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( GenerateMinefieldBehavior, GenerateMinefieldBehaviorModuleData )
|
||||
|
||||
public:
|
||||
|
||||
GenerateMinefieldBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
// module methods
|
||||
static Int getInterfaceMask() { return (MODULEINTERFACE_DIE) | (MODULEINTERFACE_UPGRADE); }
|
||||
|
||||
// BehaviorModule
|
||||
virtual DieModuleInterface* getDie() { return this; }
|
||||
virtual UpgradeModuleInterface* getUpgrade() { return this; }
|
||||
|
||||
// DamageModuleInterface
|
||||
virtual void onDie( const DamageInfo *damageInfo );
|
||||
|
||||
void setMinefieldTarget(const Coord3D* pos);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void upgradeImplementation();
|
||||
virtual Bool isSubObjectsUpgrade() { return false; }
|
||||
|
||||
virtual void getUpgradeActivationMasks(Int64& activation, Int64& conflicting) const
|
||||
{
|
||||
getGenerateMinefieldBehaviorModuleData()->m_upgradeMuxData.getUpgradeActivationMasks(activation, conflicting);
|
||||
}
|
||||
virtual void performUpgradeFX()
|
||||
{
|
||||
getGenerateMinefieldBehaviorModuleData()->m_upgradeMuxData.performUpgradeFX(getObject());
|
||||
}
|
||||
virtual Bool requiresAllActivationUpgrades() const
|
||||
{
|
||||
return getGenerateMinefieldBehaviorModuleData()->m_upgradeMuxData.m_requiresAllTriggers;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Coord3D m_target;
|
||||
Bool m_hasTarget;
|
||||
Bool m_generated;
|
||||
|
||||
const Coord3D* getMinefieldTarget() const;
|
||||
void placeMines();
|
||||
void placeMinesInFootprint(const GeometryInfo& geom, const ThingTemplate* mineTemplate);
|
||||
void placeMinesAroundCircle(const Coord3D& pos, Real radius, const ThingTemplate* mineTemplate);
|
||||
void placeMinesAlongLine(const Coord3D& posStart, const Coord3D& posEnd, const ThingTemplate* mineTemplate, Bool skipOneAtStart);
|
||||
void placeMinesAroundRect(const Coord3D& pos, Real majorRadius, Real minorRadius, const ThingTemplate* mineTemplate);
|
||||
Object* placeMineAt(const Coord3D& pt, const ThingTemplate* mineTemplate, Team* team, const Object* producer);
|
||||
};
|
||||
|
||||
#endif // __GenerateMinefieldBehavior_H_
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: GrantUpgradeCreate.h //////////////////////////////////////////////////////////////////////////
|
||||
// Author: Kris Morness, April 2002
|
||||
// Desc: GrantUpgrade create module
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __GRANTUPGRADECREATE_H_
|
||||
#define __GRANTUPGRADECREATE_H_
|
||||
|
||||
#define DEFINE_OBJECT_STATUS_NAMES
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/CreateModule.h"
|
||||
#include "GameLogic/Object.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The GrantUpgrade create module */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
class GrantUpgradeCreateModuleData : public CreateModuleData
|
||||
{
|
||||
public:
|
||||
AsciiString m_upgradeName; ///< name of the upgrade to be granted.
|
||||
UnsignedInt m_exemptStatus; ///< do not execute if this status is set in the object
|
||||
|
||||
GrantUpgradeCreateModuleData();
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
class GrantUpgradeCreate : public CreateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( GrantUpgradeCreate, "GrantUpgradeCreate" );
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( GrantUpgradeCreate, GrantUpgradeCreateModuleData );
|
||||
|
||||
|
||||
public:
|
||||
|
||||
GrantUpgradeCreate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
/// the create method
|
||||
virtual void onCreate( void );
|
||||
virtual void onBuildComplete(); ///< This is called when you are a finished game object
|
||||
|
||||
protected:
|
||||
|
||||
};
|
||||
|
||||
#endif // __GRANTUPGRADECREATE_H_
|
||||
|
||||
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// HackInternetAIUpdate.h ////////////
|
||||
// Author: Kris Morness, June 2002
|
||||
// Desc: State machine that allows hacking cash from the internet (free money).
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HACK_INTERNET_AI_UPDATE_H
|
||||
#define __HACK_INTERNET_AI_UPDATE_H
|
||||
|
||||
#include "Common/StateMachine.h"
|
||||
#include "GameLogic/Module/AIUpdate.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HackInternetStateMachine : public AIStateMachine
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HackInternetStateMachine, "HackInternetStateMachine" );
|
||||
public:
|
||||
HackInternetStateMachine( Object *owner, AsciiString name );
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HackInternetState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(HackInternetState, "HackInternetState")
|
||||
public:
|
||||
HackInternetState( StateMachine *machine ) :State( machine, "HackInternetState" )
|
||||
{
|
||||
//Added By Sadullah Nader
|
||||
//Initializations missing and needed
|
||||
m_framesRemaining = 0;
|
||||
//
|
||||
}
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
virtual void onExit( StateExitType status );
|
||||
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
private:
|
||||
UnsignedInt m_framesRemaining; //frames till next cash update
|
||||
};
|
||||
EMPTY_DTOR(HackInternetState)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class PackingState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(PackingState, "PackingState")
|
||||
public:
|
||||
PackingState( StateMachine *machine ) : State( machine, "PackingState" )
|
||||
{
|
||||
//Added By Sadullah Nader
|
||||
//Initializations inserted
|
||||
m_framesRemaining = 0;
|
||||
//
|
||||
}
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
private:
|
||||
UnsignedInt m_framesRemaining; //frames till packing animation complete
|
||||
};
|
||||
EMPTY_DTOR(PackingState)
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class UnpackingState : public State
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(UnpackingState, "UnpackingState")
|
||||
public:
|
||||
UnpackingState( StateMachine *machine ) :State( machine, "UnpackingState" )
|
||||
{
|
||||
m_framesRemaining = 0;
|
||||
}
|
||||
virtual StateReturnType update();
|
||||
virtual StateReturnType onEnter();
|
||||
virtual void onExit( StateExitType status );
|
||||
protected:
|
||||
// snapshot interface
|
||||
virtual void crc( Xfer *xfer );
|
||||
virtual void xfer( Xfer *xfer );
|
||||
virtual void loadPostProcess();
|
||||
|
||||
private:
|
||||
UnsignedInt m_framesRemaining; //frames till unpacking animation complete
|
||||
};
|
||||
EMPTY_DTOR(UnpackingState)
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
enum
|
||||
{
|
||||
UNPACKING = 1000, ///< Kneel down and set up internet satellite link
|
||||
HACK_INTERNET, ///< Once set up, start hacking for cash.
|
||||
PACKING, ///< Pack up before moving.
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HackInternetAIUpdateModuleData : public AIUpdateModuleData
|
||||
{
|
||||
public:
|
||||
UnsignedInt m_unpackTime;
|
||||
UnsignedInt m_packTime;
|
||||
UnsignedInt m_cashUpdateDelay;
|
||||
UnsignedInt m_regularCashAmount;
|
||||
UnsignedInt m_veteranCashAmount;
|
||||
UnsignedInt m_eliteCashAmount;
|
||||
UnsignedInt m_heroicCashAmount;
|
||||
UnsignedInt m_xpPerCashUpdate;
|
||||
Real m_packUnpackVariationFactor;
|
||||
|
||||
HackInternetAIUpdateModuleData()
|
||||
{
|
||||
m_unpackTime = 0;
|
||||
m_packTime = 0;
|
||||
m_cashUpdateDelay = 0;
|
||||
m_regularCashAmount = 0;
|
||||
m_veteranCashAmount = 0;
|
||||
m_eliteCashAmount = 0;
|
||||
m_heroicCashAmount = 0;
|
||||
m_xpPerCashUpdate = 0;
|
||||
m_packUnpackVariationFactor = 0.0f;
|
||||
}
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p)
|
||||
{
|
||||
AIUpdateModuleData::buildFieldParse(p);
|
||||
|
||||
static const FieldParse dataFieldParse[] =
|
||||
{
|
||||
{ "UnpackTime", INI::parseDurationUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_unpackTime ) },
|
||||
{ "PackTime", INI::parseDurationUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_packTime ) },
|
||||
{ "PackUnpackVariationFactor", INI::parseReal, NULL, offsetof( HackInternetAIUpdateModuleData, m_packUnpackVariationFactor ) },
|
||||
{ "CashUpdateDelay", INI::parseDurationUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_cashUpdateDelay ) },
|
||||
{ "RegularCashAmount", INI::parseUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_regularCashAmount ) },
|
||||
{ "VeteranCashAmount", INI::parseUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_veteranCashAmount ) },
|
||||
{ "EliteCashAmount", INI::parseUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_eliteCashAmount ) },
|
||||
{ "HeroicCashAmount", INI::parseUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_heroicCashAmount ) },
|
||||
{ "XpPerCashUpdate", INI::parseUnsignedInt, NULL, offsetof( HackInternetAIUpdateModuleData, m_xpPerCashUpdate ) },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
p.add(dataFieldParse);
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
class HackInternetAIInterface
|
||||
{
|
||||
public:
|
||||
virtual Bool isHacking() const = 0;
|
||||
virtual Bool isHackingPackingOrUnpacking() const = 0;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HackInternetAIUpdate : public AIUpdateInterface, public HackInternetAIInterface
|
||||
{
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HackInternetAIUpdate, "HackInternetAIUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( HackInternetAIUpdate, HackInternetAIUpdateModuleData )
|
||||
|
||||
private:
|
||||
|
||||
public:
|
||||
HackInternetAIUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void aiDoCommand(const AICommandParms* parms);
|
||||
|
||||
UnsignedInt getUnpackTime() const { return getHackInternetAIUpdateModuleData()->m_unpackTime; }
|
||||
UnsignedInt getPackTime() const { return getHackInternetAIUpdateModuleData()->m_packTime; }
|
||||
Real getPackUnpackVariationFactor() const { return getHackInternetAIUpdateModuleData()->m_packUnpackVariationFactor; }
|
||||
UnsignedInt getCashUpdateDelay() const { return getHackInternetAIUpdateModuleData()->m_cashUpdateDelay; }
|
||||
UnsignedInt getRegularCashAmount() const { return getHackInternetAIUpdateModuleData()->m_regularCashAmount; }
|
||||
UnsignedInt getVeteranCashAmount() const { return getHackInternetAIUpdateModuleData()->m_veteranCashAmount; }
|
||||
UnsignedInt getEliteCashAmount() const { return getHackInternetAIUpdateModuleData()->m_eliteCashAmount; }
|
||||
UnsignedInt getHeroicCashAmount() const { return getHackInternetAIUpdateModuleData()->m_heroicCashAmount; }
|
||||
UnsignedInt getXpPerCashUpdate() const { return getHackInternetAIUpdateModuleData()->m_xpPerCashUpdate; }
|
||||
|
||||
void hackInternet();
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
virtual Bool isIdle() const;
|
||||
|
||||
virtual HackInternetAIInterface* getHackInternetAIInterface() { return this; }
|
||||
virtual const HackInternetAIInterface* getHackInternetAIInterface() const { return this; }
|
||||
|
||||
virtual Bool isHacking() const;
|
||||
virtual Bool isHackingPackingOrUnpacking() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual AIStateMachine* makeStateMachine();
|
||||
|
||||
AICommandParmsStorage m_pendingCommand;
|
||||
Bool m_hasPendingCommand;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: HealContain.h ////////////////////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day
|
||||
// Desc: Objects that are contained inside a heal contain ... get healed! oh my!
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HEALCONTAIN_H_
|
||||
#define __HEALCONTAIN_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/OpenContain.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HealContainModuleData : public OpenContainModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
HealContainModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
UnsignedInt m_framesForFullHeal; ///< time (in frames) something becomes fully healed
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
/** The healing container ... bright white light ahhhhh goes here */
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HealContain : public OpenContain
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HealContain, "HealContain" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( HealContain, HealContainModuleData )
|
||||
|
||||
public:
|
||||
|
||||
HealContain( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update(); ///< called once per frame
|
||||
virtual Bool isHealContain() const { return true; } ///< true when container only contains units while healing (not a transport!)
|
||||
|
||||
protected:
|
||||
|
||||
Bool doHeal( Object *obj, UnsignedInt framesForFullHeal ); ///< do the heal on an object
|
||||
|
||||
};
|
||||
|
||||
#endif // end __HEALCONTAIN_H_
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: HealCrateCollide.h /////////////////////////////////////////////////////////////////////////
|
||||
// Author: Graham Smallwood, March 2002
|
||||
// Desc: A crate that heals everything owned by the collider
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef HEAL_CRATE_COLLIDE_H_
|
||||
#define HEAL_CRATE_COLLIDE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/Module.h"
|
||||
#include "GameLogic/Module/CrateCollide.h"
|
||||
|
||||
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
|
||||
class Thing;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HealCrateCollide : public CrateCollide
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HealCrateCollide, "HealCrateCollide" )
|
||||
MAKE_STANDARD_MODULE_MACRO( HealCrateCollide );
|
||||
|
||||
public:
|
||||
|
||||
HealCrateCollide( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
protected:
|
||||
|
||||
/// This is the game logic execution function that all real CrateCollides will implement
|
||||
virtual Bool executeCrateBehavior( Object *other );
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: HeightDieUpdate.h ////////////////////////////////////////////////////////////////////////
|
||||
// Author: Objects that will die when the are a certain height above the terrain or objects
|
||||
// Desc: Colin Day, April 2002
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HEIGHTDIEUPDATE_H_
|
||||
#define __HEIGHTDIEUPDATE_H_
|
||||
|
||||
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
|
||||
#include "GameLogic/Module/UpdateModule.h"
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HeightDieUpdateModuleData: public UpdateModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
HeightDieUpdateModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse& p);
|
||||
|
||||
Real m_targetHeightAboveTerrain; ///< die at this height above terrain
|
||||
Bool m_targetHeightIncludesStructures; ///< target height considers terrain AND structure height underneath us
|
||||
Bool m_onlyWhenMovingDown; ///< don't detonate unless moving in downward z dir
|
||||
Real m_destroyAttachedParticlesAtHeight; ///< HACK, destroy any attached particle system of object when below this height
|
||||
Bool m_snapToGroundOnDeath; ///< snap to the ground when killed
|
||||
UnsignedInt m_initialDelay; ///< Don't explode before this time
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HeightDieUpdate : public UpdateModule
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HeightDieUpdate, "HeightDieUpdate" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( HeightDieUpdate, HeightDieUpdateModuleData )
|
||||
|
||||
public:
|
||||
|
||||
HeightDieUpdate( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
|
||||
Bool m_hasDied; ///< TRUE once we have triggered death
|
||||
Bool m_particlesDestroyed; ///< TRUE once we destroy attached systems (so we do it only once)
|
||||
Coord3D m_lastPosition; ///< we record our last position for logic that needs to know our direction of travel
|
||||
UnsignedInt m_earliestDeathFrame; ///< Earliest we are allowed to think about dying
|
||||
|
||||
};
|
||||
|
||||
#endif // end __HEIGHTDIEUPDATE_H_
|
||||
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
** Command & Conquer Generals(tm)
|
||||
** Copyright 2025 Electronic Arts Inc.
|
||||
**
|
||||
** This program 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.
|
||||
**
|
||||
** This program is distributed in the hope that it will be useful,
|
||||
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
** GNU General Public License for more details.
|
||||
**
|
||||
** You should have received a copy of the GNU General Public License
|
||||
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// //
|
||||
// (c) 2001-2003 Electronic Arts Inc. //
|
||||
// //
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// FILE: HelicopterSlowDeathUpdate.h //////////////////////////////////////////////////////////////
|
||||
// Author: Colin Day, March 2002
|
||||
// Desc: Helicoptor slow deaths
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef __HelicopterSlowDeathBehavior_H_
|
||||
#define __HelicopterSlowDeathBehavior_H_
|
||||
|
||||
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
|
||||
#include "Common/AudioEventRTS.h"
|
||||
#include "GameLogic/Module/SlowDeathBehavior.h"
|
||||
|
||||
// FORWARD DECLARATIONS ///////////////////////////////////////////////////////////////////////////
|
||||
class ParticleSystemTemplate;
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HelicopterSlowDeathBehaviorModuleData : public SlowDeathBehaviorModuleData
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
HelicopterSlowDeathBehaviorModuleData( void );
|
||||
|
||||
static void buildFieldParse(MultiIniFieldParse &p );
|
||||
|
||||
Real m_spiralOrbitTurnRate; ///< (rads per frame) rate at which we do big circles down toward the ground
|
||||
Real m_spiralOrbitForwardSpeed; ///< (dist per frame) speed at which we move "forward" in the downward spiral
|
||||
Real m_spiralOrbitForwardSpeedDamping;///< every frame our forward speed in the orbit is adjusted by this amount
|
||||
Real m_minSelfSpin; ///< (rads per frame) min turning rate at which we spin around our center of gravity
|
||||
Real m_maxSelfSpin; ///< (rads per frame) max turning rate at which we spin around our center of gravity
|
||||
Real m_selfSpinUpdateDelay; ///< (frames) every this many frames we will update the self spin angle, but we'll keep it inbetween the min and max self spin
|
||||
Real m_selfSpinUpdateAmount; ///< (radian) when we update the self spin every SelfSpinUpdateDelay frames, we change it this much, but keep it between min and max self spin
|
||||
Real m_fallHowFast; ///< a fraction of gravity we use to modify the helicopert locmotor lift
|
||||
Real m_minBladeFlyOffDelay; ///< (frames) min frame that the blade will fly off at
|
||||
Real m_maxBladeFlyOffDelay; ///< (frames) max frame that the blade will fly off at
|
||||
const ParticleSystemTemplate *m_attachParticleSystem; ///< particle system to attach
|
||||
AsciiString m_attachParticleBone; ///< bone to attach particle system to
|
||||
Coord3D m_attachParticleLoc; ///< loc attach particle system to if bone not present
|
||||
AsciiString m_bladeObjectName; ///< object name of the blade piece
|
||||
AsciiString m_bladeBone; ///< bone name of main propeller blade
|
||||
const ObjectCreationList *m_oclEjectPilot; ///< OCL for ejecting pilot
|
||||
const FXList *m_fxBlade; ///< blade fly off event fx list
|
||||
const ObjectCreationList *m_oclBlade; ///< OCL at blade fly off event
|
||||
const FXList *m_fxHitGround; ///< fx for hitting the ground
|
||||
const ObjectCreationList *m_oclHitGround; ///< OCL at hit ground event
|
||||
const FXList *m_fxFinalBlowUp; ///< the final blow up
|
||||
const ObjectCreationList *m_oclFinalBlowUp;///< OCL at final blow up event
|
||||
Real m_delayFromGroundToFinalDeath; ///< (frames) delay from when we hit the ground to final BOOM!
|
||||
AsciiString m_finalRubbleObject; ///< final rubble object to create after it's ALL over
|
||||
Real m_maxBraking; ///< max braking we may use during death spiral
|
||||
|
||||
// @todo propagate this up to SlowDeathBehaviorModuleData. I don't wanna do it today, cause its 4/3. jkmcd
|
||||
AudioEventRTS m_deathSound; ///< Sound played during death sequence.
|
||||
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
class HelicopterSlowDeathBehavior : public SlowDeathBehavior
|
||||
{
|
||||
|
||||
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HelicopterSlowDeathBehavior, "HelicopterSlowDeathBehavior" )
|
||||
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( HelicopterSlowDeathBehavior, HelicopterSlowDeathBehaviorModuleData )
|
||||
|
||||
public:
|
||||
|
||||
HelicopterSlowDeathBehavior( Thing *thing, const ModuleData* moduleData );
|
||||
// virtual destructor prototype provided by memory pool declaration
|
||||
|
||||
virtual void beginSlowDeath( const DamageInfo *damageInfo ); ///< begin the slow death cycle
|
||||
virtual UpdateSleepTime update();
|
||||
|
||||
protected:
|
||||
|
||||
Int m_orbitDirection; ///< -1 or +1 ... use ORBIT_DIRECTION_LEFT/RIGHT
|
||||
Real m_forwardAngle; /**< angle of the direction "forward" we want to move in our downspin
|
||||
which is independent of the actual direction angle of the object */
|
||||
Real m_forwardSpeed; ///< the speed we're travelling forward in our spiral orbit
|
||||
Real m_selfSpin; ///< rads per frame that we change our facing direction
|
||||
Bool m_selfSpinTowardsMax; ///< TRUE when our self spin rate is increasing towards the MaxSelfSpin
|
||||
UnsignedInt m_lastSelfSpinUpdateFrame; ///< frame we last updated the self spin on
|
||||
UnsignedInt m_bladeFlyOffFrame; ///< frame we throw the blade off at
|
||||
UnsignedInt m_hitGroundFrame; ///< frame we hit the ground on
|
||||
|
||||
// @todo propagate this up to SlowDeathBehavior. I don't wanna do it today, cause its 4/3. jkmcd
|
||||
AudioEventRTS m_deathSound; ///< Sound played during death sequence.
|
||||
|
||||
};
|
||||
|
||||
#endif // end __HelicopterSlowDeathBehavior_H_
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user