RNG seam (DP5): make StableRandomDouble() and StableRandomOnlySelf(int) `virtual` so the authored HeadlessBattleMgr can override all three RNG methods to delegate to an injected IRandomSource (StableRandom(int) is already virtual). This decouples the authoritative RNG roll from IsForecast's VFX-suppression+RNG-zeroing (design 2026-06-06-rng-seam, finding F2). ZERO logic change — only the `virtual` keyword is added; the method bodies are byte-for-byte the decomp. --- Engine/BattleManagerBase.cs (~line 1586) - public double StableRandomDouble() + public virtual double StableRandomDouble() --- Engine/BattleManagerBase.cs (~line 1597) - public int StableRandomOnlySelf(int val) + public virtual int StableRandomOnlySelf(int val)