Update direct references to RemAIDeck/RemRandomDeck to use the new format

This commit is contained in:
Michael Kamensky
2018-10-19 12:13:31 +00:00
committed by Sol
parent 0f118da920
commit 4b52ff05d5
14 changed files with 29 additions and 19 deletions

View File

@@ -528,7 +528,7 @@ public class AiCostDecision extends CostDecisionMakerBase {
// are currently conventionally flagged with AILogic$ DoSacrifice. // are currently conventionally flagged with AILogic$ DoSacrifice.
c = AbilityUtils.calculateAmount(source, source.getSVar("ChosenX"), null); c = AbilityUtils.calculateAmount(source, source.getSVar("ChosenX"), null);
} else { } 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; return null;
} }
} else { } else {

View File

@@ -342,7 +342,7 @@ public class AnimateAi extends SpellAbilityAi {
// This is reasonable for now. Kamahl, Fist of Krosa and a sorcery or // This is reasonable for now. Kamahl, Fist of Krosa and a sorcery or
// two are the only things // 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 // this can do a reasonably
// good job of picking a good target // good job of picking a good target
return false; return false;

View File

@@ -1459,7 +1459,7 @@ public class ChangeZoneAi extends SpellAbilityAi {
fetchList = CardLists.filter(fetchList, new Predicate<Card>() { fetchList = CardLists.filter(fetchList, new Predicate<Card>() {
@Override @Override
public boolean apply(final Card c) { 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 false;
} }
return true; return true;

View File

@@ -114,7 +114,7 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
// spBounceAll has some AI we can compare to. // spBounceAll has some AI we can compare to.
if (origin.equals(ZoneType.Hand) || origin.equals(ZoneType.Library)) { if (origin.equals(ZoneType.Hand) || origin.equals(ZoneType.Library)) {
if (!sa.usesTargeting()) { 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; return true;
} else { } else {
// search targetable Opponents // search targetable Opponents
@@ -344,8 +344,8 @@ public class ChangeZoneAllAi extends SpellAbilityAi {
if (ComputerUtilAbility.getAbilitySourceName(sa).equals("Profaner of the Dead")) { 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 // 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 // Profaner from exile without paying its mana cost. Otherwise the card is marked AI:RemoveDeck:All and
// specific AI to support playing it in a smarter way. Feel free to expand. // 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(); return !CardLists.filter(ai.getOpponents().getCardsIn(origin), CardPredicates.Presets.CREATURES).isEmpty();
} }

View File

@@ -146,10 +146,9 @@ public class CloneAi extends SpellAbilityAi {
// Default: // Default:
// This is reasonable for now. Kamahl, Fist of Krosa and a sorcery or // This is reasonable for now. Kamahl, Fist of Krosa and a sorcery or
// two are the only things // two are the only things that clone a target. Those can just use
// that clone a target. Those can just use SVar:RemAIDeck:True until // AI:RemoveDeck:All until this can do a reasonably good job of picking
// this can do a reasonably // a good target
// good job of picking a good target
return false; return false;
} }

View File

@@ -36,7 +36,7 @@ public class ControlExchangeAi extends SpellAbilityAi {
list = CardLists.filter(list, new Predicate<Card>() { list = CardLists.filter(list, new Predicate<Card>() {
@Override @Override
public boolean apply(final Card c) { 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); object1 = ComputerUtilCard.getBestAI(list);

View File

@@ -171,7 +171,7 @@ public class ControlGainAi extends SpellAbilityAi {
} }
// do not take control on something it doesn't know how to use // do not take control on something it doesn't know how to use
return !c.hasSVar("RemAIDeck"); return !c.getRules().getAiHints().getRemAIDecks();
} }
}); });

View File

@@ -83,7 +83,7 @@ public class CopyPermanentAi extends SpellAbilityAi {
CardCollection list = new CardCollection(CardUtil.getValidCardsToTarget(sa.getTargetRestrictions(), sa)); 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 //Nothing to target
if (list.isEmpty()) { if (list.isEmpty()) {
return false; return false;

View File

@@ -38,8 +38,7 @@ public class PowerExchangeAi extends SpellAbilityAi {
list = CardLists.filter(list, new Predicate<Card>() { list = CardLists.filter(list, new Predicate<Card>() {
@Override @Override
public boolean apply(final Card c) { public boolean apply(final Card c) {
final Map<String, String> vars = c.getSVars(); return !c.getRules().getAiHints().getRemAIDecks() && c.canBeTargetedBy(sa);
return !vars.containsKey("RemAIDeck") && c.canBeTargetedBy(sa);
} }
}); });
CardLists.sortByPowerAsc(list); CardLists.sortByPowerAsc(list);

View File

@@ -133,7 +133,7 @@ public class SacrificeAi extends SpellAbilityAi {
List<Card> humanList = List<Card> humanList =
CardLists.getValidCards(opp.getCardsIn(ZoneType.Battlefield), valid.split(","), sa.getActivatingPlayer(), sa.getHostCard(), sa); 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 // (or X for X) trades for special decks
if (humanList.size() < amount) { if (humanList.size() < amount) {
return false; return false;

View File

@@ -413,6 +413,15 @@ public final class CardPredicates {
}; };
} }
public static final Predicate<Card> isRemAIDeck() {
return new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return c.getRules().getAiHints().getRemAIDecks();
}
};
}
public static class Presets { public static class Presets {
/** /**

View File

@@ -3,7 +3,7 @@ ManaCost:1 B B
Types:Creature Vampire Assassin Types:Creature Vampire Assassin
PT:3/1 PT:3/1
K:Lifelink 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 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. 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 SVar:TrigReturn:AB$ChangeZone | Cost$ PayLife<3> | Defined$ Self | Origin$ Graveyard | Destination$ Hand

View File

@@ -1,7 +1,7 @@
Name:Sentinel Tower Name:Sentinel Tower
ManaCost:4 ManaCost:4
Types:Artifact 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:TrigDmg:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ X | References$ X
SVar:X:TriggerObjectsCurrentCastSpells$Valid Sorcery,Instant 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. 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.

View File

@@ -78,6 +78,9 @@ public class DeckImportController {
final DeckRecognizer.TokenType type = t.getType(); final DeckRecognizer.TokenType type = t.getType();
if (type == DeckRecognizer.TokenType.SectionName) { if (type == DeckRecognizer.TokenType.SectionName) {
section = t.getText().toLowerCase(); section = t.getText().toLowerCase();
if (section.startsWith("//")) {
continue;
}
// can't use wildcards in switch/case, so if/else it is // can't use wildcards in switch/case, so if/else it is
if (section.startsWith("main")) { if (section.startsWith("main")) {
deckSection = DeckSection.Main; deckSection = DeckSection.Main;
@@ -101,7 +104,7 @@ public class DeckImportController {
deckSection = DeckSection.Conspiracy; deckSection = DeckSection.Conspiracy;
} }
else { else {
throw new NotImplementedException("Unexpected section: %s", t.getText()); throw new NotImplementedException("Unexpected section: " + t.getText());
} }
} }
if (type != DeckRecognizer.TokenType.KnownCard) { if (type != DeckRecognizer.TokenType.KnownCard) {