Skip to content

Commit

Permalink
Fix issues with previous implemented optimizations
Browse files Browse the repository at this point in the history
- Move the optimization patches and related flags to Phobos.h & Phobos.cpp
- Change radiation damage vs. buildings disable to apply based on values of RadApplicationDelay.Building instead of separate key
  - Add a warning about the behaviour regarding this to documentation.
- Fix radiation damage vs. buildings disable and sync logging disable to work correctly with loading a saved game with spawner.
- Fix a build warning
  • Loading branch information
Starkku committed Feb 25, 2025
1 parent 2ff45a0 commit 622f690
Show file tree
Hide file tree
Showing 10 changed files with 100 additions and 96 deletions.
6 changes: 4 additions & 2 deletions docs/New-or-Enhanced-Logics.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,6 @@ SuppressReflectDamage.Types= ; List of AttachEffectTypes
- `RadHasOwner`, if set to true, makes damage dealt by the radiation count as having been dealt by the house that fired the projectile that created the radiation field. This means that Warhead controls such as `AffectsAllies` will be respected and any units killed will count towards that player's destroyed units count.
- `RadHasInvoker`, if set to true, makes the damage dealt by the radiation count as having been dealt by the TechnoType (the 'invoker') that fired the projectile that created the radiation field. In addition to the effects of `RadHasOwner`, this will also grant experience from units killed by the radiation to the invoker. Note that if the invoker dies at any point during the radiation's lifetime it continues to behave as if not having an invoker.
- By default `UseGlobalRadApplicationDelay` is set to true. This makes game always use `RadApplicationDelay` and `RadApplicationDelay.Building` from `[Radiation]` rather than specific radiation types. This is a performance-optimizing measure that should be disabled if a radiation type declares different application delay.
- Setting `DisableRadDamageOnBuildings` to true under `[Radiation]` fully disables functionality of `RadApplicationDelay.Building`, which otherwise affects game performance even if not used. Note that this option cannot be set or changed in map files.

In `rulesmd.ini`:
```ini
Expand All @@ -185,7 +184,6 @@ In `rulesmd.ini`:

[Radiation]
UseGlobalRadApplicationDelay=true ; boolean
DisableRadDamageOnBuildings=false ; boolean

[SOMEWEAPON] ; WeaponType
RadType=Radiation ; RadType to use instead of default of [Radiation]
Expand All @@ -209,6 +207,10 @@ RadHasOwner=false ; boolean
RadHasInvoker=false ; boolean
```

```{warning}
Due to performance concerns, unless any radiation type has `RadApplicationDelay.Building` set to above 0, all functionality related to it is completely disabled in game. This decision is made at earliest available opportunity (at end of initial scenario start or after loading saved game) and will **not** update with further scenario changes or save game loadings during same game session.
```

### Laser Trails

![Laser Trails](_static/images/lasertrails.gif)
Expand Down
2 changes: 1 addition & 1 deletion src/Ext/Anim/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ DEFINE_HOOK(0x4226F6, AnimClass_CTOR, 0x6)
GET(AnimClass*, pItem, ESI);

// Do this here instead of using a duplicate hook in SyncLogger.cpp
if (!SyncLogger::HooksDisabled && pItem->UniqueID != -2)
if (!Phobos::Optimizations::DisableSyncLogging && pItem->UniqueID != -2)
SyncLogger::AddAnimCreationSyncLogEvent(CTORTemp::coords, CTORTemp::callerAddress);

AnimExt::ExtMap.Allocate(pItem);
Expand Down
4 changes: 2 additions & 2 deletions src/Ext/House/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,9 +291,9 @@ int HouseExt::ActiveHarvesterCount(HouseClass* pThis)
int HouseExt::TotalHarvesterCount(HouseClass* pThis)
{
int result = 0;
auto const pExt = HouseExt::ExtMap.Find(pThis);
auto const pHouseExt = HouseExt::ExtMap.Find(pThis);

for (auto const pTechno : pExt->OwnedCountedHarvesters)
for (auto const pTechno : pHouseExt->OwnedCountedHarvesters)
{
auto const pExt = TechnoExt::ExtMap.Find(pTechno);
result += pExt->HasBeenPlacedOnMap;
Expand Down
14 changes: 0 additions & 14 deletions src/Ext/Rules/Body.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,6 @@ void RulesExt::ExtData::LoadBeforeTypeData(RulesClass* pThis, CCINIClass* pINI)
this->AISuperWeaponDelay.Read(exINI, GameStrings::General, "AISuperWeaponDelay");
this->UseGlobalRadApplicationDelay.Read(exINI, GameStrings::Radiation, "UseGlobalRadApplicationDelay");
this->RadApplicationDelay_Building.Read(exINI, GameStrings::Radiation, "RadApplicationDelay.Building");
this->DisableRadDamageOnBuildings.Read(exINI, GameStrings::Radiation, "DisableRadDamageOnBuildings");
this->RadBuildingDamageMaxCount.Read(exINI, GameStrings::Radiation, "RadBuildingDamageMaxCount");
this->RadSiteWarhead_Detonate.Read(exINI, GameStrings::Radiation, "RadSiteWarhead.Detonate");
this->RadSiteWarhead_Detonate_Full.Read(exINI, GameStrings::Radiation, "RadSiteWarhead.Detonate.Full");
Expand Down Expand Up @@ -319,7 +318,6 @@ void RulesExt::ExtData::Serialize(T& Stm)
.Process(this->AISuperWeaponDelay)
.Process(this->UseGlobalRadApplicationDelay)
.Process(this->RadApplicationDelay_Building)
.Process(this->DisableRadDamageOnBuildings)
.Process(this->RadBuildingDamageMaxCount)
.Process(this->RadSiteWarhead_Detonate)
.Process(this->RadSiteWarhead_Detonate_Full)
Expand Down Expand Up @@ -619,15 +617,3 @@ DEFINE_HOOK(0x6744E4, RulesClass_ReadJumpjetControls_Extra, 0x7)

// skip vanilla JumpjetControls and make it earlier load
// DEFINE_JUMP(LJMP, 0x668EB5, 0x668EBD); // RulesClass_Process_SkipJumpjetControls // Really necessary? won't hurt to read again

// After rulesmd.ini has been parsed, before anything else like maps and only once on game init.
DEFINE_HOOK(0x6876B1, ReadScenarioINI_Optimizations, 0x5)
{
auto const pRulesExt = RulesExt::Global();

// Disable BuildingClass_AI_Radiation
if (pRulesExt->DisableRadDamageOnBuildings)
Patch::Apply_RAW(0x43FB23, { 0x53, 0x55, 0x56, 0x8B, 0xF1 });

return 0;
}
3 changes: 0 additions & 3 deletions src/Ext/Rules/Body.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ class RulesExt
Nullable<int> AISuperWeaponDelay;
Valueable<bool> UseGlobalRadApplicationDelay;
Valueable<int> RadApplicationDelay_Building;
Valueable<bool> DisableRadDamageOnBuildings;
Valueable<int> RadBuildingDamageMaxCount;
Valueable<bool> RadSiteWarhead_Detonate;
Valueable<bool> RadSiteWarhead_Detonate_Full;
Expand Down Expand Up @@ -208,7 +207,6 @@ class RulesExt
, AISuperWeaponDelay {}
, UseGlobalRadApplicationDelay { true }
, RadApplicationDelay_Building { 0 }
, DisableRadDamageOnBuildings { false }
, RadBuildingDamageMaxCount { -1 }
, RadSiteWarhead_Detonate { false }
, RadSiteWarhead_Detonate_Full { true }
Expand Down Expand Up @@ -381,5 +379,4 @@ class RulesExt
{
Global()->InvalidatePointer(ptr, removed);
}

};
70 changes: 0 additions & 70 deletions src/Misc/SyncLogging.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
#include <Utilities/GeneralUtils.h>
#include <Utilities/AresHelper.h>

bool SyncLogger::HooksDisabled = false;
int SyncLogger::AnimCreations_HighestX = 0;
int SyncLogger::AnimCreations_HighestY = 0;
int SyncLogger::AnimCreations_HighestZ = 0;
Expand Down Expand Up @@ -458,72 +457,3 @@ DEFINE_HOOK(0x7013A0, TechnoClass_OverrideMission_SyncLog, 0x5)

return 0;
}

// Disable sync logging hooks in non-MP games
DEFINE_HOOK(0x683AB0, ScenarioClass_Start_DisableSyncLog, 0x6)
{
if (SessionClass::IsMultiplayer())
{
Patch::Apply_LJMP(0x55DBCD, 0x55DC99); // Disable MainLoop_SaveGame
return 0;
}

if (SyncLogger::HooksDisabled)
return 0;

SyncLogger::HooksDisabled = true;

Patch::Apply_RAW(0x65C7D0, // Disable Random2Class_Random_SyncLog
{ 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90 }
);

Patch::Apply_RAW(0x65C88A, // Disable Random2Class_RandomRanged_SyncLog
{ 0xC2, 0x08, 0x00, 0x90, 0x90, 0x90 }
);

Patch::Apply_RAW(0x4C9300, // Disable FacingClass_Set_SyncLog
{ 0x83, 0xEC, 0x10, 0x53, 0x56 }
);

Patch::Apply_RAW(0x51B1F0, // Disable InfantryClass_AssignTarget_SyncLog
{ 0x53, 0x56, 0x8B, 0xF1, 0x57 }
);

Patch::Apply_RAW(0x443B90, // Disable BuildingClass_AssignTarget_SyncLog
{ 0x56, 0x8B, 0xF1, 0x57, 0x83, 0xBE, 0xAC, 0x0, 0x0, 0x0, 0x13 }
);

Patch::Apply_RAW(0x6FCDB0, // Disable TechnoClass_AssignTarget_SyncLog
{ 0x83, 0xEC, 0x0C, 0x53, 0x56 }
);

Patch::Apply_RAW(0x41AA80, // Disable AircraftClass_AssignDestination_SyncLog
{ 0x53, 0x56, 0x57, 0x8B, 0x7C, 0x24, 0x10 }
);

Patch::Apply_RAW(0x455D50, // Disable BuildingClass_AssignDestination_SyncLog
{ 0x56, 0x8B, 0xF1, 0x83, 0xBE, 0xAC, 0x0, 0x0, 0x0, 0x13 }
);

Patch::Apply_RAW(0x51AA40, // Disable InfantryClass_AssignDestination_SyncLog
{ 0x83, 0xEC, 0x2C, 0x53, 0x55 }
);

Patch::Apply_RAW(0x741970, // Disable UnitClass_AssignDestination_SyncLog
{ 0x81, 0xEC, 0x80, 0x0, 0x0, 0x0 }
);

Patch::Apply_RAW(0x41BB30, // Disable AircraftClass_OverrideMission_SyncLog
{ 0x8B, 0x81, 0xAC, 0x0, 0x0, 0x0 }
);

Patch::Apply_RAW(0x4D8F40, // Disable FootClass_OverrideMission_SyncLog
{ 0x8B, 0x54, 0x24, 0x4, 0x56 }
);

Patch::Apply_RAW(0x7013A0, // Disable TechnoClass_OverrideMission_SyncLog
{ 0x8B, 0x54, 0x24, 0x4, 0x56 }
);

return 0;
}
1 change: 0 additions & 1 deletion src/Misc/SyncLogging.h
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ class SyncLogger
static void WriteMissionOverrides(FILE* const pLogFile, int frameDigits);
static void WriteAnimCreations(FILE* const pLogFile, int frameDigits);
public:
static bool HooksDisabled;
static int AnimCreations_HighestX;
static int AnimCreations_HighestY;
static int AnimCreations_HighestZ;
Expand Down
6 changes: 6 additions & 0 deletions src/New/Type/RadTypeClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ void RadTypeClass::LoadFromINI(CCINIClass* pINI)
this->SiteWarhead_Detonate_Full.Read(exINI, section, "RadSiteWarhead.Detonate.Full");
this->HasOwner.Read(exINI, section, "RadHasOwner");
this->HasInvoker.Read(exINI, section, "RadHasInvoker");

if (this->GetBuildingApplicationDelay())
Phobos::Optimizations::DisableRadDamageOnBuildings = false;
}

template <typename T>
Expand Down Expand Up @@ -64,6 +67,9 @@ void RadTypeClass::Serialize(T& Stm)
void RadTypeClass::LoadFromStream(PhobosStreamReader& Stm)
{
this->Serialize(Stm);

if (this->GetBuildingApplicationDelay())
Phobos::Optimizations::DisableRadDamageOnBuildings = false;
}

void RadTypeClass::SaveToStream(PhobosStreamWriter& Stm)
Expand Down
81 changes: 78 additions & 3 deletions src/Phobos.cpp
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
#include "Phobos.h"

#include <Drawing.h>
#include <SessionClass.h>
#include <Unsorted.h>

#include <Utilities/Debug.h>
#include <Utilities/Patch.h>
#include <Utilities/Macro.h>
#include <Unsorted.h>

#include "Utilities/AresHelper.h"
#include "Utilities/Parser.h"

Expand All @@ -24,6 +24,10 @@ const char* Phobos::AppIconPath = nullptr;
bool Phobos::DisplayDamageNumbers = false;
bool Phobos::IsLoadingSaveGame = false;

bool Phobos::Optimizations::Applied = false;
bool Phobos::Optimizations::DisableRadDamageOnBuildings = true;
bool Phobos::Optimizations::DisableSyncLogging = false;

#ifdef STR_GIT_COMMIT
const wchar_t* Phobos::VersionDescription = L"Phobos nightly build (" STR_GIT_COMMIT L" @ " STR_GIT_BRANCH L"). DO NOT SHIP IN MODS!";
#elif !defined(IS_RELEASE_VER)
Expand Down Expand Up @@ -73,7 +77,7 @@ void Phobos::CmdLineParse(char** ppArgs, int nNumArgs)
{
auto delimIndex = arg.find("=");
auto value = arg.substr(delimIndex + 1, arg.size() - delimIndex - 1);

bool v = dontSetExceptionHandler;
if (boolParser.TryParse(value.c_str(), &v))
dontSetExceptionHandler = !v;
Expand Down Expand Up @@ -218,6 +222,13 @@ DEFINE_HOOK(0x67E44D, LoadGame_SetFlag, 0x5)
DEFINE_HOOK(0x67E68A, LoadGame_UnsetFlag, 0x5)
{
Phobos::IsLoadingSaveGame = false;
Phobos::ApplyOptimizations();
return 0;
}

DEFINE_HOOK(0x683E7F, ScenarioClass_Start_Optimizations, 0x7)
{
Phobos::ApplyOptimizations();
return 0;
}

Expand Down Expand Up @@ -245,3 +256,67 @@ DEFINE_HOOK(0x4F4583, GScreenClass_DrawText, 0x6)
return 0;
}
#endif

// Mainly used to disable hooks for optimization.
// Called after loading saved game and at end of scenario start after all INI data etc has been initialized.
// Only executed once per game session.
void Phobos::ApplyOptimizations()
{
if (Phobos::Optimizations::Applied)
return;

// Disable BuildingClass_AI_Radiation
if (Phobos::Optimizations::DisableRadDamageOnBuildings)
Patch::Apply_RAW(0x43FB23, { 0x53, 0x55, 0x56, 0x8B, 0xF1 });

if (SessionClass::IsMultiplayer())
{
// Disable MainLoop_SaveGame
Patch::Apply_LJMP(0x55DBCD, 0x55DC99);
}
else
{
// Disable Random2Class_Random_SyncLog
Patch::Apply_RAW(0x65C7D0, { 0xC3, 0x90, 0x90, 0x90, 0x90, 0x90 });

// Disable Random2Class_RandomRanged_SyncLog
Patch::Apply_RAW(0x65C88A, { 0xC2, 0x08, 0x00, 0x90, 0x90, 0x90 });

// Disable FacingClass_Set_SyncLog
Patch::Apply_RAW(0x4C9300, { 0x83, 0xEC, 0x10, 0x53, 0x56 });

// Disable InfantryClass_AssignTarget_SyncLog
Patch::Apply_RAW(0x51B1F0, { 0x53, 0x56, 0x8B, 0xF1, 0x57 });

// Disable BuildingClass_AssignTarget_SyncLog
Patch::Apply_RAW(0x443B90, { 0x56, 0x8B, 0xF1, 0x57, 0x83, 0xBE, 0xAC, 0x0, 0x0, 0x0, 0x13 });

// Disable TechnoClass_AssignTarget_SyncLog
Patch::Apply_RAW(0x6FCDB0, { 0x83, 0xEC, 0x0C, 0x53, 0x56 });

// Disable AircraftClass_AssignDestination_SyncLog
Patch::Apply_RAW(0x41AA80, { 0x53, 0x56, 0x57, 0x8B, 0x7C, 0x24, 0x10 });

// Disable BuildingClass_AssignDestination_SyncLog
Patch::Apply_RAW(0x455D50, { 0x56, 0x8B, 0xF1, 0x83, 0xBE, 0xAC, 0x0, 0x0, 0x0, 0x13 });

// Disable InfantryClass_AssignDestination_SyncLog
Patch::Apply_RAW(0x51AA40, { 0x83, 0xEC, 0x2C, 0x53, 0x55 });

// Disable UnitClass_AssignDestination_SyncLog
Patch::Apply_RAW(0x741970, { 0x81, 0xEC, 0x80, 0x0, 0x0, 0x0 });

// Disable AircraftClass_OverrideMission_SyncLog
Patch::Apply_RAW(0x41BB30, { 0x8B, 0x81, 0xAC, 0x0, 0x0, 0x0 });

// Disable FootClass_OverrideMission_SyncLog
Patch::Apply_RAW(0x4D8F40, { 0x8B, 0x54, 0x24, 0x4, 0x56 });

// Disable TechnoClass_OverrideMission_SyncLog
Patch::Apply_RAW(0x7013A0, { 0x8B, 0x54, 0x24, 0x4, 0x56 });

Phobos::Optimizations::DisableSyncLogging = true;
}

Phobos::Optimizations::Applied = true;
}
9 changes: 9 additions & 0 deletions src/Phobos.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class Phobos
#ifdef DEBUG
static bool DetachFromDebugger();
#endif
static void ApplyOptimizations();

class UI
{
Expand Down Expand Up @@ -102,4 +103,12 @@ class Phobos
static int CustomGS_ChangeDelay[7];
static int CustomGS_DefaultDelay[7];
};

class Optimizations
{
public:
static bool Applied;
static bool DisableRadDamageOnBuildings;
static bool DisableSyncLogging;
};
};

0 comments on commit 622f690

Please sign in to comment.