Initial commit of Command & Conquer Generals and Command & Conquer Generals Zero Hour source code.

This commit is contained in:
LFeenanEA 2025-02-27 17:34:39 +00:00
parent 2e338c00cb
commit 3d0ee53a05
No known key found for this signature in database
GPG key ID: C6EBE8C2EA08F7E0
6072 changed files with 2283311 additions and 0 deletions

View 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_

View 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_

View file

@ -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_

View file

@ -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_

View 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. //
// //
////////////////////////////////////////////////////////////////////////////////
// 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

View file

@ -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

View 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: 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_

View file

@ -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

View file

@ -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_

View file

@ -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_

View file

@ -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_

View file

@ -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

View file

@ -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

View 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

View file

@ -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_

View 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_

View file

@ -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_

View 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: 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_

View file

@ -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_

View file

@ -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_

View file

@ -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_

View 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_

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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_

View file

@ -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

View 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. //
// //
////////////////////////////////////////////////////////////////////////////////
// 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

View file

@ -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

View 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: 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_

View 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_

View 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_

View 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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_

View 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. //
// //
////////////////////////////////////////////////////////////////////////////////
// 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

View file

@ -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_

View file

@ -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

View 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

View 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

View file

@ -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_

View file

@ -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_

View 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: 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

View 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: 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

View 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_

View file

@ -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_

View file

@ -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_

View file

@ -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_

View file

@ -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_

View 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: 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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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_

View file

@ -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_

View file

@ -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

View file

@ -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

View file

@ -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_

View file

@ -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_

View file

@ -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_

View file

@ -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_

View file

@ -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

View 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: 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_

View file

@ -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

View file

@ -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_

View 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: 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_

View file

@ -0,0 +1,62 @@
/*
** 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: HighlanderBody.h ////////////////////////////////////////////////////////////////////////
// Author: Graham Smallwood, November 2002
// Desc: Takes damage according to armor, but can't die from normal damage. Can die from Unresistable though
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __HIGHLANDER_BODY_H
#define __HIGHLANDER_BODY_H
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/ActiveBody.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Object;
//-------------------------------------------------------------------------------------------------
/** Structure body module */
//-------------------------------------------------------------------------------------------------
class HighlanderBody : public ActiveBody
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HighlanderBody, "HighlanderBody" )
MAKE_STANDARD_MODULE_MACRO( HighlanderBody )
public:
HighlanderBody( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual void attemptDamage( DamageInfo *damageInfo ); ///< try to damage this object
protected:
};
#endif

View file

@ -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: HijackerUpdate.h /////////////////////////////////////////////////////////////////////////
// Author: Mark Lorenzen, July 2002
// Desc: Allows hijacker to keep with his hijacked vehicle (though hidden) until it dies, then
// to become a hijacker once more
//
/////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __HIJACKER_UPDATE_H
#define __HIJACKER_UPDATE_H
#include "GameLogic/Module/UpdateModule.h"
//-------------------------------------------------------------------------------------------------
class HijackerUpdateModuleData : public UpdateModuleData
{
public:
AsciiString m_attachToBone;
AsciiString m_parachuteName;
//StickBombUpdateModuleData();
static void buildFieldParse(MultiIniFieldParse& p)
{
UpdateModuleData::buildFieldParse(p);
static const FieldParse dataFieldParse[] =
{
{ "AttachToTargetBone", INI::parseAsciiString, NULL, offsetof( HijackerUpdateModuleData, m_attachToBone ) },
{ "ParachuteName", INI::parseAsciiString, NULL, offsetof( HijackerUpdateModuleData, m_parachuteName ) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
}
};
//-------------------------------------------------------------------------------------------------
class HijackerUpdate : public UpdateModule
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HijackerUpdate, "HijackerUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( HijackerUpdate, HijackerUpdateModuleData )
public:
HijackerUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual UpdateSleepTime update(); ///< called once per frame
void setTargetObject( const Object *object );
Object* getTargetObject() const;
void setUpdate(Bool u ) {m_update = u;}
void setIsInVehicle(Bool i ) {m_isInVehicle = i;}
private:
ObjectID m_targetID;
Coord3D m_ejectPos;
Bool m_update;
Bool m_isInVehicle;
Bool m_wasTargetAirborne;
// DieModuleInterface *m_ejectPilotDMI; // point to ejectpilotdiemodule
// of target vehicle if it has one
};
#endif // __HIJACKER_UPDATE_H

View file

@ -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: HiveStructureBody.h //////////////////////////////////////////////////////////////////////////
// Author: Kris Morness, October 2002
// Desc: Hive structure bodies are structure bodies with the ability to propagate specified
// damage types to slaves when available. If there are no slaves, the the structure
// will take the damage.
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __HIVE_STRUCTURE_BODY_H
#define __HIVE_STRUCTURE_BODY_H
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/StructureBody.h"
#include "GameLogic/Damage.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Object;
class HiveStructureBodyModuleData : public StructureBodyModuleData
{
public:
DamageTypeFlags m_damageTypesToPropagateToSlaves;
DamageTypeFlags m_damageTypesToSwallow; ///< A subset of the damage types to propagate. Do not take them ourselves
HiveStructureBodyModuleData();
static void buildFieldParse(MultiIniFieldParse& p)
{
StructureBodyModuleData::buildFieldParse(p);
static const FieldParse dataFieldParse[] =
{
{ "PropagateDamageTypesToSlavesWhenExisting", INI::parseDamageTypeFlags, NULL, offsetof( HiveStructureBodyModuleData, m_damageTypesToPropagateToSlaves ) },
{ "SwallowDamageTypesIfSlavesNotExisting", INI::parseDamageTypeFlags, NULL, offsetof( HiveStructureBodyModuleData, m_damageTypesToSwallow ) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
}
};
//-------------------------------------------------------------------------------------------------
/** Structure body module */
//-------------------------------------------------------------------------------------------------
class HiveStructureBody : public StructureBody
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HiveStructureBody, "HiveStructureBody" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( HiveStructureBody, HiveStructureBodyModuleData )
public:
HiveStructureBody( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
protected:
virtual void attemptDamage( DamageInfo *damageInfo ); ///< try to damage this object
};
#endif // __HIVE_STRUCTURE_BODY_H

View file

@ -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: HordeUpdate.h //////////////////////////////////////////////////////////////////////////
// Author: Steven Johnson, Feb 2002
// Desc: Horde update module
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __HordeUpdate_H_
#define __HordeUpdate_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/UpdateModule.h"
#include "Common/KindOf.h"
class SimpleObjectIterator;
class UpgradeTemplate;
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
enum HordeActionType
{
HORDEACTION_HORDE = 0,
HORDEACTION_COUNT
};
#ifdef DEFINE_HORDEACTION_NAMES
static const char *TheHordeActionTypeNames[] =
{
"HORDE",
NULL
};
#endif
//-------------------------------------------------------------------------------------------------
class HordeUpdateModuleData : public ModuleData
{
public:
UnsignedInt m_updateRate; ///< how often to recheck our horde status
KindOfMaskType m_kindof; ///< the kind(s) of units that count towards horde-ness
Int m_minCount; ///< min count to get "horde" status
Real m_minDist; ///< min dist to contribute to horde-ness
Bool m_alliesOnly; ///< if true, only allied units count towards hordeness
Bool m_exactMatch; ///< if true, only exact same type of units count towards hordeness
Real m_rubOffRadius;///< If I am this close to another guy who is a true hordesman, it'll rub off on me
HordeActionType m_action; ///< what to do if we get horde-ness
std::vector<AsciiString> m_flagSubObjNames; ///< name(s) of the flag subobj
HordeUpdateModuleData();
static void buildFieldParse(MultiIniFieldParse& p);
private:
};
// ------------------------------------------------------------------------------------------------
class HordeUpdateInterface
{
public:
virtual Bool isInHorde() const = 0;
virtual Bool hasFlag() const = 0;
virtual Bool isTrueHordeMember() const = 0;
};
//-------------------------------------------------------------------------------------------------
class HordeUpdate : public UpdateModule, public HordeUpdateInterface
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( HordeUpdate, "HordeUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( HordeUpdate, HordeUpdateModuleData )
public:
HordeUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
HordeUpdateInterface *getHordeUpdateInterface() { return this; }
virtual void onDrawableBoundToObject();
virtual Bool isInHorde() const { return m_inHorde; }
virtual Bool isTrueHordeMember() const { return m_trueHordeMember && m_inHorde; }
virtual Bool hasFlag() const { return m_hasFlag; }
virtual UpdateSleepTime update(); ///< update this object's AI
protected:
void showHideFlag(Bool show);
void joinOrLeaveHorde(SimpleObjectIterator *iter, Bool join);
private:
UnsignedInt m_lastHordeRefreshFrame; //Just like it sounds
Bool m_inHorde; //I amy be a trueMember, or I may merely inherit hordehood from a neighbor who is
Bool m_trueHordeMember; //meaning, I have enough hordesman near me to qualify
Bool m_hasFlag;
};
#endif // __HordeUpdate_H_

View file

@ -0,0 +1,62 @@
/*
** 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: ImmortalBody.h ////////////////////////////////////////////////////////////////////////
// Author: Graham Smallwood, April 2002
// Desc: Just like Active Body, but won't let health drop below 1
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __IMMORTAL_BODY_H
#define __IMMORTAL_BODY_H
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/ActiveBody.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Object;
//-------------------------------------------------------------------------------------------------
/** Structure body module */
//-------------------------------------------------------------------------------------------------
class ImmortalBody : public ActiveBody
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( ImmortalBody, "ImmortalBody" )
MAKE_STANDARD_MODULE_MACRO( ImmortalBody )
public:
ImmortalBody( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual void internalChangeHealth( Real delta ); ///< change health
protected:
};
#endif // __STRUCTUREBODY_H_

View file

@ -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: InactiveBody.h ///////////////////////////////////////////////////////////////////////////
// Author: Colin Day, November 2001
// Desc: An inactive body module, they are indestructable and largely cannot be
// affected by things in the world.
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __INACTIVEBODY_H_
#define __INACTIVEBODY_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/BodyModule.h"
//-------------------------------------------------------------------------------------------------
/** Inactive body module */
//-------------------------------------------------------------------------------------------------
class InactiveBody : public BodyModule
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( InactiveBody, "InactiveBody" )
MAKE_STANDARD_MODULE_MACRO( InactiveBody )
public:
InactiveBody( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual void attemptDamage( DamageInfo *damageInfo ); ///< try to damage this object
virtual void attemptHealing( DamageInfo *damageInfo ); ///< try to heal this object
virtual Real estimateDamage( DamageInfoInput& damageInfo ) const;
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.
void onVeterancyLevelChanged( VeterancyLevel oldLevel, VeterancyLevel newLevel ) { /* nothing */ }
virtual void setArmorSetFlag(ArmorSetType ast) { /* nothing */ }
virtual void clearArmorSetFlag(ArmorSetType ast) { /* nothing */ }
virtual void internalChangeHealth( Real delta );
private:
Bool m_dieCalled;
};
#endif // __INACTIVEBODY_H_

View file

@ -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: InstantDeathBehavior.h /////////////////////////////////////////////////////////////////////////
// Author: Steven Johnson, Sep 2002
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __InstantDeathBehavior_H_
#define __InstantDeathBehavior_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/DieModule.h"
class FXList;
class ObjectCreationList;
class WeaponTemplate;
class DamageInfo;
//-------------------------------------------------------------------------------------------------
typedef std::vector<const FXList*> FXListVec;
typedef std::vector<const ObjectCreationList*> OCLVec;
typedef std::vector<const WeaponTemplate*> WeaponTemplateVec;
//-------------------------------------------------------------------------------------------------
class InstantDeathBehaviorModuleData : public DieModuleData
{
public:
FXListVec m_fx;
OCLVec m_ocls;
WeaponTemplateVec m_weapons;
InstantDeathBehaviorModuleData();
static void buildFieldParse(MultiIniFieldParse& p);
private:
};
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class InstantDeathBehavior : public DieModule
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( InstantDeathBehavior, "InstantDeathBehavior" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( InstantDeathBehavior, InstantDeathBehaviorModuleData )
public:
InstantDeathBehavior( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
// DieModuleInterface
virtual void onDie( const DamageInfo *damageInfo );
};
#endif // __InstantDeathBehavior_H_

View file

@ -0,0 +1,180 @@
/*
** 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. //
// //
////////////////////////////////////////////////////////////////////////////////
// JetAIUpdate.h //////////
// Author: Steven Johnson, June 2002
#pragma once
#ifndef _JET_AI_UPDATE_H_
#define _JET_AI_UPDATE_H_
#include "Common/STLTypedefs.h"
#include "Common/GameMemory.h"
#include "GameLogic/AIStateMachine.h"
#include "GameLogic/Module/AIUpdate.h"
#ifdef _INTERNAL
// for occasional debugging...
//#pragma optimize("", off)
//#pragma MESSAGE("************************************** WARNING, optimization disabled for debugging purposes")
#endif
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class JetAIUpdateModuleData : public AIUpdateModuleData
{
public:
Real m_outOfAmmoDamagePerSecond; /**< amount of damage to take per SEC (not per frame) when out of ammo
note that it's expressed as a percent of max health, not an absolute */
Real m_takeoffSpeedForMaxLift; ///< percent of speed that gives us max lift
Real m_minHeight; ///< how far off the ground to lift the drawable when taxiing
Real m_parkingOffset; ///< tweaking the park loc
Real m_sneakyOffsetWhenAttacking; ///< our sneaky offset when attacking (or zero)
Bool m_keepsParkingSpaceWhenAirborne; ///< if t, keeps its parking space reservation even when airborne
Bool m_needsRunway; ///< if t, needs runways to takeoff/land
UnsignedInt m_takeoffPause; ///< pre-takeoff pause
LocomotorSetType m_attackingLoco; ///< custom attacking loco
LocomotorSetType m_returningLoco; ///< custom return-for-ammo loco
UnsignedInt m_attackLocoPersistTime; ///< if we have a custom attack loco, it persists for this long after attack is done
UnsignedInt m_attackersMissPersistTime; ///< how long after our attack we continue immunity
UnsignedInt m_lockonTime; ///< time it takes for someone to lock-on to us.
AsciiString m_lockonCursor; ///< template used for lockon.
Real m_lockonInitialDist; ///< how far away the lockon cursor starts.
Real m_lockonFreq;
Real m_lockonAngleSpin; ///< how many times to spin around it
Real m_lockonBlinky;
UnsignedInt m_returnToBaseIdleTime; ///< if we're idle for this long, return to base
JetAIUpdateModuleData();
static void buildFieldParse(MultiIniFieldParse& p);
};
//-------------------------------------------------------------------------------------------------
class JetAIUpdate : public AIUpdateInterface
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( JetAIUpdate, "JetAIUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( JetAIUpdate, JetAIUpdateModuleData )
virtual UpdateSleepTime update();
public:
JetAIUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual void onObjectCreated();
virtual void onDelete();
virtual void aiDoCommand(const AICommandParms* parms);
virtual Bool chooseLocomotorSet(LocomotorSetType wst);
virtual void setLocomotorGoalNone();
virtual Bool isIdle() const;
virtual Bool isAllowedToMoveAwayFromUnit() const;
virtual Bool getSneakyTargetingOffset(Coord3D* offset) const;
virtual void addTargeter(ObjectID id, Bool add);
virtual Bool isTemporarilyPreventingAimSuccess() const;
virtual Bool isDoingGroundMovement() const;
virtual void notifyVictimIsDead();
const Coord3D* friend_getProducerLocation() const { return &m_producerLocation; }
Real friend_getOutOfAmmoDamagePerSecond() const { return getJetAIUpdateModuleData()->m_outOfAmmoDamagePerSecond; }
Bool friend_keepsParkingSpaceWhenAirborne() const { return getJetAIUpdateModuleData()->m_keepsParkingSpaceWhenAirborne; }
Bool friend_needsRunway() const { return getJetAIUpdateModuleData()->m_needsRunway; }
Real friend_getTakeoffSpeedForMaxLift() const { return getJetAIUpdateModuleData()->m_takeoffSpeedForMaxLift; }
Real friend_getMinHeight() const { return getJetAIUpdateModuleData()->m_minHeight; }
Real friend_getParkingOffset() const { return getJetAIUpdateModuleData()->m_parkingOffset; }
UnsignedInt friend_getTakeoffPause() const { return getJetAIUpdateModuleData()->m_takeoffPause; }
void friend_setGoalPath( const std::vector<Coord3D>* path ) { getStateMachine()->setGoalPath(path); }
void friend_setTakeoffInProgress(Bool v) { setFlag(TAKEOFF_IN_PROGRESS, v); }
void friend_setLandingInProgress(Bool v) { setFlag(LANDING_IN_PROGRESS, v); }
void friend_setTaxiInProgress(Bool v) { setFlag(TAXI_IN_PROGRESS, v); }
void friend_setUseSpecialReturnLoco(Bool v) { setFlag(USE_SPECIAL_RETURN_LOCO, v); }
void friend_setAllowCircling(Bool v) { setFlag(ALLOW_CIRCLING, v); }
const Coord3D& friend_getLandingPosForHelipadStuff() const { return m_landingPosForHelipadStuff; }
void friend_enableAfterburners(Bool v);
void friend_setAllowAirLoco(Bool a);
Bool friend_isTakeoffOrLandingInProgress() const
{
return (getFlag(TAKEOFF_IN_PROGRESS) || getFlag(LANDING_IN_PROGRESS));
}
protected:
virtual AIStateMachine* makeStateMachine();
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 privateEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object
virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot
void pruneDeadTargeters();
void positionLockon();
virtual Bool getTreatAsAircraftForLocoDistToGoal() const;
Bool isParkedAt(const Object* obj) const;
private:
enum FlagType
{
HAS_PENDING_COMMAND,
ALLOW_AIR_LOCO,
HAS_PRODUCER_LOCATION,
TAKEOFF_IN_PROGRESS,
LANDING_IN_PROGRESS,
USE_SPECIAL_RETURN_LOCO,
ALLOW_CIRCLING,
ALLOW_INTERRUPT_AND_RESUME_OF_CUR_STATE_FOR_RELOAD,
TAXI_IN_PROGRESS
};
Coord3D m_producerLocation; ///< remember this, so that if our producer dies, we have a place to circle aimlessly
AICommandParmsStorage m_mostRecentCommand;
AudioEventRTS m_afterburnerSound; ///< Sound when afterburners on
UnsignedInt m_attackLocoExpireFrame;
UnsignedInt m_attackersMissExpireFrame;
UnsignedInt m_returnToBaseFrame; ///< if nonzero, return to base at this frame when we are idle, even if not out of ammo
std::list<ObjectID> m_targetedBy; ///< object(s) currently targeting us, if any
UnsignedInt m_untargetableExpireFrame;
Drawable* m_lockonDrawable;
Int m_flags;
Coord3D m_landingPosForHelipadStuff;
Bool m_enginesOn; ///<
void getProducerLocation();
void buildLockonDrawableIfNecessary();
void doLandingCommand(Object *airfield, CommandSourceType cmdSource);
inline Bool getFlag(FlagType f) const { return (m_flags & (1<<f)) != 0; }
inline void setFlag(FlagType f, Bool v) { if (v) m_flags |= (1<<f); else m_flags &= ~(1<<f); }
};
#endif

View file

@ -0,0 +1,110 @@
/*
** 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: JetSlowDeathBehavior.h ///////////////////////////////////////////////////////////////////
// Author: Colin Day
// Desc: Death sequence for jets
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __JET_SLOW_DEATH_BEHAVIOR_H_
#define __JET_SLOW_DEATH_BEHAVIOR_H_
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
#include "Common/AudioEventRTS.h"
#include "GameLogic/Module/BehaviorModule.h"
#include "GameLogic/Module/SlowDeathBehavior.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class FXList;
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class JetSlowDeathBehaviorModuleData : public SlowDeathBehaviorModuleData
{
public:
JetSlowDeathBehaviorModuleData( void );
static void buildFieldParse( MultiIniFieldParse &p );
const FXList *m_fxOnGroundDeath; ///< fx list executed on death when destoyed on ground
const ObjectCreationList *m_oclOnGroundDeath; ///< ocl list executed on death when destroyed on ground
const FXList *m_fxInitialDeath; ///< FXList for initial death
const ObjectCreationList *m_oclInitialDeath; ///< OCL for initial death
UnsignedInt m_delaySecondaryFromInitialDeath; ///< delay (in frames) from initial death, to the secondary event
const FXList *m_fxSecondary; ///< FXList for secondary event
const ObjectCreationList *m_oclSecondary; ///< OCL for secondary event
const FXList *m_fxHitGround; ///< FXList for hit ground
const ObjectCreationList *m_oclHitGround; ///< OCL for hit ground
UnsignedInt m_delayFinalBlowUpFromHitGround; ///< delay (in frames) from hit ground, to final explosion
const FXList *m_fxFinalBlowUp; ///< FxList for final blow up
const ObjectCreationList *m_oclFinalBlowUp; ///< OCL for final blow up
Real m_rollRate; ///< our initial roll rate
Real m_rollRateDelta; ///< how our roll rate changes over time
Real m_pitchRate; ///< spin speed on another axis after hitting the ground
Real m_fallHowFast; ///< a fraction of gravity we use to modify the jet locmotor lift
AudioEventRTS m_deathLoopSound; ///< looping death sound
};
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
class JetSlowDeathBehavior : public SlowDeathBehavior
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( JetSlowDeathBehavior, "JetSlowDeathBehavior" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( JetSlowDeathBehavior, JetSlowDeathBehaviorModuleData )
public:
JetSlowDeathBehavior( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
// slow death methods
virtual void onDie( const DamageInfo *damageInfo );
virtual void beginSlowDeath( const DamageInfo *damageInfo );
virtual UpdateSleepTime update( void );
protected:
UnsignedInt m_timerDeathFrame; ///< fame we died on
UnsignedInt m_timerOnGroundFrame; ///< frame we landed on the ground on
Real m_rollRate; ///< our roll rate
AudioEventRTS m_deathLoopSound; ///< death loop sound
};
#endif // end __JET_SLOW_DEATH_BEHAVIOR_H_

View file

@ -0,0 +1,61 @@
/*
** 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: KeepObjectDie.h /////////////////////////////////////////////////////////////////////////////
// Author: Kris Morness, November 2002
// Desc: Die module for things that want to leave rubble in the world and don't have other die
// modules. This fixes civilian buildings that don't have garrison contains. Garrison
// contains have a die module built in, so these buildings need something. Without it
// they default to the destroydie module which outright removes the object.
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __KEEP_OBJECT_DIE_H_
#define __KEEP_OBJECT_DIE_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/DieModule.h"
#include "Common/INI.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Thing;
class KeepObjectDie : public DieModule
{
MAKE_STANDARD_MODULE_MACRO( KeepObjectDie );
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( KeepObjectDie, "KeepObjectDie" )
public:
KeepObjectDie( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual void onDie( const DamageInfo *damageInfo );
};
#endif // __KEEP_OBJECT_DIE_H_

View file

@ -0,0 +1,112 @@
/*
** 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: LaserUpdate.h //////////////////////////////////////////////////////////////////////////
// Author: Kris Morness, July 2002
// Desc: Handles laser update processing for render purposes and game control.
// Modifications: Kris Morness - Oct 2002 -- moved to Client update (will rename later)
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __LASER_UPDATE_H
#define __LASER_UPDATE_H
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "Common/ClientUpdateModule.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Thing;
class Vector3;
enum ParticleSystemID;
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class LaserUpdateModuleData : public ClientUpdateModuleData
{
public:
AsciiString m_particleSystemName; ///< Used for the muzzle flare while laser active.
AsciiString m_parentFireBoneName; ///< Used to fire laser at specified parent bone position.
Bool m_parentFireBoneOnTurret; ///< And used to specifiy where to look for the bone.
AsciiString m_targetParticleSystemName; ///< Used for the target effect while laser active.
LaserUpdateModuleData();
static void buildFieldParse(MultiIniFieldParse& p);
private:
};
//-------------------------------------------------------------------------------------------------
/** The default update module */
//-------------------------------------------------------------------------------------------------
class LaserUpdate : public ClientUpdateModule
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( LaserUpdate, "LaserUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( LaserUpdate, LaserUpdateModuleData );
public:
LaserUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
//Actually puts the laser in the world.
void initLaser( const Object *parent, const Coord3D *startPos, const Coord3D *endPos, Int sizeDeltaFrames = 0 );
void setDecayFrames( UnsignedInt decayFrames );
const Coord3D* getStartPos() { return &m_startPos; }
const Coord3D* getEndPos() { return &m_endPos; }
Real getCurrentLaserRadius() const;
void setDirty( Bool dirty ) { m_dirty = dirty; }
Bool isDirty() { return m_dirty; }
Real getWidthScale() const { return m_currentWidthScalar; }
virtual void clientUpdate();
protected:
//If the master dies, so will this laser (although if it has a fade delay, it'll just skip to the fade)
Coord3D m_startPos;
Coord3D m_endPos;
Bool m_dirty;
ParticleSystemID m_particleSystemID;
ParticleSystemID m_targetParticleSystemID;
Bool m_widening;
Bool m_decaying;
UnsignedInt m_widenStartFrame;
UnsignedInt m_widenFinishFrame;
Real m_currentWidthScalar;
UnsignedInt m_decayStartFrame;
UnsignedInt m_decayFinishFrame;
};
#endif

View file

@ -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: LifetimeUpdate.h /////////////////////////////////////////////////////////////////////////
// Author: Colin Day, December 2001
// Desc: Update that will count down a lifetime and destroy object when it reaches zero
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __LIFETIMEUPDATE_H_
#define __LIFETIMEUPDATE_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/UpdateModule.h"
//-------------------------------------------------------------------------------------------------
class LifetimeUpdateModuleData : public UpdateModuleData
{
public:
UnsignedInt m_minFrames;
UnsignedInt m_maxFrames;
LifetimeUpdateModuleData()
{
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( LifetimeUpdateModuleData, m_minFrames ) },
{ "MaxLifetime", INI::parseDurationUnsignedInt, NULL, offsetof( LifetimeUpdateModuleData, m_maxFrames ) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
}
};
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class LifetimeUpdate : public UpdateModule
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( LifetimeUpdate, "LifetimeUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( LifetimeUpdate, LifetimeUpdateModuleData )
public:
LifetimeUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
void setLifetimeRange( UnsignedInt minFrames, UnsignedInt maxFrames );
UnsignedInt getDieFrame() const { return m_dieFrame; }
virtual UpdateSleepTime update( void );
private:
UnsignedInt calcSleepDelay(UnsignedInt minFrames, UnsignedInt maxFrames);
UnsignedInt m_dieFrame;
};
#endif // __LIFETIMEUPDATE_H_

View file

@ -0,0 +1,63 @@
/*
** 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: LocomotorSetUpgrade.h /////////////////////////////////////////////////////////////////////////////
// Author: Steven Johnson, Aug 2002
// Desc:
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __LocomotorSetUpgrade_H_
#define __LocomotorSetUpgrade_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/UpgradeModule.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Thing;
//-------------------------------------------------------------------------------------------------
/** The default die module */
//-------------------------------------------------------------------------------------------------
class LocomotorSetUpgrade : public UpgradeModule
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( LocomotorSetUpgrade, "LocomotorSetUpgrade" )
MAKE_STANDARD_MODULE_MACRO( LocomotorSetUpgrade );
public:
LocomotorSetUpgrade( 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 // __LocomotorSetUpgrade_H_

View file

@ -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: MaxHealthUpgrade.h /////////////////////////////////////////////////////////////////////////////
// Author: Kris Morness, September 2002
// Desc: UpgradeModule that increases an object's maximum health.
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __MAX_HEALTH_UPGRADE_H_
#define __MAX_HEALTH_UPGRADE_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/UpgradeModule.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Thing;
enum MaxHealthChangeType;
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
class MaxHealthUpgradeModuleData: public UpgradeModuleData
{
public:
MaxHealthUpgradeModuleData( void );
static void buildFieldParse(MultiIniFieldParse& p);
Real m_addMaxHealth;
MaxHealthChangeType m_maxHealthChangeType;
};
//-------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
class MaxHealthUpgrade : public UpgradeModule
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MaxHealthUpgrade, "MaxHealthUpgrade" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( MaxHealthUpgrade, MaxHealthUpgradeModuleData );
public:
MaxHealthUpgrade( 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_

View file

@ -0,0 +1,146 @@
/*
** 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: MinefieldBehavior.h ////////////////////////////////////////////////////////////////////
// Author: Steven Johnson, June 2002
// Desc: Minefield behavior
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __MinefieldBEHAVIOR_H_
#define __MinefieldBEHAVIOR_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/BehaviorModule.h"
#include "GameLogic/Module/CollideModule.h"
#include "GameLogic/Module/UpdateModule.h"
#include "GameLogic/Module/DamageModule.h"
#include "GameLogic/Module/DieModule.h"
//-------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
class MinefieldBehaviorModuleData : public UpdateModuleData
{
public:
MinefieldBehaviorModuleData();
static void buildFieldParse( MultiIniFieldParse &p );
const WeaponTemplate* m_detonationWeapon; ///< what happens when we detonate
Int m_detonatedBy; ///< can we be triggered by allies, etc?
Bool m_stopsRegenAfterCreatorDies;
Bool m_regenerates; ///< if t, can't be killed normally
Bool m_workersDetonate; ///< if f, workers don't detonate mines
UnsignedInt m_creatorDeathCheckRate; ///< if above is true, how often to check
UnsignedInt m_scootFromStartingPointTime; ///< if nonzero, gradually scoot to dest pt
UnsignedInt m_numVirtualMines; ///< num of "virtual" mines we have
Real m_repeatDetonateMoveThresh;
Real m_healthPercentToDrainPerSecond;
};
//-------------------------------------------------------------------------------------------------
//-------------------------------------------------------------------------------------------------
class MinefieldBehavior : public UpdateModule,
public CollideModuleInterface,
public DamageModuleInterface,
public DieModuleInterface,
public LandMineInterface
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MinefieldBehavior, "MinefieldBehavior" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( MinefieldBehavior, MinefieldBehaviorModuleData )
public:
MinefieldBehavior( Thing *thing, const ModuleData *moduleData );
// virtual destructor prototype provided by memory pool declaration
static Int getInterfaceMask() { return UpdateModule::getInterfaceMask() | (MODULEINTERFACE_COLLIDE) | (MODULEINTERFACE_DAMAGE) | (MODULEINTERFACE_DIE); }
// BehaviorModule
virtual CollideModuleInterface* getCollide() { return this; }
virtual LandMineInterface* getLandMineInterface() { return this; }
virtual DamageModuleInterface* getDamage() { return this; }
virtual DieModuleInterface* getDie() { return this; }
// DamageModuleInterface
virtual void onDamage( DamageInfo *damageInfo );
virtual void onHealing( DamageInfo *damageInfo );
virtual void onBodyDamageStateChange(const DamageInfo* damageInfo, BodyDamageType oldState, BodyDamageType newState) { }
// DieModuleInterface
virtual void onDie( const DamageInfo *damageInfo );
// UpdateModuleInterface
virtual UpdateSleepTime update();
// CollideModuleInterface
virtual void onCollide( Object *other, const Coord3D *loc, const Coord3D *normal );
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; }
// Minefield specific methods
virtual void setScootParms(const Coord3D& start, const Coord3D& end);
virtual void disarm();
private:
// mines are small, so we can get by with a small fixed number here
enum { MAX_IMMUNITY = 3 };
struct ImmuneInfo
{
ObjectID id;
UnsignedInt collideTime;
};
struct DetonatorInfo
{
ObjectID id;
Coord3D where;
};
UnsignedInt m_nextDeathCheckFrame;
UnsignedInt m_scootFramesLeft;
Coord3D m_scootVel;
Coord3D m_scootAccel;
UnsignedInt m_virtualMinesRemaining;
ImmuneInfo m_immunes[MAX_IMMUNITY];
std::vector<DetonatorInfo> m_detonators;
Bool m_ignoreDamage;
Bool m_regenerates;
Bool m_draining;
void detonateOnce(const Coord3D& position);
UpdateSleepTime calcSleepTime();
};
#endif // end __MinefieldBEHAVIOR_H_

View file

@ -0,0 +1,144 @@
/*
** 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: MissileAIUpdate.h
// Author: Michael S. Booth, December 2001
// Desc: Missile behavior
#pragma once
#ifndef _MISSILE_AI_UPDATE_H_
#define _MISSILE_AI_UPDATE_H_
#include "Common/GameType.h"
#include "Common/GlobalData.h"
#include "GameLogic/Module/AIUpdate.h"
#include "GameLogic/WeaponBonusConditionFlags.h"
#include "Common/INI.h"
#include "WWMath/Matrix3D.h"
enum ParticleSystemID;
class FXList;
//-------------------------------------------------------------------------------------------------
class MissileAIUpdateModuleData : public AIUpdateModuleData
{
public:
Bool m_tryToFollowTarget; ///< if true, attack object, not pos
UnsignedInt m_fuelLifetime; ///< num frames till missile runs out of motive power (0 == inf)
UnsignedInt m_ignitionDelay; ///< delay in frames from when missile is 'fired', to when it starts moving 15
Real m_initialVel;
Real m_initialDist;
Real m_diveDistance; ///< If I get this close to my target, start ignoring my preferred height
const FXList* m_ignitionFX; ///< FXList to do when missile 'ignites'
Bool m_useWeaponSpeed; ///< if true, limit speed of projectile to the Weapon's info
Bool m_detonateOnNoFuel; ///< If true, don't just stop thrusting, blow up when out of gas
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_lockDistance; ///< If I get this close to my target, guaranteed hit.
MissileAIUpdateModuleData();
static void buildFieldParse(MultiIniFieldParse& p);
};
//-------------------------------------------------------------------------------------------------
class MissileAIUpdate : public AIUpdateInterface, public ProjectileUpdateInterface
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MissileAIUpdate, "MissileAIUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( MissileAIUpdate, MissileAIUpdateModuleData );
public:
MissileAIUpdate( Thing *thing, const ModuleData* moduleData );
enum MissileStateType // Stored in save file, don't renumber.
{
PRELAUNCH = 0,
LAUNCH = 1, ///< released from launcher, falling
IGNITION = 2, ///< engines ignite
ATTACK_NOTURN = 3, ///< fly toward victim
ATTACK = 4, ///< fly toward victim
DEAD = 5,
KILL = 6, ///< Hit victim (cheat).
KILL_SELF = 7, ///< Destroy self.
};
virtual ProjectileUpdateInterface* getProjectileUpdateInterface() { return this; }
virtual void projectileFireAtObjectOrPosition( const Object *victim, const Coord3D *victimPos, const WeaponTemplate *detWeap, const ParticleSystemTemplate* exhaustSysOverride );
virtual void projectileLaunchAtObjectOrPosition(const Object *victim, const Coord3D* victimPos, const Object *launcher, WeaponSlotType wslot, Int specificBarrelToUse, const WeaponTemplate* detWeap, const ParticleSystemTemplate* exhaustSysOverride);
virtual Bool projectileHandleCollision( Object *other );
virtual Bool projectileIsArmed() const { return m_isArmed; }
virtual ObjectID projectileGetLauncherID() const { return m_launcherID; }
virtual Bool processCollision(PhysicsBehavior *physics, Object *other); ///< Returns true if the physics collide should apply the force. Normally not. jba.
virtual UpdateSleepTime update();
virtual void onDelete( void );
protected:
void detonate();
private:
MissileStateType m_state; ///< the behavior state of the missile
UnsignedInt m_stateTimestamp; ///< time of state change
UnsignedInt m_nextTargetTrackTime; ///< if nonzero, how often we update our target pos
ObjectID m_launcherID; ///< ID of object that launched us (zero if not yet launched)
ObjectID m_victimID; ///< ID of object that launched us (zero if not yet launched)
UnsignedInt m_fuelExpirationDate; ///< how long 'til we run out of fuel
Real m_noTurnDistLeft; ///< when zero, ok to start turning
Real m_maxAccel;
Coord3D m_originalTargetPos; ///< When firing uphill, we aim high to clear the brow of the hill. jba.
Coord3D m_prevPos;
WeaponBonusConditionFlags m_extraBonusFlags;
const WeaponTemplate* m_detonationWeaponTmpl; ///< weapon to fire at end (or null)
const ParticleSystemTemplate* m_exhaustSysTmpl;
ParticleSystemID m_exhaustID; ///< our exhaust particle system (if any)
Bool m_isTrackingTarget; ///< Was I originally shot at a moving object?
Bool m_isArmed; ///< if true, missile will explode on contact
void doPrelaunchState();
void doLaunchState();
void doIgnitionState();
void doAttackState(Bool turnOK);
void doKillState();
void doKillSelfState();
void doDeadState();
void airborneTargetGone(); ///< My airborne target has died, so I have to do something cool to make up for that
void tossExhaust();
void switchToState(MissileStateType s);
};
#endif // _MISSILE_AI_UPDATE_H_

View file

@ -0,0 +1,138 @@
/*
** 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: MissileLauncherBuildingUpdate.h /////////////////////////////////////////////////////////////////////////
// Author: Matthew D. Campbell, April 2002
// Desc: Update will change model state conditions based on special power state
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef _MissileLauncherBuildingUpdate_H_
#define _MissileLauncherBuildingUpdate_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "Common/AudioEventRTS.h"
#include "Common/INI.h"
#include "GameLogic/Module/UpdateModule.h"
class DamageInfo;
class SpecialPowerTemplate;
class SpecialPowerModule;
class FXList;
//-------------------------------------------------------------------------------------------------
class MissileLauncherBuildingUpdateModuleData : public UpdateModuleData
{
public:
SpecialPowerTemplate *m_specialPowerTemplate; ///< pointer to the special power template
UnsignedInt m_doorOpenTime; ///< in frames, time we should take to open the door
UnsignedInt m_doorWaitOpenTime; ///< in frames, time we should leave the door open after firing the superweapon
UnsignedInt m_doorClosingTime; ///< in frames, time it takes to close the door
const FXList *m_openingFX;
const FXList *m_openFX;
const FXList *m_waitingToCloseFX;
const FXList *m_closingFX;
const FXList *m_closedFX;
AudioEventRTS m_openIdleAudio;
MissileLauncherBuildingUpdateModuleData()
{
m_specialPowerTemplate = NULL;
m_doorOpenTime = 0;
m_doorWaitOpenTime = 0;
m_doorClosingTime = 0;
m_openingFX = m_openFX = m_waitingToCloseFX = m_closingFX = m_closedFX = NULL;
}
static void buildFieldParse(MultiIniFieldParse& p)
{
UpdateModuleData::buildFieldParse(p);
static const FieldParse dataFieldParse[] =
{
{ "SpecialPowerTemplate", INI::parseSpecialPowerTemplate, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_specialPowerTemplate ) },
{ "DoorOpenTime", INI::parseDurationUnsignedInt, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_doorOpenTime ) },
{ "DoorWaitOpenTime", INI::parseDurationUnsignedInt, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_doorWaitOpenTime ) },
{ "DoorCloseTime", INI::parseDurationUnsignedInt, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_doorClosingTime ) },
{ "DoorOpeningFX", INI::parseFXList, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_openingFX ) },
{ "DoorOpenFX", INI::parseFXList, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_openFX ) },
{ "DoorWaitingToCloseFX", INI::parseFXList, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_waitingToCloseFX ) },
{ "DoorClosingFX", INI::parseFXList, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_closingFX ) },
{ "DoorClosedFX", INI::parseFXList, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_closedFX ) },
{ "DoorOpenIdleAudio", INI::parseAudioEventRTS, NULL, offsetof( MissileLauncherBuildingUpdateModuleData, m_openIdleAudio ) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
}
};
//-------------------------------------------------------------------------------------------------
class MissileLauncherBuildingUpdate : public UpdateModule, public SpecialPowerUpdateInterface
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MissileLauncherBuildingUpdate, "MissileLauncherBuildingUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( MissileLauncherBuildingUpdate, MissileLauncherBuildingUpdateModuleData )
public:
MissileLauncherBuildingUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
//SpecialPowerUpdateInterface pure virtual implementations
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_doorState != m_timeoutState; }
SpecialPowerTemplate* getTemplate() const;
virtual Bool doesSpecialPowerHaveOverridableDestinationActive() const { return false; }
virtual void setSpecialPowerOverridableDestination( const Coord3D *loc ) {}
virtual SpecialPowerUpdateInterface* getSpecialPowerUpdateInterface() { return this; }
virtual CommandOption getCommandOption() const { return (CommandOption)0; }
virtual UpdateSleepTime update(); ///< Deciding whether or not to make new guys
virtual Bool isPowerCurrentlyInUse( const CommandButton *command = NULL ) const;
private:
enum DoorStateType
{
DOOR_CLOSED,
DOOR_OPENING,
DOOR_OPEN,
DOOR_WAITING_TO_CLOSE,
DOOR_CLOSING,
};
void switchToState(DoorStateType dst);
const SpecialPowerModuleInterface* m_specialPowerModule;
DoorStateType m_doorState;
DoorStateType m_timeoutState;
UnsignedInt m_timeoutFrame;
AudioEventRTS m_openIdleAudio;
};
#endif // _MissileLauncherBuildingUpdate_H_

View file

@ -0,0 +1,137 @@
/*
** 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. //
// //
////////////////////////////////////////////////////////////////////////////////
// MobMemberSlavedUpdate.h /////////////////////////////////////////////////////////////
// Will obey to spawner... or die trying... used by angry mob members
// Author: Mark Lorenzen, August 2002
#pragma once
#ifndef _MOBMEMBER_SLAVED_UPDATE_H_
#define _MOBMEMBER_SLAVED_UPDATE_H_
#define MM_SLAVED_UPDATE_RATE (LOGICFRAMES_PER_SECOND / 8) ///< This is a low priority module that only needs to be called every this many frames
#define MIN_SQUIRRELLINESS (0.01f)
#define MAX_SQUIRRELLINESS (1.0f)
#define CATCH_UP_RADIUS_MAX (50)
#define CATCH_UP_RADIUS_MIN (25)
#define DEFAULT_MUST_CATCH_UP_RADIUS (CATCH_UP_RADIUS_MAX)
#define DEFAULT_NO_NEED_TO_CATCH_UP_RADIUS (CATCH_UP_RADIUS_MIN)
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "Common/INI.h"
#include "GameLogic/Module/UpdateModule.h"
class DamageInfo;
enum ModelConditionFlagType;
//-------------------------------------------------------------------------------------------------
class MobMemberSlavedUpdateModuleData : public UpdateModuleData
{
public:
//Example: Currently used by scout drones owned by rangers AND stinger soldiers owned by stinger sites.
Int m_mustCatchUpRadius; //Distance from master I'm allowed when he's idle. If I go too far away, I'll come back.
Int m_noNeedToCatchUpRadius; //Allowable wander distance from master while guarding master.
Real m_squirrellinessRatio;
UnsignedInt m_catchUpCrisisBailTime; //after this many consecutive frames outside the catchup radius, I will teleport to the nexus
MobMemberSlavedUpdateModuleData()
{
m_mustCatchUpRadius = DEFAULT_MUST_CATCH_UP_RADIUS;
m_noNeedToCatchUpRadius = DEFAULT_NO_NEED_TO_CATCH_UP_RADIUS;
m_squirrellinessRatio = 0;
m_catchUpCrisisBailTime = 999999;//default to very large number
}
static void buildFieldParse(MultiIniFieldParse& p)
{
UpdateModuleData::buildFieldParse(p);
static const FieldParse dataFieldParse[] =
{
{ "MustCatchUpRadius", INI::parseInt, NULL, offsetof( MobMemberSlavedUpdateModuleData, m_mustCatchUpRadius ) },
{ "CatchUpCrisisBailTime", INI::parseUnsignedInt, NULL, offsetof( MobMemberSlavedUpdateModuleData, m_catchUpCrisisBailTime ) },
{ "NoNeedToCatchUpRadius", INI::parseInt, NULL, offsetof( MobMemberSlavedUpdateModuleData, m_noNeedToCatchUpRadius ) },
{ "Squirrelliness", INI::parseReal, NULL, offsetof( MobMemberSlavedUpdateModuleData, m_squirrellinessRatio ) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
}
};
enum MobStates
{
MOB_STATE_NONE,
MOB_STATE_IDLE,
MOB_STATE_CATCHUP_NOW,
MOB_STATE_CATCHING_UP,
MOB_STATE_ATTACK,
};
//-------------------------------------------------------------------------------------------------
class MobMemberSlavedUpdate : public UpdateModule, public SlavedUpdateInterface
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MobMemberSlavedUpdate, "MobMemberSlavedUpdate" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( MobMemberSlavedUpdate, MobMemberSlavedUpdateModuleData )
public:
MobMemberSlavedUpdate( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual SlavedUpdateInterface* getSlavedUpdateInterface() { return this; }// hee hee... behaves just like slavedupdate
virtual ObjectID getSlaverID() const { return m_slaver; }
virtual void onEnslave( const Object *slaver );
virtual void onSlaverDie( const DamageInfo *info );
virtual void onSlaverDamage( const DamageInfo *info );
virtual void onObjectCreated();
virtual Bool isSelfTasking() const { return m_isSelfTasking; };
void doCatchUpLogic( Coord3D *pinnedPosition );
void setMobState( MobStates state ) { m_mobState = state; };
MobStates getMobState( void ) { return m_mobState; };
virtual UpdateSleepTime update(); ///< Deciding whether or not to make new guys
private:
void startSlavedEffects( const Object *slaver ); ///< We have been marked as Slaved, so we can't be selected or move too far or other stuff
void stopSlavedEffects(); ///< We are no longer slaved.
ObjectID m_slaver; ///< To whom we are enslaved
Int m_framesToWait;
MobStates m_mobState;
RGBColor m_personalColor;
ObjectID m_primaryVictimID;
Real m_squirrellinessRatio;
Bool m_isSelfTasking;
UnsignedInt m_catchUpCrisisTimer;// how many consecutive frames have I remained outside the catchup radius
//This is a failsafe to make sure that an individual mobmember does not get isolated from his buddies
// thus causing the mob to become invincible, since they will continue to bud around the nexus
};
#endif //_MOBMEMBER_AI_UPDATE_H_

View 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: MobNexusContain.h ////////////////////////////////////////////////////////////////////////
// Author: Mark Lorenzen, August 2002
// Desc: Contain module for mob units. Acts as proxy for UI and AI
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __MOBNEXUSCONTAIN_H_
#define __MOBNEXUSCONTAIN_H_
// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/OpenContain.h"
//-------------------------------------------------------------------------------------------------
class MobNexusContainModuleData : public OpenContainModuleData
{
public:
struct InitialPayload
{
AsciiString name;
Int count;
};
Int m_slotCapacity; ///< max units that can be inside us
Real m_exitPitchRate;
Bool m_scatterNearbyOnExit;
Bool m_orientLikeContainerOnExit;
Bool m_keepContainerVelocityOnExit;
AsciiString m_exitBone;
InitialPayload m_initialPayload;
Real m_healthRegen;
MobNexusContainModuleData();
static void buildFieldParse(MultiIniFieldParse& p);
static void parseInitialPayload( INI* ini, void *instance, void *store, const void* /*userData*/ );
};
//-------------------------------------------------------------------------------------------------
class MobNexusContain : public OpenContain,
public TransportPassengerInterface // lorenzen add a MobMemberInterface
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MobNexusContain, "MobNexusContain" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( MobNexusContain, MobNexusContainModuleData )
public:
MobNexusContain( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
// lorenzen add a MobMemberInterface
// lorenzen add a MobMemberInterface
// lorenzen add a MobMemberInterface
virtual TransportPassengerInterface* getTransportPassengerInterface() { return this; }// lorenzen add a MobMemberInterface
// lorenzen add a MobMemberInterface
// lorenzen add a MobMemberInterface
// lorenzen add a MobMemberInterface
virtual Bool isValidContainerFor( const Object* obj, Bool checkCapacity) const;
virtual void onContaining( Object *obj ); ///< object now contains 'obj'
virtual void onRemoving( Object *obj ); ///< object no longer contains 'obj'
virtual UpdateSleepTime update(); ///< called once per frame
virtual Int getContainMax( void ) const;
virtual void onObjectCreated();
virtual Int getExtraSlotsInUse( void ) { return m_extraSlotsInUse; }
virtual ExitDoorType reserveDoorForExit( const ThingTemplate* objType, Object *specificObject ); ///< All types can answer if they are free to exit or not, and you can ask about a specific guy or just exit anything in general
virtual void unreserveDoorForExit( ExitDoorType exitDoor );
virtual Bool tryToEvacuate( Bool exposeStealthedUnits ); ///< Will try to kick everybody out with game checks, and will return whether anyone made it
protected:
private:
Int m_extraSlotsInUse;
};
#endif // __MOBNEXUSCONTAIN_H_

View file

@ -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: MoneyCrateCollide.h /////////////////////////////////////////////////////////////////////////
// Author: Graham Smallwood, March 2002
// Desc: A crate that gives x money to the collider
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef MONEY_CRATE_COLLIDE_H_
#define MONEY_CRATE_COLLIDE_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "Common/Module.h"
#include "GameLogic/Module/CrateCollide.h"
// FORWARD REFERENCES /////////////////////////////////////////////////////////////////////////////
class Thing;
//-------------------------------------------------------------------------------------------------
class MoneyCrateCollideModuleData : public CrateCollideModuleData
{
public:
UnsignedInt m_moneyProvided;
MoneyCrateCollideModuleData()
{
m_moneyProvided = 0;
}
static void buildFieldParse(MultiIniFieldParse& p)
{
CrateCollideModuleData::buildFieldParse(p);
static const FieldParse dataFieldParse[] =
{
{ "MoneyProvided", INI::parseUnsignedInt, NULL, offsetof( MoneyCrateCollideModuleData, m_moneyProvided ) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
}
};
//-------------------------------------------------------------------------------------------------
class MoneyCrateCollide : public CrateCollide
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( MoneyCrateCollide, "MoneyCrateCollide" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( MoneyCrateCollide, MoneyCrateCollideModuleData );
public:
MoneyCrateCollide( 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

View 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: NeutronMissileSlowDeathUpdate.h //////////////////////////////////////////////////////////
// Author: Colin Day, April 2002
// Desc: Update module for the neutron missile superweapon object
///////////////////////////////////////////////////////////////////////////////////////////////////
#pragma once
#ifndef __NEUTRONMISSILESlowDeathBehavior_H_
#define __NEUTRONMISSILESlowDeathBehavior_H_
// INCLUDES ///////////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/SlowDeathBehavior.h"
class FXList;
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
enum NeutronBlast
{
NEUTRON_BLAST_1 = 0,
NEUTRON_BLAST_2,
NEUTRON_BLAST_3,
NEUTRON_BLAST_4,
NEUTRON_BLAST_5,
NEUTRON_BLAST_6,
NEUTRON_BLAST_7,
NEUTRON_BLAST_8,
NEUTRON_BLAST_9,
MAX_NEUTRON_BLASTS // keep this last
};
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
struct BlastInfo
{
Bool enabled; ///< this blast is enabled
Real delay; ///< delay after death to start the regular blast
Real scorchDelay; ///< delay after death to start a scorch blast
Real innerRadius; ///< inner radius of damage
Real outerRadius; ///< outer radius of damage
Real maxDamage; ///< max amount
Real minDamage; ///< any object in the outerradius will always have at least this much damage done
Real toppleSpeed; ///< speed to topple things at
Real pushForceMag; ///< magnitude of the physics force to push objects
};
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
class NeutronMissileSlowDeathBehaviorModuleData : public SlowDeathBehaviorModuleData
{
public:
NeutronMissileSlowDeathBehaviorModuleData( void );
static void buildFieldParse(MultiIniFieldParse& p);
BlastInfo m_blastInfo[ MAX_NEUTRON_BLASTS ]; ///< blast information
Real m_scorchSize; ///< size of scorch mark
const FXList *m_fxList; ///< the actual fx list that creates all the visuals.
};
// ------------------------------------------------------------------------------------------------
// ------------------------------------------------------------------------------------------------
class NeutronMissileSlowDeathBehavior : public SlowDeathBehavior
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE( NeutronMissileSlowDeathBehavior, "NeutronMissileSlowDeathBehavior" )
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA( NeutronMissileSlowDeathBehavior, NeutronMissileSlowDeathBehaviorModuleData )
public:
NeutronMissileSlowDeathBehavior( Thing *thing, const ModuleData* moduleData );
// virtual destructor prototype provided by memory pool declaration
virtual UpdateSleepTime update( void ); ///< the update call
protected:
void doBlast( const BlastInfo *blastInfo ); ///< do blast
void doScorchBlast( const BlastInfo *blastInfo ); ///< do a scorch blast ring
UnsignedInt m_activationFrame; ///< frame we were activated on
Bool m_completedBlasts[ MAX_NEUTRON_BLASTS ]; ///< blasts indexes we've already done
Bool m_completedScorchBlasts[ MAX_NEUTRON_BLASTS ]; ///< scorch blast indexes we've already done
Bool m_scorchPlaced; ///< TRUE once we've placed the scorch mark
};
#endif // end __NEUTRONMISSILESlowDeathBehavior_H_

Some files were not shown because too many files have changed in this diff Show more