From 4b52ff05d57ad2a49f0158f46e16ab4acfeb1bea Mon Sep 17 00:00:00 2001 From: Michael Kamensky Date: Fri, 19 Oct 2018 12:13:31 +0000 Subject: [PATCH] Update direct references to RemAIDeck/RemRandomDeck to use the new format --- forge-ai/src/main/java/forge/ai/AiCostDecision.java | 2 +- forge-ai/src/main/java/forge/ai/ability/AnimateAi.java | 2 +- .../src/main/java/forge/ai/ability/ChangeZoneAi.java | 2 +- .../src/main/java/forge/ai/ability/ChangeZoneAllAi.java | 6 +++--- forge-ai/src/main/java/forge/ai/ability/CloneAi.java | 7 +++---- .../main/java/forge/ai/ability/ControlExchangeAi.java | 2 +- .../src/main/java/forge/ai/ability/ControlGainAi.java | 2 +- .../src/main/java/forge/ai/ability/CopyPermanentAi.java | 2 +- .../src/main/java/forge/ai/ability/PowerExchangeAi.java | 3 +-- forge-ai/src/main/java/forge/ai/ability/SacrificeAi.java | 2 +- .../src/main/java/forge/game/card/CardPredicates.java | 9 +++++++++ forge-gui/res/cardsfolder/b/blood_operative.txt | 2 +- forge-gui/res/cardsfolder/s/sentinel_tower.txt | 2 +- .../src/main/java/forge/deck/DeckImportController.java | 5 ++++- 14 files changed, 29 insertions(+), 19 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/AiCostDecision.java b/forge-ai/src/main/java/forge/ai/AiCostDecision.java index fe715d5ab2f..b923b38707a 100644 --- a/forge-ai/src/main/java/forge/ai/AiCostDecision.java +++ b/forge-ai/src/main/java/forge/ai/AiCostDecision.java @@ -528,7 +528,7 @@ public class AiCostDecision extends CostDecisionMakerBase { // are currently conventionally flagged with AILogic$ DoSacrifice. c = AbilityUtils.calculateAmount(source, source.getSVar("ChosenX"), null); } else { - // Other cards are assumed to be flagged RemAIDeck for now + // Other cards are assumed to be flagged AI:RemoveDeck:All for now return null; } } else { diff --git a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java index 76fdbbd3d0d..f9c49986042 100644 --- a/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/AnimateAi.java @@ -342,7 +342,7 @@ public class AnimateAi extends SpellAbilityAi { // This is reasonable for now. Kamahl, Fist of Krosa and a sorcery or // two are the only things - // that animate a target. Those can just use SVar:RemAIDeck:True until + // that animate a target. Those can just use AI:RemoveDeck:All until // this can do a reasonably // good job of picking a good target return false; diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java index ab2ef609098..04e7cc793b4 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAi.java @@ -1459,7 +1459,7 @@ public class ChangeZoneAi extends SpellAbilityAi { fetchList = CardLists.filter(fetchList, new Predicate() { @Override public boolean apply(final Card c) { - if (c.hasSVar("RemAIDeck") || c.hasSVar("RemRandomDeck")) { + if (c.getRules().getAiHints().getRemAIDecks() || c.getRules().getAiHints().getRemRandomDecks()) { return false; } return true; diff --git a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAllAi.java b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAllAi.java index ad5de0b33b1..84f81600df8 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAllAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ChangeZoneAllAi.java @@ -114,7 +114,7 @@ public class ChangeZoneAllAi extends SpellAbilityAi { // spBounceAll has some AI we can compare to. if (origin.equals(ZoneType.Hand) || origin.equals(ZoneType.Library)) { if (!sa.usesTargeting()) { - // TODO: improve logic for non-targeted SAs of this type (most are currently RemAIDeck, e.g. Memory Jar) + // TODO: improve logic for non-targeted SAs of this type (most are currently AI:RemoveDeck:All, e.g. Memory Jar) return true; } else { // search targetable Opponents @@ -344,8 +344,8 @@ public class ChangeZoneAllAi extends SpellAbilityAi { if (ComputerUtilAbility.getAbilitySourceName(sa).equals("Profaner of the Dead")) { // TODO: this is a stub to prevent the AI from crashing the game when, for instance, playing the opponent's - // Profaner from exile without paying its mana cost. Otherwise the card is marked RemAIDeck and there is no - // specific AI to support playing it in a smarter way. Feel free to expand. + // Profaner from exile without paying its mana cost. Otherwise the card is marked AI:RemoveDeck:All and + // there is no specific AI to support playing it in a smarter way. Feel free to expand. return !CardLists.filter(ai.getOpponents().getCardsIn(origin), CardPredicates.Presets.CREATURES).isEmpty(); } diff --git a/forge-ai/src/main/java/forge/ai/ability/CloneAi.java b/forge-ai/src/main/java/forge/ai/ability/CloneAi.java index 8479bde2c85..9fae432551b 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CloneAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CloneAi.java @@ -146,10 +146,9 @@ public class CloneAi extends SpellAbilityAi { // Default: // This is reasonable for now. Kamahl, Fist of Krosa and a sorcery or - // two are the only things - // that clone a target. Those can just use SVar:RemAIDeck:True until - // this can do a reasonably - // good job of picking a good target + // two are the only things that clone a target. Those can just use + // AI:RemoveDeck:All until this can do a reasonably good job of picking + // a good target return false; } diff --git a/forge-ai/src/main/java/forge/ai/ability/ControlExchangeAi.java b/forge-ai/src/main/java/forge/ai/ability/ControlExchangeAi.java index 8f38b905c4c..f002fca63c3 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ControlExchangeAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ControlExchangeAi.java @@ -36,7 +36,7 @@ public class ControlExchangeAi extends SpellAbilityAi { list = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card c) { - return !c.hasSVar("RemAIDeck") && c.canBeTargetedBy(sa); + return !c.getRules().getAiHints().getRemAIDecks() && c.canBeTargetedBy(sa); } }); object1 = ComputerUtilCard.getBestAI(list); diff --git a/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java b/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java index 50bdc533844..a6631ad51bb 100644 --- a/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/ControlGainAi.java @@ -171,7 +171,7 @@ public class ControlGainAi extends SpellAbilityAi { } // do not take control on something it doesn't know how to use - return !c.hasSVar("RemAIDeck"); + return !c.getRules().getAiHints().getRemAIDecks(); } }); diff --git a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java index a630836d38e..f543b662b3e 100644 --- a/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/CopyPermanentAi.java @@ -83,7 +83,7 @@ public class CopyPermanentAi extends SpellAbilityAi { CardCollection list = new CardCollection(CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa)); - list = CardLists.filter(list, Predicates.not(CardPredicates.hasSVar("RemAIDeck"))); + list = CardLists.filter(list, Predicates.not(CardPredicates.isRemAIDeck())); //Nothing to target if (list.isEmpty()) { return false; diff --git a/forge-ai/src/main/java/forge/ai/ability/PowerExchangeAi.java b/forge-ai/src/main/java/forge/ai/ability/PowerExchangeAi.java index dc6deb4ae86..2e24354ca26 100644 --- a/forge-ai/src/main/java/forge/ai/ability/PowerExchangeAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/PowerExchangeAi.java @@ -38,8 +38,7 @@ public class PowerExchangeAi extends SpellAbilityAi { list = CardLists.filter(list, new Predicate() { @Override public boolean apply(final Card c) { - final Map vars = c.getSVars(); - return !vars.containsKey("RemAIDeck") && c.canBeTargetedBy(sa); + return !c.getRules().getAiHints().getRemAIDecks() && c.canBeTargetedBy(sa); } }); CardLists.sortByPowerAsc(list); diff --git a/forge-ai/src/main/java/forge/ai/ability/SacrificeAi.java b/forge-ai/src/main/java/forge/ai/ability/SacrificeAi.java index b66785bc0ee..4cef29c7ef5 100644 --- a/forge-ai/src/main/java/forge/ai/ability/SacrificeAi.java +++ b/forge-ai/src/main/java/forge/ai/ability/SacrificeAi.java @@ -133,7 +133,7 @@ public class SacrificeAi extends SpellAbilityAi { List humanList = CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard(), sa); - // Since all of the cards have remAIDeck:True, I enabled 1 for 1 + // Since all of the cards have AI:RemoveDeck:All, I enabled 1 for 1 // (or X for X) trades for special decks if (humanList.size() < amount) { return false; diff --git a/forge-game/src/main/java/forge/game/card/CardPredicates.java b/forge-game/src/main/java/forge/game/card/CardPredicates.java index b30734de635..4809a42da8d 100644 --- a/forge-game/src/main/java/forge/game/card/CardPredicates.java +++ b/forge-game/src/main/java/forge/game/card/CardPredicates.java @@ -413,6 +413,15 @@ public final class CardPredicates { }; } + public static final Predicate isRemAIDeck() { + return new Predicate() { + @Override + public boolean apply(final Card c) { + return c.getRules().getAiHints().getRemAIDecks(); + } + }; + } + public static class Presets { /** diff --git a/forge-gui/res/cardsfolder/b/blood_operative.txt b/forge-gui/res/cardsfolder/b/blood_operative.txt index b2761115dc7..f883882404d 100644 --- a/forge-gui/res/cardsfolder/b/blood_operative.txt +++ b/forge-gui/res/cardsfolder/b/blood_operative.txt @@ -3,7 +3,7 @@ ManaCost:1 B B Types:Creature Vampire Assassin PT:3/1 K:Lifelink -T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, you may exile target card from a graveyard. +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | OptionalDecider$ You | TriggerDescription$ When CARDNAME enters the battlefield, you may exile target card from a graveyard. SVar:TrigChangeZone:DB$ChangeZone | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Card | TgtPrompt$ Select target card in a graveyard T:Mode$ Surveil | ValidPlayer$ You | Execute$ TrigReturn | TriggerZones$ Graveyard | IsPresent$ Card.StrictlySelf | PresentZone$ Graveyard | PresentPlayer$ You | TriggerDescription$ Whenever you surveil, if CARDNAME is in your graveyard, you may pay 3 life. If you do, return CARDNAME to your hand. SVar:TrigReturn:AB$ChangeZone | Cost$ PayLife<3> | Defined$ Self | Origin$ Graveyard | Destination$ Hand diff --git a/forge-gui/res/cardsfolder/s/sentinel_tower.txt b/forge-gui/res/cardsfolder/s/sentinel_tower.txt index 50f305c32d6..d3cdad16182 100644 --- a/forge-gui/res/cardsfolder/s/sentinel_tower.txt +++ b/forge-gui/res/cardsfolder/s/sentinel_tower.txt @@ -1,7 +1,7 @@ Name:Sentinel Tower ManaCost:4 Types:Artifact -T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | Execute$ TrigDmg | TriggerZones$ Battlefield | TriggerDescription$ Whenever an instant or sorcery spell is cast during your turn, CARDNAME deals damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn. +T:Mode$ SpellCast | ValidCard$ Instant,Sorcery | Execute$ TrigDmg | PlayerTurn$ True | TriggerZones$ Battlefield | TriggerDescription$ Whenever an instant or sorcery spell is cast during your turn, CARDNAME deals damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn. SVar:TrigDmg:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X | References$ X SVar:X:TriggerObjectsCurrentCastSpells$Valid Sorcery,Instant Oracle:Whenever an instant or sorcery spell is cast during your turn, Sentinel Tower deals damage to any target equal to 1 plus the number of instant and sorcery spells cast before that spell this turn. diff --git a/forge-gui/src/main/java/forge/deck/DeckImportController.java b/forge-gui/src/main/java/forge/deck/DeckImportController.java index 217115efe5a..d8182d211d0 100644 --- a/forge-gui/src/main/java/forge/deck/DeckImportController.java +++ b/forge-gui/src/main/java/forge/deck/DeckImportController.java @@ -78,6 +78,9 @@ public class DeckImportController { final DeckRecognizer.TokenType type = t.getType(); if (type == DeckRecognizer.TokenType.SectionName) { section = t.getText().toLowerCase(); + if (section.startsWith("//")) { + continue; + } // can't use wildcards in switch/case, so if/else it is if (section.startsWith("main")) { deckSection = DeckSection.Main; @@ -101,7 +104,7 @@ public class DeckImportController { deckSection = DeckSection.Conspiracy; } else { - throw new NotImplementedException("Unexpected section: %s", t.getText()); + throw new NotImplementedException("Unexpected section: " + t.getText()); } } if (type != DeckRecognizer.TokenType.KnownCard) {