From 4e63a9431d79b4bae946beb9efccbc5346c63f53 Mon Sep 17 00:00:00 2001 From: tool4EvEr Date: Wed, 13 Apr 2022 10:21:48 +0200 Subject: [PATCH] PlayAi: Fix NPE with Invoke Calamity --- .../src/main/java/forge/ai/ability/PlayAi.java | 7 ++++--- .../java/forge/game/ability/AbilityUtils.java | 18 +++--------------- .../src/main/java/forge/game/card/Card.java | 7 +------ .../res/cardsfolder/a/accelerated_mutation.txt | 2 +- .../res/cardsfolder/b/boon_of_boseiju.txt | 2 +- .../res/cardsfolder/c/cabal_conditioning.txt | 2 +- .../res/cardsfolder/d/dispersal_shield.txt | 2 +- .../res/cardsfolder/i/invoke_calamity.txt | 2 +- .../res/cardsfolder/r/reward_the_faithful.txt | 2 +- .../res/cardsfolder/r/rush_of_knowledge.txt | 2 +- .../res/cardsfolder/t/torrent_of_fire.txt | 2 +- forge-gui/res/cardsfolder/u/ugins_insight.txt | 2 +- 12 files changed, 17 insertions(+), 33 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java index 119315f7e47..6cccbb0de7e 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PlayAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PlayAi.java @@ -195,8 +195,7 @@ public class PlayAi extends SpellAbilityAi { final Card source = sa.getHostCard(); if (tgt != null) { - ZoneType zone = tgt.getZone().get(0); - cards = CardLists.getValidCards(ai.getGame().getCardsIn(zone), tgt.getValidTgts(), ai, source, sa); + cards = CardLists.getValidCards(ai.getGame().getCardsIn(tgt.getZone()), tgt.getValidTgts(), ai, source, sa); } else if (!sa.hasParam("Valid")) { cards = AbilityUtils.getDefinedCards(source, sa.getParam("Defined"), sa); } @@ -214,9 +213,11 @@ public class PlayAi extends SpellAbilityAi { // Ensure that if a ValidZone is specified, there's at least something to choose from in that zone. if (sa.hasParam("ValidZone")) { - cards = new CardCollection(AbilityUtils.filterListByType(ai.getGame().getCardsIn(ZoneType.valueOf(sa.getParam("ValidZone"))), + cards = new CardCollection(AbilityUtils.filterListByType(ai.getGame().getCardsIn(ZoneType.listValueOf(sa.getParam("ValidZone"))), sa.getParam("Valid"), sa)); } + // exclude own card + cards.remove(source); return cards; } diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 5766f20cc25..930773573ed 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -2047,7 +2047,7 @@ public class AbilityUtils { return doXMath(c.getNetToughness(), expr, c, ctb); } if (sq[0].contains("CardSumPT")) { - return doXMath((c.getNetPower() + c.getNetToughness()), expr, c, ctb); + return doXMath(c.getNetPower() + c.getNetToughness(), expr, c, ctb); } if (sq[0].contains("CardNumTypes")) { Card ce; @@ -2814,14 +2814,7 @@ public class AbilityUtils { if (sq[0].startsWith("HighestCMC_")) { final String restriction = l[0].substring(11); CardCollection list = CardLists.getValidCards(game.getCardsInGame(), restriction, player, c, ctb); - int highest = 0; - for (final Card crd : list) { - // dont check for Split card anymore - if (crd.getCMC() > highest) { - highest = crd.getCMC(); - } - } - return highest; + return Aggregates.max(list, CardPredicates.Accessors.fnGetCmc); } if (sq[0].startsWith("MostCardName")) { @@ -2918,12 +2911,6 @@ public class AbilityUtils { // Complex counting methods CardCollectionView someCards = getCardListForXCount(c, player, sq, ctb); - // 1/10 - Count$MaxCMCYouCtrl - if (sq[0].startsWith("MaxCMC")) { - int mmc = Aggregates.max(someCards, CardPredicates.Accessors.fnGetCmc); - return doXMath(mmc, expr, c, ctb); - } - return doXMath(someCards.size(), expr, c, ctb); } @@ -3861,6 +3848,7 @@ public class AbilityUtils { CardCollection list = null; if (sa instanceof SpellAbility) { SpellAbility root = ((SpellAbility)sa).getRootAbility(); + // TODO do we really need these checks? if (defined.startsWith("SacrificedCards")) { list = root.getPaidList("SacrificedCards"); } else if (defined.startsWith("Sacrificed")) { diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 4298b73bf16..968a9544b11 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -5575,7 +5575,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { } public final boolean isTributed() { return tributed; } - public final void setTributed(final boolean b) { tributed = b; } @@ -5670,7 +5669,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public boolean isForetoldByEffect() { return foretoldByEffect; } - public void setForetoldByEffect(final boolean val) { this.foretoldByEffect = val; } @@ -5678,7 +5676,6 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public boolean isForetoldThisTurn() { return foretoldThisTurn; } - public final void setForetoldThisTurn(final boolean foretoldThisTurn) { this.foretoldThisTurn = foretoldThisTurn; } @@ -5690,11 +5687,9 @@ public class Card extends GameEntity implements Comparable, IHasSVars { public int getTimesCrewedThisTurn() { return timesCrewedThisTurn; } - public final void setTimesCrewedThisTurn(final int t) { this.timesCrewedThisTurn = t; } - public void resetTimesCrewedThisTurn() { timesCrewedThisTurn = 0; } @@ -6208,7 +6203,7 @@ public class Card extends GameEntity implements Comparable, IHasSVars { int xPaid = 0; - // 2012-07-22 - If a card is on the stack, count the xManaCost in with it's CMC + // If a card is on the stack, count the xManaCost in with it's CMC if (isInZone(ZoneType.Stack) && getManaCost() != null) { xPaid = getXManaCostPaid() * getManaCost().countX(); } diff --git a/forge-gui/res/cardsfolder/a/accelerated_mutation.txt b/forge-gui/res/cardsfolder/a/accelerated_mutation.txt index 60d73f5abb8..8e252e71cb9 100644 --- a/forge-gui/res/cardsfolder/a/accelerated_mutation.txt +++ b/forge-gui/res/cardsfolder/a/accelerated_mutation.txt @@ -2,5 +2,5 @@ Name:Accelerated Mutation ManaCost:3 G G Types:Instant A:SP$ Pump | Cost$ 3 G G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ X | NumDef$ X | SpellDescription$ Target creature gets +X/+X until end of turn, where X is the highest mana value among permanents you control. -SVar:X:Count$MaxCMCYouCtrl +SVar:X:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield Oracle:Target creature gets +X/+X until end of turn, where X is the highest mana value among permanents you control. diff --git a/forge-gui/res/cardsfolder/b/boon_of_boseiju.txt b/forge-gui/res/cardsfolder/b/boon_of_boseiju.txt index 1085fe0e614..ed29916fe39 100644 --- a/forge-gui/res/cardsfolder/b/boon_of_boseiju.txt +++ b/forge-gui/res/cardsfolder/b/boon_of_boseiju.txt @@ -3,5 +3,5 @@ ManaCost:2 G Types:Instant A:SP$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ X | NumDef$ X | SubAbility$ DBUntap | SpellDescription$ Target creature gets +X/+X until end of turn, where X is the greatest mana value among permanents you control. SVar:DBUntap:DB$ Untap | Defined$ Targeted | SpellDescription$ Untap it. -SVar:X:Count$MaxCMCYouCtrl +SVar:X:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield Oracle:Target creature gets +X/+X until end of turn, where X is the greatest mana value among permanents you control. Untap it. diff --git a/forge-gui/res/cardsfolder/c/cabal_conditioning.txt b/forge-gui/res/cardsfolder/c/cabal_conditioning.txt index 17952b6f5b6..e0d793711df 100644 --- a/forge-gui/res/cardsfolder/c/cabal_conditioning.txt +++ b/forge-gui/res/cardsfolder/c/cabal_conditioning.txt @@ -2,6 +2,6 @@ Name:Cabal Conditioning ManaCost:6 B Types:Sorcery A:SP$ Discard | Cost$ 6 B | ValidTgts$ Player | TgtPrompt$ Select target player | TargetMin$ 0 | TargetMax$ MaxTgt | NumCards$ X | Mode$ TgtChoose | SpellDescription$ Any number of target players each discard a number of cards equal to the highest mana value among permanents you control. -SVar:X:Count$MaxCMCYouCtrl +SVar:X:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield SVar:MaxTgt:PlayerCountPlayers$Amount Oracle:Any number of target players each discard a number of cards equal to the highest mana value among permanents you control. diff --git a/forge-gui/res/cardsfolder/d/dispersal_shield.txt b/forge-gui/res/cardsfolder/d/dispersal_shield.txt index 0abb2ab20b6..31e100ba019 100644 --- a/forge-gui/res/cardsfolder/d/dispersal_shield.txt +++ b/forge-gui/res/cardsfolder/d/dispersal_shield.txt @@ -3,6 +3,6 @@ ManaCost:1 U Types:Instant A:SP$ Counter | Cost$ 1 U | TargetType$ Spell | ValidTgts$ Card | ConditionCheckSVar$ X | ConditionSVarCompare$ LEY | SpellDescription$ Counter target spell if its mana value is less than or equal to the highest mana value among permanents you control. SVar:X:Targeted$CardManaCost -SVar:Y:Count$MaxCMCYouCtrl +SVar:Y:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield AI:RemoveDeck:All Oracle:Counter target spell if its mana value is less than or equal to the highest mana value among permanents you control. diff --git a/forge-gui/res/cardsfolder/i/invoke_calamity.txt b/forge-gui/res/cardsfolder/i/invoke_calamity.txt index 6697716601c..bf66334ad54 100644 --- a/forge-gui/res/cardsfolder/i/invoke_calamity.txt +++ b/forge-gui/res/cardsfolder/i/invoke_calamity.txt @@ -1,7 +1,7 @@ Name:Invoke Calamity ManaCost:1 R R R R Types:Instant -A:SP$ Play | Valid$ Instant.YouOwn,Sorcery.YouOwn | WithTotalCMC$ 6 | ValidZone$ Graveyard,Hand | Amount$ 2 | WithoutManaCost$ True | Optional$ True | ReplaceGraveyard$ Exile | SubAbility$ DBExile | StackDescription$ SpellDescription | SpellDescription$ You may cast up to two instant and/or sorcery spells with total mana value 6 or less from your graveyard and/or hand without paying their mana costs. If those spells would be put into your graveyard, exile them instead. +A:SP$ Play | Valid$ Card.YouOwn | ValidSA$ Instant,Sorcery | WithTotalCMC$ 6 | ValidZone$ Graveyard,Hand | Amount$ 2 | WithoutManaCost$ True | Optional$ True | ReplaceGraveyard$ Exile | SubAbility$ DBExile | StackDescription$ SpellDescription | SpellDescription$ You may cast up to two instant and/or sorcery spells with total mana value 6 or less from your graveyard and/or hand without paying their mana costs. If those spells would be put into your graveyard, exile them instead. SVar:DBExile:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | SpellDescription$ Exile CARDNAME. DeckNeeds:Type$Instant|Sorcery DeckHas:Ability$Graveyard diff --git a/forge-gui/res/cardsfolder/r/reward_the_faithful.txt b/forge-gui/res/cardsfolder/r/reward_the_faithful.txt index eb2d0efdf91..26c1c3aaace 100644 --- a/forge-gui/res/cardsfolder/r/reward_the_faithful.txt +++ b/forge-gui/res/cardsfolder/r/reward_the_faithful.txt @@ -2,6 +2,6 @@ Name:Reward the Faithful ManaCost:W Types:Instant A:SP$ GainLife | Cost$ W | ValidTgts$ Player | TgtPrompt$ Select target player | TargetMin$ 0 | TargetMax$ MaxTgt | LifeAmount$ X | SpellDescription$ Any number of target players each gain life equal to the highest mana value among permanents you control. -SVar:X:Count$MaxCMCYouCtrl +SVar:X:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield SVar:MaxTgt:PlayerCountPlayers$Amount Oracle:Any number of target players each gain life equal to the highest mana value among permanents you control. diff --git a/forge-gui/res/cardsfolder/r/rush_of_knowledge.txt b/forge-gui/res/cardsfolder/r/rush_of_knowledge.txt index ed97b4ebc1a..534b2c2e9be 100644 --- a/forge-gui/res/cardsfolder/r/rush_of_knowledge.txt +++ b/forge-gui/res/cardsfolder/r/rush_of_knowledge.txt @@ -2,6 +2,6 @@ Name:Rush of Knowledge ManaCost:4 U Types:Sorcery A:SP$ Draw | Cost$ 4 U | Defined$ You | NumCards$ X | SpellDescription$ Draw cards equal to the highest mana value among permanents you control. -SVar:X:Count$MaxCMCYouCtrl +SVar:X:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield AI:RemoveDeck:Random Oracle:Draw cards equal to the highest mana value among permanents you control. diff --git a/forge-gui/res/cardsfolder/t/torrent_of_fire.txt b/forge-gui/res/cardsfolder/t/torrent_of_fire.txt index 2ab11d1ac39..99f1adbda40 100644 --- a/forge-gui/res/cardsfolder/t/torrent_of_fire.txt +++ b/forge-gui/res/cardsfolder/t/torrent_of_fire.txt @@ -2,5 +2,5 @@ Name:Torrent of Fire ManaCost:3 R R Types:Sorcery A:SP$ DealDamage | Cost$ 3 R R | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X | SpellDescription$ CARDNAME deals damage to any target equal to the highest mana value among permanents you control. -SVar:X:Count$MaxCMCYouCtrl +SVar:X:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield Oracle:Torrent of Fire deals damage to any target equal to the highest mana value among permanents you control. diff --git a/forge-gui/res/cardsfolder/u/ugins_insight.txt b/forge-gui/res/cardsfolder/u/ugins_insight.txt index d8dbda0a935..73dd5c199d2 100644 --- a/forge-gui/res/cardsfolder/u/ugins_insight.txt +++ b/forge-gui/res/cardsfolder/u/ugins_insight.txt @@ -2,6 +2,6 @@ Name:Ugin's Insight ManaCost:3 U U Types:Sorcery A:SP$ Scry | Cost$ 3 U U | ScryNum$ X | SubAbility$ DBDraw | SpellDescription$ Scry X, where X is the highest mana value among permanents you control, then draw three cards. -SVar:X:Count$MaxCMCYouCtrl +SVar:X:Count$HighestCMC_Permanent.YouCtrl+inZoneBattlefield SVar:DBDraw:DB$ Draw | NumCards$ 3 Oracle:Scry X, where X is the highest mana value among permanents you control, then draw three cards.