Skip to content

Commit 23c068e

Browse files
Patch 31.4 (#72)
* wip: add active effects and related cards for miniset * wip: add JimRaynor related cards * fix: JimRaynor for the opponent * feat: add Colossus counter * feat: add Mothership and Resonance Coil related cards * refactor: use cache for related cards that filter the card collection - This reduces the initiation cost of the class * feat: update tags and cardIds
1 parent 9be4b3f commit 23c068e

File tree

15 files changed

+260
-2
lines changed

15 files changed

+260
-2
lines changed

Hearthstone Deck Tracker/Hearthstone/Card.cs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,21 @@ public List<string> GetClasses()
563563
return null;
564564
}
565565

566+
public GameTag? GetFaction()
567+
{
568+
var factions = new[]
569+
{
570+
GameTag.KABAL,
571+
GameTag.GRIMY_GOONS,
572+
GameTag.JADE_LOTUS,
573+
GameTag.PROTOSS,
574+
GameTag.TERRAN,
575+
GameTag.ZERG
576+
};
577+
578+
return factions.FirstOrDefault(faction => _dbCard?.Entity.GetTag(faction) > 0);
579+
}
580+
566581
public bool ZilliaxCustomizableFunctionalModule => _dbCard?.Entity.GetTag(GameTag.ZILLIAX_CUSTOMIZABLE_FUNCTIONALMODULE) > 0;
567582

568583
public bool ZilliaxCustomizableCosmeticModule => _dbCard?.Entity.GetTag(GameTag.ZILLIAX_CUSTOMIZABLE_COSMETICMODULE) > 0;

Hearthstone Deck Tracker/Hearthstone/CardUtils.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public static bool MayCardBeRelevant(Card? card, Format? format, string? playerC
8383
HearthDb.CardIds.NonCollectible.Hunter.ArkoniteDefenseCrystal_TheAstralCompassToken,
8484
HearthDb.CardIds.NonCollectible.Rogue.ArkoniteDefenseCrystal_TheScavengersWillToken,
8585
HearthDb.CardIds.NonCollectible.Warlock.ArkoniteDefenseCrystal_TheNethersEyeToken,
86+
HearthDb.CardIds.NonCollectible.Invalid.BattlecruiserToken,
8687
};
8788

8889
public static bool IsStarship(string? cardId) => _starshipIds.Contains(cardId);
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using HearthDb.Enums;
2+
using Hearthstone_Deck_Tracker.LogReader.Interfaces;
3+
using Hearthstone_Deck_Tracker.Utility;
4+
using Entity = Hearthstone_Deck_Tracker.Hearthstone.Entities.Entity;
5+
6+
namespace Hearthstone_Deck_Tracker.Hearthstone.CounterSystem.Counters;
7+
8+
public class ColossusCounter : NumericCounter
9+
{
10+
protected override string? CardIdToShowInUI => HearthDb.CardIds.Collectible.Mage.Colossus;
11+
12+
public override string[] RelatedCards => new string[]
13+
{
14+
HearthDb.CardIds.Collectible.Mage.Colossus,
15+
};
16+
17+
public ColossusCounter(bool controlledByPlayer, GameV2 game) : base(controlledByPlayer, game)
18+
{
19+
}
20+
21+
public override bool ShouldShow()
22+
{
23+
if(!Game.IsTraditionalHearthstoneMatch) return false;
24+
if(IsPlayerCounter)
25+
return InPlayerDeckOrKnown(RelatedCards);
26+
return Counter > 2 && OpponentMayHaveRelevantCards();
27+
}
28+
29+
public override string[] GetCardsToDisplay()
30+
{
31+
return IsPlayerCounter ?
32+
GetCardsInDeckOrKnown(RelatedCards).ToArray() :
33+
FilterCardsByClassAndFormat(RelatedCards, Game.Opponent.OriginalClass);
34+
}
35+
36+
public override string ValueToShow() => string.Format(LocUtil.Get("Counter_AsteroidDamage_Damage", useCardLanguage: true), $"2x {Counter + 1}");
37+
38+
public override void HandleTagChange(GameTag tag, IHsGameState gameState, Entity entity, int value, int prevValue)
39+
{
40+
if(!Game.IsTraditionalHearthstoneMatch)
41+
return;
42+
43+
if(tag != GameTag.ZONE)
44+
return;
45+
46+
if(value != (int)Zone.PLAY && value != (int)Zone.SECRET)
47+
return;
48+
49+
if(!entity.IsSpell)
50+
return;
51+
52+
if(!entity.HasTag(GameTag.PROTOSS))
53+
return;
54+
55+
var controller = entity.GetTag(GameTag.CONTROLLER);
56+
57+
if((controller == Game.Player.Id && IsPlayerCounter) || (controller == Game.Opponent.Id && !IsPlayerCounter))
58+
Counter++;
59+
}
60+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using Hearthstone_Deck_Tracker.Hearthstone.EffectSystem.Enums;
2+
3+
namespace Hearthstone_Deck_Tracker.Hearthstone.EffectSystem.Effects.DeathKnight;
4+
5+
public class InfestorEnchantment : EntityBasedEffect
6+
{
7+
public override string CardId => HearthDb.CardIds.NonCollectible.Deathknight.Infestor_ForTheSwarmEnchantment1;
8+
protected override string CardIdToShowInUI => HearthDb.CardIds.Collectible.Deathknight.Infestor;
9+
10+
public InfestorEnchantment(int entityId, bool isControlledByPlayer) : base(entityId, isControlledByPlayer)
11+
{
12+
}
13+
14+
public override EffectDuration EffectDuration => EffectDuration.Permanent;
15+
public override EffectTag EffectTag => EffectTag.MinionModification;
16+
}

Hearthstone Deck Tracker/Hearthstone/Player.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public Player(IGame game, bool isLocalPlayer)
4141
public List<Entity> CardsPlayedThisMatch { get; } = new();
4242
public List<Entity> CardsPlayedThisTurn { get; private set; } = new List<Entity>();
4343
public List<Entity> CardsPlayedLastTurn { get; private set; } = new();
44+
public List<string?> LaunchedStarships { get; private set; } = new();
4445
public bool IsPlayingWhizbang { get; set; }
4546
public int PogoHopperPlayedCount { get; private set; }
4647
public Entity? LastDiedMinionCard => DeadMinionsCards.LastOrDefault();
@@ -492,6 +493,7 @@ public void Reset()
492493
CardsPlayedThisTurn.Clear();
493494
CardsPlayedLastTurn.Clear();
494495
CardsPlayedThisMatch.Clear();
496+
LaunchedStarships.Clear();
495497
SecretsTriggeredCards.Clear();
496498
LastDrawnCardId = null;
497499
LibramReductionCount = 0;
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using HearthDb.Enums;
4+
5+
namespace Hearthstone_Deck_Tracker.Hearthstone.RelatedCardsSystem.Cards.Mage;
6+
7+
public class ResonanceCoil: ICardWithRelatedCards
8+
{
9+
private List<Card?>? _cache = null;
10+
11+
public string GetCardId() => HearthDb.CardIds.Collectible.Mage.ResonanceCoil;
12+
13+
public bool ShouldShowForOpponent(Player opponent) => false;
14+
15+
public List<Card?> GetRelatedCards(Player player)
16+
{
17+
if(_cache != null) return _cache;
18+
19+
var cardId = GetCardId();
20+
21+
_cache = HearthDb.Cards.Collectible.Values
22+
.Where(c =>
23+
c.Entity.GetTag(GameTag.PROTOSS) > 0 &&
24+
c.Type == CardType.SPELL &&
25+
c.Id != cardId)
26+
.Select(c => new Card(c))
27+
.OrderBy(card => card.Cost)
28+
.ToList()!;
29+
30+
return _cache;
31+
}
32+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
4+
namespace Hearthstone_Deck_Tracker.Hearthstone.RelatedCardsSystem.Cards.Neutral;
5+
6+
public class JimRaynor: ICardWithRelatedCards
7+
{
8+
public string GetCardId() => HearthDb.CardIds.Collectible.Invalid.JimRaynor;
9+
10+
public bool ShouldShowForOpponent(Player opponent)
11+
{
12+
var card = Database.GetCardFromId(GetCardId());
13+
return CardUtils.MayCardBeRelevant(card, Core.Game.CurrentFormat, opponent.OriginalClass) && GetRelatedCards(opponent).Count > 0;
14+
}
15+
16+
public List<Card?> GetRelatedCards(Player player) =>
17+
player.LaunchedStarships.Select(Database.GetCardFromId)
18+
.ToList();
19+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
4+
namespace Hearthstone_Deck_Tracker.Hearthstone.RelatedCardsSystem.Cards.Neutral;
5+
6+
public class LiftOff: ICardWithRelatedCards
7+
{
8+
private readonly List<Card?> _starshipPieces = new List<Card?>
9+
{
10+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Viking),
11+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Liberator),
12+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Raven2),
13+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Banshee2),
14+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Medivac2)
15+
};
16+
17+
public string GetCardId() => HearthDb.CardIds.Collectible.Invalid.LiftOff;
18+
19+
public bool ShouldShowForOpponent(Player opponent) => false;
20+
21+
public List<Card?> GetRelatedCards(Player player) => _starshipPieces;
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
4+
namespace Hearthstone_Deck_Tracker.Hearthstone.RelatedCardsSystem.Cards.Neutral;
5+
6+
public class Starport: ICardWithRelatedCards
7+
{
8+
private readonly List<Card?> _starshipPieces = new List<Card?>
9+
{
10+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Viking),
11+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Liberator),
12+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Raven2),
13+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Banshee2),
14+
Database.GetCardFromId(HearthDb.CardIds.NonCollectible.Invalid.Starport_Medivac2)
15+
};
16+
17+
public string GetCardId() => HearthDb.CardIds.Collectible.Invalid.Starport;
18+
19+
public bool ShouldShowForOpponent(Player opponent) => false;
20+
21+
public List<Card?> GetRelatedCards(Player player) => _starshipPieces;
22+
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System.Collections.Generic;
2+
using System.Linq;
3+
using HearthDb.Enums;
4+
5+
namespace Hearthstone_Deck_Tracker.Hearthstone.RelatedCardsSystem.Cards.Priest;
6+
7+
public class Mothership: ICardWithRelatedCards
8+
{
9+
private List<Card?>? _cache = null;
10+
public string GetCardId() => HearthDb.CardIds.Collectible.Priest.Mothership;
11+
12+
public bool ShouldShowForOpponent(Player opponent) => false;
13+
14+
public List<Card?> GetRelatedCards(Player player){
15+
if(_cache != null) return _cache;
16+
17+
var cardId = GetCardId();
18+
19+
_cache = HearthDb.Cards.Collectible.Values
20+
.Where(c =>
21+
c.Entity.GetTag(GameTag.PROTOSS) > 0 &&
22+
c.Type == CardType.MINION &&
23+
c.Id != cardId)
24+
.Select(c => new Card(c))
25+
.OrderBy(card => card.Cost)
26+
.ToList()!;
27+
28+
return _cache;
29+
30+
}
31+
}

Hearthstone Deck Tracker/Hearthstone/RelatedCardsSystem/Cards/Rogue/ScroungingShipwright.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,18 @@ public class ScroungingShipwright: ICardWithRelatedCards
1717
Database.GetCardFromId(HearthDb.CardIds.Collectible.Warlock.HeartOfTheLegion),
1818
Database.GetCardFromId(HearthDb.CardIds.Collectible.Hunter.Biopod),
1919
Database.GetCardFromId(HearthDb.CardIds.Collectible.Hunter.SpecimenClaw),
20+
Database.GetCardFromId(HearthDb.CardIds.Collectible.Shaman.MissilePod),
21+
Database.GetCardFromId(HearthDb.CardIds.Collectible.Paladin.UltraCapacitor),
22+
Database.GetCardFromId(HearthDb.CardIds.Collectible.Warrior.YamatoCannon),
2023
};
2124

2225
public string GetCardId() => HearthDb.CardIds.Collectible.Rogue.ScroungingShipwright;
2326

2427
public bool ShouldShowForOpponent(Player opponent) => false;
2528

2629
public List<Card?> GetRelatedCards(Player player) =>
27-
_starshipPieces.Where(card => card != null && !card.IsClass(player.CurrentClass)).ToList();
30+
_starshipPieces.Where(card => card != null && !card.IsClass(player.CurrentClass))
31+
.OrderBy(card => card?.Cost)
32+
.ToList();
2833
}
2934

Hearthstone Deck Tracker/Hearthstone/RelatedCardsSystem/Cards/Rogue/StarshipSchematic.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ public class StarshipSchematic: ICardWithRelatedCards
1818
Database.GetCardFromId(HearthDb.CardIds.Collectible.Warlock.HeartOfTheLegion),
1919
Database.GetCardFromId(HearthDb.CardIds.Collectible.Hunter.Biopod),
2020
Database.GetCardFromId(HearthDb.CardIds.Collectible.Hunter.SpecimenClaw),
21+
Database.GetCardFromId(HearthDb.CardIds.Collectible.Shaman.MissilePod),
22+
Database.GetCardFromId(HearthDb.CardIds.Collectible.Paladin.UltraCapacitor),
23+
Database.GetCardFromId(HearthDb.CardIds.Collectible.Warrior.YamatoCannon),
2124
};
2225

2326
public string GetCardId() => HearthDb.CardIds.Collectible.Rogue.StarshipSchematic;

Hearthstone Deck Tracker/LogReader/Handlers/TagChangeActions.cs

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -515,9 +515,36 @@ private void OnParentCardChange(IHsGameState gameState, int id, IGame game, int
515515
if(!game.Entities.TryGetValue(id, out var entity))
516516
return;
517517

518-
// when a starship is launched it changes the value to 0, but we want to keep the parent stored cards
518+
// when a starship is launched it sets the value to 0
519+
// otherwise it sets to the parent starship id
519520
if(!game.Entities.TryGetValue(value, out var parentEntity))
521+
{
522+
523+
// every piece sets the parent to 0, we only need to get 1 of them
524+
if(gameState.StarshipLauchBlockIds.Contains(gameState.CurrentBlock?.Id))
525+
return;
526+
527+
if(gameState.CurrentBlock?.Type != "POWER" ||
528+
!(CardUtils.IsStarship(gameState.CurrentBlock?.CardId) || gameState.CurrentBlock?.CardId == Collectible.Neutral.TheExodar))
529+
return;
530+
531+
if(!game.Entities.TryGetValue(prevValue, out var starshipToken))
532+
return;
533+
534+
var player = entity.IsControlledBy(game.Player.Id) ? game.Player : game.Opponent;
535+
gameState.StarshipLauchBlockIds.Add(gameState.CurrentBlock?.Id);
536+
player.LaunchedStarships.Add(starshipToken.CardId);
537+
538+
var excludedPieces = new List<string>
539+
{
540+
NonCollectible.Neutral.LaunchStarship,
541+
NonCollectible.Neutral.AbortLaunch,
542+
};
543+
544+
var starshipPieces = starshipToken.Info.StoredCardIds.Where(cardId => !excludedPieces.Contains(cardId));
545+
player.LaunchedStarships.AddRange(starshipPieces);
520546
return;
547+
}
521548

522549
if(entity.CardId != null)
523550
parentEntity.Info.StoredCardIds.Add(entity.CardId);

Hearthstone Deck Tracker/LogReader/HsGameState.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ public void Reset()
6565
_maxBlockId = 0;
6666
DredgeCounter = 0;
6767
TriangulatePlayed = false;
68+
StarshipLauchBlockIds.Clear();
6869
}
6970

7071
public void SetCurrentEntity(int id)
@@ -94,6 +95,7 @@ public void BlockEnd()
9495
public Dictionary<int, IHsChoice> ChoicesById { get; } = new();
9596
public Dictionary<int, List<IHsChoice>> ChoicesByTaskList { get; } = new();
9697
public bool TriangulatePlayed { get; set; }
98+
public List<int?> StarshipLauchBlockIds { get; } = new();
9799
}
98100

99101
public class Block

Hearthstone Deck Tracker/LogReader/Interfaces/IHsGameState.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ public interface IHsGameState
4444
Dictionary<int, IHsChoice> ChoicesById { get; }
4545
Dictionary<int, List<IHsChoice>> ChoicesByTaskList { get; }
4646
bool TriangulatePlayed { get; set; }
47+
List<int?> StarshipLauchBlockIds { get; }
4748

4849
}
4950
}

0 commit comments

Comments
 (0)