mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Update direct references to RemAIDeck/RemRandomDeck to use the new format
This commit is contained in:
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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) {
|
||||||
|
|||||||
Reference in New Issue
Block a user