From 3b5f2e18b3550c9cab66f1e9e7817761d5a3318c Mon Sep 17 00:00:00 2001 From: gamer147 Date: Sun, 7 Jun 2026 21:11:49 -0400 Subject: [PATCH] refactor(engine-ambient): IsForecast/IsRandomDraw read ambient first, static fallback Step 2 of multi-instancing migration. Both flags now resolve through BattleAmbient.Current when a scope is active, otherwise hit a static fallback that preserves today's behavior unchanged for unwrapped callers. Suite green: SVSim.BattleEngine.Tests pass; SVSim.UnitTests baseline holds. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../BattleAmbientTests.cs | 48 +++++++++++++++++++ .../Engine/BattleManagerBase.cs | 20 +++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/SVSim.BattleEngine.Tests/BattleAmbientTests.cs b/SVSim.BattleEngine.Tests/BattleAmbientTests.cs index 0e29127..efd0f30 100644 --- a/SVSim.BattleEngine.Tests/BattleAmbientTests.cs +++ b/SVSim.BattleEngine.Tests/BattleAmbientTests.cs @@ -81,4 +81,52 @@ public class BattleAmbientTests Assert.That(results[0], Is.EqualTo(100)); Assert.That(results[1], Is.EqualTo(200)); } + + [Test] + public void IsForecast_ReadsAmbient_WhenScopeActive() + { + var ctx = new BattleAmbientContext { IsForecast = false }; + using var _ = BattleAmbient.Enter(ctx); + Assert.That(BattleManagerBase.IsForecast, Is.False); + ctx.IsForecast = true; + Assert.That(BattleManagerBase.IsForecast, Is.True); + } + + [Test] + public void IsForecast_WriteInsideScope_WritesAmbient_NotFallback() + { + var ctx = new BattleAmbientContext { IsForecast = false }; + using (var _ = BattleAmbient.Enter(ctx)) + { + BattleManagerBase.IsForecast = true; + Assert.That(ctx.IsForecast, Is.True); + } + } + + [Test] + public void IsForecast_OutsideScope_FallsBackToStatic() + { + Assert.That(BattleAmbient.Current, Is.Null); + BattleManagerBase.IsForecast = true; + Assert.That(BattleManagerBase.IsForecast, Is.True); + BattleManagerBase.IsForecast = false; + Assert.That(BattleManagerBase.IsForecast, Is.False); + } + + [Test] + public void IsRandomDraw_RoundtripsAmbient_And_Fallback() + { + Assert.That(BattleAmbient.Current, Is.Null); + BattleManagerBase.IsRandomDraw = true; + Assert.That(BattleManagerBase.IsRandomDraw, Is.True); + + var ctx = new BattleAmbientContext { IsRandomDraw = false }; + using (var _ = BattleAmbient.Enter(ctx)) + { + Assert.That(BattleManagerBase.IsRandomDraw, Is.False); + } + Assert.That(BattleManagerBase.IsRandomDraw, Is.True); + + BattleManagerBase.IsRandomDraw = false; + } } diff --git a/SVSim.BattleEngine/Engine/BattleManagerBase.cs b/SVSim.BattleEngine/Engine/BattleManagerBase.cs index 1b9bd0d..0a100df 100644 --- a/SVSim.BattleEngine/Engine/BattleManagerBase.cs +++ b/SVSim.BattleEngine/Engine/BattleManagerBase.cs @@ -412,9 +412,25 @@ public class BattleManagerBase private static BattleManagerBase main; - public static bool IsRandomDraw = false; + private static bool _isRandomDrawFallback = false; + public static bool IsRandomDraw { + get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.IsRandomDraw ?? _isRandomDrawFallback; + set { + var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current; + if (c != null) c.IsRandomDraw = value; + else _isRandomDrawFallback = value; + } + } - public static bool IsForecast = false; + private static bool _isForecastFallback = false; + public static bool IsForecast { + get => SVSim.BattleEngine.Ambient.BattleAmbient.Current?.IsForecast ?? _isForecastFallback; + set { + var c = SVSim.BattleEngine.Ambient.BattleAmbient.Current; + if (c != null) c.IsForecast = value; + else _isForecastFallback = value; + } + } public BattleLifeTimeSharedObject BattleLifeTimeSharedObject;