Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ static PoolSizeRec PoolSizes[] =
{ "MissileAIUpdate", 512, 32 },
{ "DumbProjectileBehavior", 64, 32 },
{ "FreeFallProjectileBehavior", 32, 32 },
{ "JumpjetMissileAIUpdate", 16, 16 },
{ "DestroyDie", 1024, 32 },
{ "UpgradeDie", 128, 32 },
{ "KeepObjectDie", 128, 32 },
Expand Down Expand Up @@ -278,6 +279,7 @@ static PoolSizeRec PoolSizes[] =
{ "TransitionDamageFX", 384, 128 },
{ "TransportAIUpdate", 64, 32 },
{ "TransportContain", 128, 32 },
{ "JumpjetContain", 16, 16 },
{ "RiderChangeContain", 128, 32 },
{ "InternetHackContain", 16, 16 },
{ "TunnelContain", 8, 8 },
Expand Down
4 changes: 4 additions & 0 deletions GeneralsMD/Code/GameEngine/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,7 @@ set(GAMEENGINE_SRC
Include/GameLogic/Module/MaxHealthUpgrade.h
Include/GameLogic/Module/MinefieldBehavior.h
Include/GameLogic/Module/MissileAIUpdate.h
Include/GameLogic/Module/JumpjetMissileAIUpdate.h
Include/GameLogic/Module/MissileLauncherBuildingUpdate.h
Include/GameLogic/Module/MobMemberSlavedUpdate.h
Include/GameLogic/Module/MobNexusContain.h
Expand Down Expand Up @@ -483,6 +484,7 @@ set(GAMEENGINE_SRC
Include/GameLogic/Module/TransportAIUpdate.h
Include/GameLogic/Module/TransportContain.h
Include/GameLogic/Module/TunnelContain.h
Include/GameLogic/Module/JumpjetContain.h
Include/GameLogic/Module/UndeadBody.h
Include/GameLogic/Module/UnitCrateCollide.h
Include/GameLogic/Module/UnpauseSpecialPowerUpgrade.h
Expand Down Expand Up @@ -960,6 +962,7 @@ set(GAMEENGINE_SRC
Source/GameLogic/Object/Contain/RiderChangeContain.cpp
Source/GameLogic/Object/Contain/TransportContain.cpp
Source/GameLogic/Object/Contain/TunnelContain.cpp
Source/GameLogic/Object/Contain/JumpjetContain.cpp
Source/GameLogic/Object/Contain/DroneCarrierContain.cpp
Source/GameLogic/Object/Create/CreateModule.cpp
Source/GameLogic/Object/Create/GrantUpgradeCreate.cpp
Expand Down Expand Up @@ -1026,6 +1029,7 @@ set(GAMEENGINE_SRC
Source/GameLogic/Object/Update/AIUpdate/HackInternetAIUpdate.cpp
Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp
Source/GameLogic/Object/Update/AIUpdate/MissileAIUpdate.cpp
Source/GameLogic/Object/Update/AIUpdate/JumpjetMissileAIUpdate.cpp
Source/GameLogic/Object/Update/AIUpdate/POWTruckAIUpdate.cpp
Source/GameLogic/Object/Update/AIUpdate/RailedTransportAIUpdate.cpp
Source/GameLogic/Object/Update/AIUpdate/RailroadGuideAIUpdate.cpp
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/Common/SpecialPowerType.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ enum SpecialPowerType CPP_11(: Int)

SPECIAL_TOGGLE_DRAWBRIDGE,

SPECIAL_JUMPJET,

SPECIALPOWER_COUNT,
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// NEW CONSTANTS NEED A BEHAVIORTYPE DEFINED IN THE SPECIALPOWER OR return one in getFallbackBehaviorType in ActionManager.cpp
Expand Down
2 changes: 2 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/GameClient/ControlBar.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ enum CommandOption CPP_11(: Int)
USES_MINE_CLEARING_WEAPONSET= 0x00200000, // uses the special mine-clearing weaponset, even if not current
CAN_USE_WAYPOINTS = 0x00400000, // button has option to use a waypoint path
MUST_BE_STOPPED = 0x00800000, // Unit must be stopped in order to be able to use button.
FORMATION_LAUNCH = 0x01000000, // code-only: jumpjet group launch, keep formation offset instead of random scatter.
};

#ifdef DEFINE_COMMAND_OPTION_NAMES
Expand Down Expand Up @@ -132,6 +133,7 @@ static const char *const TheCommandOptionNames[] =
"USES_MINE_CLEARING_WEAPONSET",
"CAN_USE_WAYPOINTS",
"MUST_BE_STOPPED",
"FORMATION_LAUNCH",

nullptr
};
Expand Down
1 change: 1 addition & 0 deletions GeneralsMD/Code/GameEngine/Include/GameLogic/Locomotor.h
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,7 @@ class Locomotor : public MemoryPoolObject, public Snapshot

AsciiString getTemplateName() const { return m_template->m_name;}
Real getMinSpeed() const { return m_template->m_minSpeed;}
Real getMinTurnSpeed() const { return m_template->m_minTurnSpeed;} ///< must be going >= this speed to turn (0 = can turn in place)
Real getAccelPitchLimit() const { return m_template->m_accelPitchLimit;} ///< Maximum amount we will pitch up or down under acceleration (including recoil.)
Real getDecelPitchLimit() const { return m_template->m_decelPitchLimit;} ///< Maximum amount we will pitch down under deceleration (including recoil.)
Real getBounceKick() const { return m_template->m_bounceKick;} ///< How much simulating rough terrain "bounces" a wheel up.
Expand Down
128 changes: 128 additions & 0 deletions GeneralsMD/Code/GameEngine/Include/GameLogic/Module/JumpjetContain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
/*
** Command & Conquer Generals Zero Hour(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: ParachuteContain.h ////////////////////////////////////////////////////////////////////////
// Author: Steven Johnson, March 2002
// Desc: Contain module for transport units.
///////////////////////////////////////////////////////////////////////////////////////////////////

#pragma once

#ifndef __JumpjetContain_H_
#define __JumpjetContain_H_

// USER INCLUDES //////////////////////////////////////////////////////////////////////////////////
#include "GameLogic/Module/OpenContain.h"

enum ModelConditionFlagType;

//-------------------------------------------------------------------------------------------------
class JumpjetContainModuleData : public OpenContainModuleData
{
public:
//Real m_pitchRateMax;
//Real m_rollRateMax;
//Real m_lowAltitudeDamping;
//Real m_paraOpenDist; ///< deploy the parachute when we have traveled this far
//Real m_freeFallDamagePercent;
ModelConditionFlagType m_conditionFlagFlying; ///< ModelConditionState to use when flying
ModelConditionFlagType m_conditionFlagLanding; ///< ModelConditionState to use before landing
Real m_landingDistance; ///< Distance from target to initiate landing state
Bool m_killWhenLandingInWater; ///< Kill the Rider when landing on water
Bool m_killWhenLandingOnCliff; ///< Kill the Rider when landing on cliffs
Bool m_killWhenLandingOnImpassable; ///< Kill the Rider when landing on impassable terrain
Real m_killWhenLandingInWaterSlop; ///< Water Surface offset when killing the rider
//AudioEventRTS m_parachuteOpenSound;

JumpjetContainModuleData();
static void buildFieldParse(MultiIniFieldParse& p);
};

//-------------------------------------------------------------------------------------------------
class JumpjetContain : public OpenContain
{

MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(JumpjetContain, "JumpjetContain")
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA(JumpjetContain, JumpjetContainModuleData)

public:

JumpjetContain(Thing* thing, const ModuleData* moduleData);
// virtual destructor prototype provided by memory pool declaration

//virtual void onDrawableBoundToObject();

virtual Bool isValidContainerFor(const Object* obj, bool checkCapacity) const;
virtual Bool isEnclosingContainerFor(const Object* obj) const { return FALSE; } ///< Does this type of Contain Visibly enclose its contents?
virtual Bool isSpecialZeroSlotContainer() const { return true; }

virtual void onContaining(Object* obj, Bool wasSelected); ///< object now contains 'obj'
virtual void onRemoving(Object* obj); ///< object no longer contains 'obj'

virtual UpdateSleepTime update(); ///< called once per frame

// virtual void containReactToTransformChange();

virtual void onCollide(Object* other, const Coord3D* loc, const Coord3D* normal);
virtual void onDie(const DamageInfo* damageInfo);

// virtual void setOverrideDestination( const Coord3D *override ); ///< Instead of falling peacefully towards a clear spot, I will now aim here

protected:

virtual Bool isFullyEnclosingContainer() const { return false; }
virtual void positionContainedObjectsRelativeToContainer();

private:

void positionRider(Object* obj);
/*void updateBonePositions();
void updateOffsetsFromBones();
void calcSwayMtx(const Coord3D* offset, Matrix3D* mtx);
void setSwayMatrices();

Real m_pitch;
Real m_roll;
Real m_pitchRate;
Real m_rollRate;
Real m_startZ;
Bool m_isLandingOverrideSet;
Coord3D m_landingOverride;
Coord3D m_riderAttachBone;
Coord3D m_riderSwayBone;
Coord3D m_paraAttachBone;
Coord3D m_paraSwayBone;
Coord3D m_riderAttachOffset;
Coord3D m_riderSwayOffset;
Coord3D m_paraAttachOffset;
Coord3D m_paraSwayOffset;
Bool m_needToUpdateRiderBones;
Bool m_needToUpdateParaBones;
Bool m_opened;*/

Bool m_landing;
};

#endif // __JumpjetContain_H_

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*
** Command & Conquer Generals Zero Hour(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 _JUMPJET_MISSILE_AI_UPDATE_H_
#define _JUMPJET_MISSILE_AI_UPDATE_H_

#include "Common/GameType.h"
#include "Common/GlobalData.h"
#include "GameLogic/Module/MissileAIUpdate.h"
//#include "GameLogic/WeaponBonusConditionFlags.h"
#include "Common/INI.h"
//#include "WWMath/Matrix3D.h"

enum ParticleSystemID;
//class FXList;


//-------------------------------------------------------------------------------------------------
class JumpjetMissileAIUpdateModuleData : public MissileAIUpdateModuleData
{
public:
Real m_initialPitchAngle; ///< initial pitch angle the missile will be launched at.
Real m_scatterRadius; ///< max random offset from target
Real m_maxSearchRadius; ///< max radius to search for possible target location
/*Bool m_avoidImpassable; ///< try to avoid impassable cells when finding target
Bool m_avoidWater; ///< try to avoid water when finding target
Bool m_avoidObjects; ///< try to objects when finding target*/
JumpjetMissileAIUpdateModuleData();

static void buildFieldParse(MultiIniFieldParse& p);

};

//-------------------------------------------------------------------------------------------------
class JumpjetMissileAIUpdate : public MissileAIUpdate
{
MEMORY_POOL_GLUE_WITH_USERLOOKUP_CREATE(JumpjetMissileAIUpdate, "JumpjetMissileAIUpdate")
MAKE_STANDARD_MODULE_MACRO_WITH_MODULE_DATA(JumpjetMissileAIUpdate, JumpjetMissileAIUpdateModuleData);

public:
JumpjetMissileAIUpdate(Thing* thing, const ModuleData* moduleData);

virtual void projectileFireAtObjectOrPosition(const Object* victim, const Coord3D* victimPos, const WeaponTemplate* detWeap, const ParticleSystemTemplate* exhaustSysOverride);
virtual Bool projectileHandleCollision(Object* other);
// virtual Bool processCollision(PhysicsBehavior *physics, Object *other); ///< Returns true if the physics collide should apply the force. Normally not. jba.

virtual Bool canLaunchToPosition(const Coord3D* targetPos, Coord3D* newPos, Bool keepFormation = false);

// virtual UpdateSleepTime update();
virtual void onDelete(void);

// Bool isLanding( void );
Real getGoalDistance(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 (INVALID_ID if not yet launched)
ObjectID m_victimID; ///< ID of object that I am rocketing towards (INVALID_ID 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)
UnsignedInt m_framesTillDecoyed; ///< Number of frames before missile will get distracted by decoy countermeasures.
Bool m_isTrackingTarget; ///< Was I originally shot at a moving object?
Bool m_isArmed; ///< if true, missile will explode on contact
Bool m_noDamage; ///< if true, missile will not cause damage when it detonates. (Used for flares).
Bool m_isJammed; ///< No target, just shooting at a scattered position

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);*/

Bool findOffsetPosition(const Coord3D* targetPos, Coord3D* newPos, Real minRadius, Real maxRadius);

};

#endif // _JUMPJET_MISSILE_AI_UPDATE_H_

Original file line number Diff line number Diff line change
Expand Up @@ -118,10 +118,13 @@ class MissileAIUpdate : public AIUpdateInterface, public ProjectileUpdateInterfa
virtual UpdateSleepTime update();
virtual void onDelete( void );

virtual void switchToState(MissileStateType s);

virtual MissileStateType getMissileState() { return m_state; }

protected:

void detonate();
virtual void detonate();

private:

Expand Down Expand Up @@ -157,7 +160,5 @@ class MissileAIUpdate : public AIUpdateInterface, public ProjectileUpdateInterfa
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);


};
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ class SpecialAbilityUpdateModuleData : public UpdateModuleData
Bool m_approachRequiresLOS;
Bool m_needToFaceTarget;
Bool m_persistenceRequiresRecharge;
Bool m_requiresMoveToTurn; ///< if set, orient by moving toward target (for locomotors that can't turn in place) instead of facing in place
Real m_facingAngleTolerance; ///< heading delta (radians) considered "facing target" when m_requiresMoveToTurn

const ParticleSystemTemplate *m_disableFXParticleSystem;
AudioEventRTS m_packSound;
Expand Down Expand Up @@ -113,6 +115,8 @@ class SpecialAbilityUpdateModuleData : public UpdateModuleData
m_preTriggerUnstealthFrames = 0;
m_needToFaceTarget = TRUE;
m_persistenceRequiresRecharge = FALSE;
m_requiresMoveToTurn = FALSE;
m_facingAngleTolerance = 0.1f; // ~5.7 degrees
}

static void buildFieldParse(MultiIniFieldParse& p)
Expand Down Expand Up @@ -159,6 +163,8 @@ class SpecialAbilityUpdateModuleData : public UpdateModuleData
{ "ApproachRequiresLOS", INI::parseBool, nullptr, offsetof( SpecialAbilityUpdateModuleData, m_approachRequiresLOS ) },
{ "NeedToFaceTarget", INI::parseBool, nullptr, offsetof( SpecialAbilityUpdateModuleData, m_needToFaceTarget ) },
{ "PersistenceRequiresRecharge",INI::parseBool, nullptr, offsetof( SpecialAbilityUpdateModuleData, m_persistenceRequiresRecharge ) },
{ "RequiresMoveToTurn", INI::parseBool, nullptr, offsetof( SpecialAbilityUpdateModuleData, m_requiresMoveToTurn ) },
{ "FacingAngleTolerance", INI::parseAngleReal, nullptr, offsetof( SpecialAbilityUpdateModuleData, m_facingAngleTolerance ) },
{ 0, 0, 0, 0 }
};
p.add(dataFieldParse);
Expand Down Expand Up @@ -270,6 +276,7 @@ class SpecialAbilityUpdate : public SpecialPowerUpdateModule
UnsignedInt m_animFrames; //Used for packing/unpacking unit before or after using ability.
ObjectID m_targetID;
Coord3D m_targetPos;
UnsignedInt m_commandOptions; //Command option flags this ability was triggered with (e.g. FORMATION_LAUNCH).
Int m_locationCount;
std::list<ObjectID> m_specialObjectIDList; //The list of special objects
UnsignedInt m_specialObjectEntries; //The size of the list of member Objects
Expand Down
Loading
Loading