Skip to content

Commit

Permalink
Add support for Dalaran Heist
Browse files Browse the repository at this point in the history
  • Loading branch information
azeier committed May 27, 2019
1 parent 4d65faf commit f8cb9ad
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 56 deletions.
82 changes: 47 additions & 35 deletions HearthWatcher/DungeonRunWatcher.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,15 @@ public void Run()
private async void Watch()
{
Running = true;
_prevCards = new List<int>[] { null, null, null };
_prevLootChoice = new[] { 0, 0, 0 };
_prevTreasureChoice = new[] { 0, 0, 0 };
_prevCards = new List<int>[] { null, null, null, null, null };
_prevLootChoice = new[] { 0, 0, 0, 0, 0 };
_prevTreasureChoice = new[] { 0, 0, 0, 0, 0 };
while(_watch)
{
await Task.Delay(_delay);
if(!_watch)
break;
if(Update())
if(await Update())
break;
}
Running = false;
Expand All @@ -73,46 +73,25 @@ private async void Watch()
CardIds.NonCollectible.Druid.RottoothHeroic,
};

public bool Update()
public async Task<bool> Update()
{
if(_dataProvider.InAdventureScreen)
{
var dungeonInfo = Reflection.GetDungeonInfo();
if(dungeonInfo != null)
{
for(var i = 0; i < dungeonInfo.Length; i++)
{
if(dungeonInfo[i]?.RunActive ?? false)
{
if(_prevCards[i] == null || !dungeonInfo[i].DbfIds.SequenceEqual(_prevCards[i])
|| _prevLootChoice[i] != dungeonInfo[i].PlayerChosenLoot
|| _prevTreasureChoice[i] != dungeonInfo[i].PlayerChosenTreasure)
{
_prevCards[i] = dungeonInfo[i].DbfIds.ToList();
_prevLootChoice[i] = dungeonInfo[i].PlayerChosenLoot;
_prevTreasureChoice[i] = dungeonInfo[i].PlayerChosenTreasure;
DungeonInfoChanged?.Invoke(dungeonInfo[i]);
}
}
else
_prevCards[i] = null;
}

if(_prevLootChoice.All(x => x > 0) && _prevTreasureChoice.All(x => x > 0))
return true;
}
else
{
_prevCards = new List<int>[] { null, null, null };
}

var shouldBreak = UpdateDungeonInfo();
if(shouldBreak)
return true;
}
else if(_dataProvider.InAiMatch && !string.IsNullOrEmpty(_dataProvider.OpponentHeroId))
{
if(Cards.All.TryGetValue(_dataProvider.OpponentHeroId, out var card))
{
if(new [] {CardSet.LOOTAPALOOZA, CardSet.GILNEAS}.Contains(card.Set) && card.Id.Contains("BOSS") || card.Set == CardSet.TROLL && card.Id.EndsWith("h"))
if(new [] {CardSet.LOOTAPALOOZA, CardSet.GILNEAS, CardSet.DALARAN}.Contains(card.Set) && card.Id.Contains("BOSS") || card.Set == CardSet.TROLL && card.Id.EndsWith("h"))
{
if(card.Set == CardSet.DALARAN)
{
UpdateDungeonInfo();
await Task.Delay(500);
}
var newRun = _initialOpponents.Contains(_dataProvider.OpponentHeroId)
|| _dataProvider.OpponentHeroHealth == 10;
DungeonRunMatchStarted?.Invoke(newRun);
Expand All @@ -122,5 +101,38 @@ public bool Update()
}
return false;
}

public bool UpdateDungeonInfo()
{
var dungeonInfo = Reflection.GetDungeonInfo();
if(dungeonInfo != null)
{
for(var i = 0; i < dungeonInfo.Length; i++)
{
if(dungeonInfo[i] != null && (dungeonInfo[i].RunActive || dungeonInfo[i].SelectedDeckId != 0))
{
if(_prevCards[i] == null || !(dungeonInfo[i].DbfIds?.SequenceEqual(_prevCards[i]) ?? false)
|| _prevLootChoice[i] != dungeonInfo[i].PlayerChosenLoot
|| _prevTreasureChoice[i] != dungeonInfo[i].PlayerChosenTreasure)
{
_prevCards[i] = dungeonInfo[i].DbfIds?.ToList();
_prevLootChoice[i] = dungeonInfo[i].PlayerChosenLoot;
_prevTreasureChoice[i] = dungeonInfo[i].PlayerChosenTreasure;
DungeonInfoChanged?.Invoke(dungeonInfo[i]);
}
}
else
_prevCards[i] = null;
}

if(_prevLootChoice.All(x => x > 0) && _prevTreasureChoice.All(x => x > 0))
return true;
}
else
{
_prevCards = new List<int>[] { null, null, null, null, null };
}
return false;
}
}
}
3 changes: 3 additions & 0 deletions Hearthstone Deck Tracker/Config.cs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ public class Config
[DefaultValue("Rumble Run {Date dd-MM HH:mm}")]
public string RumbleRunDeckNameTemplate = "Rumble Run {Date dd-MM HH:mm}";

[DefaultValue("Dalaran Heist {Date dd-MM HH:mm}")]
public string DalaranHeistDeckNameTemplate = "Dalaran Heist {Date dd-MM HH:mm}";

[DefaultValue(HsActionType.Flash)]
public HsActionType TurnStartAction = HsActionType.Flash;

Expand Down
62 changes: 44 additions & 18 deletions Hearthstone Deck Tracker/DeckManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -425,11 +425,11 @@ public static void SaveDeck(Deck baseDeck, Deck newVersion, bool overwriteCurren
DeckManagerEvents.OnDeckUpdated.Execute(newVersion);
}

public static void DungeonRunMatchStarted(bool newRun)
public static void DungeonRunMatchStarted(bool newRun, bool recursive = false)
{
if(!Config.Instance.DungeonAutoImport)
return;
Log.Info($"Dungeon run detected! New={newRun}");
Log.Info($"Dungeon run detected! New={newRun}, Recursive={recursive}");
var playerClass = Core.Game.Player.Board.FirstOrDefault(x => x.IsHero)?.Card.PlayerClass;
if(playerClass == null)
return;
Expand All @@ -445,8 +445,18 @@ public static void DungeonRunMatchStarted(bool newRun)
if(newRun)
{
var hero = Core.Game.Opponent.PlayerEntities.FirstOrDefault(x => x.IsHero)?.CardId;
var set = Database.GetCardFromId(hero)?.CardSet;
CreateDungeonDeck(playerClass, set ?? CardSet.INVALID);
var set = Database.GetCardFromId(hero)?.CardSet ?? CardSet.INVALID;
if (set == CardSet.DALARAN)
{
Watchers.DungeonRunWatcher.UpdateDungeonInfo();
if(!recursive)
{
DungeonRunMatchStarted(newRun, true);
return;
}
}
else
CreateDungeonDeck(playerClass, set);
}
else
{
Expand All @@ -470,29 +480,43 @@ public static void UpdateDungeonRunDeck(DungeonInfo info)
if(!Config.Instance.DungeonAutoImport)
return;
Log.Info("Found dungeon run deck!");
var allCards = info.DbfIds.ToList();
if(info.PlayerChosenLoot > 0)
var baseDeck = info.SelectedDeck ?? new List<int>();
var allCards = info.DbfIds?.ToList() ?? new List<int>();
if (baseDeck.All(x => allCards.Contains(x)))
{
var loot = new[] { info.LootA, info.LootB, info.LootC };
var chosen = loot[info.PlayerChosenLoot - 1];
for(var i = 1; i < chosen.Count; i++)
allCards.Add(chosen[i]);
if(info.PlayerChosenLoot > 0)
{
var loot = new[] { info.LootA, info.LootB, info.LootC };
var chosen = loot[info.PlayerChosenLoot - 1];
for(var i = 1; i < chosen.Count; i++)
allCards.Add(chosen[i]);
}
if(info.PlayerChosenTreasure > 0)
allCards.Add(info.Treasure[info.PlayerChosenTreasure - 1]);
}
if(info.PlayerChosenTreasure > 0)
allCards.Add(info.Treasure[info.PlayerChosenTreasure - 1]);
else
allCards = baseDeck;
var cards = allCards.GroupBy(x => x).Select(x =>
{
var card = Database.GetCardFromDbfId(x.Key, false);
if(card == null)
return null;
card.Count = x.Count();
return card;
}).ToList();
}).Where(x => x != null).ToList();
if(!Config.Instance.DungeonRunIncludePassiveCards)
cards.RemoveAll(c => !c.Collectible && c.HideStats);
var playerClass = ((CardClass)info.HeroCardClass).ToString().ToUpperInvariant();

string playerClass = null;
if(allCards.Count == 10)
playerClass = allCards.Select(x => Database.GetCardFromDbfId(x).PlayerClass).FirstOrDefault(x => x != null)?.ToUpperInvariant();
if (playerClass == null)
playerClass = ((CardClass)info.HeroCardClass).ToString().ToUpperInvariant();

var deck = DeckList.Instance.Decks.FirstOrDefault(x => x.IsDungeonDeck && x.Class.ToUpperInvariant() == playerClass
&& !(x.IsDungeonRunCompleted ?? false)
&& x.Cards.All(e => cards.Any(c => c.Id == e.Id && c.Count >= e.Count)));
if(deck == null && (deck = CreateDungeonDeck(playerClass, (CardSet)info.CardSet)) == null)
if(deck == null && (deck = CreateDungeonDeck(playerClass, (CardSet)info.CardSet, info.SelectedDeck)) == null)
{
Log.Info($"No existing deck - can't find default deck for {playerClass}");
return;
Expand All @@ -512,11 +536,13 @@ public static void UpdateDungeonRunDeck(DungeonInfo info)
Log.Info("Updated dungeon run deck");
}

private static Deck CreateDungeonDeck(string playerClass, CardSet set)
private static Deck CreateDungeonDeck(string playerClass, CardSet set, List<int> selectedDeck = null)
{
var shrine = Core.Game.Player.Board.FirstOrDefault(x => x.HasTag(GameTag.SHRINE))?.CardId;
Log.Info($"Creating new {playerClass} dungeon run deck (CardSet={set}, Shrine={shrine})");
var deck = DungeonRun.GetDefaultDeck(playerClass, set, shrine);
Log.Info($"Creating new {playerClass} dungeon run deck (CardSet={set}, Shrine={shrine}, SelectedDeck={selectedDeck != null})");
var deck = selectedDeck == null
? DungeonRun.GetDefaultDeck(playerClass, set, shrine)
: DungeonRun.GetDeckFromDbfIds(playerClass, set, selectedDeck);
if(deck == null)
{
Log.Info($"Could not find default deck for {playerClass} in card set {set} with Shrine={shrine}");
Expand Down
14 changes: 13 additions & 1 deletion Hearthstone Deck Tracker/Hearthstone/DungeonRun.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,19 @@ public static Deck GetDefaultDeck(string playerClass, CardSet set, string shrine
var cards = GetCards(playerClass, set, shrineCardId);
if(cards == null)
return null;
return GetDeck(playerClass, set, cards.Select(Database.GetCardFromId));
}

public static Deck GetDeckFromDbfIds(string playerClass, CardSet set, IEnumerable<int> dbfIds)
{
return GetDeck(playerClass, set, dbfIds.Select(dbfId => Database.GetCardFromDbfId(dbfId)));
}

public static Deck GetDeck(string playerClass, CardSet set, IEnumerable<Card> cards)
{
var deck = new Deck
{
Cards = new ObservableCollection<Card>(cards.Select(Database.GetCardFromId)),
Cards = new ObservableCollection<Card>(cards),
Class = CultureInfo.InvariantCulture.TextInfo.ToTitleCase(playerClass.ToLowerInvariant()),
IsDungeonDeck = true,
LastEdited = DateTime.Now
Expand All @@ -39,6 +49,8 @@ private static string GetDeckTemplate(CardSet set)
return Config.Instance.MonsterHuntDeckNameTemplate;
case CardSet.TROLL:
return Config.Instance.RumbleRunDeckNameTemplate;
case CardSet.DALARAN:
return Config.Instance.DalaranHeistDeckNameTemplate;
default:
return null;
}
Expand Down
4 changes: 2 additions & 2 deletions Hearthstone Deck Tracker/Hearthstone/Watchers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ static Watchers()
{
ArenaWatcher.OnCompleteDeck += (sender, args) => DeckManager.AutoImportArena(Config.Instance.SelectedArenaImportingBehaviour ?? ArenaImportingBehaviour.AutoImportSave, args.Info);
PackWatcher.NewPackEventHandler += (sender, args) => PackUploader.UploadPack(args.PackId, args.Cards);
DungeonRunWatcher.DungeonRunMatchStarted += DeckManager.DungeonRunMatchStarted;
DungeonRunWatcher.DungeonInfoChanged += DeckManager.UpdateDungeonRunDeck;
DungeonRunWatcher.DungeonRunMatchStarted += newRun => DeckManager.DungeonRunMatchStarted(newRun);
DungeonRunWatcher.DungeonInfoChanged += dungeonInfo => DeckManager.UpdateDungeonRunDeck(dungeonInfo);
FriendlyChallengeWatcher.OnFriendlyChallenge += OnFriendlyChallenge;
}

Expand Down

0 comments on commit f8cb9ad

Please sign in to comment.