diff --git a/Hearthstone Deck Tracker/BobsBuddy/BobsBuddyInvoker.cs b/Hearthstone Deck Tracker/BobsBuddy/BobsBuddyInvoker.cs index c9aeb2aa5..0d9552b91 100644 --- a/Hearthstone Deck Tracker/BobsBuddy/BobsBuddyInvoker.cs +++ b/Hearthstone Deck Tracker/BobsBuddy/BobsBuddyInvoker.cs @@ -16,8 +16,6 @@ using Hearthstone_Deck_Tracker.Utility.Extensions; using Entity = Hearthstone_Deck_Tracker.Hearthstone.Entities.Entity; using BobsBuddy; -using BobsBuddy.Spells; -using HearthDb; namespace Hearthstone_Deck_Tracker.BobsBuddy { @@ -55,8 +53,6 @@ private static bool ReportErrors public Entity? LastAttackingHero = null; public int LastAttackingHeroAttack; private static List _recentHDTLog = new List(); - private static List _currentOpponentSecrets = new List(); - private static Dictionary _opponentSecretMap = new(); private List _opponentHand = new(); private readonly Dictionary _opponentHandMap = new(); @@ -459,8 +455,6 @@ private void SnapshotBoardState(int turn) input.SetTurn(turn); - _currentOpponentSecrets = _game.Opponent.Secrets.ToList(); - var playerSide = GetOrderedMinions(_game.Player.Board) .Where(e => e.IsControlledBy(_game.Player.Id)) .Select(e => GetMinionFromEntity(simulator.MinionFactory, true, e, GetAttachedEntities(e.Id))); @@ -571,20 +565,8 @@ internal async void UpdateOpponentHand(Entity entity, Entity copy) await TryRerun(); } - internal async void UpdateSecret(Entity entity) + internal async void UpdateOpponentSecret(Entity entity) { - var oldSecret = _currentOpponentSecrets.Find(x => x.Id == entity.Id); - if(oldSecret != null) - _opponentSecretMap[oldSecret] = entity; - - _currentOpponentSecrets = _currentOpponentSecrets.Select(x => { - if(_opponentSecretMap.TryGetValue(x, out var retval)) - { - return retval; - } - return entity; - }).ToList(); - await TryRerun(); } @@ -628,7 +610,13 @@ private IEnumerable GetAttachedEntities(int entityId) try { - _input.SetupSecretsFromDbfidList(_currentOpponentSecrets.Select(x => x != null && !string.IsNullOrEmpty(x.CardId) ? (int?)x.Card.DbfId : null).ToList(), false); + _input.SetupSecretsFromDbfidList( + _game.Opponent.Secrets + .Select(x => !string.IsNullOrEmpty(x.CardId) ? (int?)x.Card.DbfId : null) + .Distinct(new SecretDbfIdComparer()) + .ToList(), + false + ); DebugLog($"Set opponent S. with {_input.OpponentSecrets.Count} S."); DebugLog("----- Simulation Input -----"); @@ -651,14 +639,14 @@ private IEnumerable GetAttachedEntities(int entityId) DebugLog($"[{quest.QuestCardId} ({quest.QuestProgress}/{quest.QuestProgressTotal}): {quest.RewardCardId}]"); - if(_input.PlayerSecrets.Count() > 0) + if(_input.PlayerSecrets.Any()) { DebugLog("Detected the following player S."); foreach(var s in _input.PlayerSecrets) DebugLog(s.ToString()); } - if(_input.OpponentSecrets.Count() > 0) + if(_input.OpponentSecrets.Any()) { DebugLog("Detected the following opponent S."); foreach(var s in _input.OpponentSecrets) @@ -845,5 +833,31 @@ private void AlertWithLastInputOutput(string result) if(_input != null && Output != null) Sentry.QueueBobsBuddyTerminalCase(_input, Output, result, _turn, _recentHDTLog, _game.CurrentRegion); } + + /** + * A comparer that keeps unknown secrets (null) and de-duplicates dbf ids otherwise. + * For example { 1, null, 3, 3, null} will be deduplicated to {1, null, 3, null}. + */ + private class SecretDbfIdComparer : IEqualityComparer + { + public bool Equals(int? x, int? y) + { + if (x == null || y == null) + { + return false; + } + + return x == y; + } + + public int GetHashCode(int? obj) + { + if (obj == null) + { + return 0; + } + return obj.GetHashCode(); + } + } } } diff --git a/Hearthstone Deck Tracker/GameEventHandler.cs b/Hearthstone Deck Tracker/GameEventHandler.cs index 9c56df47d..52d77acba 100644 --- a/Hearthstone Deck Tracker/GameEventHandler.cs +++ b/Hearthstone Deck Tracker/GameEventHandler.cs @@ -1940,7 +1940,7 @@ public void HandleOpponentSecretTrigger(Entity entity, string? cardId, int turn, GameEvents.OnOpponentSecretTriggered.Execute(card); if(_game.IsBattlegroundsMatch && Config.Instance.RunBobsBuddy && _game.CurrentGameStats != null) BobsBuddyInvoker.GetInstance(_game.CurrentGameStats.GameId, _game.GetTurnNumber()) - ?.UpdateSecret(entity); + ?.UpdateOpponentSecret(entity); } public void HandleOpponentDeckDiscard(Entity entity, string? cardId, int turn)