Skip to content

Commit 0ef19ad

Browse files
authored
feat(cratecollide): Add INI option to allow a crate to be picked up multiple times in one frame (TheSuperHackers#2297)
Add field AllowMultiPickup=Yes/No to a CrateCollide INI module to control the pickup behavior. 'No' represents the Retail behavior, 'Yes' represents the fixed behavior
1 parent f79f6be commit 0ef19ad

4 files changed

Lines changed: 8 additions & 2 deletions

File tree

Generals/Code/GameEngine/Include/GameLogic/Module/CrateCollide.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class CrateCollideModuleData : public CollideModuleData
4747
Bool m_isForbidOwnerPlayer; ///< This crate cannot be picked up by the player of the dead thing that made it.
4848
Bool m_isBuildingPickup; ///< This crate can be picked up by a Building (bypassing AI requirement)
4949
Bool m_isHumanOnlyPickup; ///< Can this crate only be picked up by a human player? (Mission thing)
50+
Bool m_allowMultiPickup; ///< Can this crate be picked up by multiple objects on the same frame?
5051
ScienceType m_pickupScience; ///< Can only be picked up by a unit whose player has this science
5152
FXList *m_executeFX; ///< FXList to play when activated
5253

Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ CrateCollideModuleData::CrateCollideModuleData()
5050
m_executeAnimationFades = TRUE;
5151
m_isBuildingPickup = FALSE;
5252
m_isHumanOnlyPickup = FALSE;
53+
m_allowMultiPickup = (PRESERVE_RETAIL_BEHAVIOR != 0);
5354
m_executeFX = nullptr;
5455
m_pickupScience = SCIENCE_INVALID;
5556
m_executionAnimationTemplate = AsciiString::TheEmptyString;
@@ -68,6 +69,7 @@ void CrateCollideModuleData::buildFieldParse(MultiIniFieldParse& p)
6869
{ "ForbidOwnerPlayer", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_isForbidOwnerPlayer ) },
6970
{ "BuildingPickup", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_isBuildingPickup ) },
7071
{ "HumanOnly", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_isHumanOnlyPickup ) },
72+
{ "AllowMultiPickup", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_allowMultiPickup ) },
7173
{ "PickupScience", INI::parseScience, nullptr, offsetof( CrateCollideModuleData, m_pickupScience ) },
7274
{ "ExecuteFX", INI::parseFXList, nullptr, offsetof( CrateCollideModuleData, m_executeFX ) },
7375
{ "ExecuteAnimation", INI::parseAsciiString, nullptr, offsetof( CrateCollideModuleData, m_executionAnimationTemplate ) },
@@ -164,7 +166,7 @@ Bool CrateCollide::isValidToExecute( const Object *other ) const
164166

165167
// TheSuperHackers @bugfix Stubbjax 09/02/2026 Prevent the crate from being collected multiple times in a single frame.
166168
#if !RETAIL_COMPATIBLE_CRC
167-
if (getObject()->isDestroyed())
169+
if (getObject()->isDestroyed() && !md->m_allowMultiPickup)
168170
return FALSE;
169171
#endif
170172

GeneralsMD/Code/GameEngine/Include/GameLogic/Module/CrateCollide.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class CrateCollideModuleData : public CollideModuleData
4747
Bool m_isForbidOwnerPlayer; ///< This crate cannot be picked up by the player of the dead thing that made it.
4848
Bool m_isBuildingPickup; ///< This crate can be picked up by a Building (bypassing AI requirement)
4949
Bool m_isHumanOnlyPickup; ///< Can this crate only be picked up by a human player? (Mission thing)
50+
Bool m_allowMultiPickup; ///< Can this crate be picked up by multiple objects on the same frame?
5051
ScienceType m_pickupScience; ///< Can only be picked up by a unit whose player has this science
5152
FXList *m_executeFX; ///< FXList to play when activated
5253

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ CrateCollideModuleData::CrateCollideModuleData()
5353
m_executeAnimationFades = TRUE;
5454
m_isBuildingPickup = FALSE;
5555
m_isHumanOnlyPickup = FALSE;
56+
m_allowMultiPickup = (PRESERVE_RETAIL_BEHAVIOR != 0);
5657
m_executeFX = nullptr;
5758
m_pickupScience = SCIENCE_INVALID;
5859
m_executionAnimationTemplate = AsciiString::TheEmptyString;
@@ -71,6 +72,7 @@ void CrateCollideModuleData::buildFieldParse(MultiIniFieldParse& p)
7172
{ "ForbidOwnerPlayer", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_isForbidOwnerPlayer ) },
7273
{ "BuildingPickup", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_isBuildingPickup ) },
7374
{ "HumanOnly", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_isHumanOnlyPickup ) },
75+
{ "AllowMultiPickup", INI::parseBool, nullptr, offsetof( CrateCollideModuleData, m_allowMultiPickup ) },
7476
{ "PickupScience", INI::parseScience, nullptr, offsetof( CrateCollideModuleData, m_pickupScience ) },
7577
{ "ExecuteFX", INI::parseFXList, nullptr, offsetof( CrateCollideModuleData, m_executeFX ) },
7678
{ "ExecuteAnimation", INI::parseAsciiString, nullptr, offsetof( CrateCollideModuleData, m_executionAnimationTemplate ) },
@@ -167,7 +169,7 @@ Bool CrateCollide::isValidToExecute( const Object *other ) const
167169

168170
// TheSuperHackers @bugfix Stubbjax 09/02/2026 Prevent the crate from being collected multiple times in a single frame.
169171
#if !RETAIL_COMPATIBLE_CRC
170-
if (getObject()->isDestroyed())
172+
if (getObject()->isDestroyed() && !md->m_allowMultiPickup)
171173
return FALSE;
172174
#endif
173175

0 commit comments

Comments
 (0)