diff --git a/LowVisibility/LowVisibility/LowVisibility.csproj b/LowVisibility/LowVisibility/LowVisibility.csproj
index c0a37ec..44496e8 100644
--- a/LowVisibility/LowVisibility/LowVisibility.csproj
+++ b/LowVisibility/LowVisibility/LowVisibility.csproj
@@ -37,34 +37,43 @@
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\0Harmony.dll
+ False
False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\Assembly-CSharp.dll
+ False
False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\Assembly-CSharp-firstpass.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\Mods\CustomActivatableEquipment\CustomActivatableEquipment.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\Mods\CustomAmmoCategories\CustomAmmoCategories.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\Mods\CustomComponents\CustomComponents.dll
+ False
False
E:\steam\SteamApps\common\BATTLETECH\Mods\IRBTModUtils\IRBTModUtils.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\Mods\MechEngineer\MechEngineer.dll
+ False
False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\Newtonsoft.Json.dll
+ False
@@ -74,26 +83,33 @@
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\Unity.TextMeshPro.dll
+ False
False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\UnityEngine.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\UnityEngine.AssetBundleModule.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\UnityEngine.CoreModule.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\UnityEngine.ParticleSystemModule.dll
+ False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\UnityEngine.PhysicsModule.dll
+ False
False
E:\steam\SteamApps\common\BATTLETECH\BattleTech_Data\Managed\UnityEngine.UI.dll
+ False
@@ -104,11 +120,13 @@
+
+
diff --git a/LowVisibility/LowVisibility/Object/ActionSemaphore.cs b/LowVisibility/LowVisibility/Object/ActionSemaphore.cs
new file mode 100644
index 0000000..9feffb6
--- /dev/null
+++ b/LowVisibility/LowVisibility/Object/ActionSemaphore.cs
@@ -0,0 +1,64 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace LowVisibility.Object
+{
+ public abstract class ActionSemaphore
+ {
+ protected Func shouldTakeaction;
+
+ protected Action actionToTake;
+
+ protected int counter;
+
+ protected ActionSemaphore(Func shouldTakeaction, Action actionToTake)
+ {
+ this.shouldTakeaction = shouldTakeaction;
+ this.actionToTake = actionToTake;
+ }
+
+ public int Counter => counter;
+
+ public virtual void ResetSemaphore() {
+ counter = 0;
+ }
+
+ public virtual void Enter()
+ {
+ ++counter;
+ if (shouldTakeaction()) {
+ actionToTake();
+ }
+ }
+
+ public virtual void Exit()
+ {
+ --counter;
+ counter = counter < 0 ? 0 : counter;
+ if (shouldTakeaction()) {
+ actionToTake();
+ }
+ }
+
+ public virtual void ResetHard() {
+ counter = 0;
+ if (shouldTakeaction()) {
+ actionToTake();
+ }
+ }
+
+ public virtual void ResetSoft() {
+ while (counter-- > 0) {
+ if (shouldTakeaction()) {
+ actionToTake();
+ }
+ }
+
+ if (counter < 0)
+ ResetHard();
+ }
+ }
+}
diff --git a/LowVisibility/LowVisibility/Object/VisibilityCacheGate.cs b/LowVisibility/LowVisibility/Object/VisibilityCacheGate.cs
new file mode 100644
index 0000000..ce5bba2
--- /dev/null
+++ b/LowVisibility/LowVisibility/Object/VisibilityCacheGate.cs
@@ -0,0 +1,86 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using BattleTech;
+
+namespace LowVisibility.Object
+{
+ ///
+ /// Pool all requests to rebuild the visibility cache into one place.
+ ///
+ public class VisibilityCacheGate : ActionSemaphore
+ {
+ private static VisibilityCacheGate cacheGate = new VisibilityCacheGate();
+
+ private readonly HashSet actors = new HashSet();
+
+ private VisibilityCacheGate()
+ : base(null, null)
+ {
+ shouldTakeaction = () => counter == 0;
+ actionToTake = () =>
+ {
+ List combatants = UnityGameInstance.BattleTechGame.Combat.GetAllLivingCombatants();
+ List uniDirectionalList = new List();
+ List biDirectionalList = new List();
+
+ foreach (ICombatant combatant in combatants)
+ {
+ if (actors.Contains(combatant))
+ {
+ uniDirectionalList.Add(combatant);
+ }
+ else
+ {
+ biDirectionalList.Add(combatant);
+ }
+ }
+
+ foreach (AbstractActor actor in actors)
+ {
+ actor.VisibilityCache?.UpdateCacheReciprocal(biDirectionalList);
+ actor.VisibilityCache?.RebuildCache(uniDirectionalList);
+ }
+
+ actors.Clear();
+ };
+ }
+
+ public static bool Active => cacheGate.counter > 0;
+
+ public static int GetCounter => cacheGate.counter;
+
+ public static void EnterGate()
+ {
+ cacheGate.Enter();
+ }
+
+ public static void ExitGate()
+ {
+ cacheGate.Exit();
+ }
+
+ public static void ExitAll() {
+ cacheGate.ResetHard();
+ }
+
+ public static void Reset() {
+ cacheGate.ResetSemaphore();
+ }
+
+ public static void AddActorToRefresh(AbstractActor actor) {
+ cacheGate.actors.Add(actor);
+ }
+
+ #region Overrides of ActionSemaphore
+
+ public override void ResetSemaphore() {
+ base.ResetSemaphore();
+ actors.Clear();
+ }
+
+ #endregion
+ }
+}
diff --git a/LowVisibility/LowVisibility/Patch/AbstractActorPatches.cs b/LowVisibility/LowVisibility/Patch/AbstractActorPatches.cs
index a12fde5..6467b32 100644
--- a/LowVisibility/LowVisibility/Patch/AbstractActorPatches.cs
+++ b/LowVisibility/LowVisibility/Patch/AbstractActorPatches.cs
@@ -278,5 +278,33 @@ public static void Prefix(AbstractActor __instance) {
}
}
+ [HarmonyPatch(typeof(AbstractActor), nameof(AbstractActor.HandleDeath))]
+ public static class AbstractActor_HandleDeath {
+
+ private static int counter = 0;
+
+ public static bool GateActive = false;
+
+ [HarmonyPriority(900)]
+ public static void Prefix(AbstractActor __instance) {
+ VisibilityCacheGate.EnterGate();
+ GateActive = true;
+ counter = VisibilityCacheGate.GetCounter;
+ }
+
+ [HarmonyPriority(0)]
+ public static void Postfix(AbstractActor __instance) {
+ VisibilityCacheGate.ExitGate();
+ GateActive = false;
+
+ int exitCounter = VisibilityCacheGate.GetCounter;
+ if (exitCounter < counter) {
+ Mod.Log.Debug?.Write($"Reset or unsymmetrical larger number of ExitGate() are call.");
+ }
+ else if (exitCounter > counter) {
+ Mod.Log.Error?.Write($"Fewer calls to ExitGate() than EnterGate().");
+ }
+ }
+ }
}
diff --git a/LowVisibility/LowVisibility/Patch/CombatGameStatePatches.cs b/LowVisibility/LowVisibility/Patch/CombatGameStatePatches.cs
index e96ff4d..19e7be5 100644
--- a/LowVisibility/LowVisibility/Patch/CombatGameStatePatches.cs
+++ b/LowVisibility/LowVisibility/Patch/CombatGameStatePatches.cs
@@ -45,6 +45,7 @@ static void Postfix()
Mod.Log.Trace?.Write("CGS:OCGD - entered.");
ModState.Reset();
+ VisibilityCacheGate.Reset();
}
}
@@ -57,6 +58,11 @@ public static void Postfix()
Mod.Log.Error?.Write($"Something has gone wrong in refreshing visibility cache, resetting.");
EWState.ResetCache();
}
+
+ if (AbstractActor_HandleDeath.GateActive) {
+ Mod.Log.Error?.Write($"Something has gone wrong in handling actor death, resetting VisibilityCacheGate.");
+ VisibilityCacheGate.ExitAll();
+ }
}
}
}
diff --git a/LowVisibility/LowVisibility/Patch/VisibilityCachePatches.cs b/LowVisibility/LowVisibility/Patch/VisibilityCachePatches.cs
index 3ba360e..2c27c13 100644
--- a/LowVisibility/LowVisibility/Patch/VisibilityCachePatches.cs
+++ b/LowVisibility/LowVisibility/Patch/VisibilityCachePatches.cs
@@ -9,40 +9,64 @@
namespace LowVisibility.Patch
{
- [HarmonyPatch(typeof(VisibilityCache), nameof(VisibilityCache.RebuildCache))]
- public static class VisibilityCache_RebuildCache
+ public static class VisibilityCachePatches
{
- // Lowest priority
- [HarmonyPriority(0)]
- public static void Prefix()
- {
- EWState.InBatchProcess = true;
- EWState.EWStateCache.Clear();
- }
+ public delegate AbstractActor OwningActor(VisibilityCache cache);
- // Highest priority
- [HarmonyPriority(900)]
- public static void Postfix()
- {
- EWState.InBatchProcess = false;
- }
- }
+ public static OwningActor GetOwningActor =
+ (OwningActor) Delegate.CreateDelegate(typeof(OwningActor), typeof(VisibilityCache).GetProperty("OwningActor", AccessTools.all).GetMethod);
- [HarmonyPatch(typeof(VisibilityCache), nameof(VisibilityCache.UpdateCacheReciprocal))]
- public static class VisibilityCache_UpdateCacheReciprocal
- {
- // Lowest priority
- [HarmonyPriority(0)]
- public static void Prefix()
+ [HarmonyPatch(typeof(VisibilityCache), nameof(VisibilityCache.RebuildCache))]
+ public static class VisibilityCache_RebuildCache
{
- EWState.InBatchProcess = true;
- EWState.EWStateCache.Clear();
+ // Lowest priority
+ [HarmonyPriority(0)]
+ public static bool Prefix(VisibilityCache __instance)
+ {
+ EWState.InBatchProcess = true;
+ EWState.EWStateCache.Clear();
+
+ if (VisibilityCacheGate.Active)
+ {
+ VisibilityCacheGate.AddActorToRefresh(GetOwningActor(__instance));
+ return false;
+ }
+
+ return true;
+ }
+
+ // Highest priority
+ [HarmonyPriority(900)]
+ public static void Postfix()
+ {
+ EWState.InBatchProcess = false;
+ }
}
- [HarmonyPriority(900)]
- public static void Postfix()
+ [HarmonyPatch(typeof(VisibilityCache), nameof(VisibilityCache.UpdateCacheReciprocal))]
+ public static class VisibilityCache_UpdateCacheReciprocal
{
- EWState.InBatchProcess = false;
+ // Lowest priority
+ [HarmonyPriority(0)]
+ public static bool Prefix(VisibilityCache __instance)
+ {
+ EWState.InBatchProcess = true;
+ EWState.EWStateCache.Clear();
+
+ if (VisibilityCacheGate.Active)
+ {
+ VisibilityCacheGate.AddActorToRefresh(GetOwningActor(__instance));
+ return false;
+ }
+
+ return true;
+ }
+
+ [HarmonyPriority(900)]
+ public static void Postfix()
+ {
+ EWState.InBatchProcess = false;
+ }
}
}
}