diff --git a/Core/GameEngine/Include/Common/GameDefines.h b/Core/GameEngine/Include/Common/GameDefines.h index 627e5c76eab..1bf9f096fcf 100644 --- a/Core/GameEngine/Include/Common/GameDefines.h +++ b/Core/GameEngine/Include/Common/GameDefines.h @@ -23,8 +23,60 @@ // Note: Retail compatibility must not be broken before this project officially does. // Use RETAIL_COMPATIBLE_CRC and RETAIL_COMPATIBLE_XFER_SAVE to guard breaking changes. -#ifndef PRESERVE_RETAIL_BEHAVIOR -#define PRESERVE_RETAIL_BEHAVIOR (1) // Retain behavior present in retail Generals 1.08 and Zero Hour 1.04 +#ifndef PRESERVE_BUILDING_RESUMPTION_DELAY +#define PRESERVE_BUILDING_RESUMPTION_DELAY (0) // The fix for this unfavorable behavior was approved by the Game Design Committee. +#endif + +#ifndef PRESERVE_CHINOOK_PASSENGER_DUMPING +#define PRESERVE_CHINOOK_PASSENGER_DUMPING (1) +#endif + +#ifndef PRESERVE_HARDCODED_BLACK_LOTUS_CASH_HACK +#define PRESERVE_HARDCODED_BLACK_LOTUS_CASH_HACK (1) +#endif + +#ifndef PRESERVE_MULTI_CRATE_PICKUP +#define PRESERVE_MULTI_CRATE_PICKUP (0) // The fix for this unfavorable behavior was approved by the Game Design Committee. +#endif + +#ifndef PRESERVE_NO_XP_FROM_FLAME_KILLS +#define PRESERVE_NO_XP_FROM_FLAME_KILLS (0) // The fix for this unfavorable behavior was approved by the Game Design Committee. +#endif + +#ifndef PRESERVE_NO_XP_FROM_OCL_KILLS +#define PRESERVE_NO_XP_FROM_OCL_KILLS (1) +#endif + +#ifndef PRESERVE_NO_XP_FROM_POISON_KILLS +#define PRESERVE_NO_XP_FROM_POISON_KILLS (1) +#endif + +#ifndef PRESERVE_OCCUPANT_DETECTION_VIA_DRAG_SELECTION +#define PRESERVE_OCCUPANT_DETECTION_VIA_DRAG_SELECTION (1) +#endif + +#ifndef PRESERVE_PERPETUAL_HORDE_BONUS +#define PRESERVE_PERPETUAL_HORDE_BONUS (1) +#endif + +#ifndef PRESERVE_PREMATURE_BATTLE_BUS_DEATH +#define PRESERVE_PREMATURE_BATTLE_BUS_DEATH (1) +#endif + +#ifndef PRESERVE_RADAR_WARNING_SUPPRESSION +#define PRESERVE_RADAR_WARNING_SUPPRESSION (1) +#endif + +#ifndef PRESERVE_STRUCTURE_STEALTH_DURING_REPAIR +#define PRESERVE_STRUCTURE_STEALTH_DURING_REPAIR (0) // The fix for this unfavorable behavior was approved by the Game Design Committee. +#endif + +#ifndef PRESERVE_TUNNEL_HEAL_STACKING +#define PRESERVE_TUNNEL_HEAL_STACKING (1) +#endif + +#ifndef PRESERVE_UNRELIABLE_FIRESTORMS +#define PRESERVE_UNRELIABLE_FIRESTORMS (0) // The fix for this unfavorable behavior was approved by the Game Design Committee. #endif #ifndef PRESERVE_RETAIL_SCRIPTED_CAMERA @@ -70,6 +122,10 @@ #define ENABLE_GAMETEXT_SUBSTITUTES (1) // The code can provide substitute texts when labels and strings are missing in the STR or CSF translation file #endif +#ifndef ALLOW_MONEY_PER_MINUTE_FOR_PLAYER +#define ALLOW_MONEY_PER_MINUTE_FOR_PLAYER (0) // When enabled, a money-per-minute stat is calculated and displayed in-game +#endif + // Previously the configurable shroud sat behind #if defined(RTS_DEBUG) // Enable the configurable shroud to properly draw the terrain in World Builder without RTS_DEBUG compiled in. // Disable the configurable shroud to make shroud hacking a bit less accessible in Release game builds. diff --git a/Core/GameEngine/Source/Common/System/Radar.cpp b/Core/GameEngine/Source/Common/System/Radar.cpp index b9e91fe4d9e..313b8f36e47 100644 --- a/Core/GameEngine/Source/Common/System/Radar.cpp +++ b/Core/GameEngine/Source/Common/System/Radar.cpp @@ -1189,7 +1189,7 @@ Bool Radar::tryEvent( RadarEventType event, const Coord3D *pos ) const Real distSquared = sqr(m_event[ i ].worldLoc.x - pos->x) + sqr(m_event[ i ].worldLoc.y - pos->y); Bool isClose = distSquared <= closeEnoughDistanceSq; - #if PRESERVE_RETAIL_BEHAVIOR + #if PRESERVE_RADAR_WARNING_SUPPRESSION // TheSuperHackers @tweak Preserve retail map-wide suppression for under attack events // because otherwise they trigger way too frequent from cargo planes. isClose |= (event == RADAR_EVENT_UNDER_ATTACK); diff --git a/Core/GameEngine/Source/GameClient/SelectionInfo.cpp b/Core/GameEngine/Source/GameClient/SelectionInfo.cpp index 177139a69ee..e5e273f4722 100644 --- a/Core/GameEngine/Source/GameClient/SelectionInfo.cpp +++ b/Core/GameEngine/Source/GameClient/SelectionInfo.cpp @@ -345,7 +345,7 @@ Bool addDrawableToList( Drawable *draw, void *userData ) if (!pds->drawableListToFill) return FALSE; -#if !RTS_GENERALS || !PRESERVE_RETAIL_BEHAVIOR +#if !RTS_GENERALS || !PRESERVE_OCCUPANT_DETECTION_VIA_DRAG_SELECTION // TheSuperHackers @info // In retail, drag-selecting allows the player to select stealthed objects and objects through the // fog. Some players exploit this bug to determine where an opponent's units are and consider this @@ -376,7 +376,7 @@ Bool addDrawableToList( Drawable *draw, void *userData ) return FALSE; } -#if !RTS_GENERALS && PRESERVE_RETAIL_BEHAVIOR +#if !RTS_GENERALS && PRESERVE_OCCUPANT_DETECTION_VIA_DRAG_SELECTION // TheSuperHackers @info // In retail, hidden objects such as passengers are included here when drag-selected, which causes // enemy selection logic to exit early (only 1 enemy unit can be selected at a time). Some players diff --git a/Generals/Code/GameEngine/Include/Common/TunnelTracker.h b/Generals/Code/GameEngine/Include/Common/TunnelTracker.h index 926a4dfbf5d..b8d19cb7197 100644 --- a/Generals/Code/GameEngine/Include/Common/TunnelTracker.h +++ b/Generals/Code/GameEngine/Include/Common/TunnelTracker.h @@ -60,7 +60,7 @@ class TunnelTracker : public MemoryPoolObject, static void destroyObject( Object *obj, void *userData ); ///< Callback for Iterate Contained system static void healObject( Object *obj, void *frames ); ///< Callback for Iterate Contained system -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC void healObjects(Real frames); ///< heal all objects within the tunnel #else void healObjects(); ///< heal all objects within the tunnel diff --git a/Generals/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h b/Generals/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h index 1518dda858f..cc260c0b9d5 100644 --- a/Generals/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h +++ b/Generals/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h @@ -60,7 +60,7 @@ enum HordeActionType CPP_11(: Int) HORDEACTION_COUNT, -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_PERPETUAL_HORDE_BONUS HORDEACTION_DEFAULT = HORDEACTION_HORDE, #else HORDEACTION_DEFAULT = HORDEACTION_HORDE_FIXED, ///< Does not change unmodified retail game behavior, because all its horde update modules explicitly set Action = HORDE. diff --git a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp index b1d0a74241d..10ad9d034fe 100644 --- a/Generals/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/Generals/Code/GameEngine/Source/Common/GlobalData.cpp @@ -448,7 +448,7 @@ GlobalData* GlobalData::m_theOriginal = nullptr; { "CameraAudibleRadius", INI::parseReal, nullptr, offsetof( GlobalData, m_cameraAudibleRadius ) }, { "GroupMoveClickToGatherAreaFactor", INI::parseReal, nullptr, offsetof( GlobalData, m_groupMoveClickToGatherFactor ) }, -#if !PRESERVE_RETAIL_BEHAVIOR +#if ALLOW_MONEY_PER_MINUTE_FOR_PLAYER { "AllowMoneyPerMinuteForPlayer", INI::parseBool, nullptr, offsetof( GlobalData, m_allowMoneyPerMinuteForPlayer ) }, #endif diff --git a/Generals/Code/GameEngine/Source/Common/RTS/ActionManager.cpp b/Generals/Code/GameEngine/Source/Common/RTS/ActionManager.cpp index 8be455a419a..568fa960314 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/ActionManager.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/ActionManager.cpp @@ -482,7 +482,7 @@ Bool ActionManager::canResumeConstructionOf( const Object *obj, // in the future) // Object *builder = TheGameLogic->findObjectByID( objectBeingConstructed->getBuilderID() ); -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_BUILDING_RESUMPTION_DELAY if( builder ) #else // TheSuperHackers @bugfix Stubbjax 18/11/2025 Allow scaffold to be immediately resumed after builder death. diff --git a/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp b/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp index 5a79679d3cb..b4b5d63db75 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/Player.cpp @@ -675,7 +675,7 @@ void Player::update() } } -#if !PRESERVE_RETAIL_BEHAVIOR && !RETAIL_COMPATIBLE_CRC +#if !PRESERVE_TUNNEL_HEAL_STACKING && !RETAIL_COMPATIBLE_CRC // TheSuperHackers @bugfix Stubbjax 26/09/2025 The Tunnel System now heals // all units once per frame instead of once per frame per Tunnel Network. TunnelTracker* tunnelSystem = getTunnelSystem(); diff --git a/Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp b/Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp index aeaef552da2..385d1bf20c7 100644 --- a/Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp +++ b/Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp @@ -277,7 +277,7 @@ void TunnelTracker::destroyObject( Object *obj, void * ) // ------------------------------------------------------------------------ // heal all the objects within the tunnel system using the iterateContained function -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC void TunnelTracker::healObjects(Real frames) { iterateContained(healObject, &frames, FALSE); @@ -301,7 +301,7 @@ void TunnelTracker::healObject( Object *obj, void *frames) { //get the number of frames to heal -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC Real *framesForFullHeal = (Real*)frames; #else UnsignedInt* framesForFullHeal = (UnsignedInt*)frames; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp index dfdbbbb216f..a11b49f5792 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp @@ -158,7 +158,7 @@ void PoisonedBehavior::startPoisonedEffects( const DamageInfo *damageInfo ) // We are going to take the damage dealt by the original poisoner every so often for a while. m_poisonDamageAmount = damageInfo->out.m_actualDamageDealt; -#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_RETAIL_BEHAVIOR +#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_NO_XP_FROM_POISON_KILLS // TheSuperHackers @bugfix Stubbjax 03/09/2025 Allow poison damage to award xp to the poison source. m_poisonSource = damageInfo->in.m_sourceID; #endif diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp index 473d932cdfe..ed8e846cfe1 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp @@ -593,7 +593,7 @@ void ActiveBody::attemptHealing( DamageInfo *damageInfo ) //(object pointer loses scope as soon as atteptdamage's caller ends) m_lastDamageInfo = *damageInfo; m_lastDamageCleared = false; -#if PRESERVE_RETAIL_BEHAVIOR +#if PRESERVE_STRUCTURE_STEALTH_DURING_REPAIR m_lastDamageTimestamp = TheGameLogic->getFrame(); #endif m_lastHealingTimestamp = TheGameLogic->getFrame(); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp index c85cbed40f1..0856934e280 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp @@ -50,7 +50,7 @@ CrateCollideModuleData::CrateCollideModuleData() m_executeAnimationFades = TRUE; m_isBuildingPickup = FALSE; m_isHumanOnlyPickup = FALSE; - m_allowMultiPickup = (PRESERVE_RETAIL_BEHAVIOR != 0); + m_allowMultiPickup = (PRESERVE_MULTI_CRATE_PICKUP != 0); m_executeFX = nullptr; m_pickupScience = SCIENCE_INVALID; m_executionAnimationTemplate = AsciiString::TheEmptyString; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp index bef8b3fc454..82ac87c314a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp @@ -437,7 +437,7 @@ UpdateSleepTime TunnelContain::update() if (controllingPlayer) { TunnelTracker *tunnelSystem = controllingPlayer->getTunnelSystem(); -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC if (tunnelSystem) { const TunnelContainModuleData* modData = getTunnelContainModuleData(); diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp index 3595649c6f3..0e802efaadb 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp @@ -1340,7 +1340,7 @@ class GenericObjectCreationNugget : public ObjectCreationNugget } } -#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_RETAIL_BEHAVIOR +#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_NO_XP_FROM_OCL_KILLS ObjectID sinkID = sourceObj->getExperienceTracker()->getExperienceSink(); firstObject->getExperienceTracker()->setExperienceSink(sinkID != INVALID_ID ? sinkID : sourceObj->getID()); #endif diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp index 325f703b879..2c0091b0c53 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp @@ -1195,7 +1195,7 @@ void ChinookAIUpdate::aiDoCommand(const AICommandParms* parms) { const Real THRESH = 3.0f; const Real THRESH_SQR = THRESH*THRESH; -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_CHINOOK_PASSENGER_DUMPING const bool allowExit = true; #else // TheSuperHackers @bugfix Stubbjax 04/11/2025 Passengers are no longer all dumped in a single frame. diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp index 93efc9e418a..85783ba4a4f 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp @@ -108,7 +108,7 @@ void FlammableUpdate::onDamage( DamageInfo *damageInfo ) m_flameDamageLimit = getFlammableUpdateModuleData()->m_flameDamageLimitData; } m_lastFlameDamageDealt = now; -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_NO_XP_FROM_FLAME_KILLS m_flameSource = getObject()->getID(); #else // TheSuperHackers @bugfix Stubbjax 03/09/2025 Allow flame damage to award xp to the flame source. diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp index 0b7bde5b4fa..453331703eb 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp @@ -1338,7 +1338,7 @@ void SpecialAbilityUpdate::triggerAbilityEffect() if( targetMoney && objectMoney ) { UnsignedInt cash = targetMoney->countMoney(); -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_HARDCODED_BLACK_LOTUS_CASH_HACK UnsignedInt desiredAmount = 1000; #else UnsignedInt desiredAmount = data->m_effectValue; diff --git a/Generals/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp b/Generals/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp index 2fdd9fa4dbf..b9880bcdf1a 100644 --- a/Generals/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp +++ b/Generals/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp @@ -1093,7 +1093,7 @@ UnsignedInt WeaponTemplate::fireWeaponTemplate } //------------------------------------------------------------------------------------------------- -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_UNRELIABLE_FIRESTORMS void WeaponTemplate::trimOldHistoricDamage() const { UnsignedInt expirationDate = TheGameLogic->getFrame() - TheGlobalData->m_historicDamageLimit; @@ -1156,7 +1156,7 @@ static Bool is2DDistSquaredLessThan(const Coord3D& a, const Coord3D& b, Real dis } //------------------------------------------------------------------------------------------------- -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_UNRELIABLE_FIRESTORMS void WeaponTemplate::processHistoricDamage(const Object* source, const Coord3D* pos) const { // diff --git a/GeneralsMD/Code/GameEngine/Include/Common/TunnelTracker.h b/GeneralsMD/Code/GameEngine/Include/Common/TunnelTracker.h index d9a7976a468..b1e3f5bf492 100644 --- a/GeneralsMD/Code/GameEngine/Include/Common/TunnelTracker.h +++ b/GeneralsMD/Code/GameEngine/Include/Common/TunnelTracker.h @@ -60,7 +60,7 @@ class TunnelTracker : public MemoryPoolObject, static void destroyObject( Object *obj, void *userData ); ///< Callback for Iterate Contained system static void healObject( Object *obj, void *frames ); ///< Callback for Iterate Contained system -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC void healObjects(Real frames); ///< heal all objects within the tunnel #else void healObjects(); ///< heal all objects within the tunnel diff --git a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h index 3270a9f7ab2..1ed0ab47bc6 100644 --- a/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h +++ b/GeneralsMD/Code/GameEngine/Include/GameLogic/Module/HordeUpdate.h @@ -60,7 +60,7 @@ enum HordeActionType CPP_11(: Int) HORDEACTION_COUNT, -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_PERPETUAL_HORDE_BONUS HORDEACTION_DEFAULT = HORDEACTION_HORDE, #else HORDEACTION_DEFAULT = HORDEACTION_HORDE_FIXED, ///< Does not change unmodified retail game behavior, because all its horde update modules explicitly set Action = HORDE. diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp index ae9ee6c14db..31d8be1105d 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/GlobalData.cpp @@ -448,7 +448,7 @@ GlobalData* GlobalData::m_theOriginal = nullptr; { "CameraAudibleRadius", INI::parseReal, nullptr, offsetof( GlobalData, m_cameraAudibleRadius ) }, { "GroupMoveClickToGatherAreaFactor", INI::parseReal, nullptr, offsetof( GlobalData, m_groupMoveClickToGatherFactor ) }, -#if !PRESERVE_RETAIL_BEHAVIOR +#if ALLOW_MONEY_PER_MINUTE_FOR_PLAYER { "AllowMoneyPerMinuteForPlayer", INI::parseBool, nullptr, offsetof( GlobalData, m_allowMoneyPerMinuteForPlayer ) }, #endif diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/ActionManager.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/ActionManager.cpp index 71faac30efa..565d796b558 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/ActionManager.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/ActionManager.cpp @@ -487,7 +487,7 @@ Bool ActionManager::canResumeConstructionOf( const Object *obj, // in the future) // Object *builder = TheGameLogic->findObjectByID( objectBeingConstructed->getBuilderID() ); -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_BUILDING_RESUMPTION_DELAY if( builder ) #else // TheSuperHackers @bugfix Stubbjax 18/11/2025 Allow scaffold to be immediately resumed after builder death. diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp index 27a3caec6ec..a9a53e3a006 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/Player.cpp @@ -716,7 +716,7 @@ void Player::update() } } -#if !PRESERVE_RETAIL_BEHAVIOR && !RETAIL_COMPATIBLE_CRC +#if !PRESERVE_TUNNEL_HEAL_STACKING && !RETAIL_COMPATIBLE_CRC // TheSuperHackers @bugfix Stubbjax 26/09/2025 The Tunnel System now heals // all units once per frame instead of once per frame per Tunnel Network. TunnelTracker* tunnelSystem = getTunnelSystem(); diff --git a/GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp b/GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp index 097014fa665..5e1de31615e 100644 --- a/GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp +++ b/GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp @@ -278,7 +278,7 @@ void TunnelTracker::destroyObject( Object *obj, void * ) // ------------------------------------------------------------------------ // heal all the objects within the tunnel system using the iterateContained function -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC void TunnelTracker::healObjects(Real frames) { iterateContained(healObject, &frames, FALSE); @@ -302,7 +302,7 @@ void TunnelTracker::healObject( Object *obj, void *frames) { //get the number of frames to heal -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC Real *framesForFullHeal = (Real*)frames; #else UnsignedInt* framesForFullHeal = (UnsignedInt*)frames; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp index 8f3e43f28e8..c593952333a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Behavior/PoisonedBehavior.cpp @@ -159,7 +159,7 @@ void PoisonedBehavior::startPoisonedEffects( const DamageInfo *damageInfo ) // We are going to take the damage dealt by the original poisoner every so often for a while. m_poisonDamageAmount = damageInfo->out.m_actualDamageDealt; -#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_RETAIL_BEHAVIOR +#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_NO_XP_FROM_POISON_KILLS // TheSuperHackers @bugfix Stubbjax 03/09/2025 Allow poison damage to award xp to the poison source. m_poisonSource = damageInfo->in.m_sourceID; #endif diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp index 2647a4544b6..550d5bba1e1 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/ActiveBody.cpp @@ -842,7 +842,7 @@ void ActiveBody::attemptHealing( DamageInfo *damageInfo ) //(object pointer loses scope as soon as atteptdamage's caller ends) m_lastDamageInfo = *damageInfo; m_lastDamageCleared = false; -#if PRESERVE_RETAIL_BEHAVIOR +#if PRESERVE_STRUCTURE_STEALTH_DURING_REPAIR m_lastDamageTimestamp = TheGameLogic->getFrame(); #endif m_lastHealingTimestamp = TheGameLogic->getFrame(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp index 157f93a0263..a6101fae710 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Body/UndeadBody.cpp @@ -81,7 +81,7 @@ void UndeadBody::attemptDamage( DamageInfo *damageInfo ) if( damageInfo->in.m_damageType != DAMAGE_UNRESISTABLE && !m_isSecondLife -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_PREMATURE_BATTLE_BUS_DEATH && damageInfo->in.m_amount >= getHealth() #else // TheSuperHackers @bugfix Stubbjax 20/09/2025 Battle Buses now correctly apply damage modifiers when calculating lethal damage diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp index 005d0240fc8..01decec3f0a 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Collide/CrateCollide/CrateCollide.cpp @@ -53,7 +53,7 @@ CrateCollideModuleData::CrateCollideModuleData() m_executeAnimationFades = TRUE; m_isBuildingPickup = FALSE; m_isHumanOnlyPickup = FALSE; - m_allowMultiPickup = (PRESERVE_RETAIL_BEHAVIOR != 0); + m_allowMultiPickup = (PRESERVE_MULTI_CRATE_PICKUP != 0); m_executeFX = nullptr; m_pickupScience = SCIENCE_INVALID; m_executionAnimationTemplate = AsciiString::TheEmptyString; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp index c15eefa1712..aa6a5f1aa5d 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp @@ -549,7 +549,7 @@ UpdateSleepTime TunnelContain::update() if (controllingPlayer) { TunnelTracker *tunnelSystem = controllingPlayer->getTunnelSystem(); -#if PRESERVE_RETAIL_BEHAVIOR || RETAIL_COMPATIBLE_CRC +#if PRESERVE_TUNNEL_HEAL_STACKING || RETAIL_COMPATIBLE_CRC if (tunnelSystem) { const TunnelContainModuleData* modData = getTunnelContainModuleData(); diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp index 1c359715f0e..892c1f120ab 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/ObjectCreationList.cpp @@ -1428,7 +1428,7 @@ class GenericObjectCreationNugget : public ObjectCreationNugget } } -#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_RETAIL_BEHAVIOR +#if !RETAIL_COMPATIBLE_CRC && !PRESERVE_NO_XP_FROM_OCL_KILLS ObjectID sinkID = sourceObj->getExperienceTracker()->getExperienceSink(); firstObject->getExperienceTracker()->setExperienceSink(sinkID != INVALID_ID ? sinkID : sourceObj->getID()); #endif diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp index 76ac5e844e7..8ce9bff6ba1 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp @@ -1330,7 +1330,7 @@ void ChinookAIUpdate::aiDoCommand(const AICommandParms* parms) { const Real THRESH = 3.0f; const Real THRESH_SQR = THRESH*THRESH; -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_CHINOOK_PASSENGER_DUMPING const bool allowExit = true; #else // TheSuperHackers @bugfix Stubbjax 04/11/2025 Passengers are no longer all dumped in a single frame. diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp index fc544dd5084..c3f51b6934c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/FlammableUpdate.cpp @@ -108,7 +108,7 @@ void FlammableUpdate::onDamage( DamageInfo *damageInfo ) m_flameDamageLimit = getFlammableUpdateModuleData()->m_flameDamageLimitData; } m_lastFlameDamageDealt = now; -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_NO_XP_FROM_FLAME_KILLS m_flameSource = getObject()->getID(); #else // TheSuperHackers @bugfix Stubbjax 03/09/2025 Allow flame damage to award xp to the flame source. diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp index d785c5d9d9b..fbbc907f31b 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/SpecialAbilityUpdate.cpp @@ -1484,7 +1484,7 @@ void SpecialAbilityUpdate::triggerAbilityEffect() if( targetMoney && objectMoney ) { UnsignedInt cash = targetMoney->countMoney(); -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_HARDCODED_BLACK_LOTUS_CASH_HACK UnsignedInt desiredAmount = 1000; #else UnsignedInt desiredAmount = data->m_effectValue; diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp index 4a2f3625093..d5322eea49f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/StealthUpdate.cpp @@ -312,7 +312,7 @@ Bool StealthUpdate::allowedToStealth( Object *stealthOwner ) const if( flags & STEALTH_NOT_WHILE_TAKING_DAMAGE && self->getBodyModule()->getLastDamageTimestamp() >= now - 1 ) { -#if PRESERVE_RETAIL_BEHAVIOR +#if PRESERVE_STRUCTURE_STEALTH_DURING_REPAIR //Only if it's not healing damage. if( self->getBodyModule()->getLastDamageInfo()->in.m_damageType != DAMAGE_HEALING ) #endif diff --git a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp index da4ef34b952..deef23cd706 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp @@ -1171,7 +1171,7 @@ UnsignedInt WeaponTemplate::fireWeaponTemplate } //------------------------------------------------------------------------------------------------- -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_UNRELIABLE_FIRESTORMS void WeaponTemplate::trimOldHistoricDamage() const { UnsignedInt expirationDate = TheGameLogic->getFrame() - TheGlobalData->m_historicDamageLimit; @@ -1234,7 +1234,7 @@ static Bool is2DDistSquaredLessThan(const Coord3D& a, const Coord3D& b, Real dis } //------------------------------------------------------------------------------------------------- -#if RETAIL_COMPATIBLE_CRC || PRESERVE_RETAIL_BEHAVIOR +#if RETAIL_COMPATIBLE_CRC || PRESERVE_UNRELIABLE_FIRESTORMS void WeaponTemplate::processHistoricDamage(const Object* source, const Coord3D* pos) const { //