This commit is contained in:
Churrufli
2022-01-26 23:50:47 +01:00
89 changed files with 517 additions and 272 deletions

15
.mvn/local-settings.xml Normal file
View File

@@ -0,0 +1,15 @@
<!--
Derived from: https://stackoverflow.com/a/67002852
-->
<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 http://maven.apache.org/xsd/settings-1.2.0.xsd">
<mirrors>
<mirror>
<id>4thline-repo-http-unblocker</id>
<mirrorOf>4thline-repo</mirrorOf>
<name></name>
<url>http://4thline.org/m2</url>
</mirror>
</mirrors>
</settings>

1
.mvn/maven.config Normal file
View File

@@ -0,0 +1 @@
--settings ./.mvn/local-settings.xml

View File

@@ -624,7 +624,7 @@ public class AiAttackController {
// Attempt to see if there's a defined entity that must be attacked strictly this turn...
GameEntity entity = ai.getMustAttackEntityThisTurn();
if (entity == null) {
if (nextTurn || entity == null) {
// ...or during the attacking creature controller's turn
entity = ai.getMustAttackEntity();
}
@@ -720,6 +720,7 @@ public class AiAttackController {
continue;
}
boolean mustAttack = false;
// TODO for nextTurn check if it was temporary
if (attacker.isGoaded()) {
mustAttack = true;
} else if (attacker.getSVar("MustAttack").equals("True")) {
@@ -736,7 +737,7 @@ public class AiAttackController {
mustAttack = true;
}
}
if (mustAttack || attacker.getController().getMustAttackEntity() != null || attacker.getController().getMustAttackEntityThisTurn() != null) {
if (mustAttack || (attacker.getController().getMustAttackEntity() != null && nextTurn) || (attacker.getController().getMustAttackEntityThisTurn() != null && !nextTurn)) {
combat.addAttacker(attacker, defender);
attackersLeft.remove(attacker);
numForcedAttackers++;

View File

@@ -3040,11 +3040,11 @@ public class ComputerUtil {
public static boolean aiLifeInDanger(Player ai, boolean serious, int payment) {
// TODO should also consider them as teams
for (Player opponent: ai.getOpponents()) {
// test whether the human can kill the ai next turn
Combat combat = new Combat(opponent);
boolean containsAttacker = false;
boolean thisCombat = ai.getGame().getPhaseHandler().isPlayerTurn(opponent) && ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.COMBAT_BEGIN);
for (Card att : opponent.getCreaturesInPlay()) {
if (ComputerUtilCombat.canAttackNextTurn(att, ai)) {
if ((thisCombat && CombatUtil.canAttack(att, ai)) || (!thisCombat && ComputerUtilCombat.canAttackNextTurn(att, ai))) {
combat.addAttacker(att, ai);
containsAttacker = true;
}
@@ -3052,6 +3052,8 @@ public class ComputerUtil {
if (!containsAttacker) {
continue;
}
// TODO if it's next turn ignore mustBlockCards
AiBlockController block = new AiBlockController(ai, false);
block.assignBlockersForCombat(combat);

View File

@@ -43,7 +43,7 @@ public class DamagePreventAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
if (tgt == null) {
// As far as I can tell these Defined Cards will only have one of them
final List<GameObject> objects = AbilityUtils.getDefinedObjects(sa.getHostCard(), sa.getParam("Defined"), sa);
final List<GameObject> objects = AbilityUtils.getDefinedObjects(hostCard, sa.getParam("Defined"), sa);
// react to threats on the stack
if (!game.getStack().isEmpty()) {
@@ -138,7 +138,7 @@ public class DamagePreventAi extends SpellAbilityAi {
}
}
if (sa.usesTargeting() && sa.isDividedAsYouChoose() && !sa.getTargets().isEmpty()) {
sa.addDividedAllocation(sa.getTargets().get(0), AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("Amount"), sa));
sa.addDividedAllocation(sa.getTargets().get(0), AbilityUtils.calculateAmount(hostCard, sa.getParam("Amount"), sa));
}
return chance;

View File

@@ -39,6 +39,10 @@ public class GoadAi extends SpellAbilityAi {
if (ComputerUtilCard.isUselessCreature(ai, c)) {
return false;
}
// useless
if (c.isGoadedBy(ai)) {
return false;
}
// select creatures which can attack an Opponent other than ai
for (Player o : ai.getOpponents()) {
if (ComputerUtilCombat.canAttackNextTurn(c, o)) {
@@ -64,6 +68,10 @@ public class GoadAi extends SpellAbilityAi {
if (ComputerUtilCard.isUselessCreature(ai, c)) {
return false;
}
// useless
if (c.isGoadedBy(ai)) {
return false;
}
// select only creatures AI can block
return ComputerUtilCard.canBeBlockedProfitably(ai, c, false);
}

View File

@@ -1939,7 +1939,6 @@ public class GameAction {
public void startGame(GameOutcome lastGameOutcome) {
startGame(lastGameOutcome, null);
}
public void startGame(GameOutcome lastGameOutcome, Runnable startGameHook) {
Player first = determineFirstTurnPlayer(lastGameOutcome);

View File

@@ -992,12 +992,17 @@ public class AbilityUtils {
*/
public static PlayerCollection getDefinedPlayers(final Card card, final String def, final CardTraitBase sa) {
final PlayerCollection players = new PlayerCollection();
final String defined = (def == null) ? "You" : applyAbilityTextChangeEffects(def, sa);
String changedDef = (def == null) ? "You" : applyAbilityTextChangeEffects(def, sa); // default to Self
final String[] incR = changedDef.split("\\.", 2);
String defined = incR[0];
final Game game = card == null ? null : card.getGame();
final Player player = sa instanceof SpellAbility ? ((SpellAbility)sa).getActivatingPlayer() : card.getController();
if (defined.equals("TargetedOrController")) {
if (defined.equals("Self")) {
// do nothing, Self is for Cards, not Players
} else if (defined.equals("TargetedOrController")) {
players.addAll(getDefinedPlayers(card, "Targeted", sa));
players.addAll(getDefinedPlayers(card, "TargetedController", sa));
}
@@ -1056,6 +1061,15 @@ public class AbilityUtils {
else if (defined.startsWith("Remembered")) {
addPlayer(card.getRemembered(), defined, players);
}
else if (defined.startsWith("Imprinted")) {
addPlayer(Lists.newArrayList(card.getImprintedCards()), defined, players);
}
else if (defined.startsWith("EffectSource")) {
Card root = findEffectRoot(card);
if (root != null) {
addPlayer(Lists.newArrayList(root), defined, players);
}
}
else if (defined.startsWith("DelayTriggerRemembered") && sa instanceof SpellAbility) {
SpellAbility root = ((SpellAbility)sa).getRootAbility();
if (root != null) {
@@ -1064,16 +1078,6 @@ public class AbilityUtils {
System.err.println("Warning: couldn't find trigger SA in the chain of SpellAbility " + sa);
}
}
else if (defined.equals("ImprintedController")) {
for (final Card rem : card.getImprintedCards()) {
players.add(rem.getController());
}
}
else if (defined.equals("ImprintedOwner")) {
for (final Card rem : card.getImprintedCards()) {
players.add(rem.getOwner());
}
}
else if (defined.startsWith("Triggered") && sa instanceof SpellAbility) {
String defParsed = defined.endsWith("AndYou") ? defined.substring(0, defined.indexOf("AndYou")) : defined;
if (defined.endsWith("AndYou")) {
@@ -1124,7 +1128,7 @@ public class AbilityUtils {
}
}
else {
final String triggeringType = defParsed.substring(9);
String triggeringType = defParsed.substring(9);
o = root.getTriggeringObject(AbilityKey.fromString(triggeringType));
}
if (o != null) {
@@ -1176,30 +1180,27 @@ public class AbilityUtils {
players.addAll(game.getPlayersInTurnOrder());
players.removeAll((FCollectionView<Player>)getDefinedPlayers(card, defined.substring(3), sa));
}
else if (defined.equals("EnchantedController")) {
if (card.getEnchantingCard() == null) {
return players;
}
players.add(card.getEnchantingCard().getController());
}
else if (defined.equals("EnchantedOwner")) {
if (card.getEnchantingCard() == null) {
return players;
}
players.add(card.getEnchantingCard().getOwner());
}
else if (defined.equals("EnchantedPlayer")) {
final Object o = sa.getHostCard().getEntityAttachedTo();
if (o instanceof Player) {
players.add((Player) o);
}
}
else if (defined.equals("AttackingPlayer")) {
if (!game.getPhaseHandler().inCombat()) {
return players;
else if (defined.startsWith("Enchanted")) {
if (card.getEntityAttachedTo() != null) {
addPlayer(Lists.newArrayList(card.getEntityAttachedTo()), defined, players);
}
}
else if (defined.startsWith("Equipped")) {
if (card.getEquipping() != null) {
addPlayer(Lists.newArrayList(card.getEquipping()), defined, players);
}
}
else if (defined.equals("AttackingPlayer")) {
if (game.getPhaseHandler().inCombat()) {
players.add(game.getCombat().getAttackingPlayer());
}
}
else if (defined.equals("DefendingPlayer")) {
players.add(game.getCombat().getDefendingPlayerRelatedTo(card));
}
@@ -1250,9 +1251,11 @@ public class AbilityUtils {
}
}
}
else if (defined.equals("Caster") && sa.getHostCard().wasCast()) {
else if (defined.equals("Caster")) {
if (sa.getHostCard().wasCast()) {
players.add((sa.getHostCard().getCastSA().getActivatingPlayer()));
}
}
else if (defined.equals("ActivePlayer")) {
players.add(game.getPhaseHandler().getPlayerTurn());
}
@@ -1267,11 +1270,17 @@ public class AbilityUtils {
players.add(game.getNextPlayerAfter(player, dir));
}
else {
for (Player p : game.getPlayersInTurnOrder()) {
if (p.isValid(defined, player, card, sa)) {
players.add(p);
// will be filtered below
players.addAll(game.getPlayersInTurnOrder());
}
if (incR.length > 1 && !players.isEmpty()) {
String[] valids = incR[1].split(",");
// need to add valids onto all of them
for (int i = 0; i < valids.length; i++) {
valids[i] = "Player." + valids[i];
}
return players.filter(PlayerPredicates.restriction(valids, player, card, sa));
}
return players;
}

View File

@@ -72,7 +72,7 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
if (sa.hasParam("AtRandom")) {
random = true;
Aggregates.random(abilities, amount, chosenSAs);
} else {
} else if (!abilities.isEmpty()) {
chosenSAs = p.getController().chooseSpellAbilitiesForEffect(abilities, sa, prompt, amount, ImmutableMap.of());
}

View File

@@ -476,10 +476,10 @@ public class CountersPutEffect extends SpellAbilityEffect {
// these trigger are one per counter
for (int i = 0; i < added; i++) {
final Trigger trig = TriggerHandler.parseTrigger(delTrig.toString(), sa.getHostCard(), intrinsic);
final Trigger trig = TriggerHandler.parseTrigger(delTrig.toString(), host, intrinsic);
trig.addRemembered(tgt);
final SpellAbility newSa = AbilityFactory.getAbility(trigSA, sa.getHostCard());
final SpellAbility newSa = AbilityFactory.getAbility(trigSA, host);
newSa.setIntrinsic(intrinsic);
trig.setOverridingAbility(newSa);
sa.getActivatingPlayer().getGame().getTriggerHandler().registerDelayedTrigger(trig);

View File

@@ -79,7 +79,7 @@ public class CountersRemoveAllEffect extends SpellAbilityEffect {
}
}
if (sa.hasParam("RememberAmount")) {
sa.getHostCard().setChosenNumber(numberRemoved);
sa.getHostCard().addRemembered(Integer.valueOf(numberRemoved));
}
}
}

View File

@@ -27,6 +27,7 @@ public class GoadEffect extends SpellAbilityEffect {
continue;
}
// 701.38d is handled by getGoaded
tgtC.addGoad(timestamp, player);
final GameCommand untilEOT = new GameCommand() {

View File

@@ -67,9 +67,10 @@ public class MustAttackEffect extends SpellAbilityEffect {
}
}
// TODO these should not override but add another requirement
for (final Player p : tgtPlayers) {
if ((tgt == null) || p.canBeTargetedBy(sa)) {
if (thisTurn) {
if (thisTurn || !p.getGame().getPhaseHandler().isPlayerTurn(p)) {
p.setMustAttackEntityThisTurn(entity);
} else {
p.setMustAttackEntity(entity);

View File

@@ -65,7 +65,6 @@ public class MustBlockEffect extends SpellAbilityEffect {
} else {
final Card attacker = cards.get(0);
c.addMustBlockCard(attacker);
System.out.println(c + " is adding " + attacker + " to mustBlockCards: " + c.getMustBlockCards());
}
}
}

View File

@@ -3474,6 +3474,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
runUnattachCommands();
}
public final boolean isModified() {
if (this.isEquipped() || this.hasCounters()) {
return true;
}
return Iterables.any(this.getEnchantedBy(), CardPredicates.isController(this.getController()));
}
public final void setType(final CardType type0) {
currentState.setType(type0);
}
@@ -5419,6 +5426,11 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
damageType = DamageType.Deathtouch;
}
// 704.8: if it looks like the creature might die from SBA make sure the LKI is refreshed
if (hasBeenDealtDeathtouchDamage() || (getDamage() > 0 && getLethal() <= getDamage())) {
game.updateLastStateForCard(this);
}
// Play the Damage sound
game.fireEvent(new GameEventCardDamaged(this, source, damageIn, damageType));
}
@@ -6588,8 +6600,8 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
return goad.containsValue(p);
}
public final Collection<Player> getGoaded() {
return goad.values();
public final PlayerCollection getGoaded() {
return new PlayerCollection(goad.values()); // 701.38d
}
/**

View File

@@ -852,9 +852,6 @@ public class CardFactoryUtil {
String pumpStr = "DB$ Pump | Defined$ Self | NumAtt$ " + n + " | NumDef$ " + n;
SpellAbility pump = AbilityFactory.getAbility(pumpStr, card);
if ("X".equals(n)) {
pump.setSVar("X", "Count$Valid Creature.attacking");
}
final Trigger bushidoTrigger1 = TriggerHandler.parseTrigger(trigBlock, card, intrinsic);
final Trigger bushidoTrigger2 = TriggerHandler.parseTrigger(trigBlocked, card, intrinsic);
@@ -1480,7 +1477,7 @@ public class CardFactoryUtil {
"TgtPrompt$ Select target artifact creature | CounterType$ P1P1 | CounterNum$ ModularX | Modular$ True";
String trigStr = "Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Graveyard" +
" | OptionalDecider$ TriggeredCardController | TriggerController$ TriggeredCardController" +
" | OptionalDecider$ TriggeredCardController" +
" | Secondary$ True | TriggerDescription$ When CARDNAME dies, " +
"you may put a +1/+1 counter on target artifact creature for each +1/+1 counter on CARDNAME";
@@ -1787,16 +1784,11 @@ public class CardFactoryUtil {
final String actualTrigger = "Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard"
+ "| Secondary$ True | OptionalDecider$ You | ValidCard$ Card.Self"
+ "| TriggerController$ TriggeredCardController | TriggerDescription$ " + k[0] + " " + k[1]
+ " (" + inst.getReminderText() + ")";
+ "| TriggerDescription$ " + k[0] + " " + k[1] + " (" + inst.getReminderText() + ")";
final String effect = "DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand"
+ "| ValidTgts$ Spirit.YouOwn+cmcLE" + k[1];
final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, intrinsic);
final SpellAbility sp = AbilityFactory.getAbility(effect, card);
// Soulshift X
if (k[1].equals("X")) {
sp.setSVar("X", "Count$LastStateBattlefield " + k[3]);
}
parsedTrigger.setOverridingAbility(sp);
@@ -2004,8 +1996,8 @@ public class CardFactoryUtil {
+ " | TriggerDescription$ If you cast it any time a sorcery couldn't have been cast, "
+ " the controller of the permanent it becomes sacrifices it at the beginning of the next cleanup step.";
final String strDelay = "DB$ DelayedTrigger | Mode$ Phase | Phase$ Cleanup | TriggerDescription$ At the beginning of the next cleanup step, sacrifice CARDNAME.";
final String strSac = "DB$ SacrificeAll | Defined$ Self";
final String strDelay = "DB$ DelayedTrigger | Mode$ Phase | Phase$ Cleanup | RememberObjects$ Self | TriggerDescription$ At the beginning of the next cleanup step, sacrifice CARDNAME.";
final String strSac = "DB$ SacrificeAll | Defined$ DelayTriggerRememberedLKI";
SpellAbility saDelay = AbilityFactory.getAbility(strDelay, card);
saDelay.setAdditionalAbility("Execute", (AbilitySub) AbilityFactory.getAbility(strSac, card));

View File

@@ -228,7 +228,7 @@ public final class CardPredicates {
return new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return (c != null) && c.isValid(restrictions, sourceController, source, spellAbility);
return c != null && c.isValid(restrictions, sourceController, source, spellAbility);
}
};
}
@@ -237,7 +237,7 @@ public final class CardPredicates {
return new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
return (c != null) && c.isValid(restrictions, sourceController, source, spellAbility);
return c != null && c.isValid(restrictions, sourceController, source, spellAbility);
}
};
}

View File

@@ -1328,6 +1328,10 @@ public class CardProperty {
if (card.isEquipping()) {
return false;
}
} else if (property.startsWith("modified")) {
if (!card.isModified()) {
return false;
}
} else if (property.startsWith("token")) {
if (!card.isToken() && !card.isTokenCard()) {
return false;

View File

@@ -263,7 +263,7 @@ public class TokenInfo {
}
static public Card getProtoType(final String script, final SpellAbility sa, final Player owner) {
return getProtoType(script, sa, owner, true);
return getProtoType(script, sa, owner, !sa.hasParam("LockTokenScript"));
}
static public Card getProtoType(final String script, final SpellAbility sa, final Player owner, boolean applyTextChange) {
// script might be null, or sa might be null

View File

@@ -35,10 +35,6 @@ public class AttackRequirement {
this.causesToAttack = causesToAttack;
final GameEntity mustAttack = attacker.getController().getMustAttackEntity();
if (mustAttack != null) {
defenderSpecific.add(mustAttack);
}
final GameEntity mustAttackThisTurn = attacker.getController().getMustAttackEntityThisTurn();
if (mustAttackThisTurn != null) {
defenderSpecific.add(mustAttackThisTurn);
@@ -47,6 +43,7 @@ public class AttackRequirement {
int nAttackAnything = 0;
if (attacker.isGoaded()) {
// Goad has two requirements but the other is handled by CombatUtil currently
nAttackAnything += attacker.getGoaded().size();
}
@@ -71,10 +68,6 @@ public class AttackRequirement {
}
}
final GameEntity mustAttack3 = attacker.getMustAttackEntity();
if (mustAttack3 != null) {
defenderSpecific.add(mustAttack3);
}
final GameEntity mustAttackThisTurn3 = attacker.getMustAttackEntityThisTurn();
if (mustAttackThisTurn3 != null) {
defenderSpecific.add(mustAttackThisTurn3);

View File

@@ -72,7 +72,7 @@ public class CostReveal extends CostPartWithList {
modifiedHand.remove(source); // can't pay for itself
handList = modifiedHand;
}
handList = CardLists.getValidCards(handList, getType().split(","), payer, source, ability);
handList = CardLists.getValidCards(handList, getType(), payer, source, ability);
return handList.size();
}

View File

@@ -825,6 +825,7 @@ public class PhaseHandler implements java.io.Serializable {
private Player handleNextTurn() {
game.getStack().onNextTurn();
// reset mustAttackEntity
playerTurn.setMustAttackEntityThisTurn(playerTurn.getMustAttackEntity());
playerTurn.setMustAttackEntity(null);
game.getTriggerHandler().clearThisTurnDelayedTrigger();

View File

@@ -116,8 +116,7 @@ public enum PhaseType {
String sTo = s.substring(idxArrow + 2);
PhaseType to = StringUtils.isBlank(sTo) ? PhaseType.CLEANUP : PhaseType.smartValueOf(sTo);
result.addAll(EnumSet.range(from, to));
}
else {
} else {
result.add(PhaseType.smartValueOf(s));
}
}

View File

@@ -5,6 +5,7 @@ import java.util.Comparator;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import forge.game.CardTraitBase;
import forge.game.card.Card;
import forge.game.card.CardLists;
import forge.game.card.CounterEnumType;
@@ -129,6 +130,15 @@ public final class PlayerPredicates {
};
}
public static final Predicate<Player> restriction(final String[] restrictions, final Player sourceController, final Card source, final CardTraitBase spellAbility) {
return new Predicate<Player>() {
@Override
public boolean apply(final Player c) {
return c != null && c.isValid(restrictions, sourceController, source, spellAbility);
}
};
}
public static final Comparator<Player> compareByZoneSize(final ZoneType zone) {
return new Comparator<Player>() {
@Override

View File

@@ -306,6 +306,9 @@ public final class StaticAbilityContinuous {
input = input.replaceAll("chosenEvenOdd", hostCard.getChosenEvenOdd().toString().toLowerCase());
}
input = input.replace("HostCardUID", hostCardUID);
if (params.containsKey("CalcKeywordN")) {
input = input.replace("N", String.valueOf(AbilityUtils.calculateAmount(hostCard, params.get("CalcKeywordN"), stAb)));
}
return input;
}
@@ -867,7 +870,7 @@ public final class StaticAbilityContinuous {
// but only do it if the trigger doesn't already have a overriding ability
addedTrigger.add(actualTrigger);
if (params.containsKey("TriggerRememberDefined")) {
String triggerRemembered = (params.get("TriggerRememberDefined"));
String triggerRemembered = params.get("TriggerRememberDefined");
for (final String rem : triggerRemembered.split(",")) {
for (final Object o : AbilityUtils.getDefinedEntities(hostCard, rem, stAb)) {
actualTrigger.addRemembered(o);
@@ -903,7 +906,7 @@ public final class StaticAbilityContinuous {
}
// add Types
if ((addTypes != null) || (removeTypes != null) || addAllCreatureTypes
if (addTypes != null || removeTypes != null || addAllCreatureTypes
|| removeSuperTypes || removeCardTypes || removeLandTypes || removeCreatureTypes || removeArtifactTypes || removeEnchantmentTypes) {
affectedCard.addChangedCardTypes(addTypes, removeTypes, addAllCreatureTypes, removeSuperTypes, removeCardTypes, removeSubTypes,
removeLandTypes, removeCreatureTypes, removeArtifactTypes, removeEnchantmentTypes,

View File

@@ -17,15 +17,15 @@ public class StaticAbilityIgnoreHexproofShroud {
final Game game = entity.getGame();
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
for (final StaticAbility stAb : ca.getStaticAbilities()) {
if (stAb.isSuppressed() || !stAb.checkConditions()) {
continue;
}
if (keyword.equals(Keyword.HEXPROOF) && !stAb.getParam("Mode").equals(HEXPROOF_MODE)) {
continue;
}
if (keyword.equals(Keyword.SHROUD) && !stAb.getParam("Mode").equals(SHROUD_MODE)) {
continue;
}
if (stAb.isSuppressed() || !stAb.checkConditions()) {
continue;
}
if (commonAbility(stAb, entity, spellAbility)) {
return true;
}

View File

@@ -7,6 +7,8 @@ import java.util.List;
import java.util.Map;
import forge.ai.GameState;
import forge.deck.Deck;
import forge.game.player.Player;
import forge.item.IPaperCard;
import org.apache.commons.lang3.StringUtils;
@@ -94,14 +96,26 @@ public class MatchController extends AbstractGuiGame {
}
}
public static Deck getPlayerDeck(final PlayerView playerView) {
try {
for (Player p : instance.getGameView().getGame().getPlayers()) {
if (p.getView() == playerView) {
return p.getRegisteredPlayer().getDeck();
}
}
} catch (Exception e) {
return null;
}
return null;
}
public static FImage getPlayerAvatar(final PlayerView p) {
final String lp = p.getLobbyPlayerName();
FImage avatar = avatarImages.get(lp);
if (avatar == null) {
if (StringUtils.isEmpty(p.getAvatarCardImageKey())) {
avatar = new FTextureRegionImage(FSkin.getAvatars().get(p.getAvatarIndex()));
}
else { //handle lobby players with art from cards
} else { //handle lobby players with art from cards
avatar = new CardAvatarImage(p.getAvatarCardImageKey());
}
}

View File

@@ -354,26 +354,24 @@ public class MatchScreen extends FScreen {
final GameView game = MatchController.instance.getGameView();
if (game == null) { return; }
if(gameMenu!=null) {
if(gameMenu.getChildCount()>3){
if(viewWinLose == null) {
if (gameMenu!=null) {
if (gameMenu.getChildCount()>2){
if (viewWinLose == null) {
gameMenu.getChildAt(0).setEnabled(!game.isMulligan());
gameMenu.getChildAt(1).setEnabled(!game.isMulligan());
gameMenu.getChildAt(2).setEnabled(!game.isMulligan());
gameMenu.getChildAt(3).setEnabled(!game.isMulligan());
gameMenu.getChildAt(4).setEnabled(false);
gameMenu.getChildAt(3).setEnabled(false);
} else {
gameMenu.getChildAt(0).setEnabled(false);
gameMenu.getChildAt(1).setEnabled(false);
gameMenu.getChildAt(2).setEnabled(false);
gameMenu.getChildAt(3).setEnabled(false);
gameMenu.getChildAt(4).setEnabled(true);
gameMenu.getChildAt(3).setEnabled(true);
}
}
}
if(devMenu!=null) {
if(devMenu.isVisible()){
if(viewWinLose == null)
if (devMenu!=null) {
if (devMenu.isVisible()){
if (viewWinLose == null)
devMenu.setEnabled(true);
else
devMenu.setEnabled(false);

View File

@@ -2,16 +2,12 @@ package forge.screens.match.views;
import forge.Forge;
import forge.assets.FSkinImage;
import forge.deck.Deck;
import forge.deck.FDeckViewer;
import forge.game.player.Player;
import forge.menu.FDropDownMenu;
import forge.menu.FMenuItem;
import forge.screens.match.MatchController;
import forge.screens.settings.SettingsScreen;
import forge.toolbox.FEvent;
import forge.toolbox.FEvent.FEventHandler;
import forge.toolbox.FOptionPane;
import forge.util.Localizer;
import forge.util.ThreadUtil;
@@ -47,26 +43,6 @@ public class VGameMenu extends FDropDownMenu {
GameStateDeserializer.loadGameState(MatchUtil.getGame(), ForgeConstants.USER_GAMES_DIR + "GameSave.txt");
}
}));*/
addItem(new FMenuItem(localizer.getMessage("lblDeckList"), FSkinImage.DECKLIST, new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
//pause game when spectating AI Match
if (!MatchController.instance.hasLocalPlayers()) {
if(!MatchController.instance.isGamePaused())
MatchController.instance.pauseMatch();
}
final Player player = MatchController.getHostedMatch().getGame().getPhaseHandler().getPlayerTurn();
if (player != null) {
final Deck deck = player.getRegisteredPlayer().getDeck();
if (deck != null) {
FDeckViewer.show(deck);
return;
}
}
FOptionPane.showMessageDialog(localizer.getMessage("lblNoPlayerPriorityNoDeckListViewed"));
}
}));
addItem(new FMenuItem(localizer.getMessage("lblAutoYields"), Forge.hdbuttons ? FSkinImage.HDYIELD : FSkinImage.WARNING, new FEventHandler() {
@Override
public void handleEvent(FEvent e) {

View File

@@ -2,14 +2,19 @@ package forge.screens.match.views;
import com.badlogic.gdx.utils.Align;
import forge.Forge;
import forge.Graphics;
import forge.assets.FImage;
import forge.assets.FSkinFont;
import forge.assets.FSkinImage;
import forge.deck.Deck;
import forge.deck.FDeckViewer;
import forge.game.player.PlayerView;
import forge.menu.FDropDown;
import forge.screens.match.MatchController;
import forge.toolbox.FContainer;
import forge.toolbox.FDisplayObject;
import forge.toolbox.FEvent;
import forge.toolbox.FLabel;
import forge.toolbox.FList;
import forge.util.Utils;
@@ -42,14 +47,38 @@ public class VPlayers extends FDropDown {
private static final float PADDING = Utils.scale(5);
private static final float HEIGHT = Utils.AVG_FINGER_HEIGHT * 1.8f;
private final PlayerView player;
private final Deck playerDeck;
private final FLabel btnDeck;
private boolean btnAdded = false;
private PlayerInfoPanel(PlayerView player0) {
player = player0;
playerDeck = MatchController.getPlayerDeck(player0);
btnDeck = new FLabel.ButtonBuilder().opaque(true).iconScaleFactor(0.99f).selectable().alphaComposite(1).iconInBackground(true).build();
btnDeck.setCommand(new FEvent.FEventHandler() {
@Override
public void handleEvent(FEvent e) {
if (playerDeck != null) {
//pause game when spectating AI Match
if (!MatchController.instance.hasLocalPlayers()) {
if(!MatchController.instance.isGamePaused())
MatchController.instance.pauseMatch();
}
FDeckViewer.show(playerDeck);
}
}
});
}
@Override
protected void doLayout(float width, float height) {
//TODO: Add FLabels to click to select player in top or bottom panel of Match screen
if (!btnAdded) {
btnDeck.setBounds(PADDING, PADDING, getHeight() - 2 * PADDING, getHeight() - 2 * PADDING);
btnDeck.setIcon(MatchController.getPlayerAvatar(player));
btnDeck.setOverlayIcon(Forge.hdbuttons ? FSkinImage.HDSEARCH : FSkinImage.SEARCH);
add(btnDeck);
btnAdded = true;
}
}
@Override
@@ -57,12 +86,9 @@ public class VPlayers extends FDropDown {
float x = PADDING;
float y = PADDING;
float h = getHeight() - 2 * y;
FImage avatarImage = MatchController.getPlayerAvatar(player);
g.drawImage(avatarImage, x, y, h, h);
x += h + PADDING;
g.drawText(player.getDetails(), FONT, FList.FORE_COLOR, x, y, getWidth() - PADDING - x, h, true, Align.left, true);
//Draw Player Details
g.drawText(player.getDetails() + playerDeck.getName(), FONT, FList.FORE_COLOR, x, y, getWidth() - PADDING - x, h, true, Align.left, true);
}
@Override

View File

@@ -9,6 +9,7 @@ import forge.assets.FImage;
import forge.assets.FSkinColor;
import forge.assets.FSkinColor.Colors;
import forge.assets.FSkinFont;
import forge.assets.FSkinImage;
import forge.assets.TextRenderer;
import forge.gui.UiCommand;
import forge.gui.interfaces.IButton;
@@ -110,6 +111,7 @@ public class FLabel extends FDisplayObject implements IButton {
private String text;
private FImage icon;
private FSkinImage overlayIcon;
private FSkinColor textColor, pressedColor;
private FEventHandler command;
private TextRenderer textRenderer;
@@ -172,6 +174,9 @@ public class FLabel extends FDisplayObject implements IButton {
public void setIcon(final FImage icon0) {
icon = icon0;
}
public void setOverlayIcon(final FSkinImage overlayIcon0) {
overlayIcon = overlayIcon0;
}
public boolean getIconScaleAuto() {
return iconScaleAuto;
@@ -321,6 +326,7 @@ public class FLabel extends FDisplayObject implements IButton {
}
protected void drawContent(Graphics g, float x, float y, float w, float h) {
try {
if (icon != null) {
float textY = y;
float iconWidth = icon.getWidth();
@@ -380,8 +386,18 @@ public class FLabel extends FDisplayObject implements IButton {
y += (h - iconHeight) / 2;
}
float mod = isHovered() && selectable ? iconWidth < iconHeight ? iconWidth/8f : iconHeight/8f : 0;
//draw icon
g.drawImage(icon, x-mod/2, y-mod/2, iconWidth+mod, iconHeight+mod);
//draw overlay
if (overlayIcon != null) {
float oldAlpha = g.getfloatAlphaComposite();
float overlayWidth = isHovered() ? iconWidth/2.5f : iconWidth/3.5f;
float overlayHeight = isHovered() ? iconHeight/2.5f : iconHeight/3.5f;
if (!isHovered())
g.setAlphaComposite(0.4f);
g.drawImage(overlayIcon, iconWidth-overlayWidth+mod, iconHeight-overlayHeight+mod, overlayWidth, overlayHeight);
g.setAlphaComposite(oldAlpha);
}
if (!text.isEmpty()) {
x += iconOffset;
w -= iconOffset;
@@ -397,6 +413,9 @@ public class FLabel extends FDisplayObject implements IButton {
}
drawText(g, x, y, w, h, alignment);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void drawText(Graphics g, float x, float y, float w, float h, int align) {

View File

@@ -1,10 +1,10 @@
Name:Assemble from Parts
ManaCost:B
Types:Instant
A:SP$ Effect | TgtZone$ Graveyard | ValidTgts$ Creature.YouOwn | TgtPrompt$ Select target creature card in your graveyard | StaticAbilities$ Assembly | RememberObjects$ Targeted | Name$ Assemble from Part's Perpetual Effect | Duration$ Permanent | StackDescription$ {c:Targeted} perpetually gains "{3} {B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery." | SpellDescription$ Target creature card in your graveyard perpetually gains "{3} {B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery."
SVar:Assembly:Mode$ Continuous | Affected$ Card.IsRemembered | AddAbility$ ABShuffle | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ Target creature card in your graveyard perpetually gains "{3} {B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery."
SVar:ABShuffle:AB$ ChangeZone | Cost$ 3 B ExileFromGrave<1/CARDNAME> | ActivationZone$ Graveyard | Origin$ All | Destination$ Library | Shuffle$ True | Defined$ Self | SubAbility$ DBCopy | SorcerySpeed$ True | StackDescription$ Shuffle CARDNAME into your library. | SpellDescription$ Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery.
A:SP$ Effect | TgtZone$ Graveyard | ValidTgts$ Creature.YouOwn | TgtPrompt$ Select target creature card in your graveyard | StaticAbilities$ Assembly | RememberObjects$ Targeted | Name$ Assemble from Part's Perpetual Effect | Duration$ Permanent | StackDescription$ {c:Targeted} perpetually gains "{3} {B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery." | SpellDescription$ Target creature card in your graveyard perpetually gains "{1}{B}{B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery."
SVar:Assembly:Mode$ Continuous | Affected$ Card.IsRemembered | AddAbility$ ABShuffle | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ Target creature card in your graveyard perpetually gains "{1}{B}{B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery."
SVar:ABShuffle:AB$ ChangeZone | Cost$ 1 B B ExileFromGrave<1/CARDNAME> | ActivationZone$ Graveyard | Origin$ All | Destination$ Library | Shuffle$ True | Defined$ Self | SubAbility$ DBCopy | SorcerySpeed$ True | StackDescription$ Shuffle CARDNAME into your library. | SpellDescription$ Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery.
SVar:DBCopy:DB$ CopyPermanent | Defined$ Self | SetPower$ 4 | SetToughness$ 4 | AddTypes$ Zombie | SetColor$ Black | StackDescription$ Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types.
SVar:AIPreference:ExileFromGraveCost$Creature.YouOwn+inZoneGraveyard
DeckHas:Ability$Token & Ability$Graveyard
Oracle:Target creature card in your graveyard perpetually gains "{3} {B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery."
Oracle:Target creature card in your graveyard perpetually gains "{1}{B}{B}, Exile this card from your graveyard: Shuffle it into your library. Create a token that's a copy of it, except it's a 4/4 black Zombie in addition to its other types. Activate only as a sorcery."

View File

@@ -2,7 +2,6 @@ Name:Avalanche Tusker
ManaCost:2 G U R
Types:Creature Elephant Warrior
PT:6/4
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCantBlock | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, target creature defending player controls blocks this combat if able.
SVar:TrigCantBlock:DB$ MustBlock | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select target creature | SpellDescription$ Target creature blocks CARDNAME this turn if able.
SVar:Picture:http://www.wizards.com/global/images/magic/general/avalanche_tusker.jpg
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigCantBlock | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME attacks, target creature defending player controls blocks it this combat if able.
SVar:TrigCantBlock:DB$ MustBlock | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select target creature
Oracle:Whenever Avalanche Tusker attacks, target creature defending player controls blocks it this combat if able.

View File

@@ -1,7 +1,7 @@
Name:Bloodrage Alpha
ManaCost:3 R
Types:Creature Wolf
PT:4/3
PT:4/4
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigCharm | TriggerDescription$ When CARDNAME enters the battlefield, ABILITY
SVar:TrigCharm:DB$ Charm | Choices$ DBTarget,DBDelayTrig
SVar:DBTarget:DB$ Pump | ValidTgts$ Wolf.Other+YouCtrl,Werewolf.Other+YouCtrl | AILogic$ Fight | TgtPrompt$ Select another target Wolf or Werewolf you control | SubAbility$ DBFight | StackDescription$ {c:ThisTargetedCard} | SpellDescription$ Another target Wolf or Werewolf you control fights target creature you don't control.

View File

@@ -5,11 +5,10 @@ R:Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield | ReplaceWith$
SVar:DBChooseOpp:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | ChoiceTitle$ Choose an opponent to give control to: | AILogic$ Curse | SubAbility$ MoveToPlay
SVar:MoveToPlay:DB$ ChangeZone | Hidden$ True | Origin$ All | Destination$ Battlefield | Defined$ ReplacedCard | GainControl$ True | NewController$ ChosenPlayer
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigCharm | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, ABILITY
SVar:TrigCharm:DB$ Charm | Choices$ LifePact,DiscardPact,ZombiesPact | ChoiceRestriction$ ThisGame | CharmNum$ 1
SVar:TrigCharm:DB$ Charm | Choices$ LifePact,DiscardPact,MakeZombies | ChoiceRestriction$ ThisGame | CharmNum$ 1
SVar:LifePact:DB$ SetLife | Defined$ You | LifeAmount$ 4 | SpellDescription$ Your life total becomes 4.
SVar:DiscardPact:DB$ Discard | Defined$ You | Mode$ Hand | SpellDescription$ Discard your hand.
SVar:ZombiesPact:DB$ RepeatEach | RepeatPlayers$ Player.Opponent | RepeatSubAbility$ MakeZombies | ChangeZoneTable$ True | SpellDescription$ Each opponent creates five 2/2 black Zombie creature tokens.
SVar:MakeZombies:DB$ Token | LegacyImage$ b 2 2 zombie rna | TokenAmount$ 5 | TokenScript$ b_2_2_zombie | TokenOwner$ Remembered | SpellDescription$ Each opponent creates five 2/2 black Zombie creature tokens.
SVar:MakeZombies:DB$ Token | TokenAmount$ 5 | TokenScript$ b_2_2_zombie | TokenOwner$ Opponent | SpellDescription$ Each opponent creates five 2/2 black Zombie creature tokens.
SVar:SacMe:6
AI:RemoveDeck:Random
DeckHas:Ability$Token

View File

@@ -2,9 +2,8 @@ Name:Curse of Bounty
ManaCost:1 G
Types:Enchantment Aura Curse
K:Enchant player
A:SP$ Attach | Cost$ 1 G | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, untap all nonland permanents you control. Each opponent attacking that player untaps all nonland permanents they control.
SVar:TrigRepeat:DB$ RepeatEach | RepeatPlayers$ TriggeredAttackingPlayerAndYou | RepeatSubAbility$ TrigUntap
SVar:TrigUntap:DB$ UntapAll | Defined$ Player.IsRemembered | ValidCards$ Permanent.nonLand | SpellDescription$ Whenever enchanted player is attacked, untap all nonland permanents you control. Each opponent attacking that player untaps all nonland permanents they control.
SVar:Picture:http://www.wizards.com/global/images/magic/general/curse_of_vitality.jpg
A:SP$ Attach | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigUntap | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, untap all nonland permanents you control. Each opponent attacking that player untaps all nonland permanents they control.
SVar:TrigUntap:DB$ UntapAll | Defined$ You | ValidCards$ Permanent.nonLand | SubAbility$ DBUntap
SVar:DBUntap:DB$ UntapAll | Defined$ TriggeredAttackingPlayer.Opponent | ValidCards$ Permanent.nonLand
Oracle:Enchant player\nWhenever enchanted player is attacked, untap all nonland permanents you control. Each opponent attacking that player untaps all nonland permanents they control.

View File

@@ -2,9 +2,8 @@ Name:Curse of Disturbance
ManaCost:2 B
Types:Enchantment Aura Curse
K:Enchant player
A:SP$ Attach | Cost$ 2 B | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, create a 2/2 black Zombie creature token. Each opponent attacking that player does the same.
SVar:TrigRepeat:DB$ RepeatEach | RepeatPlayers$ TriggeredAttackingPlayerAndYou | RepeatSubAbility$ TrigToken | ChangeZoneTable$ True
SVar:TrigToken:DB$ Token | TokenOwner$ Player.IsRemembered | TokenAmount$ 1 | TokenScript$ b_2_2_zombie | LegacyImage$ b 2 2 zombie c17 | SpellDescription$ Create a 2/2 black Zombie creature token. Activate only any time you could cast a sorcery.
SVar:Picture:http://www.wizards.com/global/images/magic/general/curse_of_vitality.jpg
A:SP$ Attach | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, create a 2/2 black Zombie creature token. Each opponent attacking that player does the same.
SVar:TrigToken:DB$ Token | TokenScript$ b_2_2_zombie | SubAbility$ DBToken
SVar:DBToken:DB$ Token | TokenOwner$ TriggeredAttackingPlayer.Opponent | TokenScript$ b_2_2_zombie
Oracle:Enchant player\nWhenever enchanted player is attacked, create a 2/2 black Zombie creature token. Each opponent attacking that player does the same.

View File

@@ -2,8 +2,8 @@ Name:Curse of Opulence
ManaCost:R
Types:Enchantment Aura Curse
K:Enchant player
A:SP$ Attach | Cost$ R | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, create a Gold token. Each opponent attacking that player does the same. (A Gold token is an artifact with "Sacrifice this artifact: Add one mana of any color.")
SVar:TrigRepeat:DB$ RepeatEach | RepeatPlayers$ TriggeredAttackingPlayerAndYou | RepeatSubAbility$ TrigToken | ChangeZoneTable$ True
SVar:TrigToken:DB$ Token | TokenScript$ c_a_gold_draw | TokenOwner$ Player.IsRemembered | TokenAmount$ 1
A:SP$ Attach | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, create a Gold token. Each opponent attacking that player does the same. (A Gold token is an artifact with "Sacrifice this artifact: Add one mana of any color.")
SVar:TrigToken:DB$ Token | TokenScript$ c_a_gold_draw | SubAbility$ DBToken
SVar:DBToken:DB$ Token | TokenOwner$ TriggeredAttackingPlayer.Opponent | TokenScript$ c_a_gold_draw
Oracle:Enchant player\nWhenever enchanted player is attacked, create a Gold token. Each opponent attacking that player does the same. (A Gold token is an artifact with "Sacrifice this artifact: Add one mana of any color.")

View File

@@ -2,9 +2,8 @@ Name:Curse of Verbosity
ManaCost:2 U
Types:Enchantment Aura Curse
K:Enchant player
A:SP$ Attach | Cost$ 2 U | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, draw a card. Each opponent attacking that player does the same.
SVar:TrigRepeat:DB$ RepeatEach | RepeatPlayers$ TriggeredAttackingPlayerAndYou | RepeatSubAbility$ TrigDraw
SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ Player.IsRemembered
SVar:Picture:http://www.wizards.com/global/images/magic/general/curse_of_verbosity.jpg
A:SP$ Attach | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigDraw | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, draw a card. Each opponent attacking that player does the same.
SVar:TrigDraw:DB$ Draw | NumCards$ 1 | Defined$ You | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | NumCards$ 1 | Defined$ TriggeredAttackingPlayer.Opponent
Oracle:Enchant player\nWhenever enchanted player is attacked, you draw a card. Each opponent attacking that player does the same.

View File

@@ -2,9 +2,9 @@ Name:Curse of Vitality
ManaCost:2 W
Types:Enchantment Aura Curse
K:Enchant player
A:SP$ Attach | Cost$ 2 W | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigRepeat | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, you gain 2 life. Each opponent attacking that player does the same.
SVar:TrigRepeat:DB$ RepeatEach | RepeatPlayers$ TriggeredAttackingPlayerAndYou | RepeatSubAbility$ TrigGainLife
SVar:TrigGainLife:DB$ GainLife | Defined$ Player.IsRemembered | LifeAmount$ 2
SVar:Picture:http://www.wizards.com/global/images/magic/general/curse_of_vitality.jpg
A:SP$ Attach | ValidTgts$ Player | AILogic$ Curse
T:Mode$ AttackersDeclared | ValidCard$ Creature | AttackedTarget$ Player.EnchantedBy | Execute$ TrigGainLife | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted player is attacked, you gain 2 life. Each opponent attacking that player does the same.
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2 | SubAbility$ DBGainLife
SVar:DBGainLife:DB$ GainLife | Defined$ TriggeredAttackingPlayer.Opponent | LifeAmount$ 2
DeckHas:Ability$LifeGain
Oracle:Enchant player\nWhenever enchanted player is attacked, you gain 2 life. Each opponent attacking that player does the same.

View File

@@ -3,7 +3,7 @@ ManaCost:2 R G
Types:Legendary Creature Human Archer
PT:4/4
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ At the beginning of your upkeep, target opponent creates three Walker tokens.
SVar:TrigToken:DB$ Token | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | TokenAmount$ 3 | TokenScript$ walker | TokenOwner$ TargetedPlayer
SVar:TrigToken:DB$ Token | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | TokenAmount$ 3 | TokenScript$ walker | TokenOwner$ TargetedPlayer | LockTokenScript$ True
A:AB$ DealDamage | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumDmg$ 2 | SpellDescription$ NICKNAME deals 2 damage to target creature.
T:Mode$ ChangesZone | ValidCard$ Zombie.OppCtrl | Origin$ Battlefield | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigDraw | TriggerDescription$ Whenever a Zombie an opponent controls dies, draw a card.
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1

View File

@@ -4,8 +4,9 @@ Types:Creature Sliver
PT:3/3
S:Mode$ Continuous | Affected$ Sliver | AddAbility$ ABDementiaNameCard | AddSVar$ DBDementiaReveal & DBDementiaDiscard | Description$ All Slivers have "{T}: Choose a card name. Target opponent reveals a card at random from their hand. If that card has the chosen name, that player discards it. Activate only during your turn."
SVar:ABDementiaNameCard:AB$ NameCard | Cost$ T | Defined$ You | SubAbility$ DBDementiaReveal | SpellDescription$ Choose a card name. Target opponent reveals a card at random from their hand. If that card has the chosen name, that player discards it. Activate only during your turn.
SVar:DBDementiaReveal:DB$ Reveal | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Random$ True | PlayerTurn$ True | SubAbility$ DBDementiaDiscard
SVar:DBDementiaDiscard:DB$ Discard | DiscardValid$ Card.NamedCard | Mode$ TgtChoose | Defined$ Targeted
SVar:DBDementiaReveal:DB$ Reveal | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | Random$ True | PlayerTurn$ True | RememberRevealed$ True | SubAbility$ DBDementiaDiscard
SVar:DBDementiaDiscard:DB$ Discard | DiscardValid$ Card.NamedCard+IsRemembered | Mode$ TgtChoose | Defined$ Targeted | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:All
AI:RemoveDeck:Random
SVar:Picture:http://www.wizards.com/global/images/magic/general/dementia_sliver.jpg

View File

@@ -1,12 +1,10 @@
Name:Elephant Resurgence
ManaCost:1 G
Types:Sorcery
A:SP$ RepeatEach | Cost$ 1 G | RepeatPlayers$ Player | RepeatSubAbility$ DBToken | ChangeZoneTable$ True | SpellDescription$ Each player creates a green Elephant creature token. Those creatures have "This creature's power and toughness are each equal to the number of creature cards in its controller's graveyard."
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ g_x_x_elephant_resurgence | TokenOwner$ Player.IsRemembered | LegacyImage$ g x x elephant resurgence pcy
A:SP$ Token | TokenScript$ g_x_x_elephant_resurgence | TokenOwner$ Player | SpellDescription$ Each player creates a green Elephant creature token. Those creatures have "This creature's power and toughness are each equal to the number of creature cards in its controller's graveyard."
SVar:NeedsToPlayVar:Z GE2
SVar:Z:SVar$Z1/Minus.Z2
SVar:Z1:Count$ValidGraveyard Creature.YouOwn
SVar:Z2:Count$ValidGraveyard Creature.OppOwn
AI:RemoveDeck:Random
SVar:Picture:http://www.wizards.com/global/images/magic/general/elephant_resurgence.jpg
Oracle:Each player creates a green Elephant creature token. Those creatures have "This creature's power and toughness are each equal to the number of creature cards in its controller's graveyard."

View File

@@ -6,7 +6,7 @@ K:Flying
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigInvestigate | TriggerDescription$ When CARDNAME enters the battlefield, investigate X times, where X is the number of opponents you have. (To investigate, create a colorless Clue artifact token with "{2}, Sacrifice this artifact: Draw a card.")
SVar:TrigInvestigate:DB$ Investigate | Num$ X
SVar:X:PlayerCountOpponents$Amount
T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you draw your second card each turn, put a +1/+1 counter on CARDNAME.
T:Mode$ Drawn | ValidCard$ Card.YouCtrl | Number$ 2 | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Whenever you draw your second card each turn, create a 1/1 white Spirit creature token with flying.
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_spirit_flying
DeckHas:Ability$Token & Ability$Sacrifice
Oracle:Flying\nWhen Ethereal Investigator enters the battlefield, investigate X times, where X is the number of opponents you have. (To investigate, create a colorless Clue artifact token with "{2}, Sacrifice this artifact: Draw a card.")\nWhenever you draw your second card each turn, create a 1/1 white Spirit creature token with flying.

View File

@@ -3,11 +3,12 @@ ManaCost:1 R
Types:Creature Dragon
PT:1/1
K:Flying
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ At the beginning of your end step, each Dragon card in your hand perpetually gains "This spell costs {1} less to cast."
K:Haste
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ At the beginning of your upkeep, each Dragon card in your hand perpetually gains "This spell costs {1} less to cast."
SVar:TrigEffect:DB$ Effect | RememberObjects$ ValidHand Dragon.YouOwn | StaticAbilities$ PerpetualAbility | Duration$ Permanent | Triggers$ Update | Name$ Fearsome Whelp's Perpetual Effect
SVar:PerpetualAbility:Mode$ Continuous | Affected$ Card.IsRemembered | AddStaticAbility$ DragonReduceCost | EffectZone$ Command | AffectedZone$ Battlefield,Hand,Graveyard,Exile,Stack,Library,Command | Description$ Each Dragon card in your hand perpetually gains "This spell costs {1} less to cast."
SVar:DragonReduceCost:Mode$ ReduceCost | ValidCard$ Card.Self | Type$ Spell | Amount$ 1 | EffectZone$ All | Description$ This spell costs {1} less to cast.
SVar:Update:Mode$ ChangesZone | Origin$ Any | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered | Execute$ DBUpdate
SVar:DBUpdate:DB$ UpdateRemember
DeckHints:Type$Dragon
Oracle:Flying\nAt the beginning of your end step, each Dragon card in your hand perpetually gains "This spell costs {1} less to cast.
Oracle:Flying, haste\nAt the beginning of your upkeep, each Dragon card in your hand perpetually gains "This spell costs {1} less to cast."

View File

@@ -2,7 +2,7 @@ Name:Fumiko the Lowblood
ManaCost:2 R R
Types:Legendary Creature Human Samurai
PT:3/2
K:Bushido:X
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Bushido:N | CalcKeywordN$ N | Description$ Fumiko the Lowblood has bushido X, where X is the number of attacking creatures.
SVar:N:Count$Valid Creature.attacking
S:Mode$ Continuous | Affected$ Creature.OppCtrl | AddHiddenKeyword$ CARDNAME attacks each combat if able. | Description$ Creatures your opponents control attack each combat if able.
SVar:Picture:http://www.wizards.com/global/images/magic/general/fumiko_the_lowblood.jpg
Oracle:Fumiko the Lowblood has bushido X, where X is the number of attacking creatures. (Whenever this creature blocks or becomes blocked, it gets +X/+X until end of turn.)\nCreatures your opponents control attack each combat if able.

View File

@@ -5,5 +5,6 @@ PT:1/2
S:Mode$ Continuous | Affected$ Card.Self | CheckSVar$ X | SVarCompare$ GE2 | AddPower$ 1 | AddKeyword$ Haste | Description$ As long as there are two or more instant and/or sorcery cards in your graveyard, CARDNAME gets +1/+0 and has haste.
SVar:X:Count$ValidGraveyard Instant.YouOwn,Sorcery.YouOwn
SVar:BuffedBy:Instant,Sorcery
SVar:PlayMain1:TRUE
DeckHints:Type$Instant|Sorcery
Oracle:As long as there are two or more instant and/or sorcery cards in your graveyard, Ghitu Lavarunner gets +1/+0 and has haste.

View File

@@ -3,7 +3,7 @@ ManaCost:B
Types:Creature Zombie
PT:2/1
K:CARDNAME can't block.
S:Mode$ Continuous | Affected$ Card.Self | AffectedZone$ GraveYard | EffectZone$ Graveyard | MayPlay$ True | IsPresent$ Zombie.YouCtrl | Description$ You may cast CARDNAME from your graveyard as long as you control a Zombie.
S:Mode$ Continuous | Affected$ Card.Self | AffectedZone$ Graveyard | EffectZone$ Graveyard | MayPlay$ True | IsPresent$ Zombie.YouCtrl | Description$ You may cast CARDNAME from your graveyard as long as you control a Zombie.
SVar:SacMe:3
SVar:DiscardMe:3
DeckHints:Type$Zombie

View File

@@ -5,10 +5,9 @@ PT:6/1
K:Haste
K:Trample
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigProvoke | TriggerDescription$ When CARDNAME attacks, up to one target creature defending player controls blocks it this combat if able.
SVar:TrigProvoke:DB$ MustBlock | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature.DefenderCtrl | Duration$ UntilEndOfCombat | TgtPrompt$ Select up to one target creature defending player controls
SVar:TrigProvoke:DB$ MustBlock | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Creature.DefenderCtrl | TgtPrompt$ Select up to one target creature defending player controls
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigSac | TriggerDescription$ At the beginning of the end step, sacrifice CARDNAME.
SVar:TrigSac:DB$ Sacrifice | SacValid$ Self
SVar:EndOfTurnLeavePlay:True
SVar:PlayMain1:TRUE
SVar:Picture:http://www.wizards.com/global/images/magic/general/impetuous_devils.jpg
Oracle:Trample, haste\nWhen Impetuous Devils attacks, up to one target creature defending player controls blocks it this combat if able.\nAt the beginning of the end step, sacrifice Impetuous Devils.

View File

@@ -3,7 +3,7 @@ ManaCost:3 W
Types:Creature Human Cleric
PT:3/3
K:Vigilance
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | CheckSVar$ Z | SVarCompare$ GE20 | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.wasCast+Self | CheckSVar$ Z | SVarCompare$ GE20 | Execute$ TrigSeek | TriggerDescription$ When CARDNAME enters the battlefield, if you cast it and there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library.
SVar:TrigSeek:DB$ ChangeZone | Origin$ Library | Destination$ Library | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Creature.YouOwn+cmcLE3 | ChangeNum$ 2 | RememberChanged$ True | SubAbility$ DBChangeZone1
SVar:DBChangeZone1:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.IsRemembered | ChangeNum$ 1 | Mandatory$ True | NoLooking$ True | SelectPrompt$ Select a card for the battlefield | Shuffle$ True | SubAbility$ DBChangeZone2 | StackDescription$ None
SVar:DBChangeZone2:DB$ ChangeZone | Origin$ Library | Destination$ Library | ChangeType$ Creature.IsRemembered | Mandatory$ True | NoLooking$ True | StackDescription$ None | SubAbility$ DBCleanup
@@ -12,4 +12,4 @@ SVar:X:Count$ValidGraveyard Creature.YouOwn+cmcLE3
SVar:Y:Count$ValidLibrary Creature.YouOwn+cmcLE3/Plus.X
SVar:Z:Count$ValidHand Creature.YouOwn+cmcLE3/Plus.Y
DeckNeeds:Type$Creature
Oracle:Vigilance\nWhen Inquisitor Captain enters the battlefield, if there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library.
Oracle:Vigilance\nWhen Inquisitor Captain enters the battlefield, if you cast it and there are twenty or more creature cards with mana value 3 or less among cards in your graveyard, hand, and library, seek two creature cards with mana value 3 or less. Put one of them onto the battlefield and shuffle the other into your library.

View File

@@ -2,12 +2,11 @@ Name:Kodama of the Center Tree
ManaCost:4 G
Types:Legendary Creature Spirit
PT:*/*
K:Soulshift:X:, where X is the number of Spirits you control.:Spirit.YouCtrl
S:Mode$ Continuous | EffectZone$ All | CharacteristicDefining$ True | SetPower$ X | SetToughness$ X | Description$ CARDNAME's power and toughness are each equal to the number of Spirits you control.
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ Soulshift:N | CalcKeywordN$ X | Description$ CARDNAME has soulshift X, where X is the number of Spirits you control.
SVar:X:Count$Valid Spirit.YouCtrl
AI:RemoveDeck:Random
SVar:BuffedBy:Spirit
SVar:NoZeroToughnessAI:True
DeckHints:Type$Spirit
SVar:Picture:http://www.wizards.com/global/images/magic/general/kodama_of_the_center_tree.jpg
Oracle:Kodama of the Center Tree's power and toughness are each equal to the number of Spirits you control.\nKodama of the Center Tree has soulshift X, where X is the number of Spirits you control. (When this creature dies, you may return target Spirit card with mana value X or less from your graveyard to your hand.)

View File

@@ -4,7 +4,7 @@ Types:Legendary Artifact Equipment
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | AddKeyword$ Menace | Description$ Equipped creature gets +2/+0 and has menace.
T:Mode$ Attacks | ValidCard$ Card.EquippedBy | Execute$ TrigSac | TriggerDescription$ Whenever equipped creature attacks, defending player sacrifices a creature. If they do, you create a Walker token.
SVar:TrigSac:DB$ Sacrifice | Defined$ TriggeredDefendingPlayer | SacValid$ Creature | Amount$ 1 | RememberSacrificed$ True | SubAbility$ DBToken
SVar:DBToken:DB$ Token | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GE1 | TokenAmount$ 1 | TokenScript$ walker | TokenOwner$ You | SubAbility$ DBCleanup
SVar:DBToken:DB$ Token | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ GE1 | TokenAmount$ 1 | TokenScript$ walker | TokenOwner$ You | LockTokenScript$ True | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
K:Equip:4
Oracle:Equipped creature gets +2/+0 and has menace.\nWhenever equipped creature attacks, defending player sacrifices a creature. If they do, you create a Walker token.\nEquip {4}

View File

@@ -4,9 +4,8 @@ Types:Creature Human Rogue
PT:2/1
K:Unblockable
K:CARDNAME can't block.
S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ Graveyard | MayPlay$ True | IsPresent$ Permanent.Black+YouCtrl,Permanent.Green+YouCtrl | Description$ You may cast CARDNAME from you graveyard as long as you control a black or green permanent.
S:Mode$ Continuous | Affected$ Card.Self | AffectedZone$ Graveyard | EffectZone$ Graveyard | MayPlay$ True | IsPresent$ Permanent.Black+YouCtrl,Permanent.Green+YouCtrl | Description$ You may cast CARDNAME from you graveyard as long as you control a black or green permanent.
SVar:SacMe:3
SVar:DiscardMe:3
DeckHints:Color$Black|Green
SVar:Picture:http://www.wizards.com/global/images/magic/general/marang_river_prowler.jpg
Oracle:Marang River Prowler can't block and can't be blocked.\nYou may cast Marang River Prowler from your graveyard as long as you control a black or green permanent.

View File

@@ -4,9 +4,8 @@ ManaCost:3 B G
Types:Legendary Creature Human Warrior
PT:3/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When NICKNAME enters the battlefield, create two Walker tokens.
SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ walker | TokenOwner$ You
S:Mode$ Continuous | Affected$ Card.Self | CheckSVar$ Equipped | SVarCompare$ EQ1 | AddHiddenKeyword$ CARDNAME must be blocked if able. | Description$ As long as NICKNAME is equipped, she must be blocked if able.
SVar:Equipped:Count$Valid Card.Self+equipped
SVar:TrigToken:DB$ Token | TokenAmount$ 2 | TokenScript$ walker | TokenOwner$ You | LockTokenScript$ True
S:Mode$ Continuous | Affected$ Card.Self+equipped | AddHiddenKeyword$ CARDNAME must be blocked if able. | Description$ As long as NICKNAME is equipped, she must be blocked if able.
SVar:EquipMe:Once
T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | CheckSVar$ Zombies | NoResolvingCheck$ True | SVarCompare$ GE2 | Execute$ TrigPump | TriggerDescription$ Whenever NICKNAME and at least two Zombies attack, she gains indestructible until end of turn.
SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ Indestructible

View File

@@ -6,7 +6,7 @@ T:Mode$ Sacrificed | ValidPlayer$ You | ValidCard$ Creature.Other | TriggerZones
SVar:TrigExile:DB$ ChangeZone | Defined$ TriggeredCard | Origin$ Graveyard | Destination$ Exile | SubAbility$ TokenPlus
SVar:TokenPlus:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | ConditionDefined$ TriggeredCardLKICopy | ConditionPresent$ Creature.token
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ TrigReturn | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME leaves the battlefield, return each card exiled with it to the battlefield under your control.
SVar:TrigReturn:DB$ ChangeZoneAll | ChangeTypes$ Card.ExiledWithSource | Origin$ Exile | Destination$ Battlefield | GainControl$ True
SVar:TrigReturn:DB$ ChangeZoneAll | ChangeType$ Card.ExiledWithSource | Origin$ Exile | Destination$ Battlefield | GainControl$ True
DeckNeeds:Ability$Sacrifice
DeckHas:Ability$Counters
DeckHints:Ability$Token

View File

@@ -1,7 +1,7 @@
Name:Puppet Raiser
ManaCost:3 B
Types:Creature Zombie Wizard
PT:3/3
PT:3/4
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | IsPresent$ Card.Creature+YouOwn | PresentZone$ Graveyard | PresentCompare$ GE1 | Execute$ TrigExile | TriggerDescription$ At the beginning of your end step, exile up to one target creature card from your graveyard. If you do, seek a creature card with mana value equal to the mana value of that card plus one. That card perpetually gains menace.
SVar:TrigExile:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Creature.YouOwn | TgtPrompt$ Select up to one target creature card in your graveyard | TargetMin$ 0 | TargetMax$ 1 | RememberChanged$ True | SubAbility$ DBSeek
SVar:DBSeek:DB$ ChangeZone | Origin$ Library | Destination$ Hand | AtRandom$ True | NoShuffle$ True | Mandatory$ True | NoLooking$ True | NoReveal$ True | ChangeType$ Creature.cmcEQX | ChangeNum$ 1 | Imprint$ True | SubAbility$ DBEffect

View File

@@ -0,0 +1,14 @@
Name:A-Acererak the Archlich
ManaCost:2 B
Types:Legendary Creature Zombie Wizard
PT:5/5
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | CheckSVar$ X | SVarCompare$ LT1 | Execute$ TrigBounce | TriggerDescription$ When CARDNAME enters the battlefield, if you haven't completed Tomb of Annihilation, return CARDNAME to its owner's hand and venture into the dungeon.
SVar:TrigBounce:DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand | SubAbility$ DBVenture
SVar:DBVenture:DB$ Venture
SVar:X:PlayerCountPropertyYou$DungeonCompletedNamed_Tomb of Annihilation
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Whenever CARDNAME attacks, create a number of 2/2 black Zombie creature tokens equal to the number of opponents you have.
SVar:TrigToken:DB$ Token | TokenAmount$ X | TokenScript$ b_2_2_zombie | TokenOwner$ You
SVar:X:PlayerCountOpponents$Amount
DeckHas:Ability$Token
DeckHints:Type$Zombie
Oracle:When Acererak the Archlich enters the battlefield, if you haven't completed Tomb of Annihilation, return Acererak the Archlich to its owner's hand and venture into the dungeon.\nWhenever Acererak the Archlich attacks, create a number of 2/2 black Zombie creature tokens equal to the number of opponents you have.

View File

@@ -0,0 +1,9 @@
Name:A-Cloister Gargoyle
ManaCost:1 W
Types:Artifact Creature Gargoyle
PT:0/3
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBVenture | TriggerDescription$ When CARDNAME enters the battlefield, venture into the dungeon.
SVar:DBVenture:DB$ Venture | Defined$ You
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 3 | AddKeyword$ Flying | CheckSVar$ X | SVarCompare$ GE1 | Description$ As long as you've completed a dungeon, CARDNAME gets +3/+0 and has flying.
SVar:X:PlayerCountPropertyYou$DungeonsCompleted
Oracle:When Cloister Gargoyle enters the battlefield, venture into the dungeon.\nAs long as you've completed a dungeon, Cloister Gargoyle gets +3/+0 and has flying.

View File

@@ -0,0 +1,6 @@
Name:A-Divide by Zero
ManaCost:2 U
Types:Instant
A:SP$ ChangeZone | ValidTgts$ Permanent.cmcGE1,Card.inZoneStack+cmcGE1 | TgtZone$ Stack,Battlefield | Origin$ Battlefield,Stack | Fizzle$ True | Destination$ Hand | SubAbility$ DBLearn | SpellDescription$ Return target spell or permanent with mana value 1 or greater to its owner's hand. If its mana value was 4 or less, learn.
SVar:DBLearn:DB$ Learn | ConditionDefined$ Targeted | ConditionPresent$ Card.cmcLE4 | ConditionCompare$ EQ1
Oracle:Return target spell or permanent with mana value 1 or greater to its owner's hand. If its mana value was 4 or less, learn.

View File

@@ -0,0 +1,6 @@
Name:A-Dungeon Descent
ManaCost:no cost
Types:Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Venture | Cost$ 1 T tapXType<1/Creature.Legendary/legendary creature> | SorcerySpeed$ True | SpellDescription$ Venture into the dungeon. Activate only as a sorcery.
Oracle:{T}: Add {C}.\n{1}, {T}, Tap an untapped legendary creature you control: Venture into the dungeon. Activate only as a sorcery.

View File

@@ -0,0 +1,13 @@
Name:A-Ellywick Tumblestrum
ManaCost:2 G G
Types:Legendary Planeswalker Ellywick
Loyalty:4
A:AB$ Venture | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | Defined$ You | SpellDescription$ Venture into the dungeon.
A:AB$ Dig | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | DigNum$ 6 | ChangeNum$ 1 | Optional$ True | ChangeValid$ Creature | ForceRevealToController$ True | RememberChanged$ True | RestRandomOrder$ True | SubAbility$ DBGainLife | SpellDescription$ Look at the top six cards of your library. You may reveal a creature card from among them and put it into your hand. If it's legendary, you gain 3 life. Put the rest on the bottom of your library in a random order.
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 3 | ConditionCheckSVar$ IsLegendary | ConditionSVarCompare$ GE1 | SubAbility$ DBCleanup
SVar:IsLegendary:Count$ValidHand Creature.Legendary+IsRemembered
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
A:AB$ Effect | Cost$ SubCounter<6/LOYALTY> | Planeswalker$ True | Ultimate$ True | Name$ Emblem - Ellywick Tumblestrum | Image$ emblem_ellywick_tumblestrum | StaticAbilities$ STOverrun | Duration$ Permanent | AILogic$ Always | SpellDescription$ You get an emblem with "Creatures you control have trample and haste and get +2/+2 for each differently named dungeon you've completed."
SVar:STOverrun:Mode$ Continuous | EffectZone$ Command | Affected$ Creature.YouCtrl | AffectedZone$ Battlefield | AddPower$ X | AddToughness$ X | AddKeyword$ Trample & Haste | Description$ Creatures you control have trample and haste and get +2/+2 for each differently named dungeon you've completed.
SVar:X:PlayerCountPropertyYou$DifferentlyNamedDungeonsCompleted/Twice
Oracle:[+1]: Venture into the dungeon.\n[2]: Look at the top six cards of your library. You may reveal a creature card from among them and put it into your hand. If it's legendary, you gain 3 life. Put the rest on the bottom of your library in a random order.\n[6]: You get an emblem with "Creatures you control have trample and haste and get +2/+2 for each differently named dungeon you've completed."

View File

@@ -0,0 +1,7 @@
Name:A-Fates' Reversal
ManaCost:B
Types:Sorcery
A:SP$ ChangeZone | Cost$ 1 B | Origin$ Graveyard | Destination$ Hand | TgtPrompt$ Select target creature card in your graveyard | ValidTgts$ Creature.YouOwn | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBVenture | SpellDescription$ Return up to one target creature card from your graveyard to your hand. Venture into the dungeon.
SVar:DBVenture:DB$ Venture
DeckHints:Ability$Graveyard
Oracle:Return up to one target creature card from your graveyard to your hand. Venture into the dungeon.

View File

@@ -0,0 +1,10 @@
Name:A-Find the Path
ManaCost:2 G
Types:Enchantment Aura
K:Enchant land
A:SP$ Attach | Cost$ 2 G | ValidTgts$ Land | AILogic$ Pump
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBVenture | TriggerDescription$ When CARDNAME enters the battlefield, venture into the dungeon.
SVar:DBVenture:DB$ Venture | Defined$ You
S:Mode$ Continuous | Affected$ Land.EnchantedBy | AddAbility$ ABMana | Description$ Enchanted land has "{T}: Add two mana of any one colour."
SVar:ABMana:AB$ Mana | Cost$ T | Produced$ Any | Amount$ 2 | SpellDescription$ Add two mana of any one colour.
Oracle:Enchant land\nWhen Find the Path enters the battlefield, venture into the dungeon.\nEnchanted land has "{T}: Add two mana of any one colour."

View File

@@ -0,0 +1,10 @@
Name:A-Hullbreaker Horror
ManaCost:5 U U
Types:Creature Kraken Horror
PT:7/8
K:Flash
T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | Execute$ TrigCharm | TriggerZones$ Battlefield | TriggerDescription$ Whenever you cast a spell, ABILITY
SVar:TrigCharm:DB$ Charm | Choices$ ControlReturn,ControlBounce | MinCharmNum$ 0 | CharmNum$ 1
SVar:ControlReturn:DB$ ChangeZone | ValidTgts$ Card.YouDontCtrl | TgtPrompt$ Select target spell you don't control | TgtZone$ Stack | Origin$ Stack | Fizzle$ True | Destination$ Hand | SpellDescription$ Return target spell you don't control to its owner's hand.
SVar:ControlBounce:DB$ ChangeZone | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | TgtZone$ Battlefield | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target nonland permanent to its owner's hand.
Oracle:Flash\nWhenever you cast a spell, choose up to one —\n• Return target spell you don't control to its owner's hand.\n• Return target nonland permanent to its owner's hand.

View File

@@ -0,0 +1,9 @@
Name:A-Lier, Disciple of the Drowned
ManaCost:3 U U
Types:Legendary Creature Human Wizard
PT:3/4
S:Mode$ Continuous | Affected$ Card | AddHiddenKeyword$ This spell can't be countered. | AffectedZone$ Stack | Description$ Spells can't be countered.
S:Mode$ Continuous | Affected$ Instant.YouOwn,Sorcery.YouOwn | AffectedZone$ Graveyard | AddKeyword$ Flashback | Condition$ PlayerTurn | Description$ As long as it's your turn, each instant and sorcery card in your graveyard has flashback. The flashback cost is equal to that card's mana cost.
DeckHints:Type$Instant|Sorcery
DeckHas:Ability$Graveyard
Oracle:Spells can't be countered.\nAs long as it's your turn, each instant and sorcery card in your graveyard has flashback. The flashback cost is equal to that card's mana cost.

View File

@@ -0,0 +1,11 @@
Name:A-Precipitous Drop
ManaCost:1 B
Types:Enchantment Aura
K:Enchant creature
A:SP$ Attach | Cost$ 2 B | ValidTgts$ Creature | AILogic$ Curse
T:Mode$ ChangesZone | ValidCard$ Card.Self | Destination$ Battlefield | Execute$ TrigVenture | TriggerDescription$ When CARDNAME enters the battlefield, venture into the dungeon.
SVar:TrigVenture:DB$ Venture
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ -X | AddToughness$ -X | Description$ Enchanted creature gets -2/-2. It gets -5/-5 instead as long as you've completed a dungeon.
SVar:X:Count$Compare Y GE1.5.2
SVar:Y:PlayerCountPropertyYou$DungeonsCompleted
Oracle:Enchant creature\nWhen Precipitous Drop enters the battlefield, venture into the dungeon.\nEnchanted creature gets -2/-2. It gets -5/-5 instead as long as you've completed a dungeon.

View File

@@ -0,0 +1,11 @@
Name:A-Teferi, Time Raveler
ManaCost:2 W U
Types:Legendary Planeswalker Teferi
Loyalty:5
S:Mode$ CantBeCast | ValidCard$ Card | Condition$ PlayerTurn | Caster$ Opponent | Description$ Your opponents can't cast spells during your turn.
A:AB$ Effect | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | StaticAbilities$ STPlay | Duration$ UntilYourNextTurn | AILogic$ Main2 | SpellDescription$ Until your next turn, you may cast sorcery spells as though they had flash.
SVar:STPlay:Mode$ CastWithFlash | ValidCard$ Sorcery | ValidSA$ Spell | EffectZone$ Command | Caster$ You | Description$ Until your next turn, you may cast sorcery spells as though they had flash.
SVar:PlayMain1:TRUE
A:AB$ ChangeZone | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | Origin$ Battlefield | Destination$ Hand | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Artifact,Creature,Enchantment | TgtPrompt$ Select target artifact, creature, or enchantment | SpellDescription$ Return up to one target artifact, creature, or enchantment to its owner's hand. Draw a card. | SubAbility$ DBDraw
SVar:DBDraw:DB$ Draw | NumCards$ 1
Oracle:Your opponents can't cast spells during your turn.\n[+1]: Until your next turn, you may cast sorcery spells as though they had flash.\n[3]: Return up to one target artifact, creature, or enchantment to its owner's hand. Draw a card.

View File

@@ -0,0 +1,10 @@
Name:A-Triumphant Adventurer
ManaCost:W B
Types:Creature Human Knight
PT:2/1
K:Deathtouch
S:Mode$ Continuous | Affected$ Card.Self | AddKeyword$ First Strike | Condition$ PlayerTurn | Description$ As long as it's your turn, CARDNAME has first strike.
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DBVenture | Secondary$ True | TriggerDescription$ Whenever CARDNAME attacks, venture into the dungeon.
SVar:DBVenture:DB$ Venture | Defined$ You
SVar:HasAttackEffect:TRUE
Oracle:Deathtouch\nAs long as it's your turn, Triumphant Adventurer has first strike.\nWhenever Triumphant Adventurer attacks, venture into the dungeon.

View File

@@ -4,8 +4,7 @@ Types:Enchantment
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME enters the battlefield, create a Blood token and conjure a card named Blood Artist onto the battlefield.
SVar:TrigToken:DB$ Token | TokenScript$ c_a_blood_draw | SubAbility$ DBMakeCard
SVar:DBMakeCard:DB$ MakeCard | Name$ Blood Artist | Zone$ Battlefield
T:Mode$ Sacrificed | ValidCard$ Blood.token+YouCtrl | Execute$ TrigLoseLife | TriggerZones$ Battlefield | TriggerDescription$ Whenever you sacrifice a Blood token, each opponent loses 1 life and you gain 1 life.
SVar:TrigLoseLife:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1 | SubAbility$ TrigGainLife
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 1
DeckHas:Ability$Token & Ability$Sacrifice & Ability$LifeGain & Type$Blood
Oracle:When Sanguine Brushstroke enters the battlefield, create a Blood token and conjure a card named Blood Artist onto the battlefield.\nWhenever you sacrifice a Blood token, each opponent loses 1 life and you gain 1 life.
T:Mode$ Sacrificed | ValidCard$ Blood.token+YouCtrl | Execute$ TrigLoseLife | TriggerZones$ Battlefield | TriggerDescription$ Whenever you sacrifice a Blood token, each opponent loses 1 life.
SVar:TrigLoseLife:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1
DeckHas:Ability$Token & Ability$Sacrifice & Type$Blood
Oracle:When Sanguine Brushstroke enters the battlefield, create a Blood token and conjure a card named Blood Artist onto the battlefield.\nWhenever you sacrifice a Blood token, each opponent loses 1 life.

View File

@@ -7,7 +7,7 @@ K:ETBReplacement:Other:DBRemoveCounterAll
SVar:DBRemoveCounterAll:DB$ RemoveCounterAll | ValidCards$ Permanent | AllCounterTypes$ True | StackDescription$ SpellDescription | SubAbility$ DBPutCounters | RememberAmount$ True | SpellDescription$ As CARDNAME enters the battlefield, remove all counters from all permanents. CARDNAME enters the battlefield with a +1/+1 counter on it for each counter removed this way.
SVar:DBPutCounters:DB$ PutCounter | ETB$ True | Defined$ Self | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:X:Count$ChosenNumber
SVar:X:Count$RememberedNumber
AI:RemoveDeck:Random
DeckHas:Ability$Counters
Oracle:Flying\nAs Thief of Blood enters the battlefield, remove all counters from all permanents. Thief of Blood enters the battlefield with a +1/+1 counter on it for each counter removed this way.

View File

@@ -3,8 +3,8 @@ ManaCost:2 R R
Types:Creature Dragon
PT:4/4
K:Flying
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigAnimate | TriggerDescription$ When CARDNAME enters the battlefield, target land you don't control loses all abilities except mana abilities and gains "At the beginning of your upkeep, this permanent deals 2 damage to you unless you sacrifice it."
SVar:TrigAnimate:DB$ Animate | ValidTgts$ Land.YouDontCtrl | TgtPrompt$ Select target land you don't control | RemoveNonManaAbilities$ True | Triggers$ UpkeepShock | Duration$ Permanent
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigAnimate | TriggerDescription$ When CARDNAME enters the battlefield, target nonbasic land you don't control loses all abilities except mana abilities and gains "At the beginning of your upkeep, this permanent deals 2 damage to you unless you sacrifice it."
SVar:TrigAnimate:DB$ Animate | ValidTgts$ Land.nonBasic+YouDontCtrl | TgtPrompt$ Select target nonbasic land you don't control | RemoveNonManaAbilities$ True | Triggers$ UpkeepShock | Duration$ Permanent
SVar:UpkeepShock:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of your upkeep, this permanent deals 2 damage to you unless you sacrifice it.
SVar:TrigDamage:DB$ DealDamage | Defined$ You | NumDmg$ 2 | UnlessCost$ Sac<1/CARDNAME> | UnlessPayer$ TriggeredPlayer
Oracle:Flying\nWhen Town-razer Tyrant enters the battlefield, target land you don't control loses all abilities except mana abilities and gains "At the beginning of your upkeep, this permanent deals 2 damage to you unless you sacrifice it."
Oracle:Flying\nWhen Town-razer Tyrant enters the battlefield, target nonbasic land you don't control loses all abilities except mana abilities and gains "At the beginning of your upkeep, this permanent deals 2 damage to you unless you sacrifice it."

View File

@@ -0,0 +1,11 @@
Name:Chishiro, the Shattered Blade
ManaCost:2 R G
Types:Legendary Creature Snake Samurai
PT:4/4
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | TriggerZones$ Battlefield | ValidCard$ Aura.YouCtrl,Equipment.YouCtrl | Execute$ TrigToken | TriggerDescription$ Whenever an Aura or Equipment enters the battlefield under your control, create a 2/2 red Spirit creature token with menace.
SVar:TrigToken:DB$ Token | TokenScript$ r_2_2_spirit_menace
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigCounters | TriggerDescription$ At the beginning of your end step, put a +1/+1 counter on each modified creature you control. (Equipment, Auras you control, and counters are modifications.)
SVar:TrigCounters:DB$ PutCounterAll | ValidCards$ Creature.YouCtrl+modified | CounterType$ P1P1 | CounterNum$ 1
DeckHints:Type$Aura|Equipment & Ability$Counters
DeckHas:Ability$Token & Type$Spirit & Ability$Counters
Oracle:Whenever an Aura or Equipment enters the battlefield under your control, create a 2/2 red Spirit creature token with menace.\nAt the beginning of your end step, put a +1/+1 counter on each modified creature you control. (Equipment, Auras you control, and counters are modifications.)

View File

@@ -0,0 +1,9 @@
Name:Goro-Goro, Disciple of Ryusei
ManaCost:1 R
Types:Legendary Creature Samurai Goblin
PT:2/2
A:AB$ PumpAll | Cost$ R | ValidCards$ Creature.YouCtrl | KW$ Haste | SpellDescription$ Creatures you control gain haste until end of turn.
A:AB$ Token | Cost$ 3 R R | TokenScript$ r_5_5_dragon_spirit_flying | IsPresent$ Creature.YouCtrl+attacking+modified | StackDescription$ Create a 5/5 red Dragon Spirit creature token with flying. | SpellDescription$ Create a 5/5 red Dragon Spirit creature token with flying. Activate only if you control an attacking modified creature.
DeckHas:Ability$Token & Type$Dragon|Spirit
DeckHints:Type$Equipment|Aura & Ability$Counters
Oracle:{R}: Creatures you control gain haste until end of turn.\n{3}{R}{R}: Create a 5/5 red Dragon Spirit creature token with flying. Activate only if you control an attacking modified creature.

View File

@@ -426,9 +426,17 @@ FatPackExtraSlots=20 BasicLands, 20 BasicLands+
402 U Prosperous Innkeeper @Eric Deschamps
[rebalanced]
A7 U A-Cloister Gargoyle @Mark Zug
A53 M A-Demilich @Daniel Zrom
A81 U A-Wizard Class @Marta Nael
A87 M A-Acererak the Archlich @Andrey Kuzinskiy
A102 C A-Fates' Reversal @Alix Branwyn
A115 C A-Precipitous Drop @Gabor Szikszai
A180 U A-Druid Class @Svetlin Velinov
A181 M A-Ellywick Tumblestrum @Anna Steinbauer
A183 C A-Find the Path @Lindsey Look
A237 R A-Triumphant Adventurer @Alexander Mokhov
A255 R A-Dungeon Descent @Kasia 'Kafis' Zielińska
[dungeons]
S Dungeon of the Mad Mage

View File

@@ -433,6 +433,9 @@ Prerelease=6 Boosters, 1 RareMythic+
411 L Mountain @Daria Khlebnikova
412 L Forest @Pig Hands
[rebalanced]
A63 R A-Hullbreaker Horror @Svetlin Velinov
[tokens]
b_1_1_slug
b_2_2_zombie

View File

@@ -413,6 +413,9 @@ Prerelease=6 Boosters, 1 RareMythic+
390 U Play with Fire @Svetlin Velinov
391 U Join the Dance @Raoul Vitale
[rebalanced]
A59 M A-Lier, Disciple of the Drowned @Ekaterina Burmak
[tokens]
b_1_1_bat_flying
b_2_2_zombie_decayed

View File

@@ -5,6 +5,8 @@ Name=Kamigawa: Neon Dynasty
Code2=NEO
MciCode=neo
Type=Expansion
TODO: Make sure Booster is correct closer to release - these are placeholders
Booster=10 Common, 3 Uncommon, 1 RareMythic, 1 BasicLand
ScryfallCode=NEO
[cards]

View File

@@ -362,6 +362,7 @@ ScryfallCode=SLD
383 R Krark's Thumb @Wooden Cyclops
383★ R Krark's Thumb @Wooden Cyclops
384 R Swamp @Jeanne D'Angelo
385 R Island @Jeanne D'Angelo
477 R Path to Exile @Riot Games
478 R Rhystic Study @Riot Games
479 R Duress @Riot Games

View File

@@ -408,6 +408,9 @@ ScryfallCode=STX
381 U Rip Apart @Anna Podedworna
382 U Decisive Denial @Lorenzo Mastroianni
[rebalanced]
A41 U A-Divide by Zero @Liiga Smilshkalne
[lesson]
2 Environmental Sciences
2 Expanded Anatomy

View File

@@ -326,6 +326,9 @@ ScryfallCode=WAR
235★ U Samut, Tyrant Smasher @Norikatsu Miyoshi
236★ U Vraska, Swarm's Eminence @Ryota Murayama
[rebalanced]
A221 R A-Teferi, Time Raveler @Chris Rallis
[tokens]
wubrg_2_2_citizen
b_0_0_zombie_army

View File

@@ -4,4 +4,4 @@ Order:108
Subtype:Custom
Type:Casual
Rarities:L, C
Banned:Arcum's Astrolabe; Chatterstorm; Cloud of Faeries; Cloudpost; Cranial Plating; Daze; Expedition Map; Empty the Warrens; Fall from Favor; Frantic Search; Gitaxian Probe; Grapeshot; Gush; High Tide; Hymn to Tourach; Invigorate; Mystic Sanctuary; Peregrine Drake; Sinkhole; Sojourner's Companion; Temporal Fissure; Treasure Cruise
Banned:Arcum's Astrolabe; Atog; Bonder's Ornament; Chatterstorm; Cloud of Faeries; Cloudpost; Cranial Plating; Daze; Expedition Map; Empty the Warrens; Fall from Favor; Frantic Search; Gitaxian Probe; Grapeshot; Gush; High Tide; Hymn to Tourach; Invigorate; Mystic Sanctuary; Peregrine Drake; Prophetic Prism; Sinkhole; Sojourner's Companion; Temporal Fissure; Treasure Cruise

View File

@@ -4,5 +4,5 @@ Type:Digital
Subtype:Arena
Effective:2019-11-21
Order:142
Sets:XLN, RIX, DOM, M19, GRN, G18, RNA, WAR, M20, ELD, HA1, THB, HA2, IKO, HA3, M21, JMP, AKR, ZNR, KLR, KHM, HA4, STX, STA, HA5, AFR, J21, MID, VOW
Banned:Agent of Treachery; Brainstorm; Channel; Counterspell; Dark Ritual; Demonic Tutor; Field of the Dead; Fires of Invention; Lightning Bolt; Natural Order; Nexus of Fate; Oko, Thief of Crowns; Omnath, Locus of Creation; Once Upon a Time; Swords to Plowshares; Teferi, Time Raveler; Thassa's Oracle; Tibalt's Trickery; Time Warp; Uro, Titan of Nature's Wrath; Veil of Summer; Wilderness Reclamation; Winota, Joiner of Forces
Sets:XLN, RIX, DOM, M19, GRN, G18, RNA, WAR, M20, ELD, HA1, THB, HA2, IKO, HA3, M21, JMP, AKR, ANB, ZNR, KLR, KHM, HA4, STX, STA, HA5, AFR, J21, MID, VOW, Y22
Banned:Agent of Treachery; Brainstorm; Channel; Counterspell; Dark Ritual; Demonic Tutor; Field of the Dead; Fires of Invention; Lightning Bolt; Memory Lapse; Natural Order; Nexus of Fate; Oko, Thief of Crowns; Once Upon a Time; Swords to Plowshares; Thassa's Oracle; Tibalt's Trickery; Time Warp; Uro, Titan of Nature's Wrath; Veil of Summer; Wilderness Reclamation; Winota, Joiner of Forces

View File

@@ -4,4 +4,4 @@ Order:105
Subtype:Legacy
Type:Sanctioned
Sets:7ED, 9ED, ORI, M14, M15, 6ED, 8ED, M11, 3ED, M10, M12, 10E, M13, G18, M21, M20, M19, 5ED, 2ED, 4ED, LEB, LEA, 5DN, SOM, KTK, THS, DIS, JOU, MOR, TMP, SOI, FEM, USG, ALL, ROE, EXO, TSP, LRW, TOR, ALA, RIX, DGM, DKA, MBS, AER, RNA, GTC, CSP, HML, NPH, OGW, ZNR, EMN, UDS, SHM, BNG, SOK, EVE, INV, THB, DOM, NMS, VIS, WAR, GRN, PCY, SCG, MRD, XLN, ONS, IKO, MMQ, CHK, ULG, AKH, MIR, ISD, AVR, KLD, APC, RTR, WWK, PLC, HOU, LEG, AFR, ARN, ICE, STX, LGN, ARB, KHM, CFX, TSB, ZEN, ELD, JUD, GPT, BFZ, BOK, DTK, FRF, FUT, WTH, ODY, RAV, ATQ, DRK, PLS, STH, DST, TD2, HA1, ME4, HA3, HA2, HA5, HA4, MED, ANB, ME3, KLR, PZ2, ANA, PRM, PZ1, AJMP, ME2, TD1, TD0, TPR, VMA, AKR, MBP, PZEN, PGTW, PL21, PFUT, PWAR, PAL01, PJUD, PAL00, PTKDF, PWOR, PWP12, PSTH, POGW, PFRF, PG07, PSUS, PUST, J18, PWP10, PAL02, PAL03, PWP11, J19, PGRN, PM10, PDP14, PRTR, PMPS06, PBNG, PJ21, G09, PNPH, PM15, PAL06, G08, PDST, J20, PMBS, PMPS07, PEXO, PDOM, PONS, PRW2, PMPS11, PMPS, PM19, PWWK, PCEL, PAL04, PAL05, PMPS10, PDTK, PALP, F10, F04, PMOR, PAL99, PEMN, PCNS, PPLC, PRAV, PPP1, PI14, PXLN, PF20, PTSP, F05, F11, PSCG, PBOOK, F07, F13, PODY, PM12, P08, PSS1, P2HG, P09, PTOR, PDP13, F12, F06, PALA, PXTC, F02, F16, PHOU, PSOM, PI13, PCON, PDGM, PIDW, PMRD, PRNA, P9ED, PHEL, F17, F03, PURL, F15, F01, PWOS, PPC1, PBOK, PTMP, PS19, PS18, PF19, PGPT, PCHK, FNM, F14, PISD, PAKH, PDP15, PRIX, PS15, PPCY, OLGC, OVNT, PLGN, PS14, P03, PDTP, PM14, FS, PPLS, MPR, PKTK, PS16, PRWK, PS17, PBFZ, PSS2, PINV, G03, P8ED, PARL, P04, P10, PSDC, JGP, G99, WW, P11, P05, PDIS, PROE, PDP10, F08, P10E, PELP, PMH1, P07, P5DN, PGRU, SHC, PM11, P06, PUSG, PCMP, PULG, F09, PUDS, PARB, DRC94, PMPS09, PORI, J12, G06, PMMQ, G07, J13, PMPS08, PM20, PSOI, PJSE, G05, G11, PNAT, PSOK, PEVE, PRED, G10, G04, PSHM, PPRO, PAPC, PJJT, ARENA, PKLD, G00, J14, PLGM, P15A, PCSP, PWPN, PJAS, PWP21, PWP09, PDKA, PNEM, PPTK, J15, G01, PG08, PLRW, PMEI, PM13, PHJ, PGTC, J17, PRES, PWCQ, PJOU, PDP12, PAER, PAVR, PTHS, G02, J16, PSUM, PGPX, UGF, PSS3, MM2, MM3, MB1, FMB1, A25, 2XM, MMA, PLIST, CHR, EMA, IMA, TSR, UMA, PUMA, E02, DPA, ATH, MD1, GK1, GK2, CST, BRB, BTD, DKM, FVE, V17, V13, STA, MPS_RNA, V16, SLD, V12, CC1, MPS_GRN, DRB, FVR, SS3, SS1, MPS_AKH, FVL, V15, MPS_KLD, ZNE, PDS, SS2, PD3, SLU, V14, PD2, EXP, MPS_WAR, DDQ, DDE, GS1, DDS, DDU, DD1, DDL, DDF, DDP, DD2, DDR, DDH, DDT, DDK, DDG, DDC, DDM, DDJ, DDO, GVL, JVC, DDI, DVD, DDN, EVG, DDD, C18, C19, C21, C20, C13, CMA, C14, C15, KHC, ZNC, AFC, C17, C16, COM, CM1, CM2, PO2, S99, W16, W17, S00, PTK, CP3, POR, CP1, CP2, CMR, MH2, H1R, CNS, BBD, MH1, CN2, JMP, PCA, GNT, ARC, GN2, PC2, E01, HOP, PLG20, PLG21, CC2, MID, MIC, VOW, VOC
Banned:Adriana's Valor; Advantageous Proclamation; Arcum's Astrolabe; Assemble the Rank and Vile; Backup Plan; Brago's Favor; Deathrite Shaman; Double Stroke; Dreadhorde Arcanist; Echoing Boon; Emissary's Ploy; Gitaxian Probe; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Incendiary Dissent; Iterative Analysis; Lurrus of the Dream-Den; Muzzio's Preparations; Natural Unity; Oko, Thief of Crowns; Power Play; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Sovereign's Realm; Summoner's Bond; Underworld Breach; Unexpected Potential; Weight Advantage; Worldknit; Amulet of Quoz; Bronze Tablet; Contract from Below; Darkpact; Demonic Attorney; Jeweled Bird; Rebirth; Tempest Efreet; Timmerian Fiends; Ancestral Recall; Balance; Bazaar of Baghdad; Black Lotus; Channel; Chaos Orb; Demonic Consultation; Demonic Tutor; Dig Through Time; Earthcraft; Falling Star; Fastbond; Flash; Frantic Search; Goblin Recruiter; Gush; Hermit Druid; Imperial Seal; Library of Alexandria; Mana Crypt; Mana Drain; Mana Vault; Memory Jar; Mental Misstep; Mind Twist; Mind's Desire; Mishra's Workshop; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystical Tutor; Necropotence; Oath of Druids; Sensei's Divining Top; Shahrazad; Skullclamp; Sol Ring; Strip Mine; Survival of the Fittest; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Treasure Cruise; Vampiric Tutor; Wheel of Fortune; Windfall; Wrenn and Six; Yawgmoth's Bargain; Yawgmoth's Will; Zirda, the Dawnwaker; Cleanse; Crusade; Imprison; Invoke Prejudice; Jihad; Pradesh Gypsies; Stone-Throwing Devils
Banned:Adriana's Valor; Advantageous Proclamation; Arcum's Astrolabe; Assemble the Rank and Vile; Backup Plan; Brago's Favor; Deathrite Shaman; Double Stroke; Dreadhorde Arcanist; Echoing Boon; Emissary's Ploy; Gitaxian Probe; Hired Heist; Hold the Perimeter; Hymn of the Wilds; Immediate Action; Incendiary Dissent; Iterative Analysis; Lurrus of the Dream-Den; Muzzio's Preparations; Natural Unity; Oko, Thief of Crowns; Power Play; Ragavan, Nimble Pilferer; Secret Summoning; Secrets of Paradise; Sentinel Dispatch; Sovereign's Realm; Summoner's Bond; Underworld Breach; Unexpected Potential; Weight Advantage; Worldknit; Amulet of Quoz; Bronze Tablet; Contract from Below; Darkpact; Demonic Attorney; Jeweled Bird; Rebirth; Tempest Efreet; Timmerian Fiends; Ancestral Recall; Balance; Bazaar of Baghdad; Black Lotus; Channel; Chaos Orb; Demonic Consultation; Demonic Tutor; Dig Through Time; Earthcraft; Falling Star; Fastbond; Flash; Frantic Search; Goblin Recruiter; Gush; Hermit Druid; Imperial Seal; Library of Alexandria; Mana Crypt; Mana Drain; Mana Vault; Memory Jar; Mental Misstep; Mind Twist; Mind's Desire; Mishra's Workshop; Mox Emerald; Mox Jet; Mox Pearl; Mox Ruby; Mox Sapphire; Mystical Tutor; Necropotence; Oath of Druids; Sensei's Divining Top; Shahrazad; Skullclamp; Sol Ring; Strip Mine; Survival of the Fittest; Time Vault; Time Walk; Timetwister; Tinker; Tolarian Academy; Treasure Cruise; Vampiric Tutor; Wheel of Fortune; Windfall; Wrenn and Six; Yawgmoth's Bargain; Yawgmoth's Will; Zirda, the Dawnwaker; Cleanse; Crusade; Imprison; Invoke Prejudice; Jihad; Pradesh Gypsies; Stone-Throwing Devils

View File

@@ -4,4 +4,4 @@ Order:101
Subtype:Standard
Type:Sanctioned
Sets:ZNR, KHM, STX, AFR, MID, VOW
Banned:Omnath, Locus of Creation
Banned:Alrund's Epiphany; Divide by Zero; Faceless Haven; Omnath, Locus of Creation

View File

@@ -0,0 +1,7 @@
Name:Spirit Token
ManaCost:no cost
Colors:red
Types:Creature Spirit
PT:2/2
K:Menace
Oracle:Menace

View File

@@ -0,0 +1,7 @@
Name:Dragon Spirit Token
ManaCost:no cost
Types:Creature Dragon Spirit
Colors:red
K:Flying
PT:5/5
Oracle:Flying

View File

@@ -17,10 +17,8 @@ import forge.card.ColorSet;
import forge.card.MagicColor;
import forge.card.mana.ManaCostShard;
import forge.game.GameView;
import forge.game.card.CardView;
import forge.game.card.CardView.CardStateView;
import forge.game.zone.ZoneType;
import forge.game.card.CounterType;
import forge.item.InventoryItemFromSet;
import forge.item.PaperCard;
import forge.item.PreconDeck;

View File

@@ -429,7 +429,7 @@ public final class CardScriptParser {
"leastPower", "leastToughness", "greatestCMC",
"greatestRememberedCMC", "lowestRememberedCMC", "lowestCMC",
"enchanted", "unenchanted", "enchanting", "equipped", "unequipped",
"equipping", "token", "nonToken", "hasXCost", "suspended",
"equipping", "modified", "token", "nonToken", "hasXCost", "suspended",
"delved", "attacking", "attackingYou", "notattacking",
"attackedBySourceThisCombat", "blocking", "blockingSource",
"blockingCreatureYouCtrl", "blockingRemembered",