From b73551593123863e9fe8f6d981f6fdb5b390eb94 Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Wed, 17 Jul 2024 10:51:15 +0100 Subject: [PATCH 1/2] Headless now calculates planetary shields on CPU Currently planet shields do nothing on Headless as they are emptied out and pretty much turned off as it's not possible to simulate how much energy is inside of them as energyMaxTarget is set to zero as well as isEmpty being set to True. You can start reading more about this here: https://github.com/NebulaModTeam/nebula/issues/668#issuecomment-2227037945 While I totally understand putting 0.95 here for the headless server to assume that the shield is always attempting to be charged to 95% capacity, I believe that this is function over form. I noticed during my testing that the RecalculatePhysicsShape method is no longer called once the variable (0.95 in this instance) became a full 1.0f, this value was read-in from the ComputeShader for PlanetAT's. Setting it to 0.95 seemed to allow the method to be called enough so that the energyMaxTarget was updated quickly enough during the game. --- .../Patches/Dynamic/Dedicated_Server_Patch.cs | 42 ++++++++++++++++--- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs index c47e646f5..8820b8ac4 100644 --- a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs @@ -171,15 +171,47 @@ public static bool UICommunicatorIndicatorOnLateUpdate_Prefix() return false; } - [HarmonyPostfix] + [HarmonyPrefix] [HarmonyPatch(typeof(PlanetATField), nameof(PlanetATField.RecalculatePhysicsShape))] - public static void RecalculatePhysicsShape_Postfix(PlanetATField __instance) + public static bool RecalculatePhysicsShape_Prefix(PlanetATField __instance) { - // vanilla use GPU to calculate the shape of shield that is not fully covered the whole planet - // In this patch it will act as it has been fully covered to make the planet shield effective - if (!__instance.isEmpty) + // If we're the server, let's update the planet shields manually. + // This is required as checks to planetary shields fail, as there is no GPU to simulate the shields + // they become `isEmpty = true`. This causes some checks to fail such as: + // - Relays still landing on a planet when a shield is online + // - Some space to surface weaponry ignoring the shields + if (Multiplayer.IsDedicated) { + if (__instance.generatorCount == 0) + { + __instance.ClearPhysics(); + __instance.energyMaxTarget = 0L; + } + + __instance.CreatePhysics(); __instance.isSpherical = true; + + /* + * This is usually computed on the GPU, No idea what math the GPU does though, so we're shoving 0.95 here. + * On my own testing this goes as low as 0.35 during initial planet shield spin up + * and when it hits 1.0 it seems to stop calling this method. + */ + __instance.energyMaxTarget = (long)(1200000000000.0 * 0.95 + 0.5); + + if (__instance.energy > 0) + { + __instance.isEmpty = false; + } + + // I believe these are used in raycasting tests to see if a relay would hit a shield, so we need them. + if (__instance.colliderHotTicks > 0) + __instance.OpenColliderObject(); + else + __instance.CloseColliderObject(); + + return false; } + + return true; } } From 1832fb07beaee06d934d19fc4d759992a5da30a4 Mon Sep 17 00:00:00 2001 From: AlienXAXS Date: Wed, 17 Jul 2024 22:29:24 +0100 Subject: [PATCH 2/2] Removed dedicated server check --- .../Patches/Dynamic/Dedicated_Server_Patch.cs | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs index 8820b8ac4..430ef278d 100644 --- a/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs +++ b/NebulaPatcher/Patches/Dynamic/Dedicated_Server_Patch.cs @@ -180,38 +180,33 @@ public static bool RecalculatePhysicsShape_Prefix(PlanetATField __instance) // they become `isEmpty = true`. This causes some checks to fail such as: // - Relays still landing on a planet when a shield is online // - Some space to surface weaponry ignoring the shields - if (Multiplayer.IsDedicated) + if (__instance.generatorCount == 0) { - if (__instance.generatorCount == 0) - { - __instance.ClearPhysics(); - __instance.energyMaxTarget = 0L; - } - - __instance.CreatePhysics(); - __instance.isSpherical = true; - - /* - * This is usually computed on the GPU, No idea what math the GPU does though, so we're shoving 0.95 here. - * On my own testing this goes as low as 0.35 during initial planet shield spin up - * and when it hits 1.0 it seems to stop calling this method. - */ - __instance.energyMaxTarget = (long)(1200000000000.0 * 0.95 + 0.5); - - if (__instance.energy > 0) - { - __instance.isEmpty = false; - } - - // I believe these are used in raycasting tests to see if a relay would hit a shield, so we need them. - if (__instance.colliderHotTicks > 0) - __instance.OpenColliderObject(); - else - __instance.CloseColliderObject(); - - return false; + __instance.ClearPhysics(); + __instance.energyMaxTarget = 0L; } - return true; + __instance.CreatePhysics(); + __instance.isSpherical = true; + + /* + * This is usually computed on the GPU, No idea what math the GPU does though, so we're shoving 0.95 here. + * On my own testing this goes as low as 0.35 during initial planet shield spin up + * and when it hits 1.0 it seems to stop calling this method. + */ + __instance.energyMaxTarget = (long)(1200000000000.0 * 0.95 + 0.5); + + if (__instance.energy > 0) + { + __instance.isEmpty = false; + } + + // I believe these are used in raycasting tests to see if a relay would hit a shield, so we need them. + if (__instance.colliderHotTicks > 0) + __instance.OpenColliderObject(); + else + __instance.CloseColliderObject(); + + return false; } }