mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-15 18:28:00 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
@@ -81,7 +81,12 @@ public class ControlExchangeAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
|
|
||||||
CardCollection list = CardLists.getValidCards(aiPlayer.getGame().getCardsIn(ZoneType.Battlefield),
|
// for TrigTwoTargets logic, only get the opponents' cards for the first target
|
||||||
|
CardCollectionView unfilteredList = "TrigTwoTargets".equals(sa.getParam("AILogic")) ?
|
||||||
|
aiPlayer.getOpponents().getCardsIn(ZoneType.Battlefield) :
|
||||||
|
aiPlayer.getGame().getCardsIn(ZoneType.Battlefield);
|
||||||
|
|
||||||
|
CardCollection list = CardLists.getValidCards(unfilteredList,
|
||||||
tgt.getValidTgts(), aiPlayer, sa.getHostCard(), sa);
|
tgt.getValidTgts(), aiPlayer, sa.getHostCard(), sa);
|
||||||
|
|
||||||
// only select the cards that can be targeted
|
// only select the cards that can be targeted
|
||||||
@@ -106,7 +111,51 @@ public class ControlExchangeAi extends SpellAbilityAi {
|
|||||||
|
|
||||||
// add best Target
|
// add best Target
|
||||||
sa.getTargets().add(best);
|
sa.getTargets().add(best);
|
||||||
|
|
||||||
|
// second target needed (the AI's own worst)
|
||||||
|
if ("TrigTwoTargets".equals(sa.getParam("AILogic"))) {
|
||||||
|
return doTrigTwoTargetsLogic(aiPlayer, sa, best);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean doTrigTwoTargetsLogic(Player ai, SpellAbility sa, Card bestFirstTgt) {
|
||||||
|
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
||||||
|
final int creatureThreshold = 100; // TODO: make this configurable from the AI profile
|
||||||
|
final int nonCreatureThreshold = 2;
|
||||||
|
|
||||||
|
CardCollection list = CardLists.getValidCards(ai.getCardsIn(ZoneType.Battlefield),
|
||||||
|
tgt.getValidTgts(), ai, sa.getHostCard(), sa);
|
||||||
|
|
||||||
|
// only select the cards that can be targeted
|
||||||
|
list = CardLists.getTargetableCards(list, sa);
|
||||||
|
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Card aiWorst = ComputerUtilCard.getWorstAI(list);
|
||||||
|
if (aiWorst == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aiWorst != null && aiWorst != bestFirstTgt) {
|
||||||
|
if (bestFirstTgt.isCreature() && aiWorst.isCreature()) {
|
||||||
|
if ((ComputerUtilCard.evaluateCreature(bestFirstTgt) > ComputerUtilCard.evaluateCreature(aiWorst) + creatureThreshold) || sa.isMandatory()) {
|
||||||
|
sa.getTargets().add(aiWorst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// TODO: compare non-creatures by CMC - can be improved, at least shouldn't give control of things like the Power Nine
|
||||||
|
if ((bestFirstTgt.getCMC() > aiWorst.getCMC() + nonCreatureThreshold) || sa.isMandatory()) {
|
||||||
|
sa.getTargets().add(aiWorst);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sa.clearTargets();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,10 @@ public class ForgeScript {
|
|||||||
return sa.hasParam("Equip");
|
return sa.hasParam("Equip");
|
||||||
} else if (property.equals("Boast")) {
|
} else if (property.equals("Boast")) {
|
||||||
return sa.isBoast();
|
return sa.isBoast();
|
||||||
|
} else if (property.equals("Foretelling")) {
|
||||||
|
return sa.isForetelling();
|
||||||
|
} else if (property.equals("Foretold")) {
|
||||||
|
return sa.isForetold();
|
||||||
} else if (property.equals("MayPlaySource")) {
|
} else if (property.equals("MayPlaySource")) {
|
||||||
StaticAbility m = sa.getMayPlay();
|
StaticAbility m = sa.getMayPlay();
|
||||||
if (m == null) {
|
if (m == null) {
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ public class Game {
|
|||||||
private final Match match;
|
private final Match match;
|
||||||
private GameStage age = GameStage.BeforeMulligan;
|
private GameStage age = GameStage.BeforeMulligan;
|
||||||
private GameOutcome outcome;
|
private GameOutcome outcome;
|
||||||
|
private Game maingame = null;
|
||||||
|
|
||||||
private final GameView view;
|
private final GameView view;
|
||||||
private final Tracker tracker = new Tracker();
|
private final Tracker tracker = new Tracker();
|
||||||
@@ -219,7 +220,11 @@ public class Game {
|
|||||||
changeZoneLKIInfo.clear();
|
changeZoneLKIInfo.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Game(Iterable<RegisteredPlayer> players0, GameRules rules0, Match match0) { /* no more zones to map here */
|
public Game(Iterable<RegisteredPlayer> players0, GameRules rules0, Match match0) {
|
||||||
|
this(players0, rules0, match0, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Game(Iterable<RegisteredPlayer> players0, GameRules rules0, Match match0, int startingLife) { /* no more zones to map here */
|
||||||
rules = rules0;
|
rules = rules0;
|
||||||
match = match0;
|
match = match0;
|
||||||
this.id = nextId();
|
this.id = nextId();
|
||||||
@@ -243,7 +248,11 @@ public class Game {
|
|||||||
allPlayers.add(pl);
|
allPlayers.add(pl);
|
||||||
ingamePlayers.add(pl);
|
ingamePlayers.add(pl);
|
||||||
|
|
||||||
|
if (startingLife != -1) {
|
||||||
|
pl.setStartingLife(startingLife);
|
||||||
|
} else {
|
||||||
pl.setStartingLife(psc.getStartingLife());
|
pl.setStartingLife(psc.getStartingLife());
|
||||||
|
}
|
||||||
pl.setMaxHandSize(psc.getStartingHand());
|
pl.setMaxHandSize(psc.getStartingHand());
|
||||||
pl.setStartingHandSize(psc.getStartingHand());
|
pl.setStartingHandSize(psc.getStartingHand());
|
||||||
|
|
||||||
@@ -430,6 +439,14 @@ public class Game {
|
|||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final Game getMaingame() {
|
||||||
|
return maingame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMaingame(final Game maingame0) {
|
||||||
|
maingame = maingame0;
|
||||||
|
}
|
||||||
|
|
||||||
public ReplacementHandler getReplacementHandler() {
|
public ReplacementHandler getReplacementHandler() {
|
||||||
return replacementHandler;
|
return replacementHandler;
|
||||||
}
|
}
|
||||||
@@ -452,13 +469,17 @@ public class Game {
|
|||||||
result.setTurnsPlayed(getPhaseHandler().getTurn());
|
result.setTurnsPlayed(getPhaseHandler().getTurn());
|
||||||
|
|
||||||
outcome = result;
|
outcome = result;
|
||||||
|
if (maingame == null) {
|
||||||
match.addGamePlayed(this);
|
match.addGamePlayed(this);
|
||||||
|
}
|
||||||
|
|
||||||
view.updateGameOver(this);
|
view.updateGameOver(this);
|
||||||
|
|
||||||
// The log shall listen to events and generate text internally
|
// The log shall listen to events and generate text internally
|
||||||
|
if (maingame == null) {
|
||||||
fireEvent(new GameEventGameOutcome(result, match.getOutcomes()));
|
fireEvent(new GameEventGameOutcome(result, match.getOutcomes()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Zone getZoneOf(final Card card) {
|
public Zone getZoneOf(final Card card) {
|
||||||
return card.getLastKnownZone();
|
return card.getLastKnownZone();
|
||||||
@@ -492,6 +513,14 @@ public class Game {
|
|||||||
return cards;
|
return cards;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CardCollectionView getCardsInOwnedBy(final Iterable<ZoneType> zones, Player p) {
|
||||||
|
CardCollection cards = new CardCollection();
|
||||||
|
for (final ZoneType z : zones) {
|
||||||
|
cards.addAll(getCardsIncludePhasingIn(z));
|
||||||
|
}
|
||||||
|
return CardLists.filter(cards, CardPredicates.isOwner(p));
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isCardExiled(final Card c) {
|
public boolean isCardExiled(final Card c) {
|
||||||
return getCardsIn(ZoneType.Exile).contains(c);
|
return getCardsIn(ZoneType.Exile).contains(c);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ public class GameAction {
|
|||||||
// Reset Activations per Turn
|
// Reset Activations per Turn
|
||||||
for (final Card card : game.getCardsInGame()) {
|
for (final Card card : game.getCardsInGame()) {
|
||||||
card.resetActivationsPerTurn();
|
card.resetActivationsPerTurn();
|
||||||
|
// need to reset this in exile
|
||||||
|
card.resetForetoldThisTurn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -168,7 +170,7 @@ public class GameAction {
|
|||||||
|
|
||||||
// Don't copy Tokens, copy only cards leaving the battlefield
|
// Don't copy Tokens, copy only cards leaving the battlefield
|
||||||
// and returning to hand (to recreate their spell ability information)
|
// and returning to hand (to recreate their spell ability information)
|
||||||
if (suppress || toBattlefield || zoneTo.is(ZoneType.Stack)) {
|
if (suppress || toBattlefield) {
|
||||||
copied = c;
|
copied = c;
|
||||||
|
|
||||||
if (lastKnownInfo == null) {
|
if (lastKnownInfo == null) {
|
||||||
@@ -193,10 +195,6 @@ public class GameAction {
|
|||||||
lastKnownInfo = CardUtil.getLKICopy(c);
|
lastKnownInfo = CardUtil.getLKICopy(c);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasFacedown) {
|
|
||||||
c.forceTurnFaceUp();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!c.isToken()) {
|
if (!c.isToken()) {
|
||||||
copied = CardFactory.copyCard(c, false);
|
copied = CardFactory.copyCard(c, false);
|
||||||
|
|
||||||
@@ -518,6 +516,18 @@ public class GameAction {
|
|||||||
|
|
||||||
c = changeZone(zoneFrom, zoneTo, c, position, cause, params);
|
c = changeZone(zoneFrom, zoneTo, c, position, cause, params);
|
||||||
|
|
||||||
|
// Move card in maingame if take card from subgame
|
||||||
|
// 720.4a
|
||||||
|
if (zoneFrom != null && zoneFrom.is(ZoneType.Sideboard) && game.getMaingame() != null) {
|
||||||
|
Card maingameCard = c.getOwner().getMappingMaingameCard(c);
|
||||||
|
if (maingameCard != null) {
|
||||||
|
if (maingameCard.getZone().is(ZoneType.Stack)) {
|
||||||
|
game.getMaingame().getStack().remove(maingameCard);
|
||||||
|
}
|
||||||
|
game.getMaingame().getAction().moveTo(ZoneType.Subgame, maingameCard, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (zoneFrom == null) {
|
if (zoneFrom == null) {
|
||||||
c.setCastFrom(null);
|
c.setCastFrom(null);
|
||||||
c.setCastSA(null);
|
c.setCastSA(null);
|
||||||
|
|||||||
@@ -204,7 +204,50 @@ public final class GameActionUtil {
|
|||||||
flashback.setPayCosts(new Cost(k[1], false));
|
flashback.setPayCosts(new Cost(k[1], false));
|
||||||
}
|
}
|
||||||
alternatives.add(flashback);
|
alternatives.add(flashback);
|
||||||
|
} else if (keyword.startsWith("Foretell")) {
|
||||||
|
// Fortell cast only from Exile
|
||||||
|
if (!source.isInZone(ZoneType.Exile) || !source.isForetold() || source.isForetoldThisTurn()) {
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
// skip this part for fortell by external source
|
||||||
|
if (keyword.equals("Foretell")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final SpellAbility foretold = sa.copy(activator);
|
||||||
|
foretold.setAlternativeCost(AlternativeCost.Foretold);
|
||||||
|
foretold.getRestrictions().setZone(ZoneType.Exile);
|
||||||
|
|
||||||
|
// Stack Description only for Permanent or it might crash
|
||||||
|
if (source.isPermanent()) {
|
||||||
|
final StringBuilder sbStack = new StringBuilder();
|
||||||
|
sbStack.append(sa.getStackDescription()).append(" (Foretold)");
|
||||||
|
foretold.setStackDescription(sbStack.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
final String[] k = keyword.split(":");
|
||||||
|
foretold.setPayCosts(new Cost(k[1], false));
|
||||||
|
|
||||||
|
alternatives.add(foretold);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// foretell by external source
|
||||||
|
if (source.isForetoldByEffect() && source.isInZone(ZoneType.Exile) && source.isForetold() && !source.isForetoldThisTurn() && !source.getManaCost().isNoCost()) {
|
||||||
|
// Its foretell cost is equal to its mana cost reduced by {2}.
|
||||||
|
final SpellAbility foretold = sa.copy(activator);
|
||||||
|
foretold.putParam("ReduceCost", "2");
|
||||||
|
foretold.setAlternativeCost(AlternativeCost.Foretold);
|
||||||
|
foretold.getRestrictions().setZone(ZoneType.Exile);
|
||||||
|
|
||||||
|
// Stack Description only for Permanent or it might crash
|
||||||
|
if (source.isPermanent()) {
|
||||||
|
final StringBuilder sbStack = new StringBuilder();
|
||||||
|
sbStack.append(sa.getStackDescription()).append(" (Foretold)");
|
||||||
|
foretold.setStackDescription(sbStack.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
alternatives.add(foretold);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -352,6 +352,9 @@ public final class AbilityFactory {
|
|||||||
if (mapParams.containsKey("TargetsWithSameCreatureType")) {
|
if (mapParams.containsKey("TargetsWithSameCreatureType")) {
|
||||||
abTgt.setWithSameCreatureType(true);
|
abTgt.setWithSameCreatureType(true);
|
||||||
}
|
}
|
||||||
|
if (mapParams.containsKey("TargetsWithSameCardType")) {
|
||||||
|
abTgt.setWithSameCardType(true);
|
||||||
|
}
|
||||||
if (mapParams.containsKey("TargetsWithSameController")) {
|
if (mapParams.containsKey("TargetsWithSameController")) {
|
||||||
abTgt.setSameController(true);
|
abTgt.setSameController(true);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,7 @@ public enum ApiType {
|
|||||||
SkipTurn (SkipTurnEffect.class),
|
SkipTurn (SkipTurnEffect.class),
|
||||||
StoreSVar (StoreSVarEffect.class),
|
StoreSVar (StoreSVarEffect.class),
|
||||||
StoreMap (StoreMapEffect.class),
|
StoreMap (StoreMapEffect.class),
|
||||||
|
Subgame (SubgameEffect.class),
|
||||||
Surveil (SurveilEffect.class),
|
Surveil (SurveilEffect.class),
|
||||||
SwitchBlock (SwitchBlockEffect.class),
|
SwitchBlock (SwitchBlockEffect.class),
|
||||||
Tap (TapEffect.class),
|
Tap (TapEffect.class),
|
||||||
|
|||||||
@@ -332,8 +332,7 @@ public abstract class SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void addForgetOnMovedTrigger(final Card card, final String zone) {
|
protected static SpellAbility getForgetSpellAbility(final Card card) {
|
||||||
String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | Destination$ Any | TriggerZones$ Command | Static$ True";
|
|
||||||
String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard";
|
String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard";
|
||||||
String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"
|
String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"
|
||||||
+ " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0";
|
+ " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0";
|
||||||
@@ -341,11 +340,23 @@ public abstract class SpellAbilityEffect {
|
|||||||
SpellAbility saForget = AbilityFactory.getAbility(forgetEffect, card);
|
SpellAbility saForget = AbilityFactory.getAbility(forgetEffect, card);
|
||||||
AbilitySub saExile = (AbilitySub) AbilityFactory.getAbility(exileEffect, card);
|
AbilitySub saExile = (AbilitySub) AbilityFactory.getAbility(exileEffect, card);
|
||||||
saForget.setSubAbility(saExile);
|
saForget.setSubAbility(saExile);
|
||||||
|
return saForget;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static void addForgetOnMovedTrigger(final Card card, final String zone) {
|
||||||
|
String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ " + zone + " | ExcludedDestinations$ Stack | Destination$ Any | TriggerZones$ Command | Static$ True";
|
||||||
|
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
||||||
parsedTrigger.setOverridingAbility(saForget);
|
parsedTrigger.setOverridingAbility(getForgetSpellAbility(card));
|
||||||
final Trigger addedTrigger = card.addTrigger(parsedTrigger);
|
card.addTrigger(parsedTrigger);
|
||||||
addedTrigger.setIntrinsic(true);
|
}
|
||||||
|
|
||||||
|
protected static void addForgetOnCastTrigger(final Card card) {
|
||||||
|
String trig = "Mode$ SpellCast | ValidCard$ Card.IsRemembered | TriggerZones$ Command | Static$ True";
|
||||||
|
|
||||||
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
||||||
|
parsedTrigger.setOverridingAbility(getForgetSpellAbility(card));
|
||||||
|
card.addTrigger(parsedTrigger);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void addExileOnMovedTrigger(final Card card, final String zone) {
|
protected static void addExileOnMovedTrigger(final Card card, final String zone) {
|
||||||
@@ -368,35 +379,18 @@ public abstract class SpellAbilityEffect {
|
|||||||
|
|
||||||
protected static void addForgetOnPhasedInTrigger(final Card card) {
|
protected static void addForgetOnPhasedInTrigger(final Card card) {
|
||||||
String trig = "Mode$ PhaseIn | ValidCard$ Card.IsRemembered | TriggerZones$ Command | Static$ True";
|
String trig = "Mode$ PhaseIn | ValidCard$ Card.IsRemembered | TriggerZones$ Command | Static$ True";
|
||||||
String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard";
|
|
||||||
String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"
|
|
||||||
+ " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0";
|
|
||||||
|
|
||||||
SpellAbility saForget = AbilityFactory.getAbility(forgetEffect, card);
|
|
||||||
AbilitySub saExile = (AbilitySub) AbilityFactory.getAbility(exileEffect, card);
|
|
||||||
saForget.setSubAbility(saExile);
|
|
||||||
|
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
||||||
parsedTrigger.setOverridingAbility(saForget);
|
parsedTrigger.setOverridingAbility(getForgetSpellAbility(card));
|
||||||
final Trigger addedTrigger = card.addTrigger(parsedTrigger);
|
card.addTrigger(parsedTrigger);
|
||||||
addedTrigger.setIntrinsic(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void addForgetCounterTrigger(final Card card, final String counterType) {
|
protected static void addForgetCounterTrigger(final Card card, final String counterType) {
|
||||||
String trig = "Mode$ CounterRemoved | TriggerZones$ Command | ValidCard$ Card.IsRemembered | CounterType$ " + counterType + " | NewCounterAmount$ 0 | Static$ True";
|
String trig = "Mode$ CounterRemoved | TriggerZones$ Command | ValidCard$ Card.IsRemembered | CounterType$ " + counterType + " | NewCounterAmount$ 0 | Static$ True";
|
||||||
|
|
||||||
String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard";
|
|
||||||
String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"
|
|
||||||
+ " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0";
|
|
||||||
|
|
||||||
SpellAbility saForget = AbilityFactory.getAbility(forgetEffect, card);
|
|
||||||
AbilitySub saExile = (AbilitySub) AbilityFactory.getAbility(exileEffect, card);
|
|
||||||
saForget.setSubAbility(saExile);
|
|
||||||
|
|
||||||
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, card, true);
|
||||||
parsedTrigger.setOverridingAbility(saForget);
|
parsedTrigger.setOverridingAbility(getForgetSpellAbility(card));
|
||||||
final Trigger addedTrigger = card.addTrigger(parsedTrigger);
|
card.addTrigger(parsedTrigger);
|
||||||
addedTrigger.setIntrinsic(true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static void addLeaveBattlefieldReplacement(final Card card, final SpellAbility sa, final String zone) {
|
protected static void addLeaveBattlefieldReplacement(final Card card, final SpellAbility sa, final String zone) {
|
||||||
|
|||||||
@@ -701,6 +701,13 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("ExileFaceDown")) {
|
if (sa.hasParam("ExileFaceDown")) {
|
||||||
movedCard.turnFaceDown(true);
|
movedCard.turnFaceDown(true);
|
||||||
}
|
}
|
||||||
|
if (sa.hasParam("Foretold")) {
|
||||||
|
movedCard.setForetold(true);
|
||||||
|
movedCard.setForetoldThisTurn(true);
|
||||||
|
movedCard.setForetoldByEffect(true);
|
||||||
|
// look at the exiled card
|
||||||
|
movedCard.addMayLookTemp(sa.getActivatingPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
if (sa.hasParam("TrackDiscarded")) {
|
if (sa.hasParam("TrackDiscarded")) {
|
||||||
movedCard.setMadnessWithoutCast(true);
|
movedCard.setMadnessWithoutCast(true);
|
||||||
@@ -1240,6 +1247,13 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
|
|||||||
if (sa.hasParam("ExileFaceDown")) {
|
if (sa.hasParam("ExileFaceDown")) {
|
||||||
movedCard.turnFaceDown(true);
|
movedCard.turnFaceDown(true);
|
||||||
}
|
}
|
||||||
|
if (sa.hasParam("Foretold")) {
|
||||||
|
movedCard.setForetold(true);
|
||||||
|
movedCard.setForetoldThisTurn(true);
|
||||||
|
movedCard.setForetoldByEffect(true);
|
||||||
|
// look at the exiled card
|
||||||
|
movedCard.addMayLookTemp(sa.getActivatingPlayer());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
movedCard = game.getAction().moveTo(destination, c, 0, cause, moveParams);
|
movedCard = game.getAction().moveTo(destination, c, 0, cause, moveParams);
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
package forge.game.ability.effects;
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import forge.game.Game;
|
||||||
import forge.game.ability.AbilityUtils;
|
import forge.game.ability.AbilityUtils;
|
||||||
import forge.game.ability.SpellAbilityEffect;
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.TargetRestrictions;
|
import forge.util.CardTranslation;
|
||||||
|
import forge.util.Localizer;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
@@ -21,21 +23,27 @@ public class ControlExchangeEffect extends SpellAbilityEffect {
|
|||||||
protected String getStackDescription(SpellAbility sa) {
|
protected String getStackDescription(SpellAbility sa) {
|
||||||
Card object1 = null;
|
Card object1 = null;
|
||||||
Card object2 = null;
|
Card object2 = null;
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
List<Card> tgts = null;
|
||||||
List<Card> tgts = tgt == null ? new ArrayList<>() : Lists.newArrayList(sa.getTargets().getTargetCards());
|
if (sa.usesTargeting()) {
|
||||||
|
tgts = Lists.newArrayList(sa.getTargets().getTargetCards());
|
||||||
if (tgts.size() > 0) {
|
if (tgts.size() > 0) {
|
||||||
object1 = tgts.get(0);
|
object1 = tgts.get(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (sa.hasParam("Defined")) {
|
if (sa.hasParam("Defined")) {
|
||||||
List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
||||||
object2 = cards.isEmpty() ? null : cards.get(0);
|
object2 = cards.isEmpty() ? null : cards.get(0);
|
||||||
if (cards.size() > 1 && sa.hasParam("BothDefined")) {
|
if (cards.size() > 1 && !sa.usesTargeting()) {
|
||||||
object1 = cards.get(1);
|
object1 = cards.get(1);
|
||||||
}
|
}
|
||||||
} else if (tgts.size() > 1) {
|
} else if (tgts.size() > 1) {
|
||||||
object2 = tgts.get(1);
|
object2 = tgts.get(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (object1 == null || object2 == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
return object1 + " exchanges controller with " + object2;
|
return object1 + " exchanges controller with " + object2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,17 +52,22 @@ public class ControlExchangeEffect extends SpellAbilityEffect {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void resolve(SpellAbility sa) {
|
public void resolve(SpellAbility sa) {
|
||||||
|
Card host = sa.getHostCard();
|
||||||
|
Game game = host.getGame();
|
||||||
Card object1 = null;
|
Card object1 = null;
|
||||||
Card object2 = null;
|
Card object2 = null;
|
||||||
final TargetRestrictions tgt = sa.getTargetRestrictions();
|
|
||||||
List<Card> tgts = tgt == null ? new ArrayList<>() : Lists.newArrayList(sa.getTargets().getTargetCards());
|
List<Card> tgts = null;
|
||||||
|
if (sa.usesTargeting()) {
|
||||||
|
tgts = Lists.newArrayList(sa.getTargets().getTargetCards());
|
||||||
if (tgts.size() > 0) {
|
if (tgts.size() > 0) {
|
||||||
object1 = tgts.get(0);
|
object1 = tgts.get(0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (sa.hasParam("Defined")) {
|
if (sa.hasParam("Defined")) {
|
||||||
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("Defined"), sa);
|
final List<Card> cards = AbilityUtils.getDefinedCards(host, sa.getParam("Defined"), sa);
|
||||||
object2 = cards.isEmpty() ? null : cards.get(0);
|
object2 = cards.isEmpty() ? null : cards.get(0);
|
||||||
if (cards.size() > 1 && sa.hasParam("BothDefined")) {
|
if (cards.size() > 1 && !sa.usesTargeting()) {
|
||||||
object1 = cards.get(1);
|
object1 = cards.get(1);
|
||||||
}
|
}
|
||||||
} else if (tgts.size() > 1) {
|
} else if (tgts.size() > 1) {
|
||||||
@@ -73,7 +86,16 @@ public class ControlExchangeEffect extends SpellAbilityEffect {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final long tStamp = sa.getActivatingPlayer().getGame().getNextTimestamp();
|
if (sa.hasParam("Optional")) {
|
||||||
|
if (!sa.getActivatingPlayer().getController().confirmAction(sa, null,
|
||||||
|
Localizer.getInstance().getMessage("lblExchangeControl",
|
||||||
|
CardTranslation.getTranslatedName(object1.getName()),
|
||||||
|
CardTranslation.getTranslatedName(object2.getName())))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final long tStamp = game.getNextTimestamp();
|
||||||
object2.setController(player1, tStamp);
|
object2.setController(player1, tStamp);
|
||||||
object1.setController(player2, tStamp);
|
object1.setController(player2, tStamp);
|
||||||
if (sa.hasParam("RememberExchanged")) {
|
if (sa.hasParam("RememberExchanged")) {
|
||||||
|
|||||||
@@ -13,9 +13,11 @@ import forge.game.card.Card;
|
|||||||
import forge.game.card.CardCollectionView;
|
import forge.game.card.CardCollectionView;
|
||||||
import forge.game.card.CardFactory;
|
import forge.game.card.CardFactory;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
|
import forge.game.card.CardPredicates;
|
||||||
import forge.game.card.CardZoneTable;
|
import forge.game.card.CardZoneTable;
|
||||||
import forge.game.event.GameEventCombatChanged;
|
import forge.game.event.GameEventCombatChanged;
|
||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
|
import forge.game.player.PlayerActionConfirmMode;
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.zone.ZoneType;
|
import forge.game.zone.ZoneType;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
@@ -141,12 +143,25 @@ public class CopyPermanentEffect extends TokenEffectBase {
|
|||||||
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
|
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
|
||||||
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
|
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
|
||||||
if (!choices.isEmpty()) {
|
if (!choices.isEmpty()) {
|
||||||
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") +" ";
|
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard");
|
||||||
|
|
||||||
Card choosen = chooser.getController().chooseSingleEntityForEffect(choices, sa, title, false, null);
|
if (sa.hasParam("WithDifferentNames")) {
|
||||||
|
// any Number of choices with different names
|
||||||
|
while (!choices.isEmpty()) {
|
||||||
|
Card choosen = chooser.getController().chooseSingleEntityForEffect(choices, sa, title, true, null);
|
||||||
|
|
||||||
if (choosen != null) {
|
if (choosen != null) {
|
||||||
tgtCards.add(choosen);
|
tgtCards.add(choosen);
|
||||||
|
choices = CardLists.filter(choices, Predicates.not(CardPredicates.sharesNameWith(choosen)));
|
||||||
|
} else if (chooser.getController().confirmAction(sa, PlayerActionConfirmMode.OptionalChoose, Localizer.getInstance().getMessage("lblCancelChooseConfirm"))) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Card choosen = chooser.getController().chooseSingleEntityForEffect(choices, sa, title, false, null);
|
||||||
|
if (choosen != null) {
|
||||||
|
tgtCards.add(choosen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -208,3 +223,5 @@ public class CopyPermanentEffect extends TokenEffectBase {
|
|||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -215,6 +215,7 @@ public class EffectEffect extends SpellAbilityEffect {
|
|||||||
}
|
}
|
||||||
if (sa.hasParam("ForgetOnMoved")) {
|
if (sa.hasParam("ForgetOnMoved")) {
|
||||||
addForgetOnMovedTrigger(eff, sa.getParam("ForgetOnMoved"));
|
addForgetOnMovedTrigger(eff, sa.getParam("ForgetOnMoved"));
|
||||||
|
addForgetOnCastTrigger(eff);
|
||||||
} else if (sa.hasParam("ExileOnMoved")) {
|
} else if (sa.hasParam("ExileOnMoved")) {
|
||||||
addExileOnMovedTrigger(eff, sa.getParam("ExileOnMoved"));
|
addExileOnMovedTrigger(eff, sa.getParam("ExileOnMoved"));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,254 @@
|
|||||||
|
package forge.game.ability.effects;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
import forge.card.MagicColor;
|
||||||
|
import forge.game.Game;
|
||||||
|
import forge.game.GameOutcome;
|
||||||
|
import forge.game.ability.ApiType;
|
||||||
|
import forge.game.ability.SpellAbilityEffect;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.card.CardCollectionView;
|
||||||
|
import forge.game.event.GameEventSubgameStart;
|
||||||
|
import forge.game.event.GameEventSubgameEnd;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.player.PlayerController;
|
||||||
|
import forge.game.player.RegisteredPlayer;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.game.zone.PlayerZone;
|
||||||
|
import forge.game.zone.ZoneType;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.util.CardTranslation;
|
||||||
|
import forge.util.Lang;
|
||||||
|
import forge.util.Localizer;
|
||||||
|
import forge.util.collect.FCollectionView;
|
||||||
|
|
||||||
|
public class SubgameEffect extends SpellAbilityEffect {
|
||||||
|
|
||||||
|
private final Game createSubGame(Game maingame, int startingLife) {
|
||||||
|
List<RegisteredPlayer> players = Lists.newArrayList();
|
||||||
|
|
||||||
|
// Add remaining players to subgame
|
||||||
|
for (Player p : maingame.getPlayers()) {
|
||||||
|
players.add(p.getRegisteredPlayer());
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Game(players, maingame.getRules(), maingame.getMatch(), startingLife);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void setCardsInZone(Player player, final ZoneType zoneType, final CardCollectionView oldCards, boolean addMapping) {
|
||||||
|
PlayerZone zone = player.getZone(zoneType);
|
||||||
|
List<Card> newCards = Lists.newArrayList();
|
||||||
|
for (final Card card : oldCards) {
|
||||||
|
if (card.isToken() || card.isCopiedSpell()) continue;
|
||||||
|
Card newCard = Card.fromPaperCard(card.getPaperCard(), player);
|
||||||
|
newCards.add(newCard);
|
||||||
|
if (addMapping) {
|
||||||
|
// Build mapping between maingame cards and subgame cards,
|
||||||
|
// so when subgame pick a card from maingame (like Wish effects),
|
||||||
|
// The maingame card will also be moved.
|
||||||
|
// (Will be move to Subgame zone, which will be added back to libary after subgame ends.)
|
||||||
|
player.addMaingameCardMapping(newCard, card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
zone.setCards(newCards);
|
||||||
|
}
|
||||||
|
|
||||||
|
private final void initVariantsZonesSubgame(final Game subgame, final Player maingamePlayer, final Player player) {
|
||||||
|
PlayerZone com = player.getZone(ZoneType.Command);
|
||||||
|
RegisteredPlayer registeredPlayer = player.getRegisteredPlayer();
|
||||||
|
|
||||||
|
// Vanguard
|
||||||
|
if (registeredPlayer.getVanguardAvatars() != null) {
|
||||||
|
for(PaperCard avatar:registeredPlayer.getVanguardAvatars()) {
|
||||||
|
com.add(Card.fromPaperCard(avatar, player));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Commander
|
||||||
|
List<Card> commanders = Lists.newArrayList();
|
||||||
|
final CardCollectionView commandCards = maingamePlayer.getCardsIn(ZoneType.Command);
|
||||||
|
for (final Card card : commandCards) {
|
||||||
|
if (card.isCommander()) {
|
||||||
|
Card cmd = Card.fromPaperCard(card.getPaperCard(), player);
|
||||||
|
if (cmd.hasKeyword("If CARDNAME is your commander, choose a color before the game begins.")) {
|
||||||
|
List<String> colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS);
|
||||||
|
String prompt = Localizer.getInstance().getMessage("lblChooseAColorFor", cmd.getName());
|
||||||
|
List<String> chosenColors;
|
||||||
|
SpellAbility cmdColorsa = new SpellAbility.EmptySa(ApiType.ChooseColor, cmd, player);
|
||||||
|
chosenColors = player.getController().chooseColors(prompt,cmdColorsa, 1, 1, colorChoices);
|
||||||
|
cmd.setChosenColors(chosenColors);
|
||||||
|
subgame.getAction().nofityOfValue(cmdColorsa, cmd, Localizer.getInstance().getMessage("lblPlayerPickedChosen", player.getName(), Lang.joinHomogenous(chosenColors)), player);
|
||||||
|
}
|
||||||
|
cmd.setCommander(true);
|
||||||
|
com.add(cmd);
|
||||||
|
commanders.add(cmd);
|
||||||
|
com.add(Player.createCommanderEffect(subgame, cmd));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!commanders.isEmpty()) {
|
||||||
|
player.setCommanders(commanders);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conspiracies
|
||||||
|
// 720.2 doesn't mention Conspiracy cards so I guess they don't move
|
||||||
|
}
|
||||||
|
|
||||||
|
private void prepareAllZonesSubgame(final Game maingame, final Game subgame) {
|
||||||
|
final FCollectionView<Player> players = subgame.getPlayers();
|
||||||
|
final FCollectionView<Player> maingamePlayers = maingame.getPlayers();
|
||||||
|
final List<ZoneType> outsideZones = Arrays.asList(ZoneType.Hand, ZoneType.Battlefield,
|
||||||
|
ZoneType.Graveyard, ZoneType.Exile, ZoneType.Stack, ZoneType.Sideboard, ZoneType.Ante);
|
||||||
|
|
||||||
|
for (int i = 0; i < players.size(); i++) {
|
||||||
|
final Player player = players.get(i);
|
||||||
|
final Player maingamePlayer = maingamePlayers.get(i);
|
||||||
|
|
||||||
|
// Library
|
||||||
|
setCardsInZone(player, ZoneType.Library, maingamePlayer.getCardsIn(ZoneType.Library), false);
|
||||||
|
|
||||||
|
// Sideboard
|
||||||
|
// 720.4
|
||||||
|
final CardCollectionView outsideCards = maingame.getCardsInOwnedBy(outsideZones, maingamePlayer);
|
||||||
|
if (!outsideCards.isEmpty()) {
|
||||||
|
setCardsInZone(player, ZoneType.Sideboard, outsideCards, true);
|
||||||
|
|
||||||
|
// Assign Companion
|
||||||
|
PlayerController person = player.getController();
|
||||||
|
Card companion = player.assignCompanion(subgame, person);
|
||||||
|
// Create an effect that lets you cast your companion from your sideboard
|
||||||
|
if (companion != null) {
|
||||||
|
PlayerZone commandZone = player.getZone(ZoneType.Command);
|
||||||
|
companion = subgame.getAction().moveTo(ZoneType.Command, companion, null);
|
||||||
|
commandZone.add(Player.createCompanionEffect(subgame, companion));
|
||||||
|
|
||||||
|
player.updateZoneForView(commandZone);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Schemes
|
||||||
|
setCardsInZone(player, ZoneType.SchemeDeck, maingamePlayer.getCardsIn(ZoneType.SchemeDeck), false);
|
||||||
|
|
||||||
|
// Planes
|
||||||
|
setCardsInZone(player, ZoneType.PlanarDeck, maingamePlayer.getCardsIn(ZoneType.PlanarDeck), false);
|
||||||
|
|
||||||
|
// Vanguard and Commanders
|
||||||
|
initVariantsZonesSubgame(subgame, maingamePlayer, player);
|
||||||
|
|
||||||
|
player.shuffle(null);
|
||||||
|
player.getZone(ZoneType.SchemeDeck).shuffle();
|
||||||
|
player.getZone(ZoneType.PlanarDeck).shuffle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolve(SpellAbility sa) {
|
||||||
|
final Card hostCard = sa.getHostCard();
|
||||||
|
final Game maingame = hostCard.getGame();
|
||||||
|
|
||||||
|
int startingLife = -1;
|
||||||
|
if (sa.hasParam("StartingLife")) {
|
||||||
|
startingLife = Integer.parseInt(sa.getParam("StartingLife"));
|
||||||
|
}
|
||||||
|
Game subgame = createSubGame(maingame, startingLife);
|
||||||
|
subgame.setMaingame(maingame);
|
||||||
|
|
||||||
|
String startMessage = Localizer.getInstance().getMessage("lblSubgameStart",
|
||||||
|
CardTranslation.getTranslatedName(hostCard.getName()));
|
||||||
|
maingame.fireEvent(new GameEventSubgameStart(subgame, startMessage));
|
||||||
|
|
||||||
|
prepareAllZonesSubgame(maingame, subgame);
|
||||||
|
subgame.getAction().startGame(null, null);
|
||||||
|
subgame.clearCaches();
|
||||||
|
|
||||||
|
// Find out winners and losers
|
||||||
|
final GameOutcome outcome = subgame.getOutcome();
|
||||||
|
List<Player> winPlayers = Lists.newArrayList();
|
||||||
|
List<Player> notWinPlayers = Lists.newArrayList();
|
||||||
|
StringBuilder sbWinners = new StringBuilder();
|
||||||
|
StringBuilder sbLosers = new StringBuilder();
|
||||||
|
for (Player p : maingame.getPlayers()) {
|
||||||
|
if (outcome.isWinner(p.getRegisteredPlayer())) {
|
||||||
|
if (!winPlayers.isEmpty()) {
|
||||||
|
sbWinners.append(", ");
|
||||||
|
}
|
||||||
|
sbWinners.append(p.getName());
|
||||||
|
winPlayers.add(p);
|
||||||
|
} else {
|
||||||
|
if (!notWinPlayers.isEmpty()) {
|
||||||
|
sbLosers.append(", ");
|
||||||
|
}
|
||||||
|
sbLosers.append(p.getName());
|
||||||
|
notWinPlayers.add(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa.hasParam("RememberPlayers")) {
|
||||||
|
final String param = sa.getParam("RememberPlayers");
|
||||||
|
if (param.equals("Win")) {
|
||||||
|
for (Player p : winPlayers) {
|
||||||
|
hostCard.addRemembered(p);
|
||||||
|
}
|
||||||
|
} else if (param.equals("NotWin")) {
|
||||||
|
for (Player p : notWinPlayers) {
|
||||||
|
hostCard.addRemembered(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String endMessage = outcome.isDraw() ? Localizer.getInstance().getMessage("lblSubgameEndDraw") :
|
||||||
|
Localizer.getInstance().getMessage("lblSubgameEnd", sbWinners.toString(), sbLosers.toString());
|
||||||
|
maingame.fireEvent(new GameEventSubgameEnd(maingame, endMessage));
|
||||||
|
|
||||||
|
// Setup maingame library
|
||||||
|
final FCollectionView<Player> subgamePlayers = subgame.getRegisteredPlayers();
|
||||||
|
final FCollectionView<Player> players = maingame.getPlayers();
|
||||||
|
for (int i = 0; i < players.size(); i++) {
|
||||||
|
final Player subgamePlayer = subgamePlayers.get(i);
|
||||||
|
final Player player = players.get(i);
|
||||||
|
|
||||||
|
// All cards moved to Subgame Zone will be put into library when subgame ends.
|
||||||
|
// 720.5
|
||||||
|
final CardCollectionView movedCards = player.getCardsIn(ZoneType.Subgame);
|
||||||
|
PlayerZone library = player.getZone(ZoneType.Library);
|
||||||
|
for (final Card card : movedCards) {
|
||||||
|
library.add(card);
|
||||||
|
}
|
||||||
|
player.getZone(ZoneType.Subgame).removeAllCards(true);
|
||||||
|
|
||||||
|
// Move commander if it is no longer in subgame's commander zone
|
||||||
|
// 720.5c
|
||||||
|
List<Card> subgameCommanders = Lists.newArrayList();
|
||||||
|
List<Card> movedCommanders = Lists.newArrayList();
|
||||||
|
for (final Card card : subgamePlayer.getCardsIn(ZoneType.Command)) {
|
||||||
|
if (card.isCommander()) {
|
||||||
|
subgameCommanders.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final Card card : player.getCardsIn(ZoneType.Command)) {
|
||||||
|
if (card.isCommander()) {
|
||||||
|
boolean isInSubgameCommand = false;
|
||||||
|
for (final Card subCard : subgameCommanders) {
|
||||||
|
if (card.getName().equals(subCard.getName())) {
|
||||||
|
isInSubgameCommand = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!isInSubgameCommand) {
|
||||||
|
movedCommanders.add(card);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (final Card card : movedCommanders) {
|
||||||
|
maingame.getAction().moveTo(ZoneType.Library, card, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.shuffle(sa);
|
||||||
|
player.getZone(ZoneType.SchemeDeck).shuffle();
|
||||||
|
player.getZone(ZoneType.PlanarDeck).shuffle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -177,6 +177,10 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|
|
||||||
private boolean manifested = false;
|
private boolean manifested = false;
|
||||||
|
|
||||||
|
private boolean foretold = false;
|
||||||
|
private boolean foretoldThisTurn = false;
|
||||||
|
private boolean foretoldByEffect = false;
|
||||||
|
|
||||||
private long bestowTimestamp = -1;
|
private long bestowTimestamp = -1;
|
||||||
private long transformedTimestamp = 0;
|
private long transformedTimestamp = 0;
|
||||||
private boolean tributed = false;
|
private boolean tributed = false;
|
||||||
@@ -1694,7 +1698,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
} else {
|
} else {
|
||||||
sbLong.append(parts[0]).append(" ").append(ManaCostParser.parse(parts[1])).append("\r\n");
|
sbLong.append(parts[0]).append(" ").append(ManaCostParser.parse(parts[1])).append("\r\n");
|
||||||
}
|
}
|
||||||
} else if (keyword.startsWith("Morph") || keyword.startsWith("Megamorph") || keyword.startsWith("Escape")) {
|
} else if (keyword.startsWith("Morph") || keyword.startsWith("Megamorph") || keyword.startsWith("Escape") || keyword.startsWith("Foretell:")) {
|
||||||
String[] k = keyword.split(":");
|
String[] k = keyword.split(":");
|
||||||
sbLong.append(k[0]);
|
sbLong.append(k[0]);
|
||||||
if (k.length > 1) {
|
if (k.length > 1) {
|
||||||
@@ -1789,6 +1793,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
|| keyword.equals("Changeling") || keyword.equals("Delve")
|
|| keyword.equals("Changeling") || keyword.equals("Delve")
|
||||||
|| keyword.equals("Split second") || keyword.equals("Sunburst")
|
|| keyword.equals("Split second") || keyword.equals("Sunburst")
|
||||||
|| keyword.equals("Suspend") // for the ones without amounnt
|
|| keyword.equals("Suspend") // for the ones without amounnt
|
||||||
|
|| keyword.equals("Foretell") // for the ones without cost
|
||||||
|| keyword.equals("Hideaway") || keyword.equals("Ascend")
|
|| keyword.equals("Hideaway") || keyword.equals("Ascend")
|
||||||
|| keyword.equals("Totem armor") || keyword.equals("Battle cry")
|
|| keyword.equals("Totem armor") || keyword.equals("Battle cry")
|
||||||
|| keyword.equals("Devoid") || keyword.equals("Riot")){
|
|| keyword.equals("Devoid") || keyword.equals("Riot")){
|
||||||
@@ -2236,7 +2241,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
sbBefore.append("\r\n");
|
sbBefore.append("\r\n");
|
||||||
} else if (keyword.startsWith("Entwine") || keyword.startsWith("Madness")
|
} else if (keyword.startsWith("Entwine") || keyword.startsWith("Madness")
|
||||||
|| keyword.startsWith("Miracle") || keyword.startsWith("Recover")
|
|| keyword.startsWith("Miracle") || keyword.startsWith("Recover")
|
||||||
|| keyword.startsWith("Escape")) {
|
|| keyword.startsWith("Escape") || keyword.startsWith("Foretell:")) {
|
||||||
final String[] k = keyword.split(":");
|
final String[] k = keyword.split(":");
|
||||||
final Cost cost = new Cost(k[1], false);
|
final Cost cost = new Cost(k[1], false);
|
||||||
|
|
||||||
@@ -5319,6 +5324,42 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final boolean isForetold() {
|
||||||
|
// in exile and foretold
|
||||||
|
if (this.isInZone(ZoneType.Exile)) {
|
||||||
|
return this.foretold;
|
||||||
|
}
|
||||||
|
// cast as foretold, currently only spells
|
||||||
|
if (this.getCastSA() != null) {
|
||||||
|
return this.getCastSA().isForetold();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setForetold(final boolean foretold) {
|
||||||
|
this.foretold = foretold;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForetoldByEffect() {
|
||||||
|
return foretoldByEffect;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForetoldByEffect(final boolean val) {
|
||||||
|
this.foretoldByEffect = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForetoldThisTurn() {
|
||||||
|
return foretoldThisTurn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void setForetoldThisTurn(final boolean foretoldThisTurn) {
|
||||||
|
this.foretoldThisTurn = foretoldThisTurn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetForetoldThisTurn() {
|
||||||
|
foretoldThisTurn = false;
|
||||||
|
}
|
||||||
|
|
||||||
public final void animateBestow() {
|
public final void animateBestow() {
|
||||||
animateBestow(true);
|
animateBestow(true);
|
||||||
}
|
}
|
||||||
@@ -6567,11 +6608,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
return numberGameActivations.containsKey(original) ? numberGameActivations.get(original) : 0;
|
return numberGameActivations.containsKey(original) ? numberGameActivations.get(original) : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resetTurnActivations() {
|
|
||||||
numberTurnActivations.clear();
|
|
||||||
numberTurnActivationsStatic.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getChosenModesTurn(SpellAbility ability) {
|
public List<String> getChosenModesTurn(SpellAbility ability) {
|
||||||
SpellAbility original = null;
|
SpellAbility original = null;
|
||||||
SpellAbility root = ability.getRootAbility();
|
SpellAbility root = ability.getRootAbility();
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ public class CardFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
out.setZone(in.getZone());
|
out.setZone(in.getZone());
|
||||||
out.setState(in.getCurrentStateName(), true);
|
out.setState(in.getFaceupCardStateName(), true);
|
||||||
out.setBackSide(in.isBackSide());
|
out.setBackSide(in.isBackSide());
|
||||||
|
|
||||||
// this's necessary for forge.game.GameAction.unattachCardLeavingBattlefield(Card)
|
// this's necessary for forge.game.GameAction.unattachCardLeavingBattlefield(Card)
|
||||||
|
|||||||
@@ -66,7 +66,6 @@ import java.util.Map.Entry;
|
|||||||
import io.sentry.Sentry;
|
import io.sentry.Sentry;
|
||||||
import io.sentry.event.BreadcrumbBuilder;
|
import io.sentry.event.BreadcrumbBuilder;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* CardFactoryUtil class.
|
* CardFactoryUtil class.
|
||||||
@@ -1404,6 +1403,13 @@ public class CardFactoryUtil {
|
|||||||
return doXMath(StringUtils.isNumeric(v) ? Integer.parseInt(v) : xCount(c, c.getSVar(v)), m, c);
|
return doXMath(StringUtils.isNumeric(v) ? Integer.parseInt(v) : xCount(c, c.getSVar(v)), m, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Count$Foretold.<True>.<False>
|
||||||
|
if (sq[0].startsWith("Foretold")) {
|
||||||
|
String v = c.isForetold() ? sq[1] : sq[2];
|
||||||
|
// TODO move this to AbilityUtils
|
||||||
|
return doXMath(StringUtils.isNumeric(v) ? Integer.parseInt(v) : xCount(c, c.getSVar(v)), m, c);
|
||||||
|
}
|
||||||
|
|
||||||
// Count$Presence_<Type>.<True>.<False>
|
// Count$Presence_<Type>.<True>.<False>
|
||||||
if (sq[0].startsWith("Presence")) {
|
if (sq[0].startsWith("Presence")) {
|
||||||
final String type = sq[0].split("_")[1];
|
final String type = sq[0].split("_")[1];
|
||||||
@@ -1449,7 +1455,6 @@ public class CardFactoryUtil {
|
|||||||
return forge.util.MyRandom.getRandom().nextInt(1+max-min) + min;
|
return forge.util.MyRandom.getRandom().nextInt(1+max-min) + min;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Count$Domain
|
// Count$Domain
|
||||||
if (sq[0].startsWith("Domain")) {
|
if (sq[0].startsWith("Domain")) {
|
||||||
int n = 0;
|
int n = 0;
|
||||||
@@ -1997,7 +2002,6 @@ public class CardFactoryUtil {
|
|||||||
final Set<String> hexproofkw = Sets.newHashSet();
|
final Set<String> hexproofkw = Sets.newHashSet();
|
||||||
final Set<String> allkw = Sets.newHashSet();
|
final Set<String> allkw = Sets.newHashSet();
|
||||||
|
|
||||||
|
|
||||||
for (Card c : CardLists.getValidCards(cardlist, restrictions, p, host, null)) {
|
for (Card c : CardLists.getValidCards(cardlist, restrictions, p, host, null)) {
|
||||||
for (KeywordInterface inst : c.getKeywords()) {
|
for (KeywordInterface inst : c.getKeywords()) {
|
||||||
final String k = inst.getOriginal();
|
final String k = inst.getOriginal();
|
||||||
@@ -2155,7 +2159,6 @@ public class CardFactoryUtil {
|
|||||||
return re;
|
return re;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static ReplacementEffect makeEtbCounter(final String kw, final Card card, final boolean intrinsic)
|
public static ReplacementEffect makeEtbCounter(final String kw, final Card card, final boolean intrinsic)
|
||||||
{
|
{
|
||||||
String parse = kw;
|
String parse = kw;
|
||||||
@@ -4095,6 +4098,60 @@ public class CardFactoryUtil {
|
|||||||
newSA.setAlternativeCost(AlternativeCost.Evoke);
|
newSA.setAlternativeCost(AlternativeCost.Evoke);
|
||||||
newSA.setIntrinsic(intrinsic);
|
newSA.setIntrinsic(intrinsic);
|
||||||
inst.addSpellAbility(newSA);
|
inst.addSpellAbility(newSA);
|
||||||
|
} else if (keyword.startsWith("Foretell")) {
|
||||||
|
|
||||||
|
final SpellAbility foretell = new AbilityStatic(card, new Cost(ManaCost.TWO, false), null) {
|
||||||
|
@Override
|
||||||
|
public boolean canPlay() {
|
||||||
|
if (!getRestrictions().canPlay(getHostCard(), this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Player activator = this.getActivatingPlayer();
|
||||||
|
final Game game = activator.getGame();
|
||||||
|
|
||||||
|
if (!activator.hasKeyword("Foretell on any player’s turn") && !game.getPhaseHandler().isPlayerTurn(activator)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isForetelling() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resolve() {
|
||||||
|
final Game game = getHostCard().getGame();
|
||||||
|
final Card c = game.getAction().exile(getHostCard(), this);
|
||||||
|
c.setForetold(true);
|
||||||
|
c.setForetoldThisTurn(true);
|
||||||
|
c.turnFaceDown(true);
|
||||||
|
// look at the exiled card
|
||||||
|
c.addMayLookTemp(getActivatingPlayer());
|
||||||
|
|
||||||
|
// only done when the card is foretold by the static ability
|
||||||
|
getActivatingPlayer().addForetoldThisTurn();
|
||||||
|
|
||||||
|
if (!isIntrinsic()) {
|
||||||
|
// because it doesn't work other wise
|
||||||
|
c.setForetoldByEffect(true);
|
||||||
|
}
|
||||||
|
String sb = TextUtil.concatWithSpace(getActivatingPlayer().toString(),"has foretold.");
|
||||||
|
game.getGameLog().add(GameLogEntryType.STACK_RESOLVE, sb);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
final StringBuilder sbDesc = new StringBuilder();
|
||||||
|
sbDesc.append("Foretell (").append(inst.getReminderText()).append(")");
|
||||||
|
foretell.setDescription(sbDesc.toString());
|
||||||
|
foretell.putParam("Secondary", "True");
|
||||||
|
|
||||||
|
foretell.getRestrictions().setZone(ZoneType.Hand);
|
||||||
|
foretell.setIntrinsic(intrinsic);
|
||||||
|
inst.addSpellAbility(foretell);
|
||||||
|
|
||||||
} else if (keyword.startsWith("Fortify")) {
|
} else if (keyword.startsWith("Fortify")) {
|
||||||
String[] k = keyword.split(":");
|
String[] k = keyword.split(":");
|
||||||
// Get cost string
|
// Get cost string
|
||||||
|
|||||||
@@ -1670,36 +1670,40 @@ public class CardProperty {
|
|||||||
if (property.equals("pseudokicked")) {
|
if (property.equals("pseudokicked")) {
|
||||||
if (!card.isOptionalCostPaid(OptionalCost.Generic)) return false;
|
if (!card.isOptionalCostPaid(OptionalCost.Generic)) return false;
|
||||||
}
|
}
|
||||||
} else if (property.startsWith("surged")) {
|
} else if (property.equals("surged")) {
|
||||||
if (card.getCastSA() == null) {
|
if (card.getCastSA() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return card.getCastSA().isSurged();
|
return card.getCastSA().isSurged();
|
||||||
} else if (property.startsWith("dashed")) {
|
} else if (property.equals("dashed")) {
|
||||||
if (card.getCastSA() == null) {
|
if (card.getCastSA() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return card.getCastSA().isDash();
|
return card.getCastSA().isDash();
|
||||||
} else if (property.startsWith("escaped")) {
|
} else if (property.equals("escaped")) {
|
||||||
if (card.getCastSA() == null) {
|
if (card.getCastSA() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return card.getCastSA().isEscape();
|
return card.getCastSA().isEscape();
|
||||||
} else if (property.startsWith("evoked")) {
|
} else if (property.equals("evoked")) {
|
||||||
if (card.getCastSA() == null) {
|
if (card.getCastSA() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return card.getCastSA().isEvoke();
|
return card.getCastSA().isEvoke();
|
||||||
} else if (property.startsWith("prowled")) {
|
} else if (property.equals("prowled")) {
|
||||||
if (card.getCastSA() == null) {
|
if (card.getCastSA() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return card.getCastSA().isProwl();
|
return card.getCastSA().isProwl();
|
||||||
} else if (property.startsWith("spectacle")) {
|
} else if (property.equals("spectacle")) {
|
||||||
if (card.getCastSA() == null) {
|
if (card.getCastSA() == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return card.getCastSA().isSpectacle();
|
return card.getCastSA().isSpectacle();
|
||||||
|
} else if (property.equals("foretold")) {
|
||||||
|
if (!card.isForetold()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (property.equals("HasDevoured")) {
|
} else if (property.equals("HasDevoured")) {
|
||||||
if (card.getDevouredCards().isEmpty()) {
|
if (card.getDevouredCards().isEmpty()) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -278,6 +278,10 @@ public final class CardUtil {
|
|||||||
|
|
||||||
newCopy.copyChangedTextFrom(in);
|
newCopy.copyChangedTextFrom(in);
|
||||||
|
|
||||||
|
newCopy.setForetold(in.isForetold());
|
||||||
|
newCopy.setForetoldThisTurn(in.isForetoldThisTurn());
|
||||||
|
newCopy.setForetoldByEffect(in.isForetoldByEffect());
|
||||||
|
|
||||||
newCopy.setMeldedWith(getLKICopy(in.getMeldedWith(), cachedMap));
|
newCopy.setMeldedWith(getLKICopy(in.getMeldedWith(), cachedMap));
|
||||||
|
|
||||||
newCopy.setTimestamp(in.getTimestamp());
|
newCopy.setTimestamp(in.getTimestamp());
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package forge.game.cost;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
import forge.game.ability.AbilityUtils;
|
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CounterEnumType;
|
import forge.game.card.CounterEnumType;
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package forge.game.event;
|
||||||
|
|
||||||
|
import forge.game.Game;
|
||||||
|
|
||||||
|
public class GameEventSubgameEnd extends GameEvent {
|
||||||
|
public final Game maingame;
|
||||||
|
public final String message;
|
||||||
|
|
||||||
|
public GameEventSubgameEnd(Game game, String message0) {
|
||||||
|
maingame = game;
|
||||||
|
message = message0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
|
return visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package forge.game.event;
|
||||||
|
|
||||||
|
import forge.game.Game;
|
||||||
|
|
||||||
|
public class GameEventSubgameStart extends GameEvent {
|
||||||
|
public final Game subgame;
|
||||||
|
public final String message;
|
||||||
|
|
||||||
|
public GameEventSubgameStart(Game subgame0, String message0) {
|
||||||
|
subgame = subgame0;
|
||||||
|
message = message0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public <T> T visit(IGameEventVisitor<T> visitor) {
|
||||||
|
return visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,6 +44,8 @@ public interface IGameEventVisitor<T> {
|
|||||||
T visit(GameEventSpellAbilityCast gameEventSpellAbilityCast);
|
T visit(GameEventSpellAbilityCast gameEventSpellAbilityCast);
|
||||||
T visit(GameEventSpellResolved event);
|
T visit(GameEventSpellResolved event);
|
||||||
T visit(GameEventSpellRemovedFromStack event);
|
T visit(GameEventSpellRemovedFromStack event);
|
||||||
|
T visit(GameEventSubgameStart event);
|
||||||
|
T visit(GameEventSubgameEnd event);
|
||||||
T visit(GameEventSurveil event);
|
T visit(GameEventSurveil event);
|
||||||
T visit(GameEventTokenCreated event);
|
T visit(GameEventTokenCreated event);
|
||||||
T visit(GameEventTurnBegan gameEventTurnBegan);
|
T visit(GameEventTurnBegan gameEventTurnBegan);
|
||||||
@@ -92,6 +94,8 @@ public interface IGameEventVisitor<T> {
|
|||||||
public T visit(GameEventSpellResolved event) { return null; }
|
public T visit(GameEventSpellResolved event) { return null; }
|
||||||
public T visit(GameEventSpellAbilityCast event) { return null; }
|
public T visit(GameEventSpellAbilityCast event) { return null; }
|
||||||
public T visit(GameEventSpellRemovedFromStack event) { return null; }
|
public T visit(GameEventSpellRemovedFromStack event) { return null; }
|
||||||
|
public T visit(GameEventSubgameStart event) { return null; }
|
||||||
|
public T visit(GameEventSubgameEnd event) { return null; }
|
||||||
public T visit(GameEventSurveil event) { return null; }
|
public T visit(GameEventSurveil event) { return null; }
|
||||||
public T visit(GameEventTokenCreated event) { return null; }
|
public T visit(GameEventTokenCreated event) { return null; }
|
||||||
public T visit(GameEventTurnBegan event) { return null; }
|
public T visit(GameEventTurnBegan event) { return null; }
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ public enum Keyword {
|
|||||||
FLASH("Flash", SimpleKeyword.class, true, "You may cast this spell any time you could cast an instant."),
|
FLASH("Flash", SimpleKeyword.class, true, "You may cast this spell any time you could cast an instant."),
|
||||||
FLASHBACK("Flashback", KeywordWithCost.class, false, "You may cast this card from your graveyard by paying %s rather than paying its mana cost. If you do, exile it as it resolves."),
|
FLASHBACK("Flashback", KeywordWithCost.class, false, "You may cast this card from your graveyard by paying %s rather than paying its mana cost. If you do, exile it as it resolves."),
|
||||||
FLYING("Flying", SimpleKeyword.class, true, "This creature can't be blocked except by creatures with flying or reach."),
|
FLYING("Flying", SimpleKeyword.class, true, "This creature can't be blocked except by creatures with flying or reach."),
|
||||||
|
FORETELL("Foretell", KeywordWithCost.class, false, "During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost."),
|
||||||
FORTIFY("Fortify", KeywordWithCost.class, false, "%s: Attach to target land you control. Fortify only as a sorcery."),
|
FORTIFY("Fortify", KeywordWithCost.class, false, "%s: Attach to target land you control. Fortify only as a sorcery."),
|
||||||
FRENZY("Frenzy", KeywordWithAmount.class, false, "Whenever this creature attacks and isn't blocked, it gets +%d/+0 until end of turn."),
|
FRENZY("Frenzy", KeywordWithAmount.class, false, "Whenever this creature attacks and isn't blocked, it gets +%d/+0 until end of turn."),
|
||||||
GRAFT("Graft", KeywordWithAmount.class, false, "This permanent enters the battlefield with {%d:+1/+1 counter} on it. Whenever another creature enters the battlefield, you may move a +1/+1 counter from this permanent onto it."),
|
GRAFT("Graft", KeywordWithAmount.class, false, "This permanent enters the battlefield with {%d:+1/+1 counter} on it. Whenever another creature enters the battlefield, you may move a +1/+1 counter from this permanent onto it."),
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ import forge.game.*;
|
|||||||
import forge.game.ability.AbilityKey;
|
import forge.game.ability.AbilityKey;
|
||||||
import forge.game.card.Card;
|
import forge.game.card.Card;
|
||||||
import forge.game.card.CardCollection;
|
import forge.game.card.CardCollection;
|
||||||
import forge.game.card.CardCollectionView;
|
|
||||||
import forge.game.card.CardLists;
|
import forge.game.card.CardLists;
|
||||||
import forge.game.card.CardPredicates.Presets;
|
import forge.game.card.CardPredicates.Presets;
|
||||||
import forge.game.card.CardZoneTable;
|
import forge.game.card.CardZoneTable;
|
||||||
@@ -175,8 +174,7 @@ public class PhaseHandler implements java.io.Serializable {
|
|||||||
game.fireEvent(new GameEventTurnBegan(playerTurn, turn));
|
game.fireEvent(new GameEventTurnBegan(playerTurn, turn));
|
||||||
|
|
||||||
// Tokens starting game in play should suffer from Sum. Sickness
|
// Tokens starting game in play should suffer from Sum. Sickness
|
||||||
final CardCollectionView list = playerTurn.getCardsIncludePhasingIn(ZoneType.Battlefield);
|
for (final Card c : playerTurn.getCardsIncludePhasingIn(ZoneType.Battlefield)) {
|
||||||
for (final Card c : list) {
|
|
||||||
if (playerTurn.getTurn() > 0 || !c.isStartsGameInPlay()) {
|
if (playerTurn.getTurn() > 0 || !c.isStartsGameInPlay()) {
|
||||||
c.setSickness(false);
|
c.setSickness(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ import java.util.concurrent.ConcurrentSkipListMap;
|
|||||||
public class Player extends GameEntity implements Comparable<Player> {
|
public class Player extends GameEntity implements Comparable<Player> {
|
||||||
public static final List<ZoneType> ALL_ZONES = Collections.unmodifiableList(Arrays.asList(ZoneType.Battlefield,
|
public static final List<ZoneType> ALL_ZONES = Collections.unmodifiableList(Arrays.asList(ZoneType.Battlefield,
|
||||||
ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante,
|
ZoneType.Library, ZoneType.Graveyard, ZoneType.Hand, ZoneType.Exile, ZoneType.Command, ZoneType.Ante,
|
||||||
ZoneType.Sideboard, ZoneType.PlanarDeck, ZoneType.SchemeDeck));
|
ZoneType.Sideboard, ZoneType.PlanarDeck, ZoneType.SchemeDeck, ZoneType.Subgame));
|
||||||
|
|
||||||
private final Map<Card, Integer> commanderDamage = Maps.newHashMap();
|
private final Map<Card, Integer> commanderDamage = Maps.newHashMap();
|
||||||
|
|
||||||
@@ -111,6 +111,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
private int numDrawnThisDrawStep = 0;
|
private int numDrawnThisDrawStep = 0;
|
||||||
private int numDiscardedThisTurn = 0;
|
private int numDiscardedThisTurn = 0;
|
||||||
private int numTokenCreatedThisTurn = 0;
|
private int numTokenCreatedThisTurn = 0;
|
||||||
|
private int numForetoldThisTurn = 0;
|
||||||
private int numCardsInHandStartedThisTurnWith = 0;
|
private int numCardsInHandStartedThisTurnWith = 0;
|
||||||
private final Map<String, FCollection<String>> notes = Maps.newHashMap();
|
private final Map<String, FCollection<String>> notes = Maps.newHashMap();
|
||||||
|
|
||||||
@@ -140,6 +141,7 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
private final Map<ZoneType, PlayerZone> zones = Maps.newEnumMap(ZoneType.class);
|
private final Map<ZoneType, PlayerZone> zones = Maps.newEnumMap(ZoneType.class);
|
||||||
private final Map<Long, Integer> adjustLandPlays = Maps.newHashMap();
|
private final Map<Long, Integer> adjustLandPlays = Maps.newHashMap();
|
||||||
private final Set<Long> adjustLandPlaysInfinite = Sets.newHashSet();
|
private final Set<Long> adjustLandPlaysInfinite = Sets.newHashSet();
|
||||||
|
private Map<Card, Card> maingameCardsMap = Maps.newHashMap();;
|
||||||
|
|
||||||
private CardCollection currentPlanes = new CardCollection();
|
private CardCollection currentPlanes = new CardCollection();
|
||||||
private Set<String> prowl = Sets.newHashSet();
|
private Set<String> prowl = Sets.newHashSet();
|
||||||
@@ -1666,6 +1668,22 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
numTokenCreatedThisTurn = 0;
|
numTokenCreatedThisTurn = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final int getNumForetoldThisTurn() {
|
||||||
|
return numForetoldThisTurn;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void addForetoldThisTurn() {
|
||||||
|
numForetoldThisTurn++;
|
||||||
|
final Map<AbilityKey, Object> runParams = AbilityKey.newMap();
|
||||||
|
runParams.put(AbilityKey.Player, this);
|
||||||
|
runParams.put(AbilityKey.Num, numForetoldThisTurn);
|
||||||
|
game.getTriggerHandler().runTrigger(TriggerType.Foretell, runParams, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final void resetNumForetoldThisTurn() {
|
||||||
|
numForetoldThisTurn = 0;
|
||||||
|
}
|
||||||
|
|
||||||
public final int getNumDiscardedThisTurn() {
|
public final int getNumDiscardedThisTurn() {
|
||||||
return numDiscardedThisTurn;
|
return numDiscardedThisTurn;
|
||||||
}
|
}
|
||||||
@@ -1905,6 +1923,14 @@ public class Player extends GameEntity implements Comparable<Player> {
|
|||||||
return !adjustLandPlaysInfinite.isEmpty();
|
return !adjustLandPlaysInfinite.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void addMaingameCardMapping(Card subgameCard, Card maingameCard) {
|
||||||
|
maingameCardsMap.put(subgameCard, maingameCard);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final Card getMappingMaingameCard(Card subgameCard) {
|
||||||
|
return maingameCardsMap.get(subgameCard);
|
||||||
|
}
|
||||||
|
|
||||||
public final ManaPool getManaPool() {
|
public final ManaPool getManaPool() {
|
||||||
return manaPool;
|
return manaPool;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
|||||||
if (!(o instanceof Card)) {
|
if (!(o instanceof Card)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!matchesValid(o, getParam("ValidCard").split(","), this.getHostCard())) {
|
if (!matchesValid(o, getParam("ValidCard").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
} else if (hasParam("ValidPlayer")) {
|
} else if (hasParam("ValidPlayer")) {
|
||||||
@@ -53,7 +53,17 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
|||||||
if (!(o instanceof Player)) {
|
if (!(o instanceof Player)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (!matchesValid(o, getParam("ValidPlayer").split(","), this.getHostCard())) {
|
if (!matchesValid(o, getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (hasParam("ValidObject")) {
|
||||||
|
if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidObject").split(","), getHostCard())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasParam("ValidSource")) {
|
||||||
|
if (!matchesValid(runParams.get(AbilityKey.Source), getParam("ValidSource").split(","), getHostCard())) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -81,6 +91,7 @@ public class ReplaceAddCounter extends ReplacementEffect {
|
|||||||
} else if (o instanceof Player) {
|
} else if (o instanceof Player) {
|
||||||
sa.setReplacingObject(AbilityKey.Player, o);
|
sa.setReplacingObject(AbilityKey.Player, o);
|
||||||
}
|
}
|
||||||
|
sa.setReplacingObject(AbilityKey.Object, o);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ public enum AlternativeCost {
|
|||||||
Escape,
|
Escape,
|
||||||
Evoke,
|
Evoke,
|
||||||
Flashback,
|
Flashback,
|
||||||
|
Foretold,
|
||||||
Madness,
|
Madness,
|
||||||
Offering,
|
Offering,
|
||||||
Outlast, // ActivatedAbility
|
Outlast, // ActivatedAbility
|
||||||
|
|||||||
@@ -823,6 +823,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
return this.isAlternativeCost(AlternativeCost.Flashback);
|
return this.isAlternativeCost(AlternativeCost.Flashback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isForetelling() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
public boolean isForetold() {
|
||||||
|
return this.isAlternativeCost(AlternativeCost.Foretold);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the aftermath
|
* @return the aftermath
|
||||||
*/
|
*/
|
||||||
@@ -1048,21 +1056,11 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
final Card c = (Card) entity;
|
final Card c = (Card) entity;
|
||||||
CardCollection pl = AbilityUtils.getDefinedCards(getHostCard(), getParam("TargetsWithSharedCardType"), this);
|
CardCollection pl = AbilityUtils.getDefinedCards(getHostCard(), getParam("TargetsWithSharedCardType"), this);
|
||||||
for (final Card crd : pl) {
|
for (final Card crd : pl) {
|
||||||
if (!c.sharesCardTypeWith(crd)) {
|
// one of those types
|
||||||
return false;
|
if (hasParam("TargetsWithSharedTypes")) {
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (hasParam("TargetsWithSharedTypes") && entity instanceof Card) {
|
|
||||||
final Card c = (Card) entity;
|
|
||||||
final SpellAbility parent = getParentTargetingCard();
|
|
||||||
final Card parentTargeted = parent != null ? parent.getTargetCard() : null;
|
|
||||||
if (parentTargeted == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
boolean flag = false;
|
boolean flag = false;
|
||||||
for (final String type : getParam("TargetsWithSharedTypes").split(",")) {
|
for (final String type : getParam("TargetsWithSharedTypes").split(",")) {
|
||||||
if (c.getType().hasStringType(type) && parentTargeted.getType().hasStringType(type)) {
|
if (c.getType().hasStringType(type) && crd.getType().hasStringType(type)) {
|
||||||
flag = true;
|
flag = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1070,7 +1068,14 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
if (!flag) {
|
if (!flag) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
if (!c.sharesCardTypeWith(crd)) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (hasParam("TargetsWithControllerProperty") && entity instanceof Card) {
|
if (hasParam("TargetsWithControllerProperty") && entity instanceof Card) {
|
||||||
final String prop = getParam("TargetsWithControllerProperty");
|
final String prop = getParam("TargetsWithControllerProperty");
|
||||||
final Card c = (Card) entity;
|
final Card c = (Card) entity;
|
||||||
@@ -1164,6 +1169,16 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tr.isWithSameCardType()) {
|
||||||
|
if (entity instanceof Card) {
|
||||||
|
for (final Card c : targetChosen.getTargetCards()) {
|
||||||
|
if (entity != c && !c.sharesCardTypeWith((Card) entity)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
String[] validTgt = tr.getValidTgts();
|
String[] validTgt = tr.getValidTgts();
|
||||||
if (entity instanceof GameEntity) {
|
if (entity instanceof GameEntity) {
|
||||||
GameEntity e = (GameEntity)entity;
|
GameEntity e = (GameEntity)entity;
|
||||||
@@ -1780,6 +1795,11 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (incR[0].equals("Static")) {
|
||||||
|
if (!(root instanceof AbilityStatic)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
else { //not a spell/ability type
|
else { //not a spell/ability type
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,6 +118,10 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
|
|||||||
this.optionalCostPaid = true;
|
this.optionalCostPaid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (value.equals("Foretold")) {
|
||||||
|
this.foretold = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (params.containsKey("ConditionOptionalPaid")) {
|
if (params.containsKey("ConditionOptionalPaid")) {
|
||||||
this.optionalBoolean = Boolean.parseBoolean(params.get("ConditionOptionalPaid"));
|
this.optionalBoolean = Boolean.parseBoolean(params.get("ConditionOptionalPaid"));
|
||||||
}
|
}
|
||||||
@@ -250,6 +254,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
|
|||||||
if (this.kicked2 && !sa.isOptionalCostPaid(OptionalCost.Kicker2)) return false;
|
if (this.kicked2 && !sa.isOptionalCostPaid(OptionalCost.Kicker2)) return false;
|
||||||
if (this.altCostPaid && !sa.isOptionalCostPaid(OptionalCost.AltCost)) return false;
|
if (this.altCostPaid && !sa.isOptionalCostPaid(OptionalCost.AltCost)) return false;
|
||||||
if (this.surgeCostPaid && !sa.isSurged()) return false;
|
if (this.surgeCostPaid && !sa.isSurged()) return false;
|
||||||
|
if (this.foretold && !sa.isForetold()) return false;
|
||||||
|
|
||||||
if (this.optionalCostPaid && this.optionalBoolean && !sa.isOptionalCostPaid(OptionalCost.Generic)) return false;
|
if (this.optionalCostPaid && this.optionalBoolean && !sa.isOptionalCostPaid(OptionalCost.Generic)) return false;
|
||||||
if (this.optionalCostPaid && !this.optionalBoolean && sa.isOptionalCostPaid(OptionalCost.Generic)) return false;
|
if (this.optionalCostPaid && !this.optionalBoolean && sa.isOptionalCostPaid(OptionalCost.Generic)) return false;
|
||||||
|
|||||||
@@ -405,6 +405,7 @@ public class SpellAbilityVariables implements Cloneable {
|
|||||||
protected boolean optionalCostPaid = false; // Undergrowth other Pseudo-kickers
|
protected boolean optionalCostPaid = false; // Undergrowth other Pseudo-kickers
|
||||||
protected boolean optionalBoolean = true; // Just in case you need to check if something wasn't kicked, etc
|
protected boolean optionalBoolean = true; // Just in case you need to check if something wasn't kicked, etc
|
||||||
protected boolean surgeCostPaid = false;
|
protected boolean surgeCostPaid = false;
|
||||||
|
protected boolean foretold = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return the allTargetsLegal
|
* @return the allTargetsLegal
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ public class TargetRestrictions {
|
|||||||
private boolean sameController = false;
|
private boolean sameController = false;
|
||||||
private boolean withoutSameCreatureType = false;
|
private boolean withoutSameCreatureType = false;
|
||||||
private boolean withSameCreatureType = false;
|
private boolean withSameCreatureType = false;
|
||||||
|
private boolean withSameCardType = false;
|
||||||
private boolean singleTarget = false;
|
private boolean singleTarget = false;
|
||||||
private boolean randomTarget = false;
|
private boolean randomTarget = false;
|
||||||
|
|
||||||
@@ -108,6 +109,7 @@ public class TargetRestrictions {
|
|||||||
this.sameController = target.isSameController();
|
this.sameController = target.isSameController();
|
||||||
this.withoutSameCreatureType = target.isWithoutSameCreatureType();
|
this.withoutSameCreatureType = target.isWithoutSameCreatureType();
|
||||||
this.withSameCreatureType = target.isWithSameCreatureType();
|
this.withSameCreatureType = target.isWithSameCreatureType();
|
||||||
|
this.withSameCardType = target.isWithSameCardType();
|
||||||
this.singleTarget = target.isSingleTarget();
|
this.singleTarget = target.isSingleTarget();
|
||||||
this.randomTarget = target.isRandomTarget();
|
this.randomTarget = target.isRandomTarget();
|
||||||
}
|
}
|
||||||
@@ -622,6 +624,20 @@ public class TargetRestrictions {
|
|||||||
this.withSameCreatureType = b;
|
this.withSameCreatureType = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the withSameCardType
|
||||||
|
*/
|
||||||
|
public boolean isWithSameCardType() {
|
||||||
|
return withSameCardType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param b the withSameCardType to set
|
||||||
|
*/
|
||||||
|
public void setWithSameCardType(boolean b) {
|
||||||
|
this.withSameCardType = b;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
* copy.
|
* copy.
|
||||||
|
|||||||
@@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Forge Team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.game.trigger;
|
||||||
|
|
||||||
|
import forge.game.ability.AbilityKey;
|
||||||
|
import forge.game.card.Card;
|
||||||
|
import forge.game.player.Player;
|
||||||
|
import forge.game.spellability.SpellAbility;
|
||||||
|
import forge.util.Localizer;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Forge
|
||||||
|
*/
|
||||||
|
public class TriggerForetell extends Trigger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param params
|
||||||
|
* a {@link java.util.HashMap} object.
|
||||||
|
* @param host
|
||||||
|
* a {@link forge.game.card.Card} object.
|
||||||
|
* @param intrinsic
|
||||||
|
* the intrinsic
|
||||||
|
*/
|
||||||
|
public TriggerForetell(final Map<String, String> params, final Card host, final boolean intrinsic) {
|
||||||
|
super(params, host, intrinsic);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getImportantStackObjects(SpellAbility sa) {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(Localizer.getInstance().getMessage("lblPlayer")).append(": ").append(sa.getTriggeringObject(AbilityKey.Player));
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc} */
|
||||||
|
@Override
|
||||||
|
public final void setTriggeringObjects(final SpellAbility sa, Map<AbilityKey, Object> runParams) {
|
||||||
|
sa.setTriggeringObjectsFrom(runParams, AbilityKey.Player);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** {@inheritDoc}
|
||||||
|
* @param runParams*/
|
||||||
|
@Override
|
||||||
|
public final boolean performTest(final Map<AbilityKey, Object> runParams) {
|
||||||
|
Player p = (Player) runParams.get(AbilityKey.Player);
|
||||||
|
if (hasParam("ValidPlayer")) {
|
||||||
|
if (!matchesValid(p, getParam("ValidPlayer").split(","), getHostCard())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasParam("OnlyFirst")) {
|
||||||
|
if ((int) runParams.get(AbilityKey.Num) != 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -64,6 +64,7 @@ public enum TriggerType {
|
|||||||
Fight(TriggerFight.class),
|
Fight(TriggerFight.class),
|
||||||
FightOnce(TriggerFightOnce.class),
|
FightOnce(TriggerFightOnce.class),
|
||||||
FlippedCoin(TriggerFlippedCoin.class),
|
FlippedCoin(TriggerFlippedCoin.class),
|
||||||
|
Foretell(TriggerForetell.class),
|
||||||
Immediate(TriggerImmediate.class),
|
Immediate(TriggerImmediate.class),
|
||||||
Investigated(TriggerInvestigated.class),
|
Investigated(TriggerInvestigated.class),
|
||||||
LandPlayed(TriggerLandPlayed.class),
|
LandPlayed(TriggerLandPlayed.class),
|
||||||
|
|||||||
@@ -52,7 +52,6 @@ import forge.game.keyword.Keyword;
|
|||||||
import forge.game.player.Player;
|
import forge.game.player.Player;
|
||||||
import forge.game.spellability.AbilityStatic;
|
import forge.game.spellability.AbilityStatic;
|
||||||
import forge.game.spellability.OptionalCost;
|
import forge.game.spellability.OptionalCost;
|
||||||
import forge.game.spellability.Spell;
|
|
||||||
import forge.game.spellability.SpellAbility;
|
import forge.game.spellability.SpellAbility;
|
||||||
import forge.game.spellability.SpellAbilityStackInstance;
|
import forge.game.spellability.SpellAbilityStackInstance;
|
||||||
import forge.game.spellability.TargetChoices;
|
import forge.game.spellability.TargetChoices;
|
||||||
@@ -241,8 +240,7 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
|
|||||||
|
|
||||||
if (sp.isSpell()) {
|
if (sp.isSpell()) {
|
||||||
source.setController(activator, 0);
|
source.setController(activator, 0);
|
||||||
final Spell spell = (Spell) sp;
|
if (sp.isCastFaceDown()) {
|
||||||
if (spell.isCastFaceDown()) {
|
|
||||||
// Need to override for double faced cards
|
// Need to override for double faced cards
|
||||||
source.turnFaceDown(true);
|
source.turnFaceDown(true);
|
||||||
} else if (source.isFaceDown()) {
|
} else if (source.isFaceDown()) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ public enum ZoneType {
|
|||||||
Ante(false, "lblAnteZone"),
|
Ante(false, "lblAnteZone"),
|
||||||
SchemeDeck(true, "lblSchemeDeckZone"),
|
SchemeDeck(true, "lblSchemeDeckZone"),
|
||||||
PlanarDeck(true, "lblPlanarDeckZone"),
|
PlanarDeck(true, "lblPlanarDeckZone"),
|
||||||
|
Subgame(true, "lblSubgameZone"),
|
||||||
None(true, "lblNoneZone");
|
None(true, "lblNoneZone");
|
||||||
|
|
||||||
public static final List<ZoneType> STATIC_ABILITIES_SOURCE_ZONES = Arrays.asList(Battlefield, Graveyard, Exile, Command/*, Hand*/);
|
public static final List<ZoneType> STATIC_ABILITIES_SOURCE_ZONES = Arrays.asList(Battlefield, Graveyard, Exile, Command/*, Hand*/);
|
||||||
|
|||||||
@@ -1847,7 +1847,7 @@ public class GameSimulatorTest extends SimulationTestCase {
|
|||||||
sim.simulateSpellAbility(gideonSA);
|
sim.simulateSpellAbility(gideonSA);
|
||||||
sim.simulateSpellAbility(sparkDoubleSA);
|
sim.simulateSpellAbility(sparkDoubleSA);
|
||||||
|
|
||||||
Card simSpark = (Card)sim.getGameCopier().find(sparkDouble);
|
Card simSpark = sim.getSimulatedGameState().findById(sparkDouble.getId());
|
||||||
|
|
||||||
assertNotNull(simSpark);
|
assertNotNull(simSpark);
|
||||||
assertTrue(simSpark.isInZone(ZoneType.Battlefield));
|
assertTrue(simSpark.isInZone(ZoneType.Battlefield));
|
||||||
|
|||||||
@@ -202,6 +202,12 @@ public class Forge implements ApplicationListener {
|
|||||||
ImageCache.preloadCache(filteredkeys);
|
ImageCache.preloadCache(filteredkeys);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void openHomeScreen(boolean openNewGameMenu) {
|
||||||
|
openScreen(HomeScreen.instance);
|
||||||
|
if(openNewGameMenu)
|
||||||
|
HomeScreen.instance.openNewGamMenu();
|
||||||
|
}
|
||||||
|
|
||||||
private void afterDbLoaded() {
|
private void afterDbLoaded() {
|
||||||
stopContinuousRendering(); //save power consumption by disabling continuous rendering once assets loaded
|
stopContinuousRendering(); //save power consumption by disabling continuous rendering once assets loaded
|
||||||
|
|
||||||
@@ -210,7 +216,7 @@ public class Forge implements ApplicationListener {
|
|||||||
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); //start background music
|
SoundSystem.instance.setBackgroundMusic(MusicPlaylist.MENUS); //start background music
|
||||||
destroyThis = false; //Allow back()
|
destroyThis = false; //Allow back()
|
||||||
Gdx.input.setCatchKey(Keys.MENU, true);
|
Gdx.input.setCatchKey(Keys.MENU, true);
|
||||||
openScreen(HomeScreen.instance);
|
openHomeScreen(false);
|
||||||
splashScreen = null;
|
splashScreen = null;
|
||||||
|
|
||||||
boolean isLandscapeMode = isLandscapeMode();
|
boolean isLandscapeMode = isLandscapeMode();
|
||||||
|
|||||||
@@ -135,6 +135,10 @@ public class HomeScreen extends FScreen {
|
|||||||
QuestWorld = questWorld;
|
QuestWorld = questWorld;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void openNewGamMenu(){
|
||||||
|
NewGameMenu.getPreferredScreen().open();
|
||||||
|
}
|
||||||
|
|
||||||
public boolean getQuestCommanderMode() {
|
public boolean getQuestCommanderMode() {
|
||||||
return QuestCommander;
|
return QuestCommander;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,14 +77,22 @@ public class ControlWinLose {
|
|||||||
|
|
||||||
/** Action performed when "quit" button is pressed in default win/lose UI. */
|
/** Action performed when "quit" button is pressed in default win/lose UI. */
|
||||||
public void actionOnQuit() {
|
public void actionOnQuit() {
|
||||||
|
boolean openHomeScreen = false;
|
||||||
// Reset other stuff
|
// Reset other stuff
|
||||||
saveOptions();
|
saveOptions();
|
||||||
try { MatchController.getHostedMatch().endCurrentGame();
|
try {
|
||||||
|
if(MatchController.getHostedMatch().subGameCount > 0) {
|
||||||
|
openHomeScreen = true;
|
||||||
|
MatchController.getHostedMatch().subGameCount--;
|
||||||
|
}
|
||||||
|
MatchController.getHostedMatch().endCurrentGame();
|
||||||
} catch (NullPointerException e) {}
|
} catch (NullPointerException e) {}
|
||||||
view.hide();
|
view.hide();
|
||||||
if(humancount == 0) {
|
if(humancount == 0) {
|
||||||
Forge.back();
|
Forge.back();
|
||||||
}
|
}
|
||||||
|
if (openHomeScreen)
|
||||||
|
Forge.openHomeScreen(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,9 +5,7 @@ T:Mode$ PlaneswalkedTo | ValidCard$ Card.Self | Execute$ TrigLife | OptionalDeci
|
|||||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigLife | TriggerZones$ Command | Secondary$ True | OptionalDecider$ You | TriggerDescription$ When you planeswalk to CARDNAME or at the beginning of your upkeep, you may exchange life totals with target player.
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | Execute$ TrigLife | TriggerZones$ Command | Secondary$ True | OptionalDecider$ You | TriggerDescription$ When you planeswalk to CARDNAME or at the beginning of your upkeep, you may exchange life totals with target player.
|
||||||
SVar:TrigLife:DB$ ExchangeLife | Optional$ True | ValidTgts$ Player | TgtPrompt$ Select target player to exchange life totals with
|
SVar:TrigLife:DB$ ExchangeLife | Optional$ True | ValidTgts$ Player | TgtPrompt$ Select target player to exchange life totals with
|
||||||
T:Mode$ PlanarDice | Result$ Chaos | TriggerZones$ Command | Execute$ RolledChaos | TriggerDescription$ Whenever you roll {CHAOS}, exchange control of two target permanents that share a card type.
|
T:Mode$ PlanarDice | Result$ Chaos | TriggerZones$ Command | Execute$ RolledChaos | TriggerDescription$ Whenever you roll {CHAOS}, exchange control of two target permanents that share a card type.
|
||||||
SVar:RolledChaos:DB$ Pump | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | SubAbility$ DBExchange
|
SVar:RolledChaos:DB$ ExchangeControl | TargetMin$ 2 | TargetMax$ 2 | ValidTgts$ Permanent | TgtPrompt$ Select target permanents that share a permanent type | TargetsWithSameCardType$ True
|
||||||
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent | TgtPrompt$ Select target permanent card | TargetsWithSharedTypes$ Creature,Artifact,Enchantment,Planeswalker,Land,Tribal | TargetUnique$ True
|
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/cliffside_market.jpg
|
|
||||||
Oracle:When you planeswalk to Cliffside Market or at the beginning of your upkeep, you may exchange life totals with target player.\nWhenever you roll {CHAOS}, exchange control of two target permanents that share a card type.
|
Oracle:When you planeswalk to Cliffside Market or at the beginning of your upkeep, you may exchange life totals with target player.\nWhenever you roll {CHAOS}, exchange control of two target permanents that share a card type.
|
||||||
@@ -4,5 +4,4 @@ Types:Enchantment
|
|||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Artifact,Creature,Enchantment | TriggerZones$ Battlefield | Execute$ TrigExchangeControl | TriggerDescription$ Whenever an artifact, creature, or enchantment enters the battlefield, its controller chooses target permanent another player controls that shares a card type with it. Exchange control of those permanents.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Artifact,Creature,Enchantment | TriggerZones$ Battlefield | Execute$ TrigExchangeControl | TriggerDescription$ Whenever an artifact, creature, or enchantment enters the battlefield, its controller chooses target permanent another player controls that shares a card type with it. Exchange control of those permanents.
|
||||||
SVar:TrigExchangeControl:DB$ ExchangeControl | Defined$ TriggeredCard | TargetingPlayer$ TriggeredCardController | TargetsWithDefinedController$ NonTriggeredCardController | ValidTgts$ Permanent | TargetsWithSharedCardType$ TriggeredCard
|
SVar:TrigExchangeControl:DB$ ExchangeControl | Defined$ TriggeredCard | TargetingPlayer$ TriggeredCardController | TargetsWithDefinedController$ NonTriggeredCardController | ValidTgts$ Permanent | TargetsWithSharedCardType$ TriggeredCard
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/confusion_in_the_ranks.jpg
|
|
||||||
Oracle:Whenever an artifact, creature, or enchantment enters the battlefield, its controller chooses target permanent another player controls that shares a card type with it. Exchange control of those permanents.
|
Oracle:Whenever an artifact, creature, or enchantment enters the battlefield, its controller chooses target permanent another player controls that shares a card type with it. Exchange control of those permanents.
|
||||||
|
|||||||
@@ -4,8 +4,7 @@ Types:Creature Human Rogue
|
|||||||
PT:2/3
|
PT:2/3
|
||||||
T:Mode$ Untaps | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigExchangeControl | OptionalDecider$ You | TriggerDescription$ Inspired — Whenever CARDNAME becomes untapped, you may exchange control of target nonland permanent you control and target permanent an opponent controls that shares a card type with it.
|
T:Mode$ Untaps | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigExchangeControl | OptionalDecider$ You | TriggerDescription$ Inspired — Whenever CARDNAME becomes untapped, you may exchange control of target nonland permanent you control and target permanent an opponent controls that shares a card type with it.
|
||||||
SVar:TrigExchangeControl:DB$ Pump | ValidTgts$ Permanent.YouCtrl+nonLand | TgtPrompt$ Select target nonland permanent you control | SubAbility$ DBExchange
|
SVar:TrigExchangeControl:DB$ Pump | ValidTgts$ Permanent.YouCtrl+nonLand | TgtPrompt$ Select target nonland permanent you control | SubAbility$ DBExchange
|
||||||
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent.OppCtrl | TgtPrompt$ Select target permanent an opponent controls that shares a card type with it | TargetsWithSharedTypes$ Creature,Artifact,Enchantment,Planeswalker,Tribal
|
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent.OppCtrl | TgtPrompt$ Select target permanent an opponent controls that shares a card type with it | TargetsWithSharedCardType$ ParentTarget
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/daring_thief.jpg
|
|
||||||
Oracle:Inspired — Whenever Daring Thief becomes untapped, you may exchange control of target nonland permanent you control and target permanent an opponent controls that shares a card type with it.
|
Oracle:Inspired — Whenever Daring Thief becomes untapped, you may exchange control of target nonland permanent you control and target permanent an opponent controls that shares a card type with it.
|
||||||
|
|||||||
@@ -2,9 +2,8 @@ Name:Gauntlets of Chaos
|
|||||||
ManaCost:5
|
ManaCost:5
|
||||||
Types:Artifact
|
Types:Artifact
|
||||||
A:AB$ Pump | Cost$ 5 Sac<1/CARDNAME> | ValidTgts$ Artifact.YouCtrl,Creature.YouCtrl,Land.YouCtrl | TgtPrompt$ target artifact, creature, or land you control | StackDescription$ None | SubAbility$ DBExchange | SpellDescription$ Exchange control of target artifact, creature, or land you control and target permanent an opponent controls that shares one of those types with it. If those permanents are exchanged this way, destroy all Auras attached to them.
|
A:AB$ Pump | Cost$ 5 Sac<1/CARDNAME> | ValidTgts$ Artifact.YouCtrl,Creature.YouCtrl,Land.YouCtrl | TgtPrompt$ target artifact, creature, or land you control | StackDescription$ None | SubAbility$ DBExchange | SpellDescription$ Exchange control of target artifact, creature, or land you control and target permanent an opponent controls that shares one of those types with it. If those permanents are exchanged this way, destroy all Auras attached to them.
|
||||||
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent.OppCtrl | TgtPrompt$ Select target permanent an opponent controls that shares one of those types | TargetsWithSharedTypes$ Artifact,Creature,Land | RememberExchanged$ True | SubAbility$ DBDestroyAll
|
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent.OppCtrl | TgtPrompt$ Select target permanent an opponent controls that shares one of those types | TargetsWithSharedCardType$ ParentTarget | TargetsWithSharedTypes$ Artifact,Creature,Land | RememberExchanged$ True | SubAbility$ DBDestroyAll
|
||||||
SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Aura.AttachedTo Card.IsRemembered | SubAbility$ DBCleanup
|
SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Aura.AttachedTo Card.IsRemembered | SubAbility$ DBCleanup
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/gauntlets_of_chaos.jpg
|
|
||||||
Oracle:{5}, Sacrifice Gauntlets of Chaos: Exchange control of target artifact, creature, or land you control and target permanent an opponent controls that shares one of those types with it. If those permanents are exchanged this way, destroy all Auras attached to them.
|
Oracle:{5}, Sacrifice Gauntlets of Chaos: Exchange control of target artifact, creature, or land you control and target permanent an opponent controls that shares one of those types with it. If those permanents are exchanged this way, destroy all Auras attached to them.
|
||||||
|
|||||||
@@ -5,12 +5,9 @@ PT:2/3
|
|||||||
K:Deathtouch
|
K:Deathtouch
|
||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, look at the top four cards of target opponent's library, exile one of them face down, then put the rest on the bottom of that library in a random order. For as long as that card remains exiled, you may look at it, you may cast it, and you may spend mana as though it were mana of any type to cast that spell.
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, look at the top four cards of target opponent's library, exile one of them face down, then put the rest on the bottom of that library in a random order. For as long as that card remains exiled, you may look at it, you may cast it, and you may spend mana as though it were mana of any type to cast that spell.
|
||||||
SVar:TrigDig:DB$Dig | ValidTgts$ Opponent | DigNum$ 4 | ChangeNum$ 1 | DestinationZone$ Exile | DestinationZone2$ Library | LibraryPosition$ -1 | RestRandomOrder$ True | ExileFaceDown$ True | ChangeValid$ Card | RememberChanged$ True | SubAbility$ DBEffect | RememberChanged$ True
|
SVar:TrigDig:DB$Dig | ValidTgts$ Opponent | DigNum$ 4 | ChangeNum$ 1 | DestinationZone$ Exile | DestinationZone2$ Library | LibraryPosition$ -1 | RestRandomOrder$ True | ExileFaceDown$ True | ChangeValid$ Card | RememberChanged$ True | SubAbility$ DBEffect | RememberChanged$ True
|
||||||
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay1,STPlay2 | Duration$ Permanent | Triggers$ TrigCleanup | SVars$ DBExileSelf | SubAbility$ DBCleanup
|
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay1,STPlay2 | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:STPlay1:Mode$ Continuous | MayLookAt$ You | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at the card, you may cast it, and you may spend mana as though it were mana of any type to cast that spell.
|
SVar:STPlay1:Mode$ Continuous | MayLookAt$ You | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at the card, you may cast it, and you may spend mana as though it were mana of any type to cast that spell.
|
||||||
SVar:STPlay2:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreType$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand | AffectedZone$ Exile | Secondary$ True | Description$ You may look at the card, you may cast it, and you may spend mana as though it were mana of any type to cast that spell.
|
SVar:STPlay2:Mode$ Continuous | MayPlay$ True | MayPlayIgnoreType$ True | EffectZone$ Command | Affected$ Card.IsRemembered+nonLand | AffectedZone$ Exile | Secondary$ True | Description$ You may look at the card, you may cast it, and you may spend mana as though it were mana of any type to cast that spell.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBExileSelf | Static$ True
|
|
||||||
SVar:DBExileSelf:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:PlayMain1:TRUE
|
SVar:PlayMain1:TRUE
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/gonti_lord_of_luxury.jpg
|
|
||||||
Oracle:Deathtouch\nWhen Gonti, Lord of Luxury enters the battlefield, look at the top four cards of target opponent's library, exile one of them face down, then put the rest on the bottom of that library in a random order. You may look at and cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell.
|
Oracle:Deathtouch\nWhen Gonti, Lord of Luxury enters the battlefield, look at the top four cards of target opponent's library, exile one of them face down, then put the rest on the bottom of that library in a random order. You may look at and cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any type to cast that spell.
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ Name:Gustha's Scepter
|
|||||||
ManaCost:0
|
ManaCost:0
|
||||||
Types:Artifact
|
Types:Artifact
|
||||||
A:AB$ ChangeZone | Cost$ T | ChangeType$ Card | ChangeNum$ 1 | Origin$ Hand | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | Mandatory$ True | SubAbility$ DBEffect | SpellDescription$ Exile a card from your hand face down. You may look at it for as long as it remains exiled.
|
A:AB$ ChangeZone | Cost$ T | ChangeType$ Card | ChangeNum$ 1 | Origin$ Hand | Destination$ Exile | ExileFaceDown$ True | RememberChanged$ True | Mandatory$ True | SubAbility$ DBEffect | SpellDescription$ Exile a card from your hand face down. You may look at it for as long as it remains exiled.
|
||||||
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STLook | Duration$ Permanent | Triggers$ TrigCleanup | SVars$ DBExileSelf | SubAbility$ DBCleanup
|
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STLook | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:STLook:Mode$ Continuous | MayLookAt$ You | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at it for as long as it remains exiled.
|
SVar:STLook:Mode$ Continuous | MayLookAt$ You | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at it for as long as it remains exiled.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBExileSelf | Static$ True
|
|
||||||
SVar:DBExileSelf:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
A:AB$ ChooseCard | Cost$ T | Defined$ You | Amount$ 1 | Mandatory$ True | AILogic$ AtLeast1 | ChoiceTitle$ Choose a card you own to put into your hand | Choices$ Card.IsRemembered+YouOwn+ExiledWithSource | ChoiceZone$ Exile | SubAbility$ MoveChosen | SpellDescription$ Return a card you own exiled with CARDNAME to your hand.
|
A:AB$ ChooseCard | Cost$ T | Defined$ You | Amount$ 1 | Mandatory$ True | AILogic$ AtLeast1 | ChoiceTitle$ Choose a card you own to put into your hand | Choices$ Card.IsRemembered+YouOwn+ExiledWithSource | ChoiceZone$ Exile | SubAbility$ MoveChosen | SpellDescription$ Return a card you own exiled with CARDNAME to your hand.
|
||||||
SVar:MoveChosen:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ ChosenCard
|
SVar:MoveChosen:DB$ ChangeZone | Origin$ Exile | Destination$ Hand | Defined$ ChosenCard
|
||||||
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget
|
T:Mode$ ChangesZone | Origin$ Exile | Destination$ Any | Static$ True | ValidCard$ Card.IsRemembered+ExiledWithSource | Execute$ DBForget
|
||||||
@@ -15,5 +13,4 @@ T:Mode$ ChangesController | ValidCard$ Card.Self | TriggerZones$ Battlefield | E
|
|||||||
SVar:DBChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Exile | Destination$ Graveyard | SubAbility$ DBCleanup
|
SVar:DBChangeZoneAll:DB$ ChangeZoneAll | ChangeType$ Card.IsRemembered | Origin$ Exile | Destination$ Graveyard | SubAbility$ DBCleanup
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/gusthas_scepter.jpg
|
|
||||||
Oracle:{T}: Exile a card from your hand face down. You may look at it for as long as it remains exiled.\n{T}: Return a card you own exiled with Gustha's Scepter to your hand.\nWhen you lose control of Gustha's Scepter, put all cards exiled with Gustha's Scepter into their owner's graveyard.
|
Oracle:{T}: Exile a card from your hand face down. You may look at it for as long as it remains exiled.\n{T}: Return a card you own exiled with Gustha's Scepter to your hand.\nWhen you lose control of Gustha's Scepter, put all cards exiled with Gustha's Scepter into their owner's graveyard.
|
||||||
|
|||||||
@@ -3,16 +3,15 @@ ManaCost:3 U
|
|||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ ChooseCard | Cost$ 3 U | ValidTgts$ Player | Choices$ Creature.cmcEQY | TargetControls$ True | References$ Y | Mandatory$ True | AILogic$ WorstCard | RememberChosen$ True | SubAbility$ DBChooseCreatureYou | SpellDescription$ You and target player exchange control of the creature you each control with the highest converted mana cost. Then exchange control of artifacts the same way. If two or more permanents a player controls are tied for highest cost, their controller chooses one of them.
|
A:SP$ ChooseCard | Cost$ 3 U | ValidTgts$ Player | Choices$ Creature.cmcEQY | TargetControls$ True | References$ Y | Mandatory$ True | AILogic$ WorstCard | RememberChosen$ True | SubAbility$ DBChooseCreatureYou | SpellDescription$ You and target player exchange control of the creature you each control with the highest converted mana cost. Then exchange control of artifacts the same way. If two or more permanents a player controls are tied for highest cost, their controller chooses one of them.
|
||||||
SVar:DBChooseCreatureYou:DB$ ChooseCard | Choices$ Creature.YouCtrl+cmcEQX | References$ X | Mandatory$ True | RememberChosen$ True | SubAbility$ DBExchangeCreature
|
SVar:DBChooseCreatureYou:DB$ ChooseCard | Choices$ Creature.YouCtrl+cmcEQX | References$ X | Mandatory$ True | RememberChosen$ True | SubAbility$ DBExchangeCreature
|
||||||
SVar:DBExchangeCreature:DB$ ExchangeControl | BothDefined$ True | Defined$ Remembered | SubAbility$ DBCleanCreature
|
SVar:DBExchangeCreature:DB$ ExchangeControl | Defined$ Remembered | SubAbility$ DBCleanCreature
|
||||||
SVar:DBCleanCreature:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBChooseArtifactYou
|
SVar:DBCleanCreature:DB$ Cleanup | ClearRemembered$ True | SubAbility$ DBChooseArtifactYou
|
||||||
SVar:DBChooseArtifactYou:DB$ ChooseCard | Choices$ Artifact.YouCtrl+cmcEQZ | References$ Z | Mandatory$ True | RememberChosen$ True | SubAbility$ DBChooseArtifactOpp
|
SVar:DBChooseArtifactYou:DB$ ChooseCard | Choices$ Artifact.YouCtrl+cmcEQZ | References$ Z | Mandatory$ True | RememberChosen$ True | SubAbility$ DBChooseArtifactOpp
|
||||||
SVar:DBChooseArtifactOpp:DB$ ChooseCard | Defined$ ParentTarget | Choices$ Artifact.cmcEQW | TargetControls$ True | References$ W | Mandatory$ True | AILogic$ WorstCard | RememberChosen$ True | SubAbility$ DBExchangeArtifact
|
SVar:DBChooseArtifactOpp:DB$ ChooseCard | Defined$ ParentTarget | Choices$ Artifact.cmcEQW | TargetControls$ True | References$ W | Mandatory$ True | AILogic$ WorstCard | RememberChosen$ True | SubAbility$ DBExchangeArtifact
|
||||||
SVar:DBExchangeArtifact:DB$ ExchangeControl | BothDefined$ True | Defined$ Remembered | SubAbility$ DBCleanup
|
SVar:DBExchangeArtifact:DB$ ExchangeControl | Defined$ Remembered | SubAbility$ DBCleanup
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:X:Count$HighestCMC_Creature.YouCtrl+inZoneBattlefield
|
SVar:X:Count$HighestCMC_Creature.YouCtrl+inZoneBattlefield
|
||||||
SVar:Y:Count$HighestCMC_Creature.TargetedPlayerCtrl+inZoneBattlefield
|
SVar:Y:Count$HighestCMC_Creature.TargetedPlayerCtrl+inZoneBattlefield
|
||||||
SVar:Z:Count$HighestCMC_Artifact.YouCtrl+inZoneBattlefield
|
SVar:Z:Count$HighestCMC_Artifact.YouCtrl+inZoneBattlefield
|
||||||
SVar:W:Count$HighestCMC_Artifact.TargetedPlayerCtrl+inZoneBattlefield
|
SVar:W:Count$HighestCMC_Artifact.TargetedPlayerCtrl+inZoneBattlefield
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/juxtapose.jpg
|
|
||||||
Oracle:You and target player exchange control of the creature you each control with the highest converted mana cost. Then exchange control of artifacts the same way. If two or more permanents a player controls are tied for highest cost, their controller chooses one of them.
|
Oracle:You and target player exchange control of the creature you each control with the highest converted mana cost. Then exchange control of artifacts the same way. If two or more permanents a player controls are tied for highest cost, their controller chooses one of them.
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ HandLifeModifier:-1/+8
|
|||||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigExchangeChoose | TriggerDescription$ At the beginning of your upkeep, exchange control of a permanent you control chosen at random and a permanent target opponent controls chosen at random.
|
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ TrigExchangeChoose | TriggerDescription$ At the beginning of your upkeep, exchange control of a permanent you control chosen at random and a permanent target opponent controls chosen at random.
|
||||||
SVar:TrigExchangeChoose:DB$ ChooseCard | ValidTgts$ Opponent | Choices$ Permanent.TargetedPlayerCtrl | AtRandom$ True | Amount$ 1 | RememberChosen$ True | SubAbility$ ChooseYou
|
SVar:TrigExchangeChoose:DB$ ChooseCard | ValidTgts$ Opponent | Choices$ Permanent.TargetedPlayerCtrl | AtRandom$ True | Amount$ 1 | RememberChosen$ True | SubAbility$ ChooseYou
|
||||||
SVar:ChooseYou:DB$ ChooseCard | Choices$ Permanent.YouCtrl | Amount$ 1 | AtRandom$ True | RememberChosen$ True | SubAbility$ DBExchange
|
SVar:ChooseYou:DB$ ChooseCard | Choices$ Permanent.YouCtrl | Amount$ 1 | AtRandom$ True | RememberChosen$ True | SubAbility$ DBExchange
|
||||||
SVar:DBExchange:DB$ ExchangeControl | Defined$ Remembered | BothDefined$ True | SubAbility$ DBCleanup
|
SVar:DBExchange:DB$ ExchangeControl | Defined$ Remembered | SubAbility$ DBCleanup
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:Picture:https://downloads.cardforge.org/images/cards/VAN/Karona, False God Avatar.full.jpg
|
SVar:Picture:https://downloads.cardforge.org/images/cards/VAN/Karona, False God Avatar.full.jpg
|
||||||
Oracle:Hand -1, life +8\nAt the beginning of your upkeep, exchange control of a permanent you control chosen at random and a permanent target opponent controls chosen at random.
|
Oracle:Hand -1, life +8\nAt the beginning of your upkeep, exchange control of a permanent you control chosen at random and a permanent target opponent controls chosen at random.
|
||||||
|
|||||||
@@ -5,10 +5,8 @@ PT:3/3
|
|||||||
K:Morph:4 U U
|
K:Morph:4 U U
|
||||||
T:Mode$ TurnFaceUp | ValidCard$ Card.Self | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ When CARDNAME is turned face up, counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may cast that card without paying its mana cost as long as it remains exiled.
|
T:Mode$ TurnFaceUp | ValidCard$ Card.Self | Execute$ TrigCounter | TriggerZones$ Battlefield | TriggerDescription$ When CARDNAME is turned face up, counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may cast that card without paying its mana cost as long as it remains exiled.
|
||||||
SVar:TrigCounter:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | RememberCountered$ True | ForgetOtherTargets$ True | Destination$ Exile | SubAbility$ DBEffect
|
SVar:TrigCounter:DB$ Counter | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | RememberCountered$ True | ForgetOtherTargets$ True | Destination$ Exile | SubAbility$ DBEffect
|
||||||
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay | Duration$ Permanent | Triggers$ TrigCleanup | SVars$ DBCleanup | References$ PlayOpp,PlayYou,TrigCleanup,DBCleanup
|
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:STPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may cast cards without paying their mana cost as long as they remain exiled.
|
SVar:STPlay:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may cast cards without paying their mana cost as long as they remain exiled.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBCleanup | Static$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:DBCleanup:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/kheru_spellsnatcher.jpg
|
|
||||||
Oracle:Morph {4}{U}{U} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)\nWhen Kheru Spellsnatcher is turned face up, counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may cast that card without paying its mana cost for as long as it remains exiled.
|
Oracle:Morph {4}{U}{U} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)\nWhen Kheru Spellsnatcher is turned face up, counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may cast that card without paying its mana cost for as long as it remains exiled.
|
||||||
|
|||||||
@@ -4,10 +4,8 @@ Types:Creature Faerie Rogue
|
|||||||
PT:1/4
|
PT:1/4
|
||||||
K:Flying
|
K:Flying
|
||||||
A:AB$ Dig | Cost$ 1 U Q | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Target opponent exiles the top card of their library. Until end of turn, you may play that card.
|
A:AB$ Dig | Cost$ 1 U Q | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Target opponent exiles the top card of their library. Until end of turn, you may play that card.
|
||||||
SVar:DBEffect:DB$ Effect | Duration$ EndOfTurn | RememberObjects$ Remembered | StaticAbilities$ STPlay | Triggers$ TrigCleanup | SVars$ DBExileSelf | SubAbility$ DBCleanup
|
SVar:DBEffect:DB$ Effect | Duration$ EndOfTurn | RememberObjects$ Remembered | StaticAbilities$ STPlay | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play a card this turn.
|
SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play a card this turn.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBExileSelf | Static$ True
|
|
||||||
SVar:DBExileSelf:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
Oracle:Flying\n{1}{U}, {Q}: Target opponent exiles the top card of their library. Until end of turn, you may play that card. ({Q} is the untap symbol.)
|
Oracle:Flying\n{1}{U}, {Q}: Target opponent exiles the top card of their library. Until end of turn, you may play that card. ({Q} is the untap symbol.)
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ Name:Legerdemain
|
|||||||
ManaCost:2 U U
|
ManaCost:2 U U
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Pump | Cost$ 2 U U | ValidTgts$ Artifact,Creature | TgtPrompt$ target artifact or creature | StackDescription$ None | SubAbility$ DBExchange | SpellDescription$ Exchange control of target artifact or creature and another target permanent that shares one of those types with it. (This effect lasts indefinitely.)
|
A:SP$ Pump | Cost$ 2 U U | ValidTgts$ Artifact,Creature | TgtPrompt$ target artifact or creature | StackDescription$ None | SubAbility$ DBExchange | SpellDescription$ Exchange control of target artifact or creature and another target permanent that shares one of those types with it. (This effect lasts indefinitely.)
|
||||||
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent | TgtPrompt$ Select target permanent that shares one of those types | TargetsWithSharedTypes$ Artifact,Creature | TargetUnique$ True
|
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent | TgtPrompt$ Select target permanent that shares one of those types | TargetsWithSharedCardType$ ParentTarget | TargetsWithSharedTypes$ Artifact,Creature | TargetUnique$ True
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/legerdemain.jpg
|
SVar:Picture:http://www.wizards.com/global/images/magic/general/legerdemain.jpg
|
||||||
Oracle:Exchange control of target artifact or creature and another target permanent that shares one of those types with it. (This effect lasts indefinitely.)
|
Oracle:Exchange control of target artifact or creature and another target permanent that shares one of those types with it. (This effect lasts indefinitely.)
|
||||||
|
|||||||
@@ -2,10 +2,8 @@ Name:Ornate Kanzashi
|
|||||||
ManaCost:5
|
ManaCost:5
|
||||||
Types:Artifact
|
Types:Artifact
|
||||||
A:AB$ Dig | Cost$ 2 T | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Target opponent exiles the top card of their library. You may play that card this turn.
|
A:AB$ Dig | Cost$ 2 T | ValidTgts$ Opponent | TgtPrompt$ Select target opponent | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | RememberChanged$ True | SubAbility$ DBEffect | SpellDescription$ Target opponent exiles the top card of their library. You may play that card this turn.
|
||||||
SVar:DBEffect:DB$ Effect | Duration$ EndOfTurn | RememberObjects$ Remembered | StaticAbilities$ STPlay | Triggers$ TrigCleanup | SVars$ DBExileSelf | SubAbility$ DBCleanup
|
SVar:DBEffect:DB$ Effect | Duration$ EndOfTurn | RememberObjects$ Remembered | StaticAbilities$ STPlay | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play a card this turn.
|
SVar:STPlay:Mode$ Continuous | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play a card this turn.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBExileSelf | Static$ True
|
|
||||||
SVar:DBExileSelf:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
Oracle:{2}, {T}: Target opponent exiles the top card of their library. You may play that card this turn.
|
Oracle:{2}, {T}: Target opponent exiles the top card of their library. You may play that card this turn.
|
||||||
|
|||||||
@@ -2,11 +2,8 @@ Name:Praetor's Grasp
|
|||||||
ManaCost:1 B B
|
ManaCost:1 B B
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ ChangeZone | Cost$ 1 B B | Origin$ Library | Destination$ Exile | ExileFaceDown$ True | ValidTgts$ Opponent | ChangeType$ Card | ChangeNum$ 1 | IsCurse$ True | RememberChanged$ True | SubAbility$ DBEffect | StackDescription$ SpellDescription | SpellDescription$ Search target opponent's library for a card and exile it face down. Then that player shuffles their library. You may look at and play that card for as long as it remains exiled.
|
A:SP$ ChangeZone | Cost$ 1 B B | Origin$ Library | Destination$ Exile | ExileFaceDown$ True | ValidTgts$ Opponent | ChangeType$ Card | ChangeNum$ 1 | IsCurse$ True | RememberChanged$ True | SubAbility$ DBEffect | StackDescription$ SpellDescription | SpellDescription$ Search target opponent's library for a card and exile it face down. Then that player shuffles their library. You may look at and play that card for as long as it remains exiled.
|
||||||
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay | Duration$ Permanent | Triggers$ TrigCleanup | SVars$ DBExileSelf | SubAbility$ DBCleanup
|
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:STPlay:Mode$ Continuous | MayLookAt$ You | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at and play a card as long as it remains exiled.
|
SVar:STPlay:Mode$ Continuous | MayLookAt$ You | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at and play a card as long as it remains exiled.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBExileSelf | Static$ True
|
|
||||||
SVar:DBExileSelf:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/praetors_grasp.jpg
|
|
||||||
Oracle:Search target opponent's library for a card and exile it face down. Then that player shuffles their library. You may look at and play that card for as long as it remains exiled.
|
Oracle:Search target opponent's library for a card and exile it face down. Then that player shuffles their library. You may look at and play that card for as long as it remains exiled.
|
||||||
|
|||||||
@@ -2,11 +2,8 @@ Name:Release to the Wind
|
|||||||
ManaCost:2 U
|
ManaCost:2 U
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ ChangeZone | Cost$ 2 U | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | Origin$ Battlefield | SubAbility$ DBEffect | Destination$ Exile | SpellDescription$ Exile target nonland permanent. For as long as that card remains exiled, its owner may cast it without paying its mana cost.
|
A:SP$ ChangeZone | Cost$ 2 U | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | Origin$ Battlefield | SubAbility$ DBEffect | Destination$ Exile | SpellDescription$ Exile target nonland permanent. For as long as that card remains exiled, its owner may cast it without paying its mana cost.
|
||||||
SVar:DBEffect:DB$ Effect | RememberObjects$ ParentTarget | EffectOwner$ TargetedOwner | StaticAbilities$ STPlay1,STPlay2 | Duration$ Permanent | Triggers$ TrigCleanup | SVars$ DBExileSelf | SubAbility$ DBCleanup
|
SVar:DBEffect:DB$ Effect | RememberObjects$ ParentTarget | EffectOwner$ TargetedOwner | StaticAbilities$ STPlay1,STPlay2 | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:STPlay1:Mode$ Continuous | MayLookAt$ You | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ For as long as that card remains exiled, its owner may cast it without paying its mana cost.
|
SVar:STPlay1:Mode$ Continuous | MayLookAt$ You | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ For as long as that card remains exiled, its owner may cast it without paying its mana cost.
|
||||||
SVar:STPlay2:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Secondary$ True
|
SVar:STPlay2:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Secondary$ True
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBExileSelf | Static$ True
|
|
||||||
SVar:DBExileSelf:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/release_to_the_wind.jpg
|
|
||||||
Oracle:Exile target nonland permanent. For as long as that card remains exiled, its owner may cast it without paying its mana cost.
|
Oracle:Exile target nonland permanent. For as long as that card remains exiled, its owner may cast it without paying its mana cost.
|
||||||
@@ -1,8 +1,7 @@
|
|||||||
Name:Role Reversal
|
Name:Role Reversal
|
||||||
ManaCost:U U R
|
ManaCost:U U R
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Pump | Cost$ U U R | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | SubAbility$ DBExchange | StackDescription$ None | SpellDescription$ Exchange control of two target permanents that share a permanent type.
|
A:SP$ ExchangeControl | Cost$ U U R | TargetMin$ 2 | TargetMax$ 2 | ValidTgts$ Permanent | TgtPrompt$ Select target permanents that share a permanent type | TargetsWithSameCardType$ True | SpellDescription$ Exchange control of two target permanents that share a permanent type.
|
||||||
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent | TgtPrompt$ Select target permanent shares a card type with it | TargetsWithSharedTypes$ Creature,Artifact,Enchantment,Planeswalker,Land | TargetUnique$ True
|
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
Oracle:Exchange control of two target permanents that share a permanent type.
|
Oracle:Exchange control of two target permanents that share a permanent type.
|
||||||
|
|||||||
10
forge-gui/res/cardsfolder/s/shahrazad.txt
Normal file
10
forge-gui/res/cardsfolder/s/shahrazad.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Shahrazad
|
||||||
|
ManaCost:W W
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Subgame | RememberPlayers$ NotWin | SubAbility$ DBRepeatEachPlayer | SpellDescription$ Players play a Magic subgame, using their libraries as their decks. Each player who doesn't win the subgame loses half their life, rounded up. | StackDescription$ SpellDescription
|
||||||
|
SVar:DBRepeatEachPlayer:DB$ RepeatEach | RepeatPlayers$ Remembered | ClearRememberedBeforeLoop$ True | RepeatSubAbility$ DBLoseLife | SpellDescription$ Each player who doesn't win the subgame loses half their life, rounded up. | StackDescription$ SpellDescription
|
||||||
|
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ X | References$ X | Defined$ Player.IsRemembered
|
||||||
|
SVar:X:PlayerCountRemembered$LifeTotal/HalfUp
|
||||||
|
AI:RemoveDeck:All
|
||||||
|
AI:RemoveDeck:Random
|
||||||
|
Oracle:Players play a Magic subgame, using their libraries as their decks. Each player who doesn't win the subgame loses half their life, rounded up.
|
||||||
@@ -5,13 +5,11 @@ Text:If a player would draw a card, that player exiles the top card of an oppone
|
|||||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEffects | Static$ True
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEffects | Static$ True
|
||||||
#Create an effect for each player. The effect contains both Shared Fate's abilities.
|
#Create an effect for each player. The effect contains both Shared Fate's abilities.
|
||||||
SVar:TrigEffects:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBEffect
|
SVar:TrigEffects:DB$ RepeatEach | RepeatPlayers$ Player | RepeatSubAbility$ DBEffect
|
||||||
SVar:DBEffect:DB$ Effect | EffectOwner$ Remembered | StaticAbilities$ STPlay | Triggers$ TrigCleanup | ReplacementEffects$ RDraw | SVars$ DBChooseOpp,DBExile,DBCleanup | Duration$ UntilHostLeavesPlay
|
SVar:DBEffect:DB$ Effect | EffectOwner$ Remembered | StaticAbilities$ STPlay | ReplacementEffects$ RDraw | SVars$ DBChooseOpp,DBExile | Duration$ UntilHostLeavesPlay | ForgetOnMoved$ Exile
|
||||||
SVar:RDraw:Event$ Draw | ActiveZones$ Command | ValidPlayer$ You | ReplaceWith$ DBChooseOpp | Description$ If you would draw a card, exile the top card of an opponent's library face down instead.
|
SVar:RDraw:Event$ Draw | ActiveZones$ Command | ValidPlayer$ You | ReplaceWith$ DBChooseOpp | Description$ If you would draw a card, exile the top card of an opponent's library face down instead.
|
||||||
SVar:DBChooseOpp:DB$ ChoosePlayer | ChoiceTitle$ Choose an opponent whose top library card to exile | Choices$ Player.Opponent | AILogic$ Curse | SubAbility$ DBExile
|
SVar:DBChooseOpp:DB$ ChoosePlayer | ChoiceTitle$ Choose an opponent whose top library card to exile | Choices$ Player.Opponent | AILogic$ Curse | SubAbility$ DBExile
|
||||||
SVar:DBExile:DB$ Dig | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | ExileFaceDown$ True | Defined$ Player.Chosen | RememberChanged$ True
|
SVar:DBExile:DB$ Dig | DigNum$ 1 | ChangeNum$ All | DestinationZone$ Exile | ExileFaceDown$ True | Defined$ Player.Chosen | RememberChanged$ True
|
||||||
SVar:STPlay:Mode$ Continuous | MayLookAt$ You | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at and play cards exiled with Shared Fate.
|
SVar:STPlay:Mode$ Continuous | MayLookAt$ You | MayPlay$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may look at and play cards exiled with Shared Fate.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBCleanup | Static$ True
|
|
||||||
SVar:DBCleanup:DB$ Cleanup | ForgetDefined$ TriggeredCard
|
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
Oracle:If a player would draw a card, that player exiles the top card of an opponent's library face down instead.\nEach player may look at and play cards they exiled with Shared Fate.
|
Oracle:If a player would draw a card, that player exiles the top card of an opponent's library face down instead.\nEach player may look at and play cards they exiled with Shared Fate.
|
||||||
|
|||||||
@@ -1,9 +1,7 @@
|
|||||||
Name:Shifting Loyalties
|
Name:Shifting Loyalties
|
||||||
ManaCost:5 U
|
ManaCost:5 U
|
||||||
Types:Sorcery
|
Types:Sorcery
|
||||||
A:SP$ Pump | Cost$ 5 U | ValidTgts$ Permanent | TgtPrompt$ Select target permanent | SubAbility$ DBExchange | StackDescription$ None | SpellDescription$ Exchange control of two target permanents that share a card type.
|
A:SP$ ExchangeControl | Cost$ 5 U | TargetMin$ 2 | TargetMax$ 2 | ValidTgts$ Permanent | TgtPrompt$ Select target permanents that share a permanent type | TargetsWithSameCardType$ True | SpellDescription$ Exchange control of two target permanents that share a card type.
|
||||||
SVar:DBExchange:DB$ ExchangeControl | Defined$ ParentTarget | ValidTgts$ Permanent | TgtPrompt$ Select target permanent shares a card type with it | TargetsWithSharedTypes$ Creature,Artifact,Enchantment,Planeswalker,Land,Tribal | TargetUnique$ True
|
|
||||||
AI:RemoveDeck:All
|
AI:RemoveDeck:All
|
||||||
AI:RemoveDeck:Random
|
AI:RemoveDeck:Random
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/shifting_loyalties.jpg
|
|
||||||
Oracle:Exchange control of two target permanents that share a card type. (Artifact, creature, enchantment, land, and planeswalker are card types.)
|
Oracle:Exchange control of two target permanents that share a card type. (Artifact, creature, enchantment, land, and planeswalker are card types.)
|
||||||
|
|||||||
@@ -2,9 +2,7 @@ Name:Spelljack
|
|||||||
ManaCost:3 U U U
|
ManaCost:3 U U U
|
||||||
Types:Instant
|
Types:Instant
|
||||||
A:SP$ Counter | Cost$ 3 U U U | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | RememberCountered$ True | ForgetOtherTargets$ True | Destination$ Exile | SubAbility$ DBEffect | SpellDescription$ Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may play it without paying its mana cost for as long as it remains exiled. (If it has X in its mana cost, X is 0.)
|
A:SP$ Counter | Cost$ 3 U U U | TargetType$ Spell | TgtPrompt$ Select target spell | ValidTgts$ Card | RememberCountered$ True | ForgetOtherTargets$ True | Destination$ Exile | SubAbility$ DBEffect | SpellDescription$ Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may play it without paying its mana cost for as long as it remains exiled. (If it has X in its mana cost, X is 0.)
|
||||||
SVar:DBEffect:DB$ Effect | Name$ Spelljack Effect | RememberObjects$ Remembered | StaticAbilities$ Play | Duration$ Permanent | Triggers$ TrigCleanup | SVars$ DBCleanup | References$ Play,TrigCleanup,DBCleanup
|
SVar:DBEffect:DB$ Effect | Name$ Spelljack Effect | RememberObjects$ Remembered | StaticAbilities$ Play | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup
|
||||||
SVar:Play:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play cards exiled with Spelljack.
|
SVar:Play:Mode$ Continuous | MayPlay$ True | MayPlayWithoutManaCost$ True | EffectZone$ Command | Affected$ Card.IsRemembered | AffectedZone$ Exile | Description$ You may play cards exiled with Spelljack.
|
||||||
SVar:TrigCleanup:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Command | Execute$ DBCleanup | Static$ True
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
SVar:DBCleanup:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
|
|
||||||
SVar:Picture:http://www.wizards.com/global/images/magic/general/spelljack.jpg
|
|
||||||
Oracle:Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may play it without paying its mana cost for as long as it remains exiled. (If it has X in its mana cost, X is 0.)
|
Oracle:Counter target spell. If that spell is countered this way, exile it instead of putting it into its owner's graveyard. You may play it without paying its mana cost for as long as it remains exiled. (If it has X in its mana cost, X is 0.)
|
||||||
|
|||||||
9
forge-gui/res/cardsfolder/upcoming/alrunds_epiphany.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/alrunds_epiphany.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Alrund's Epiphany
|
||||||
|
ManaCost:5 U U
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Token | Cost$ 5 U U | LegacyImage$ u 1 1 bird flying khm | TokenAmount$ 2 | TokenScript$ u_1_1_bird_flying | TokenOwner$ You | SubAbility$ DBAddTurn | SpellDescription$ Create two 1/1 blue Bird creature tokens with flying. Take an extra turn after this one. Exile CARDNAME.
|
||||||
|
SVar:DBAddTurn: DB$ AddTurn | Defined$ You | NumTurns$ 1 | SubAbility$ DBChange | StackDescription$ None
|
||||||
|
SVar:DBChange:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | StackDescription$ None
|
||||||
|
K:Foretell:4 U U
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:Create two 1/1 blue Bird creature tokens with flying. Take an extra turn after this one. Exile Alrund's Epiphany.\nForetell {4}{U}{U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
11
forge-gui/res/cardsfolder/upcoming/ascent_of_the_worthy.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/ascent_of_the_worthy.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Ascent of the Worthy
|
||||||
|
ManaCost:1 W B
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBChoose,DBChoose,DBChangeZone
|
||||||
|
SVar:DBChoose:DB$ ChooseCard | Choices$ Creature.YouCtrl | SubAbility$ DBEffect | SpellDescription$ Choose a creature you control. Until your next turn, all damage that would be dealt to creatures you control is dealt to that creature instead.
|
||||||
|
SVar:DBEffect:DB$ Effect | ReplacementEffects$ DamageEvent | SVars$ GideonSac | References$ DamageEvent,GideonSac | ExileOnMoved$ True | RememberObjects$ ChosenCard | Duration$ UntilYourNextTurn
|
||||||
|
SVar:DamageEvent:Event$ DamageDone | ActiveZones$ Command | ValidTarget$ Creature.YouCtrl | ReplaceWith$ GideonSac | DamageTarget$ Remembered | Description$ All damage that would be dealt this turn to creatures you control is dealt to the chosen creature instead (if it's still on the battlefield).
|
||||||
|
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouOwn | WithCounters$ Flying_1 | AnimateSubAbility$ Animate | SpellDescription$ Return target creature card from your graveyard to the battlefield with a flying counter on it.
|
||||||
|
SVar:GideonSac:DB$ ReplaceEffect | VarName$ Affected | VarValue$ Remembered | VarType$ Card
|
||||||
|
SVar:Animate:DB$Animate | Defined$ Remembered | Types$ Angel,Warrior | Permanent$ True
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI, II — Choose a creature you control. Until your next turn, all damage that would be dealt to creatures you control is dealt to that creature instead.\nIII — Return target creature card from your graveyard to the battlefield with a flying counter on it. That creature is an Angel Warrior in addition to its other types.
|
||||||
7
forge-gui/res/cardsfolder/upcoming/augury_raven.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/augury_raven.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Augury Raven
|
||||||
|
ManaCost:3 U
|
||||||
|
Types:Creature Bird
|
||||||
|
PT:3/3
|
||||||
|
K:Flying
|
||||||
|
K:Foretell:1 U
|
||||||
|
Oracle:Flying\nForetell {1}{U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
10
forge-gui/res/cardsfolder/upcoming/battle_for_bretagard.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/battle_for_bretagard.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Battle for Bretagard
|
||||||
|
ManaCost:1 G W
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:TrigToken1,TrigToken2,DBCopy
|
||||||
|
SVar:TrigToken1:DB$ Token | TokenAmount$ 1 | TokenScript$ w_1_1_human_warrior | TokenOwner$ You | SpellDescription$ Create a 1/1 white Human Warrior creature token.
|
||||||
|
SVar:TrigToken2:DB$ Token | TokenAmount$ 1 | TokenScript$ g_1_1_elf_warrior | TokenOwner$ You | SpellDescription$ Create a 1/1 green Elf Warrior creature token.
|
||||||
|
SVar:DBCopy:DB$ CopyPermanent | Choices$ Artifact.token+YouCtrl,Creature.token+YouCtrl | WithDifferentNames$ True | SpellDescription$ Choose any number of artifact tokens and/or creature tokens you control with different names. For each of them, create a token that’s a copy of it.
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI — Create a 1/1 white Human Warrior creature token.\nII — Create a 1/1 green Elf Warrior creature token.\nIII — Choose any number of artifact tokens and/or creature tokens you control with different names. For each of them, create a token that’s a copy of it.
|
||||||
|
|
||||||
9
forge-gui/res/cardsfolder/upcoming/battle_mammoth.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/battle_mammoth.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Battle Mammoth
|
||||||
|
ManaCost:3 G G
|
||||||
|
Types:Creature Elephant
|
||||||
|
PT:6/5
|
||||||
|
K:Trample
|
||||||
|
T:Mode$ BecomesTarget | ValidTarget$ Permanent.YouCtrl+inZoneBattlefield | ValidSource$ Card.OppCtrl | TriggerZones$ Battlefield | Execute$ TrigDraw | OptionalDecider$ You | TriggerDescription$ Whenever a permanent you control becomes the target of a spell or ability an opponent controls, you may draw a card.
|
||||||
|
SVar:TrigDraw:DB$Draw | NumCards$ 1 | SpellDescription$ Draw a card.
|
||||||
|
K:Foretell:2 G G
|
||||||
|
Oracle:Trample\nWhenever a permanent you control becomes the target of a spell or ability an opponent controls, you may draw a card.\nForetell {2}{G}{G} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
Name:Battle of Frost and Fire
|
||||||
|
ManaCost:3 U R
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBDamageAll,DBScry,DBEffect
|
||||||
|
SVar:DBDamageAll:DB$ DamageAll | NumDmg$ 4 | ValidCards$ Creature.nonGiant,Planeswalker | ValidDescription$ each non-Giant creature and each planeswalker. | SpellDescription$ CARDNAME deals 4 damage to each non-Giant creature and each planeswalker.
|
||||||
|
SVar:DBScry:DB$ Scry | ScryNum$ 3 | SpellDescription$ Scry 3.
|
||||||
|
SVar:DBEffect:DB$ Effect | Triggers$ CastSpell | SpellDescription$ Whenever you cast a spell with converted mana cost 5 or greater this turn, draw two cards, then discard a card.
|
||||||
|
SVar:CastSpell:Mode$ SpellCast | ValidCard$ Card.cmcGE5 | ValidActivatingPlayer$ You | TriggerZones$ Command | Execute$ DBDraw | TriggerDescription$ Whenever you cast a spell with converted mana cost 5 or greater this turn, draw two cards, then discard a card.
|
||||||
|
SVar:DBDraw:DB$ Draw | Defined$ You | NumCards$ 2 | SubAbility$ DBDiscard
|
||||||
|
SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ 1 | Mode$ TgtChoose
|
||||||
|
DeckHints:Type$Giant
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI — Battle of Frost and Fire deals 4 damage to each non-Giant creature and each planeswalker.\nII — Scry 3.\nIII — Whenever you cast a spell with converted mana cost 5 or greater this turn, draw two cards, then discard a card.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Behold the Multiverse
|
||||||
|
ManaCost:3 U
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Scry | Cost$ 3 U | ScryNum$ 2 | SubAbility$ DBDraw | AILogic$ BestOpportunity | SpellDescription$ Scry 2, then draw two cards.
|
||||||
|
SVar:DBDraw:DB$Draw | NumCards$ 2
|
||||||
|
K:Foretell:1 U
|
||||||
|
Oracle:Scry 2, then draw two cards.\nForetell {1}{U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
11
forge-gui/res/cardsfolder/upcoming/bloodline_pretender.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/bloodline_pretender.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Bloodline Pretender
|
||||||
|
ManaCost:3
|
||||||
|
Types:Artifact Creature Shapeshifter
|
||||||
|
PT:2/2
|
||||||
|
K:Changeling
|
||||||
|
K:ETBReplacement:Other:ChooseCT
|
||||||
|
SVar:ChooseCT:DB$ ChooseType | Defined$ You | Type$ Creature | AILogic$ MostProminentInComputerDeck | SpellDescription$ As CARDNAME enters the battlefield, choose a creature type.
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Creature.Other+ChosenType+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Whenever another creature of the chosen type enters the battlefield under your control, put a +1/+1 counter on CARDNAME.
|
||||||
|
SVar:TrigPutCounter:DB$PutCounter | CounterType$ P1P1 | CounterNum$ 1
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:Changeling\nAs Bloodline Pretender enters the battlefield, choose a creature type.\nWhenever another creature of the chosen type enters the battlefield under your control, put a +1/+1 counter on Bloodline Pretender.
|
||||||
11
forge-gui/res/cardsfolder/upcoming/cosmos_charger.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/cosmos_charger.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Cosmos Charger
|
||||||
|
ManaCost:3 U
|
||||||
|
Types:Creature Horse Spirit
|
||||||
|
PT:3/3
|
||||||
|
K:Flash
|
||||||
|
K:Flying
|
||||||
|
S:Mode$ ReduceCost | ValidSpell$ Static.Foretelling | Activator$ You | Amount$ 1 | Description$ Foretelling cards from your hand costs {1} less and can be done on any player’s turn.
|
||||||
|
S:Mode$ Continuous | Affected$ You | AddKeyword$ Foretell on any player’s turn | Secondary$ True | Description$ Foretelling cards from your hand on any player’s turn.
|
||||||
|
K:Foretell:2 U
|
||||||
|
Oracle:Flash\nFlying\nForetelling cards from your hand costs {1} less and can be done on any player’s turn.\nForetell {2}{U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
|
|
||||||
7
forge-gui/res/cardsfolder/upcoming/crush_the_weak.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/crush_the_weak.txt
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Crush the Weak
|
||||||
|
ManaCost:2 R
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DamageAll | Cost$ 2 R | ValidCards$ Creature | NumDmg$ 2 | RememberDamaged$ True | ReplaceDyingDefined$ Remembered | SubAbility$ DBCleanup | SpellDescription$ CARDNAME deals 2 damage to each creature. If a creature dealt damage this way would die this turn, exile it instead. | StackDescription$ SpellDescription
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
K:Foretell:R
|
||||||
|
Oracle:Crush the Weak deals 2 damage to each creature. If a creature dealt damage this way would die this turn, exile it instead.\nForetell {R} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
6
forge-gui/res/cardsfolder/upcoming/demon_bolt.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/demon_bolt.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Demon Bolt
|
||||||
|
ManaCost:2 R
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ DealDamage | Cost$ 2 R | ValidTgts$ Creature,Planeswalker | TgtPrompt$ Select target creature or planeswalker. | NumDmg$ 4 | SpellDescription$ CARDNAME deals 4 damage to target creature or planeswalker.
|
||||||
|
K:Foretell:R
|
||||||
|
Oracle:Demon Bolt deals 4 damage to target creature or planeswalker.\nForetell {R} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
6
forge-gui/res/cardsfolder/upcoming/depart_the_realm.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/depart_the_realm.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Depart the Realm
|
||||||
|
ManaCost:1 U
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ ChangeZone | Cost$ 1 U | ValidTgts$ Permanent.nonLand | TgtPrompt$ Select target nonland permanent | Origin$ Battlefield | Destination$ Hand | SpellDescription$ Return target nonland permanent to its owner's hand.
|
||||||
|
K:Foretell:U
|
||||||
|
Oracle:Return target nonland permanent to its owner's hand.\nForetell {U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
6
forge-gui/res/cardsfolder/upcoming/doomskar.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/doomskar.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Doomskar
|
||||||
|
ManaCost:3 W W
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ DestroyAll | Cost$ 3 W W | ValidCards$ Creature | SpellDescription$ Destroy all creatures.
|
||||||
|
K:Foretell:1 W W
|
||||||
|
Oracle:Destroy all creatures.\nForetell {1}{W}{W} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
11
forge-gui/res/cardsfolder/upcoming/doomskar_oracle.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/doomskar_oracle.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Doomskar Oracle
|
||||||
|
ManaCost:2 W
|
||||||
|
Types:Creature Human Cleric
|
||||||
|
PT:3/2
|
||||||
|
T:Mode$ SpellCast | ValidCard$ Card.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigGainLife | CheckSVar$ YouCastThisTurn | SVarCompare$ EQ2 | NoResolvingCheck$ True | TriggerDescription$ Whenever you cast your second spell each turn, you gain 2 life.
|
||||||
|
SVar:TrigGainLife:DB$ GainLife | Defined$ You | LifeAmount$ 2
|
||||||
|
SVar:YouCastThisTurn:Count$ThisTurnCast_Card.YouCtrl
|
||||||
|
SVar:BuffedBy:Card
|
||||||
|
K:Foretell:W
|
||||||
|
DeckHas:Ability$LifeGain
|
||||||
|
Oracle:Whenever you cast your second spell each turn, you gain 2 life.\nForetell {W} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
9
forge-gui/res/cardsfolder/upcoming/doomskar_titan.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/doomskar_titan.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Doomskar Titan
|
||||||
|
ManaCost:4 R R
|
||||||
|
Types:Creature Giant Berserker
|
||||||
|
PT:4/4
|
||||||
|
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigPumpAll | TriggerDescription$ When CARDNAME enters the battlefield, creatures you control get +1/0 and gain haste until end of turn.
|
||||||
|
SVar:TrigPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl | NumAtt$ 1 | KW$ Haste
|
||||||
|
SVar:PlayMain1:TRUE
|
||||||
|
K:Foretell:4 R
|
||||||
|
Oracle:When Doomskar Titan enters the battlefield, creatures you control get +1/+) and gain haste until end of turn.\nForetell {4}{R} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
8
forge-gui/res/cardsfolder/upcoming/dream_devourer.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/dream_devourer.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Dream Devourer
|
||||||
|
ManaCost:1 B
|
||||||
|
Types:Creature Demon Cleric
|
||||||
|
PT:0/3
|
||||||
|
S:Mode$ Continuous | Affected$ Card.nonLand+YouOwn+withoutForetell | AffectedZone$ Hand | AddKeyword$ Foretell | Description$ Each nonland card in your hand without foretell has foretell. Its foretell cost is equal to its mana cost reduced by {2}. (During your turn, you may pay {2} and exile it from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
|
T:Mode$ Foretell | ValidPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever you foretell a card, CARDNAME gets +2/+0 until end of turn.
|
||||||
|
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 2
|
||||||
|
Oracle:Each nonland card in your hand without foretell has foretell. Its foretell cost is equal to its mana cost reduced by {2}. (During your turn, you may pay {2} and exile it from your hand face down. Cast it on a later turn for its foretell cost.)\n Whenever you foretell a card, Dream Devourer gets +2/+0 until end of turn.
|
||||||
8
forge-gui/res/cardsfolder/upcoming/dual_strike.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/dual_strike.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Dual Strike
|
||||||
|
ManaCost:R R
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ DelayedTrigger | Cost$ R R | AILogic$ SpellCopy | Execute$ EffTrigCopy | ThisTurn$ True | Mode$ SpellCast | ValidCard$ Instant.cmcLE4,Sorcery.cmcLE4 | ValidActivatingPlayer$ You | SpellDescription$ When you cast your next instant or sorcery spell with converted mana cost 4 or less this turn, copy that spell. You may choose new targets for the copy.
|
||||||
|
SVar:EffTrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True
|
||||||
|
SVar:AIPriorityModifier:9
|
||||||
|
K:Foretell:R
|
||||||
|
Oracle:When you cast your next instant or sorcery spell with converted mana cost 4 or less this turn, copy that spell. You may choose new targets for that copy.\nForetell {R} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Dwarven Reinforcements
|
||||||
|
ManaCost:3 R
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Token | Cost$ 3 R | LegacyImage$ r 2 1 dwarf berserker khm | TokenAmount$ 2 | TokenScript$ r_2_1_dwarf_berserker | TokenOwner$ You | SpellDescription$ Create 2 2/1 red Dwarf Berserker creature tokens.
|
||||||
|
K:Foretell:1 R
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:Create 2 2/1 red Dwarf Berserker creature tokens.\nForetell {1}{R} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
11
forge-gui/res/cardsfolder/upcoming/ethereal_valkyrie.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/ethereal_valkyrie.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Ethereal Valkyrie
|
||||||
|
ManaCost:4 U W
|
||||||
|
Types:Creature Spirit Angel
|
||||||
|
PT:4/4
|
||||||
|
K:Flying
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ DBDraw | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, draw a card, then exile a card from your hand face down. It becomes foretold. Its foretell cost is its mana cost reduced by {2}. (On a later turn, you may cast it for its foretell cost, even if this creature has left the battlefield.)
|
||||||
|
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DBDraw | Secondary$ True | TriggerDescription$ Whenever CARDNAME enters the battlefield or attacks, draw a card, then exile a card from your hand face down. It becomes foretold. Its foretell cost is its mana cost reduced by {2}. (On a later turn, you may cast it for its foretell cost, even if this creature has left the battlefield.)
|
||||||
|
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SubAbility$ DBExile
|
||||||
|
SVar:DBExile:DB$ ChangeZone | Origin$ Hand | Destination$ Exile | ChangeType$ Card | ChangeNum$ 1 | ExileFaceDown$ True | Mandatory$ True | Foretold$ True
|
||||||
|
Oracle:Whenever Ethereal Valkyrie enters the battlefield or attacks, draw a card, then exile a card from your hand face down. It becomes foretold. Its foretell cost is its mana cost reduced by {2}. (On a later turn, you may cast it for its foretell cost, even if this creature has left the battlefield.)
|
||||||
|
|
||||||
11
forge-gui/res/cardsfolder/upcoming/fall_of_the_impostor.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/fall_of_the_impostor.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Fall of the Impostor
|
||||||
|
ManaCost:1 G W
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBPutCounter,DBPutCounter,DBExileGreatest
|
||||||
|
SVar:DBPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | TargetMin$ 0 | TargetMax$ 1 | SpellDescription$ Put a +1/+1 counter on up to one target creature.
|
||||||
|
SVar:DBExileGreatest:DB$ Pump | ValidTgts$ Player.Opponent | RememberTargets$ True | SubAbility$ DBChooseExiled | SpellDescription$ Exile a creature with the greatest power among creatures target opponent controls.
|
||||||
|
SVar:DBChooseExiled:DB$ ChooseCard | Choices$ Creature.greatestPowerControlledByRemembered | MinAmount$ 1 | Amount$ 1 | Mandatory$ True | ChoiceZone$ Battlefield | SubAbility$ DBChangeZone
|
||||||
|
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ ChosenCard | SubAbility$ DBCleanup
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:I - Put a +1/+1 counter on up to one target creature.\nII - Put a +1/+1 counter on up to one target creature.\nIII - Exile a creature with the greatest power among creatures target opponent controls.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Forging the Tyrite Sword
|
||||||
|
ManaCost:1 R W
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBToken,DBToken,DBChangeZone
|
||||||
|
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_treasure_sac | TokenOwner$ You $ SpellDescription
|
||||||
|
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Library | Destination$ Hand | ChangeType$ Card.namedHalvar; God of Battle,Equipment | ChangeNum$ 1 | SpellDescription$ Search your library for a card named Halvar, God of Battle or an Equipment card, reveal it, put it into your hand, then shuffle your library.
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI, II — Create a Treasure token.\nIII — Search your library for a card named Halvar, God of Battle or an Equipment card, reveal it, put it into your hand, then shuffle your library.
|
||||||
22
forge-gui/res/cardsfolder/upcoming/glorious_protector.txt
Normal file
22
forge-gui/res/cardsfolder/upcoming/glorious_protector.txt
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
Name:Glorious Protector
|
||||||
|
ManaCost:2 W W
|
||||||
|
Types:Creature Angel Cleric
|
||||||
|
PT:3/4
|
||||||
|
K:Flash
|
||||||
|
K:Flying
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ When CARDNAME enters the battlefield, you may exile any number of other non-Angel creatures you control until CARDNAME leaves the battlefield.
|
||||||
|
SVar:TrigExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | RememberChanged$ True | Hidden$ True | ChangeType$ Creature.nonAngel+YouCtrl | ChangeNum$ MaxTgts | SelectPrompt$ Choose any number of non-Angel creatures you control | SubAbility$ DBEffect | References$ MaxTgts
|
||||||
|
SVar:DBEffect:DB$ Effect | Triggers$ ComeBack | RememberObjects$ RememberedCard | ImprintCards$ Self | SVars$ TrigReturn,ExileSelf | ConditionPresent$ Card.Self | Duration$ Permanent | ForgetOnMoved$ Exile
|
||||||
|
SVar:ComeBack:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.IsImprinted | Execute$ TrigReturn | TriggerZones$ Command | TriggerController$ TriggeredCardController | Static$ True | TriggerDescription$ That creature is exiled until EFFECTSOURCE leaves the battlefield
|
||||||
|
SVar:TrigReturn:DB$ ChangeZoneAll | Origin$ Exile | Destination$ Battlefield | ChangeType$ Card.IsRemembered | SubAbility$ ExileSelf
|
||||||
|
SVar:ExileSelf:DB$ ChangeZone | Origin$ Command | Destination$ Exile | Defined$ Self
|
||||||
|
#Triggers to forget remembered on this
|
||||||
|
T:Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Exile | Destination$ Any | TriggerZones$ Battlefield | Static$ True | Execute$ TrigForget
|
||||||
|
SVar:TrigForget:DB$ Pump | ForgetObjects$ TriggeredCard
|
||||||
|
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Battlefield | Destination$ Any | Static$ True | Execute$ TrigForgetAll
|
||||||
|
SVar:TrigForgetAll:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
SVar:X:Count$ValidExile Card.IsRemembered+ExiledWithSource/Times.2
|
||||||
|
SVar:MaxTgts:Count$Valid Creature.nonAngel+YouCtrl
|
||||||
|
AI:RemoveDeck:Random
|
||||||
|
K:Foretell:2 W
|
||||||
|
Oracle:Flash\nFlying\nWhen Glorious Protector enters the battlefield, you may exile any number of non-Angel creatures you control until Glorious Protector leaves the battlefield.\nForetell {2}{W} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Gods' Hall Guardian
|
||||||
|
ManaCost:5 W
|
||||||
|
Types:Creature Cat
|
||||||
|
PT:3/6
|
||||||
|
K:Vigilance
|
||||||
|
K:Foretell:3 W
|
||||||
|
Oracle:Vigilance\nForetell {3}{W} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Harald, King of Skemfar
|
||||||
|
ManaCost:1 B G
|
||||||
|
Types:Legendary Creature Elf Warrior
|
||||||
|
PT:3/2
|
||||||
|
K:Menace
|
||||||
|
T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefield | Execute$ TrigDig | TriggerDescription$ When CARDNAME enters the battlefield, look at the top five cards of your library. You may reveal an Elf, Warrior, or Tyvar card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||||
|
SVar:TrigDig:DB$ Dig | DigNum$ 5 | ChangeNum$ 1 | Optional$ True | ForceRevealToController$ True | ChangeValid$ Elf,Warrior,Tyvar | RestRandomOrder$ True
|
||||||
|
DeckHints:Type$Elf|Tyvar
|
||||||
|
Oracle:Menace (This creature can’t be blocked except by two or more creatures.)\nWhen Harald, King of Skemfar enters the battlefield, look at the top five cards of your library. You may reveal an Elf, Warrior, or Tyvar card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Name:Harald Unites the Elves
|
||||||
|
ManaCost:2 B G
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBMill,DBPutCounterAll,DBEffect
|
||||||
|
SVar:DBMill:DB$ Mill | NumCards$ 3 | Defined$ You | SubAbility$ DBChangeZone | SpellDescription$ Mill three cards. You may put an Elf card or Tyvar card from your graveyard onto the battlefield.
|
||||||
|
SVar:DBChangeZone:DB$ ChangeZone | Hidden$ True | ChangeType$ Elf.YouOwn,Tyvar.YouOwn | ChangeNum$ 1 | Origin$ Graveyard | Destination$ Battlefield
|
||||||
|
SVar:DBPutCounterAll:DB$ PutCounterAll | ValidCards$ Creature.Elf+YouCtrl | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on each Elf you control.
|
||||||
|
SVar:DBEffect:DB$ Effect | Triggers$ TrigAttack | SpellDescription$ Whenever an Elf you control attacks this turn, target creature an opponent controls gets -1/-1 until end of turn.
|
||||||
|
SVar:TrigAttack:Mode$ Attacks | ValidCard$ Creature.Elf+YouCtrl | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever an Elf you control attacks this turn, target creature an opponent controls gets -1/-1 until end of turn.
|
||||||
|
SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.OppCtrl | TgtPrompt$ Select target creature | NumAtt$ -1 | NumDef$ -1 | IsCurse$ True
|
||||||
|
DeckHints:Type$Elf|Tyvar
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI - Mill three cards. You may put an Elf card or Tyvar card from your graveyard onto the battlefield.\nII - Put a +1/+1 counter on each Elf you control.\nIII - Whenever an Elf you control attacks this turn, target creature an opponent controls gets -1/-1 until end of turn.
|
||||||
12
forge-gui/res/cardsfolder/upcoming/immersturm_predator.txt
Normal file
12
forge-gui/res/cardsfolder/upcoming/immersturm_predator.txt
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Name:Immersturm Predator
|
||||||
|
ManaCost:2 B R
|
||||||
|
Types:Creature Vampire Dragon
|
||||||
|
PT:3/3
|
||||||
|
K:Flying
|
||||||
|
T:Mode$ Taps | ValidCard$ Card.Self | Execute$ TrigExile | TriggerDescription$ Whenever CARDNAME becomes tapped, exile up to one target card from a graveyard and put a +1/+1 counter on CARDNAME.
|
||||||
|
SVar:TrigExile:DB$ Changezone | ValidTgts$ Card | TargetMin$ 0 | TargetMax$ 1 | Origin$ Graveyard | Destination$ Exile | TgtPrompt$ Choose target card in a graveyard | SubAbility$ DBPutCounter
|
||||||
|
SVar:DBPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||||
|
A:AB$ Pump | Cost$ Sac<1/Creature.Other/another creature> | Defined$ Self | KW$ Indestructible | SubAbility$ DBTap | SpellDescription$ CARDNAME gains indestructible until end of turn. Tap it.
|
||||||
|
SVar:DBTap:DB$ Tap | Defined$ Self
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:Flying\nWhenever Immersturm Predator becomes tapped, exile up to one target card from a graveyard and put a +1/+1 counter on Immersturm Predator.\nSacrifice another creature: Immersturm Predator gains indestructible until end of turn. Tap it.
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
Name:Invasion of the Giants
|
||||||
|
ManaCost:U R
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBScry,DBDraw,DBEffect
|
||||||
|
SVar:DBScry:DB$ Scry | ScryNum$ 2 | SpellDescription$ Scry 2.
|
||||||
|
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SubAbility$ DBReveal | SpellDescription$ Draw a card. Then you may reveal a Giant card from your hand. When you do, CARDNAME deals 2 damage to target opponent or planeswalker.
|
||||||
|
SVar:DBReveal:DB$ ImmediateTrigger | Execute$ TrigDealDamage | UnlessCost$ Reveal<1/Giant> | UnlessPayer$ You | UnlessSwitched$ True | SpellDescription$ You may reveal a Giant card from your hand. When you do, CARDNAME deals 2 damage to target opponent or planeswalker.
|
||||||
|
SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Player.Opponent,Planeswalker | TgtPrompt$ Select target opponent or planeswalker. | NumDmg$ 2
|
||||||
|
SVar:DBEffect:DB$ Effect | StaticAbilities$ ReduceCost | Triggers$ TrigCastSpell | SVars$ RemoveEffect| SpellDescription$ The next Giant spell you cast this turn costs {2} less to cast.
|
||||||
|
SVar:ReduceCost:Mode$ ReduceCost | EffectZone$ Command | Type$ Spell | ValidCard$ Giant | Activator$ You | Amount$ 2
|
||||||
|
SVar:TrigCastSpell:Mode$ SpellCast | ValidCard$ Giant | ValidActivatingPlayer$ You | TriggerZones$ Command | Execute$ RemoveEffect | Static$ True
|
||||||
|
SVar:RemoveEffect:DB$ ChangeZone | Origin$ Command | Destination$ Exile
|
||||||
|
DeckHints:Type$Giant
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI - Scry 2.\nII - Draw a card. Then you may reveal a Giant card from your hand. When you do, Invasion of the Giants deals 2 damage to target opponent or planeswalker.\nIII - The next Giant spell you cast this turn costs {2} less to cast.
|
||||||
6
forge-gui/res/cardsfolder/upcoming/iron_verdict.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/iron_verdict.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Iron Verdict
|
||||||
|
ManaCost:2 W
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ DealDamage | Cost$ 2 W | ValidTgts$ Creature.tapped | NumDmg$ 5 | TgtPrompt$ Select target tapped creature | SpellDescription$ CARDNAME deals 5 damage to target tapped creature.
|
||||||
|
K:Foretell:W
|
||||||
|
Oracle:Iron Verdict deals 5 damage to target tapped creature.\nForetell {W} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Jarl of the Forsaken
|
||||||
|
ManaCost:3 B
|
||||||
|
Types:Creature Zombie Cleric
|
||||||
|
PT:3/2
|
||||||
|
K:Flash
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDestroy | TriggerController$ TriggeredCardController | TriggerDescription$ When CARDNAME enters the battlefield, destroy target creature or planeswalker an opponent controls that was dealt damage this turn.
|
||||||
|
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature.OppCtrl+wasDealtDamageThisTurn,Planeswalker.OppCtrl+wasDealtDamageThisTurn | TgtPrompt$ Select target creature or planeswalker an opponent controls that was dealt damage this turn.
|
||||||
|
K:Foretell:1 B
|
||||||
|
Oracle:Flash\nWhen Jarl of the Forsaken enters the battlefield, destroy target creature or planeswalker an opponent controls that was dealt damage this turn.\nForetell {1}{B} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
11
forge-gui/res/cardsfolder/upcoming/kardur_doomscourge.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/kardur_doomscourge.txt
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
Name:Kardur, Doomscourge
|
||||||
|
ManaCost:2 B R
|
||||||
|
Types:Legendary Creature Demon Berserker
|
||||||
|
PT:4/3
|
||||||
|
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigGoad | TriggerDescription$ When CARDNAME enters the battlefield, until your next turn, creatures your opponents control attack each combat if able and attack a player other than you if able.
|
||||||
|
SVar:TrigGoad:DB$ Goad | Defined$ Valid Creature.YouDontCtrl
|
||||||
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.attackingLKI | Execute$ TrigDrain | TriggerZones$ Battlefield | TriggerDescription$ Whenever an attacking creature dies, each opponent loses 1 life and you gain 1 life.
|
||||||
|
SVar:TrigDrain:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1 | SubAbility$ DBGainOneLife
|
||||||
|
SVar:DBGainOneLife:DB$ GainLife | Defined$ You | LifeAmount$ 1
|
||||||
|
DeckHas:Ability$LifeGain
|
||||||
|
Oracle:When Kardur Doomscourge enters the battlefield, until your next turn, creatures your opponents control attack each combat if able and attack a player other than you if able.\nWhenever an attacking creature dies, each opponent loses 1 life and you gain 1 life.
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Name:Kardur's Vicious Return
|
||||||
|
ManaCost:2 B R
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBSacrifice,DBDiscard,DBReturn
|
||||||
|
SVar:DBSacrifice:DB$ ImmediateTrigger | Execute$ TrigDealDamage | UnlessCost$ Sac<1/Creature> | UnlessPayer$ You | UnlessSwitched$ True | SpellDescription$ You may sacrifice a creature. When you do, CARDNAME deals 3 damage to any target.
|
||||||
|
SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target. | NumDmg$ 3
|
||||||
|
SVar:DBDiscard:DB$ Discard | Defined$ Player | NumCards$ 1 | Mode$ TgtChoose | SpellDescription$ Each player discards a card.
|
||||||
|
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouCtrl | RememberChanged$ True | SubAbility$ DBPutCounter | SpellDescription$ Return target creature card from your graveyard to the battlefield. Put a +1/+1 counter on it. It gains haste until your next turn.
|
||||||
|
SVar:DBPutCounter:DB$PutCounter | CounterType$ P1P1 | CounterNum$ 1 | Defined$ Remembered | SubAbility$ DBPump
|
||||||
|
SVar:DBPump:DB$ Pump | Defined$ Remembered | KW$ Haste | UntilYourNextTurn$ True | SubAbility$ DBCleanup
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
DeckHas:Ability$Counters
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI - You may sacrifice a creature. When you do, Kardur's Vicious Return deals 3 damage to any target.\nII - Each player discards a card.\nIII - Return target creature card from your graveyard to the battlefield. Put a +1/+1 counter on it. It gains haste until your next turn.
|
||||||
8
forge-gui/res/cardsfolder/upcoming/karfell_harbinger.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/karfell_harbinger.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Karfell Harbinger
|
||||||
|
ManaCost:1 U
|
||||||
|
Types:Creature Zombie Wizard
|
||||||
|
PT:1/3
|
||||||
|
A:AB$ Mana | Cost$ T | Produced$ U | RestrictValid$ Static.Foretelling,Spell.Instant,Spell.Sorcery | SpellDescription$ Add {U}. Spend this mana only to foretell a card from your hand or cast an instant or sorcery spell.
|
||||||
|
DeckHints:Type$Instant|Sorcery
|
||||||
|
Oracle:{T}: Add {U}. Spend this mana only to foretell a card from your hand or cast an instant or sorcery spell.
|
||||||
|
|
||||||
6
forge-gui/res/cardsfolder/upcoming/kayas_onslaught.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/kayas_onslaught.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Kaya's Onslaught
|
||||||
|
ManaCost:2 W
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Pump | Cost$ 2 W | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ 1 | NumDef$ 1 | KW$ Double Strike | SpellDescription$ Target creature gets +1/+1 and gains double strike until end of turn. | StackDescription$ SpellDescription
|
||||||
|
K:Foretell:W
|
||||||
|
Oracle:Target creature gets +1/+1 and gains double strike until end of turn.\nForetell {W} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
Name:Kolvori, God of Kinship
|
||||||
|
ManaCost:2 G G
|
||||||
|
Types:Legendary Creature God
|
||||||
|
PT:2/2
|
||||||
|
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 4 | AddToughness$ 2 | AddKeyword$ Vigilance | IsPresent$ Creature.Legendary+YouCtrl | PresentCompare$ GE3 | Description$ As long as you control three or more legendary creatures, CARDNAME gets +4/+2 and has vigilance.
|
||||||
|
A:AB$ Dig | Cost$ 1 G T | DigNum$ 6 | ChangeNum$ 1 | ChangeValid$ Creature.Legendary | Optional$ True | RestRandomOrder$ True | SpellDescription$ Look at the top six cards of your library. You may reveal a legendary creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||||
|
AlternateMode:Modal
|
||||||
|
Oracle:As long as you control three or more legendary creatures, Kolvori gets +4/+2 and has vigilance.\n{1}{G}, {T}: Look at the top six cards of your library. You may reveal a legendary creature card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:The Ringhart Crest
|
||||||
|
ManaCost:1 G
|
||||||
|
Types:Legendary Artifact
|
||||||
|
K:ETBReplacement:Other:ChooseCT
|
||||||
|
SVar:ChooseCT:DB$ ChooseType | Defined$ You | Type$ Creature | AILogic$ MostProminentInComputerDeck | SpellDescription$ As CARDNAME enters the battlefield, choose a creature type.
|
||||||
|
A:AB$ Mana | Cost$ T | Produced$ G | RestrictValid$ Creature.ChosenType,Creature.Legendary | SpellDescription$ {T}: Add {G}. Spend this mana only to cast a creature spell of the chosen type or a legendary creature spell.
|
||||||
|
Oracle:As The Ringhart Crest enters the battlefield, choose a creature type.\n{T}: Add {G}. Spend this mana only to cast a creature spell of the chosen type or a legendary creature spell.
|
||||||
6
forge-gui/res/cardsfolder/upcoming/mammoth_growth.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/mammoth_growth.txt
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Name:Mammoth Growth
|
||||||
|
ManaCost:2 G
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | NumAtt$ +4 | NumDef$ +4 | SpellDescription$ Target creature gets +4/+4 until end of turn.
|
||||||
|
K:Foretell:G
|
||||||
|
Oracle:Target creature gets +4/+4 until end of turn.\nForetell {G} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
10
forge-gui/res/cardsfolder/upcoming/niko_defies_destiny.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/niko_defies_destiny.txt
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
Name:Niko Defies Destiny
|
||||||
|
ManaCost:1 W U
|
||||||
|
Types:Enchantment Saga
|
||||||
|
K:Saga:3:DBGainLife,DBMana,DBChangeZone
|
||||||
|
SVar:DBGainLife:DB$ GainLife | LifeAmount$ X | References$ X | SpellDescription$ You gain 2 life for each foretold card you own in exile.
|
||||||
|
SVar:X:Count$ValidExile Card.foretold/Times.2
|
||||||
|
SVar:DBMana:DB$ Mana | Produced$ W U | RestrictValid$ Static.Foretelling,Card.withForetell | SpellDescription$ Add {W}{U}. Spend this mana only to foretell cards or cast spells that have foretell.
|
||||||
|
SVar:DBChangeZone:DB$ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Card.YouCtrl+withForetell | SpellDescription$ Return target card with foretell from your graveyard to your hand.
|
||||||
|
DeckHas:Ability$Graveyard & Ability$GainLife
|
||||||
|
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI — You gain 2 life for each foretold card you own in exile.\nII — Add {W}{U}. Spend this mana only to foretell cards or cast spells that have foretell.\nIII — Return target card with foretell from your graveyard to your hand.
|
||||||
14
forge-gui/res/cardsfolder/upcoming/old_growth_troll.txt
Normal file
14
forge-gui/res/cardsfolder/upcoming/old_growth_troll.txt
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
Name:Old-Growth Troll
|
||||||
|
ManaCost:G G G
|
||||||
|
Types:Creature Troll Warrior
|
||||||
|
PT:4/4
|
||||||
|
K:Trample
|
||||||
|
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self+Creature | TriggerController$ TriggeredCardController | Execute$ DBReturn | TriggerDescription$ When CARDNAME dies, if it was a creature. return it to the battlefield. It's an Aura enchantment with enchant Forest you control and “Enchanted Forest has ‘{T}: Add {G}{G}’ and ‘{1}, {T}, Sacrifice this land: Create a tapped 4/4 green Troll Warrior creature token with trample.’”
|
||||||
|
SVar:DBReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Battlefield | AnimateSubAbility$ DBAnimate
|
||||||
|
SVar:DBAnimate:DB$ Animate | Defined$ Remembered | Types$ Enchantment,Aura | RemoveCardTypes$ True | RemoveAllAbilities$ True | Keywords$ Enchant Forest you control | Abilities$ SPAttach | staticAbilities$ STAura | Permanent$ True
|
||||||
|
SVar:STAura:Mode$ Continuous | Affected$ Land.EnchantedBy | AddAbility$ ABMana & ABToken | Description$ Enchanted Forest has ‘{T}: Add {G}{G}’ and ‘{1}, {T}, Sacrifice this land: Create a tapped 4/4 green Troll Warrior creature token with trample.’
|
||||||
|
SVar:SPAttach:SP$ Attach | Cost$ 0 | ValidTgts$ Forest.YouCtrl | AILogic$ Pump
|
||||||
|
SVar:ABMana:AB$ Mana | Cost$ T | Produced$ G | Amount$ 2 | SpellDescription$ Add {G}{G}.
|
||||||
|
SVar:ABToken:AB$ Token | Cost$ 1 T Sac<1/CARDNAME> | TokenAmount$1 | TokenScript$ g_4_4_troll_warrior_trample | TokenOwner$ You | LegacyImage$ g 4 4 troll warrior trample khm | TokenTapped$ True | SpellDescription$ Create a tapped 4/4 green Troll Warrior creature token with trample.
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:Trample\nWhen Old-Growth Troll dies, if it was a creature, return it to the battlefield. It’s an Aura enchantment with enchant Forest you control and “Enchanted Forest has ‘{T}: Add {G}{G}’ and ‘{1}, {T}, Sacrifice this land: Create a tapped 4/4 green Troll Warrior creature token with trample.’”
|
||||||
8
forge-gui/res/cardsfolder/upcoming/poison_the_cup.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/poison_the_cup.txt
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Poison the Cup
|
||||||
|
ManaCost:1 B B
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Destroy | Cost$ 1 B B | ValidTgts$ Creature | TgtPrompt$ Select target creature | SubAbility$ DBScry | SpellDescription$ Destroy target creature. If this spell was foretold, scry 2.
|
||||||
|
SVar:DBScry:DB$ Scry | ScryNum$ 2 | Condition$ Foretold
|
||||||
|
K:Foretell:1 B
|
||||||
|
Oracle:Destroy target creature. If this spell was foretold, scry 2.\nForetell {1}{B} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
|
|
||||||
9
forge-gui/res/cardsfolder/upcoming/ravenform.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/ravenform.txt
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Ravenform
|
||||||
|
ManaCost:2 U
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ ChangeZone | Cost$ 2 U | ValidTgts$ Creature,Artifact | TgtPrompt$ Select target artifact or creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBToken | AILogic$ Pongify | SpellDescription$ Exile target artifact or creature. Its controller creates a 1/1 Blue bird creature token with flying.
|
||||||
|
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ u_1_1_bird_flying | TokenOwner$ TargetedController
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
K:Foretell:U
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:Exile target artifact or creature. Its controller creates a 1/1 Blue bird creature token with flying.\nForetell {U} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -6,9 +6,9 @@ K:Flying
|
|||||||
K:Vigilance
|
K:Vigilance
|
||||||
R:Event$ Moved | ValidCard$ Land.Snow+OppCtrl | Destination$ Battlefield | ReplaceWith$ ETBTapped | ActiveZones$ Battlefield | Description$ Snow lands your opponents control enter the battlefield tapped.
|
R:Event$ Moved | ValidCard$ Land.Snow+OppCtrl | Destination$ Battlefield | ReplaceWith$ ETBTapped | ActiveZones$ Battlefield | Description$ Snow lands your opponents control enter the battlefield tapped.
|
||||||
SVar:ETBTapped:DB$ ChangeZone | Origin$ All | Destination$ Battlefield | Tapped$ True | Defined$ ReplacedCard
|
SVar:ETBTapped:DB$ ChangeZone | Origin$ All | Destination$ Battlefield | Tapped$ True | Defined$ ReplacedCard
|
||||||
S:Mode$ RaiseCost | ValidCard$ Card.cmcGE4 | Type$ Spell | Activator$ Opponent | Amount$ 2 | Description$ Spells your opponents cast with converted mana cost 4 or greater cost {2} more to cast.
|
S:Mode$ RaiseCost | ValidCard$ Card.nonCreature+cmcGE4 | Type$ Spell | Activator$ Opponent | Amount$ 2 | Description$ Noncreature spells your opponents cast with converted mana cost 4 or greater cost {2} more to cast.
|
||||||
AlternateMode:Modal
|
AlternateMode:Modal
|
||||||
Oracle:Flying, vigilance\nSnow lands your opponents control enter the battlefield tapped.\nSpells your opponents cast with converted mana cost 4 or greater cost {2} more to cast.
|
Oracle:Flying, vigilance\nSnow lands your opponents control enter the battlefield tapped.\nNoncreature spells your opponents cast with converted mana cost 4 or greater cost {2} more to cast.
|
||||||
|
|
||||||
ALTERNATE
|
ALTERNATE
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
Name:Return Upon the Tide
|
||||||
|
ManaCost:4 B
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ ChangeZone | Cost$ 4 B | Origin$ Graveyard | Destination$ Battlefield | TgtPrompt$ Choose target creature card in your graveyard | ValidTgts$ Creature.YouCtrl | SubAbility$ DBToken | SpellDescription$ Return target creature card from your graveyard to the battlefield. If it's an Elf, create two 1/1 green Elf Warrior creature tokens.
|
||||||
|
SVar:DBToken:DB$ Token | TokenAmount$ 2 | TokenScript$ g_1_1_elf_warrior | LegacyImage$ g 1 1 elf warrior khm | TokenOwner$ You | ConditionCheckSVar$ X | ConditionSVarCompare$ GE1 | References$ X
|
||||||
|
SVar:X:Targeted$Valid Elf
|
||||||
|
K:ForeTell:3 B
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:Return target creature card from your graveyard to the battlefield. If it's an Elf, create two 1/1 green Elf Warrior creature tokens.\nForetell {3}{B} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
Name:Rise of the Dread Marn
|
||||||
|
ManaCost:2 B
|
||||||
|
Types:Instant
|
||||||
|
A:SP$ Token | Cost$ 2 B | LegacyImage$ b 2 2 zombie berserker khm | TokenAmount$ X | References$ X | TokenScript$ b_2_2_zombie_berserker | TokenOwner$ You | SpellDescription$ Create X 2/2 black Zombie Berserker creature tokens, where X is the number of nontoken creatures that died this turn.
|
||||||
|
SVar:X:Count$ThisTurnEntered_Graveyard_from_Battlefield_Creature.nonToken
|
||||||
|
K:Foretell:B
|
||||||
|
DeckHas:Ability$Token
|
||||||
|
Oracle:Create X 2/2 black Zombie Berserker creature tokens, where X is the number of nontoken creatures that died this turn.\nForetell {B} (During your turn, you may pay {2} and exile this card from your hand face down. Cast it on a later turn for its foretell cost.)
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user