Merge remote-tracking branch 'upstream/master'

This commit is contained in:
CCTV-1
2020-03-08 16:11:00 +08:00
76 changed files with 4333 additions and 411 deletions

View File

@@ -1447,7 +1447,8 @@ public class ComputerUtilCard {
} }
if (pumpedDmg > dmg) { if (pumpedDmg > dmg) {
if ((!c.hasKeyword(Keyword.INFECT) && pumpedDmg >= opp.getLife()) if ((!c.hasKeyword(Keyword.INFECT) && pumpedDmg >= opp.getLife())
|| (c.hasKeyword(Keyword.INFECT) && opp.canReceiveCounters(CounterType.POISON) && pumpedDmg >= opp.getPoisonCounters())) { || (c.hasKeyword(Keyword.INFECT) && opp.canReceiveCounters(CounterType.POISON) && pumpedDmg >= opp.getPoisonCounters())
|| ("PumpForTrample".equals(sa.getParam("AILogic")))) {
return true; return true;
} }
} }

View File

@@ -34,12 +34,12 @@ import forge.game.card.CardCollectionView;
import forge.game.card.CardLists; import forge.game.card.CardLists;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.player.PlayerCollection;
import forge.game.player.PlayerPredicates; import forge.game.player.PlayerPredicates;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions; import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.Aggregates; import forge.util.Aggregates;
import forge.util.collect.FCollectionView;
//AB:GainControl|ValidTgts$Creature|TgtPrompt$Select target legendary creature|LoseControl$Untap,LoseControl|SpellDescription$Gain control of target xxxxxxx //AB:GainControl|ValidTgts$Creature|TgtPrompt$Select target legendary creature|LoseControl$Untap,LoseControl|SpellDescription$Gain control of target xxxxxxx
@@ -54,8 +54,6 @@ import forge.util.collect.FCollectionView;
// (as a "&"-separated list; like Haste, Sacrifice CARDNAME at EOT, any standard keyword) // (as a "&"-separated list; like Haste, Sacrifice CARDNAME at EOT, any standard keyword)
// OppChoice - set to True if opponent chooses creature (for Preacher) - not implemented yet // OppChoice - set to True if opponent chooses creature (for Preacher) - not implemented yet
// Untap - set to True if target card should untap when control is taken // Untap - set to True if target card should untap when control is taken
// DestroyTgt - actions upon which the tgt should be destroyed. same list as LoseControl
// NoRegen - set if destroyed creature can't be regenerated. used only with DestroyTgt
/** /**
* <p> * <p>
@@ -77,7 +75,7 @@ public class ControlGainAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions(); final TargetRestrictions tgt = sa.getTargetRestrictions();
final Game game = ai.getGame(); final Game game = ai.getGame();
final FCollectionView<Player> opponents = ai.getOpponents(); final PlayerCollection opponents = ai.getOpponents();
// if Defined, then don't worry about targeting // if Defined, then don't worry about targeting
if (tgt == null) { if (tgt == null) {
@@ -94,18 +92,19 @@ public class ControlGainAi extends SpellAbilityAi {
sa.setTargetingPlayer(targetingPlayer); sa.setTargetingPlayer(targetingPlayer);
return targetingPlayer.getController().chooseTargetsFor(sa); return targetingPlayer.getController().chooseTargetsFor(sa);
} }
if (tgt.isRandomTarget()) {
sa.getTargets().add(Aggregates.random(tgt.getAllCandidates(sa, false)));
}
if (tgt.canOnlyTgtOpponent()) { if (tgt.canOnlyTgtOpponent()) {
List<Player> oppList = Lists List<Player> oppList = opponents.filter(PlayerPredicates.isTargetableBy(sa));
.newArrayList(Iterables.filter(opponents, PlayerPredicates.isTargetableBy(sa)));
if (oppList.isEmpty()) { if (oppList.isEmpty()) {
return false; return false;
} }
sa.getTargets().add(oppList.get(0)); if (tgt.isRandomTarget()) {
sa.getTargets().add(Aggregates.random(oppList));
} else {
sa.getTargets().add(oppList.get(0));
}
} }
} }

View File

@@ -1,7 +1,7 @@
package forge.ai.ability; package forge.ai.ability;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.ai.*; import forge.ai.*;
import forge.game.Game; import forge.game.Game;
@@ -12,11 +12,9 @@ import forge.game.card.CardPredicates;
import forge.game.combat.Combat; import forge.game.combat.Combat;
import forge.game.combat.CombatUtil; import forge.game.combat.CombatUtil;
import forge.game.keyword.Keyword; import forge.game.keyword.Keyword;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
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.game.zone.ZoneType; import forge.game.zone.ZoneType;
import java.util.List; import java.util.List;
@@ -28,7 +26,6 @@ public class MustBlockAi extends SpellAbilityAi {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final Game game = aiPlayer.getGame(); final Game game = aiPlayer.getGame();
final Combat combat = game.getCombat(); final Combat combat = game.getCombat();
final PhaseHandler ph = game.getPhaseHandler();
final boolean onlyLethal = !"AllowNonLethal".equals(sa.getParam("AILogic")); final boolean onlyLethal = !"AllowNonLethal".equals(sa.getParam("AILogic"));
if (combat == null || !combat.isAttacking(source)) { if (combat == null || !combat.isAttacking(source)) {
@@ -39,7 +36,6 @@ public class MustBlockAi extends SpellAbilityAi {
return false; return false;
} }
final TargetRestrictions abTgt = sa.getTargetRestrictions();
final List<Card> list = determineGoodBlockers(source, aiPlayer, combat.getDefenderPlayerByAttacker(source), sa, onlyLethal,false); final List<Card> list = determineGoodBlockers(source, aiPlayer, combat.getDefenderPlayerByAttacker(source), sa, onlyLethal,false);
if (!list.isEmpty()) { if (!list.isEmpty()) {
@@ -69,7 +65,6 @@ public class MustBlockAi extends SpellAbilityAi {
@Override @Override
protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) { protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) {
final Card source = sa.getHostCard(); final Card source = sa.getHostCard();
final TargetRestrictions abTgt = sa.getTargetRestrictions();
// only use on creatures that can attack // only use on creatures that can attack
if (!ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) { if (!ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) {
@@ -94,7 +89,7 @@ public class MustBlockAi extends SpellAbilityAi {
boolean chance = false; boolean chance = false;
if (abTgt != null) { if (sa.usesTargeting()) {
final List<Card> list = determineGoodBlockers(definedAttacker, ai, ai.getWeakestOpponent(), sa, true,true); final List<Card> list = determineGoodBlockers(definedAttacker, ai, ai.getWeakestOpponent(), sa, true,true);
if (list.isEmpty()) { if (list.isEmpty()) {
return false; return false;
@@ -119,6 +114,9 @@ public class MustBlockAi extends SpellAbilityAi {
sa.getTargets().add(blocker); sa.getTargets().add(blocker);
chance = true; chance = true;
} else if (sa.hasParam("Choices")) {
// currently choice is attacked player
return true;
} else { } else {
return false; return false;
} }
@@ -126,16 +124,9 @@ public class MustBlockAi extends SpellAbilityAi {
return chance; return chance;
} }
private List<Card> determineGoodBlockers(final Card attacker, final Player ai, Player defender, SpellAbility sa, private List<Card> determineBlockerFromList(final Card attacker, final Player ai, Iterable<Card> options, SpellAbility sa,
final boolean onlyLethal, final boolean testTapped) { final boolean onlyLethal, final boolean testTapped) {
final Card source = sa.getHostCard(); List<Card> list = CardLists.filter(options, new Predicate<Card>() {
final TargetRestrictions abTgt = sa.getTargetRestrictions();
List<Card> list = Lists.newArrayList();
list = CardLists.filter(defender.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
list = CardLists.getTargetableCards(list, sa);
list = CardLists.getValidCards(list, abTgt.getValidTgts(), source.getController(), source, sa);
list = CardLists.filter(list, new Predicate<Card>() {
@Override @Override
public boolean apply(final Card c) { public boolean apply(final Card c) {
boolean tapped = c.isTapped(); boolean tapped = c.isTapped();
@@ -161,4 +152,40 @@ public class MustBlockAi extends SpellAbilityAi {
return list; return list;
} }
private List<Card> determineGoodBlockers(final Card attacker, final Player ai, Player defender, SpellAbility sa,
final boolean onlyLethal, final boolean testTapped) {
List<Card> list = Lists.newArrayList();
list = CardLists.filter(defender.getCardsIn(ZoneType.Battlefield), CardPredicates.Presets.CREATURES);
if (sa.usesTargeting()) {
list = CardLists.getTargetableCards(list, sa);
}
return determineBlockerFromList(attacker, ai, list, sa, onlyLethal, testTapped);
}
@Override
protected Card chooseSingleCard(Player ai, SpellAbility sa, Iterable<Card> options, boolean isOptional,
Player targetedPlayer) {
final Card host = sa.getHostCard();
Card attacker = host;
if (sa.hasParam("DefinedAttacker")) {
List<Card> attackers = AbilityUtils.getDefinedCards(host, sa.getParam("DefinedAttacker"), sa);
attacker = Iterables.getFirst(attackers, null);
}
if (attacker == null) {
return Iterables.getFirst(options, null);
}
List<Card> better = determineBlockerFromList(attacker, ai, options, sa, false, false);
if (!better.isEmpty()) {
return Iterables.getFirst(options, null);
}
return Iterables.getFirst(options, null);
}
} }

View File

@@ -312,17 +312,21 @@ public final class CardDb implements ICardDatabase, IDeckGenPool {
return tryGetCard(request); return tryGetCard(request);
} }
public int getCardCollectorNumber(String cardName, String reqEdition) { public String getCardCollectorNumber(String cardName, String reqEdition, int artIndex) {
cardName = getName(cardName); cardName = getName(cardName);
CardEdition edition = editions.get(reqEdition); CardEdition edition = editions.get(reqEdition);
if (edition == null) if (edition == null)
return -1; return null;
int numMatches = 0;
for (CardInSet card : edition.getCards()) { for (CardInSet card : edition.getCards()) {
if (card.name.equalsIgnoreCase(cardName)) { if (card.name.equalsIgnoreCase(cardName)) {
return card.collectorNumber; numMatches += 1;
if (numMatches == artIndex) {
return card.collectorNumber;
}
} }
} }
return -1; return null;
} }
private PaperCard tryGetCard(CardRequest request) { private PaperCard tryGetCard(CardRequest request) {

View File

@@ -38,6 +38,8 @@ import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.*; import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/** /**
@@ -75,10 +77,10 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public static class CardInSet { public static class CardInSet {
public final CardRarity rarity; public final CardRarity rarity;
public final int collectorNumber; public final String collectorNumber;
public final String name; public final String name;
public CardInSet(final String name, final int collectorNumber, final CardRarity rarity) { public CardInSet(final String name, final String collectorNumber, final CardRarity rarity) {
this.name = name; this.name = name;
this.collectorNumber = collectorNumber; this.collectorNumber = collectorNumber;
this.rarity = rarity; this.rarity = rarity;
@@ -86,7 +88,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public String toString() { public String toString() {
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
if (collectorNumber != -1) { if (collectorNumber != null) {
sb.append(collectorNumber); sb.append(collectorNumber);
sb.append(' '); sb.append(' ');
} }
@@ -266,24 +268,23 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
Map<String, Integer> tokenNormalized = new HashMap<>(); Map<String, Integer> tokenNormalized = new HashMap<>();
List<CardEdition.CardInSet> processedCards = new ArrayList<>(); List<CardEdition.CardInSet> processedCards = new ArrayList<>();
if (contents.containsKey("cards")) { if (contents.containsKey("cards")) {
final Pattern pattern = Pattern.compile(
/*
The following pattern will match the WAR Japanese art entries,
it should also match the Un-set and older alternate art cards
like Merseine from FEM (should the editions files ever be updated)
*/
"(^(?<cnum>[0-9]+.?) )?((?<rarity>[SCURML]) )?(?<name>.*)$"
);
for(String line : contents.get("cards")) { for(String line : contents.get("cards")) {
if (StringUtils.isBlank(line)) Matcher matcher = pattern.matcher(line);
continue; if (matcher.matches()) {
String collectorNumber = matcher.group("cnum");
// Optional collector number at the start. CardRarity r = CardRarity.smartValueOf(matcher.group("rarity"));
String[] split = line.split(" ", 2); String cardName = matcher.group("name");
int collectorNumber = -1; CardInSet cis = new CardInSet(cardName, collectorNumber, r);
if (split.length >= 2 && StringUtils.isNumeric(split[0])) { processedCards.add(cis);
collectorNumber = Integer.parseInt(split[0]);
line = split[1];
} }
// You may omit rarity for early development
CardRarity r = CardRarity.smartValueOf(line.substring(0, 1));
boolean hadRarity = r != CardRarity.Unknown && line.charAt(1) == ' ';
String cardName = hadRarity ? line.substring(2) : line;
CardInSet cis = new CardInSet(cardName, collectorNumber, r);
processedCards.add(cis);
} }
} }

View File

@@ -73,7 +73,7 @@ public enum DeckFormat {
private final Set<String> bannedCards = ImmutableSet.of( private final Set<String> bannedCards = ImmutableSet.of(
"Ancestral Recall", "Balance", "Black Lotus", "Black Vise", "Channel", "Chaos Orb", "Contract From Below", "Counterbalance", "Darkpact", "Demonic Attorney", "Demonic Tutor", "Earthcraft", "Edric, Spymaster of Trest", "Falling Star", "Ancestral Recall", "Balance", "Black Lotus", "Black Vise", "Channel", "Chaos Orb", "Contract From Below", "Counterbalance", "Darkpact", "Demonic Attorney", "Demonic Tutor", "Earthcraft", "Edric, Spymaster of Trest", "Falling Star",
"Fastbond", "Flash", "Goblin Recruiter", "Grindstone", "Hermit Druid", "Imperial Seal", "Jeweled Bird", "Karakas", "Library of Alexandria", "Mana Crypt", "Mana Drain", "Mana Vault", "Metalworker", "Mind Twist", "Mishra's Workshop", "Fastbond", "Flash", "Goblin Recruiter", "Grindstone", "Hermit Druid", "Imperial Seal", "Jeweled Bird", "Karakas", "Library of Alexandria", "Mana Crypt", "Mana Drain", "Mana Vault", "Metalworker", "Mind Twist", "Mishra's Workshop",
"Mox Emerald", "Mox Jet", "Mox Pearl", "Mox Ruby", "Mox Sapphire", "Necropotence", "Shahrazad", "Skullclamp", "Sol Ring", "Strip Mine", "Survival of the Fittest", "Sword of Body and Mind", "Time Vault", "Time Walk", "Timetwister", "Mox Emerald", "Mox Jet", "Mox Pearl", "Mox Ruby", "Mox Sapphire", "Najeela, the Blade Blossom", "Necropotence", "Shahrazad", "Skullclamp", "Sol Ring", "Strip Mine", "Survival of the Fittest", "Sword of Body and Mind", "Time Vault", "Time Walk", "Timetwister",
"Timmerian Fiends", "Tolarian Academy", "Umezawa's Jitte", "Vampiric Tutor", "Wheel of Fortune", "Yawgmoth's Will"); "Timmerian Fiends", "Tolarian Academy", "Umezawa's Jitte", "Vampiric Tutor", "Wheel of Fortune", "Yawgmoth's Will");
@Override @Override

View File

@@ -375,7 +375,7 @@ public class GameAction {
// the LKI needs to be the Card itself, // the LKI needs to be the Card itself,
// or it might not updated correctly // or it might not updated correctly
// TODO be reworked when ZoneTrigger Update is done // TODO be reworked when ZoneTrigger Update is done
if (toBattlefield) { if (toBattlefield || zoneTo.is(ZoneType.Stack)) {
lastKnownInfo = c; lastKnownInfo = c;
} }
@@ -565,16 +565,31 @@ public class GameAction {
public final void controllerChangeZoneCorrection(final Card c) { public final void controllerChangeZoneCorrection(final Card c) {
System.out.println("Correcting zone for " + c.toString()); System.out.println("Correcting zone for " + c.toString());
final Zone oldBattlefield = game.getZoneOf(c); final Zone oldBattlefield = game.getZoneOf(c);
if (oldBattlefield == null || oldBattlefield.getZoneType() == ZoneType.Stack) {
if (oldBattlefield == null || oldBattlefield.is(ZoneType.Stack)) {
return; return;
} }
final Player original = oldBattlefield.getPlayer(); final Player original = oldBattlefield.getPlayer();
final PlayerZone newBattlefield = c.getController().getZone(oldBattlefield.getZoneType()); final Player controller = c.getController();
if (original == null || controller == null || original.equals(controller)) {
return;
}
final PlayerZone newBattlefield = controller.getZone(oldBattlefield.getZoneType());
if (newBattlefield == null || oldBattlefield.equals(newBattlefield)) { if (newBattlefield == null || oldBattlefield.equals(newBattlefield)) {
return; return;
} }
// 702.94e A paired creature becomes unpaired if any of the following occur:
// another player gains control of it or the creature its paired with
if (c.isPaired()) {
Card partner = c.getPairedWith();
c.setPairedWith(null);
partner.setPairedWith(null);
partner.updateStateForView();
}
game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
for (Player p : game.getPlayers()) { for (Player p : game.getPlayers()) {
((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(false); ((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(false);

View File

@@ -62,7 +62,9 @@ public class AttachEffect extends SpellAbilityEffect {
if (sa.hasParam("ChooseAnObject")) { if (sa.hasParam("ChooseAnObject")) {
Card c = p.getController().chooseSingleEntityForEffect(attachments, sa, sa.getParam("ChooseAnObject")); Card c = p.getController().chooseSingleEntityForEffect(attachments, sa, sa.getParam("ChooseAnObject"));
attachments.clear(); attachments.clear();
attachments.add(c); if (c != null) {
attachments.add(c);
}
} }
} else { } else {
attachments = new CardCollection(source); attachments = new CardCollection(source);

View File

@@ -6,7 +6,6 @@ import java.util.List;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import forge.GameCommand; import forge.GameCommand;
import forge.card.mana.ManaCost;
import forge.game.Game; import forge.game.Game;
import forge.game.GameEntity; import forge.game.GameEntity;
import forge.game.ability.AbilityUtils; import forge.game.ability.AbilityUtils;
@@ -18,7 +17,6 @@ import forge.game.combat.Combat;
import forge.game.event.GameEventCardStatsChanged; import forge.game.event.GameEventCardStatsChanged;
import forge.game.event.GameEventCombatChanged; import forge.game.event.GameEventCombatChanged;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.Ability;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.collect.FCollectionView; import forge.util.collect.FCollectionView;
@@ -26,9 +24,7 @@ import forge.util.Localizer;
import forge.util.CardTranslation; import forge.util.CardTranslation;
public class ControlGainEffect extends SpellAbilityEffect { public class ControlGainEffect extends SpellAbilityEffect {
/* (non-Javadoc)
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
*/
@Override @Override
protected String getStackDescription(SpellAbility sa) { protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder(); final StringBuilder sb = new StringBuilder();
@@ -67,15 +63,17 @@ public class ControlGainEffect extends SpellAbilityEffect {
if (null == c || c.hasKeyword("Other players can't gain control of CARDNAME.")) { if (null == c || c.hasKeyword("Other players can't gain control of CARDNAME.")) {
return; return;
} }
final Game game = host.getGame();
if (c.isInPlay()) { if (c.isInPlay()) {
c.removeTempController(tStamp); c.removeTempController(tStamp);
game.getAction().controllerChangeZoneCorrection(c);
if (tapOnLose) { if (tapOnLose) {
c.tap(); c.tap();
} }
} // if } // if
host.removeGainControlTargets(c); host.removeGainControlTargets(c);
} }
@Override @Override
@@ -84,11 +82,9 @@ public class ControlGainEffect extends SpellAbilityEffect {
final boolean bUntap = sa.hasParam("Untap"); final boolean bUntap = sa.hasParam("Untap");
final boolean bTapOnLose = sa.hasParam("TapOnLose"); final boolean bTapOnLose = sa.hasParam("TapOnLose");
final boolean bNoRegen = sa.hasParam("NoRegen");
final boolean remember = sa.hasParam("RememberControlled"); final boolean remember = sa.hasParam("RememberControlled");
final boolean forget = sa.hasParam("ForgetControlled"); final boolean forget = sa.hasParam("ForgetControlled");
final boolean attacking = sa.hasParam("Attacking"); final boolean attacking = sa.hasParam("Attacking");
final List<String> destroyOn = sa.hasParam("DestroyTgt") ? Arrays.asList(sa.getParam("DestroyTgt").split(",")) : null;
final List<String> keywords = sa.hasParam("AddKWs") ? Arrays.asList(sa.getParam("AddKWs").split(" & ")) : null; final List<String> keywords = sa.hasParam("AddKWs") ? Arrays.asList(sa.getParam("AddKWs").split(" & ")) : null;
final List<String> lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null; final List<String> lose = sa.hasParam("LoseControl") ? Arrays.asList(sa.getParam("LoseControl").split(",")) : null;
@@ -189,18 +185,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
} }
} }
if (destroyOn != null) {
if (destroyOn.contains("LeavesPlay")) {
sa.getHostCard().addLeavesPlayCommand(getDestroyCommand(tgtC, source, bNoRegen));
}
if (destroyOn.contains("Untap")) {
sa.getHostCard().addUntapCommand(getDestroyCommand(tgtC, source, bNoRegen));
}
if (destroyOn.contains("LoseControl")) {
sa.getHostCard().addChangeControllerCommand(getDestroyCommand(tgtC, source, bNoRegen));
}
}
if (keywords != null) { if (keywords != null) {
// Add keywords only until end of turn // Add keywords only until end of turn
final GameCommand untilKeywordEOT = new GameCommand() { final GameCommand untilKeywordEOT = new GameCommand() {
@@ -241,43 +225,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
} // end foreach target } // end foreach target
} }
/**
* <p>
* getDestroyCommand.
* </p>
*
* @param i
* a int.
* @return a {@link forge.GameCommand} object.
*/
private static GameCommand getDestroyCommand(final Card c, final Card hostCard, final boolean bNoRegen) {
final GameCommand destroy = new GameCommand() {
private static final long serialVersionUID = 878543373519872418L;
@Override
public void run() {
final Game game = hostCard.getGame();
final Ability ability = new Ability(hostCard, ManaCost.ZERO) {
@Override
public void resolve() {
game.getAction().destroy(c, null, !bNoRegen, null);
}
};
final StringBuilder sb = new StringBuilder();
sb.append(hostCard).append(" - destroy ").append(c.getName()).append(".");
if (bNoRegen) {
sb.append(" It can't be regenerated.");
}
ability.setStackDescription(sb.toString());
ability.setTrigger(true);
game.getStack().addSimultaneousStackEntry(ability);
}
};
return destroy;
}
/** /**
* <p> * <p>
* getLoseControlCommand. * getLoseControlCommand.

View File

@@ -1,34 +1,62 @@
package forge.game.ability.effects; package forge.game.ability.effects;
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.card.CardCollectionView;
import forge.game.card.CardLists;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions; import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import com.google.common.collect.Lists;
public class MustBlockEffect extends SpellAbilityEffect { public class MustBlockEffect extends SpellAbilityEffect {
@Override @Override
public void resolve(SpellAbility sa) { public void resolve(SpellAbility sa) {
final Card host = sa.getHostCard(); final Card host = sa.getHostCard();
final Player activator = sa.getActivatingPlayer();
final Game game = activator.getGame();
List<Card> tgtCards = Lists.newArrayList();
if (sa.hasParam("Choices")) {
Player chooser = activator;
if (sa.hasParam("Chooser")) {
final String choose = sa.getParam("Chooser");
chooser = AbilityUtils.getDefinedPlayers(sa.getHostCard(), choose, sa).get(0);
}
CardCollectionView choices = game.getCardsIn(ZoneType.Battlefield);
choices = CardLists.getValidCards(choices, sa.getParam("Choices"), activator, host);
if (!choices.isEmpty()) {
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") +" ";
Card choosen = chooser.getController().chooseSingleEntityForEffect(choices, sa, title, false);
if (choosen != null) {
tgtCards.add(choosen);
}
}
} else {
tgtCards = getTargetCards(sa);
}
List<Card> tgtCards = getTargetCards(sa);
final TargetRestrictions tgt = sa.getTargetRestrictions();
final boolean mustBlockAll = sa.hasParam("BlockAllDefined"); final boolean mustBlockAll = sa.hasParam("BlockAllDefined");
List<Card> cards; List<Card> cards;
if (sa.hasParam("DefinedAttacker")) { if (sa.hasParam("DefinedAttacker")) {
cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("DefinedAttacker"), sa); cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("DefinedAttacker"), sa);
} else { } else {
cards = new ArrayList<>(); cards = Lists.newArrayList(host);
cards.add(host);
} }
for (final Card c : tgtCards) { for (final Card c : tgtCards) {
if ((tgt == null) || c.canBeTargetedBy(sa)) { if ((!sa.usesTargeting()) || c.canBeTargetedBy(sa)) {
if (mustBlockAll) { if (mustBlockAll) {
c.addMustBlockCards(cards); c.addMustBlockCards(cards);
} else { } else {
@@ -48,8 +76,6 @@ public class MustBlockEffect extends SpellAbilityEffect {
// end standard pre- // end standard pre-
final List<Card> tgtCards = getTargetCards(sa);
String attacker = null; String attacker = null;
if (sa.hasParam("DefinedAttacker")) { if (sa.hasParam("DefinedAttacker")) {
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("DefinedAttacker"), sa); final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("DefinedAttacker"), sa);
@@ -58,10 +84,13 @@ public class MustBlockEffect extends SpellAbilityEffect {
attacker = host.toString(); attacker = host.toString();
} }
for (final Card c : tgtCards) { if (sa.hasParam("Choices")) {
sb.append(c).append(" must block ").append(attacker).append(" if able."); sb.append("Choosen creature ").append(" must block ").append(attacker).append(" if able.");
} else {
for (final Card c : getTargetCards(sa)) {
sb.append(c).append(" must block ").append(attacker).append(" if able.");
}
} }
return sb.toString(); return sb.toString();
} }

View File

@@ -1518,27 +1518,38 @@ public class CardProperty {
} else if (property.startsWith("blockedByThisTurn")) { } else if (property.startsWith("blockedByThisTurn")) {
return !card.getBlockedByThisTurn().isEmpty(); return !card.getBlockedByThisTurn().isEmpty();
} else if (property.startsWith("blockedValidThisTurn ")) { } else if (property.startsWith("blockedValidThisTurn ")) {
if (card.getBlockedThisTurn() == null) { CardCollectionView blocked = card.getBlockedThisTurn();
if (blocked == null) {
return false; return false;
} }
String valid = property.split(" ")[1]; String valid = property.split(" ")[1];
for(Card c : card.getBlockedThisTurn()) { for(Card c : blocked) {
if (c.isValid(valid, card.getController(), source, spellAbility)) { if (c.isValid(valid, card.getController(), source, spellAbility)) {
return true; return true;
} }
} }
for(Card c : AbilityUtils.getDefinedCards(source, valid, spellAbility)) {
if (blocked.contains(c)) {
return true;
}
};
return false; return false;
} else if (property.startsWith("blockedByValidThisTurn ")) { } else if (property.startsWith("blockedByValidThisTurn ")) {
if (card.getBlockedByThisTurn() == null) { CardCollectionView blocked = card.getBlockedByThisTurn();
if (blocked == null) {
return false; return false;
} }
String valid = property.split(" ")[1]; String valid = property.split(" ")[1];
for(Card c : card.getBlockedByThisTurn()) { for(Card c : blocked) {
if (c.isValid(valid, card.getController(), source, spellAbility)) { if (c.isValid(valid, card.getController(), source, spellAbility)) {
return true; return true;
} }
} }
for(Card c : AbilityUtils.getDefinedCards(source, valid, spellAbility)) {
if (blocked.contains(c)) {
return true;
}
};
return false; return false;
} else if (property.startsWith("blockedBySourceThisTurn")) { } else if (property.startsWith("blockedBySourceThisTurn")) {
return source.getBlockedByThisTurn().contains(card); return source.getBlockedByThisTurn().contains(card);
@@ -1779,4 +1790,4 @@ public class CardProperty {
return true; return true;
} }
} }

View File

@@ -100,17 +100,21 @@ public class TrackableTypes {
if (newCollection != null) { if (newCollection != null) {
//swap in objects in old collection for objects in new collection //swap in objects in old collection for objects in new collection
for (int i = 0; i < newCollection.size(); i++) { for (int i = 0; i < newCollection.size(); i++) {
T newObj = newCollection.get(i); try {
if (newObj != null) { T newObj = newCollection.get(i);
T existingObj = from.getTracker().getObj(itemType, newObj.getId()); if (newObj != null) {
if (existingObj != null) { //if object exists already, update its changed properties T existingObj = from.getTracker().getObj(itemType, newObj.getId());
existingObj.copyChangedProps(newObj); if (existingObj != null) { //if object exists already, update its changed properties
newCollection.remove(i); existingObj.copyChangedProps(newObj);
newCollection.add(i, existingObj); newCollection.remove(i);
} newCollection.add(i, existingObj);
else { //if object is new, cache in object lookup }
from.getTracker().putObj(itemType, newObj.getId(), newObj); else { //if object is new, cache in object lookup
from.getTracker().putObj(itemType, newObj.getId(), newObj);
}
} }
} catch (IndexOutOfBoundsException e) {
System.err.println("got an IndexOutOfBoundsException, trying to continue ...");
} }
} }
} }

View File

@@ -1162,7 +1162,7 @@ public class FSkin {
} }
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
FView.SINGLETON_INSTANCE.setSplashProgessBarMessage(localizer.getMessage("splash.loading.processingimagesprites") + ": ", 8); FView.SINGLETON_INSTANCE.setSplashProgessBarMessage(localizer.getMessage("splash.loading.processingimagesprites") + ": ", 12);
// Grab and test various sprite files. // Grab and test various sprite files.
final String defaultDir = ForgeConstants.DEFAULT_SKINS_DIR; final String defaultDir = ForgeConstants.DEFAULT_SKINS_DIR;

View File

@@ -90,6 +90,10 @@ public class FSkin {
public static void loadLight(String skinName, final SplashScreen splashScreen) { public static void loadLight(String skinName, final SplashScreen splashScreen) {
preferredName = skinName.toLowerCase().replace(' ', '_'); preferredName = skinName.toLowerCase().replace(' ', '_');
//reset hd buttons/icons
Forge.hdbuttons = false;
Forge.hdstart = false;
//ensure skins directory exists //ensure skins directory exists
final FileHandle dir = Gdx.files.absolute(ForgeConstants.SKINS_DIR); final FileHandle dir = Gdx.files.absolute(ForgeConstants.SKINS_DIR);
if (!dir.exists() || !dir.isDirectory()) { if (!dir.exists() || !dir.isDirectory()) {
@@ -205,21 +209,21 @@ public class FSkin {
textures.put(f6.path(), textures.get(f3.path())); textures.put(f6.path(), textures.get(f3.path()));
} }
if (f7.exists()){ if (f7.exists()){
Texture t = new Texture(f7, true); Texture t = new Texture(f7, false);
t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); //t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f7.path(), t); textures.put(f7.path(), t);
} }
//hdbuttons //hdbuttons
if (f11.exists()) { if (f11.exists()) {
Texture tf11 = new Texture(f11, true); Texture t = new Texture(f11, true);
tf11.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f11.path(), tf11); textures.put(f11.path(), t);
Forge.hdbuttons = true; Forge.hdbuttons = true;
} else { Forge.hdbuttons = false; } //how to refresh buttons when a theme don't have hd buttons? } else { Forge.hdbuttons = false; } //how to refresh buttons when a theme don't have hd buttons?
if (f12.exists()) { if (f12.exists()) {
Texture tf12 = new Texture(f12, true); Texture t = new Texture(f12, true);
tf12.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear); t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f12.path(), tf12); textures.put(f12.path(), t);
Forge.hdstart = true; Forge.hdstart = true;
} else { Forge.hdstart = false; } } else { Forge.hdstart = false; }
//update colors //update colors

View File

@@ -28,7 +28,7 @@ public enum FSkinImage implements FImage {
HDEXILE (FSkinProp.IMG_HDZONE_EXILE, SourceFile.BUTTONS), HDEXILE (FSkinProp.IMG_HDZONE_EXILE, SourceFile.BUTTONS),
FLASHBACK (FSkinProp.IMG_ZONE_FLASHBACK, SourceFile.ICONS), FLASHBACK (FSkinProp.IMG_ZONE_FLASHBACK, SourceFile.ICONS),
HDFLASHBACK (FSkinProp.IMG_HDZONE_FLASHBACK, SourceFile.BUTTONS), HDFLASHBACK (FSkinProp.IMG_HDZONE_FLASHBACK, SourceFile.BUTTONS),
GRAVEYARD (FSkinProp.IMG_ZONE_GRAVEYARD, SourceFile.ICONS), GRAVEYARD (FSkinProp.IMG_ZONE_GRAVEYARD, SourceFile.ICONS),
HDGRAVEYARD (FSkinProp.IMG_HDZONE_GRAVEYARD, SourceFile.BUTTONS), HDGRAVEYARD (FSkinProp.IMG_HDZONE_GRAVEYARD, SourceFile.BUTTONS),
@@ -126,6 +126,14 @@ public enum FSkinImage implements FImage {
ARCSON (FSkinProp.ICO_ARCSON, SourceFile.ICONS), ARCSON (FSkinProp.ICO_ARCSON, SourceFile.ICONS),
ARCSHOVER (FSkinProp.ICO_ARCSHOVER, SourceFile.ICONS), ARCSHOVER (FSkinProp.ICO_ARCSHOVER, SourceFile.ICONS),
//choice-search-misc
HDCHOICE (FSkinProp.ICO_HDCHOICE, SourceFile.BUTTONS),
HDSIDEBOARD (FSkinProp.ICO_HDSIDEBOARD, SourceFile.BUTTONS),
HDPREFERENCE (FSkinProp.ICO_HDPREFERENCE, SourceFile.BUTTONS),
HDIMPORT (FSkinProp.ICO_HDIMPORT, SourceFile.BUTTONS),
HDEXPORT (FSkinProp.ICO_HDEXPORT, SourceFile.BUTTONS),
BLANK (FSkinProp.ICO_BLANK, SourceFile.ICONS),
//Achievement Trophies //Achievement Trophies
COMMON_TROPHY (FSkinProp.IMG_COMMON_TROPHY, SourceFile.TROPHIES), COMMON_TROPHY (FSkinProp.IMG_COMMON_TROPHY, SourceFile.TROPHIES),
UNCOMMON_TROPHY (FSkinProp.IMG_UNCOMMON_TROPHY, SourceFile.TROPHIES), UNCOMMON_TROPHY (FSkinProp.IMG_UNCOMMON_TROPHY, SourceFile.TROPHIES),
@@ -168,6 +176,22 @@ public enum FSkinImage implements FImage {
QUEST_MINUS (FSkinProp.ICO_QUEST_MINUS, SourceFile.ICONS), QUEST_MINUS (FSkinProp.ICO_QUEST_MINUS, SourceFile.ICONS),
QUEST_PLUS (FSkinProp.ICO_QUEST_PLUS, SourceFile.ICONS), QUEST_PLUS (FSkinProp.ICO_QUEST_PLUS, SourceFile.ICONS),
QUEST_PLUSPLUS (FSkinProp.ICO_QUEST_PLUSPLUS, SourceFile.ICONS), QUEST_PLUSPLUS (FSkinProp.ICO_QUEST_PLUSPLUS, SourceFile.ICONS),
QUEST_BIG_ELIXIR (FSkinProp.ICO_QUEST_BIG_ELIXIR, SourceFile.ICONS),
QUEST_BIG_BREW (FSkinProp.ICO_QUEST_BIG_BREW, SourceFile.ICONS),
QUEST_BIG_BM (FSkinProp.ICO_QUEST_BIG_BM, SourceFile.ICONS),
QUEST_BIG_STAKES (FSkinProp.ICO_QUEST_BIG_STAKES, SourceFile.ICONS),
QUEST_BIG_HOUSE (FSkinProp.ICO_QUEST_BIG_HOUSE, SourceFile.ICONS),
QUEST_BIG_COIN (FSkinProp.ICO_QUEST_BIG_COIN, SourceFile.ICONS),
QUEST_BIG_BOOK (FSkinProp.ICO_QUEST_BIG_BOOK, SourceFile.ICONS),
QUEST_BIG_MAP (FSkinProp.ICO_QUEST_BIG_MAP, SourceFile.ICONS),
QUEST_BIG_ZEP (FSkinProp.ICO_QUEST_BIG_ZEP, SourceFile.ICONS),
QUEST_BIG_CHARM (FSkinProp.ICO_QUEST_BIG_CHARM, SourceFile.ICONS),
QUEST_BIG_BOOTS (FSkinProp.ICO_QUEST_BIG_BOOTS, SourceFile.ICONS),
QUEST_BIG_SHIELD (FSkinProp.ICO_QUEST_BIG_SHIELD, SourceFile.ICONS),
QUEST_BIG_ARMOR (FSkinProp.ICO_QUEST_BIG_ARMOR, SourceFile.ICONS),
QUEST_BIG_AXE (FSkinProp.ICO_QUEST_BIG_AXE, SourceFile.ICONS),
QUEST_BIG_SWORD (FSkinProp.ICO_QUEST_BIG_SWORD, SourceFile.ICONS),
QUEST_BIG_BAG (FSkinProp.ICO_QUEST_BIG_BAG, SourceFile.ICONS),
//Interface icons //Interface icons
QUESTION (FSkinProp.ICO_QUESTION, SourceFile.ICONS), QUESTION (FSkinProp.ICO_QUESTION, SourceFile.ICONS),
@@ -241,7 +265,9 @@ public enum FSkinImage implements FImage {
ENCHANTMENT (FSkinProp.IMG_ENCHANTMENT, SourceFile.MANAICONS), ENCHANTMENT (FSkinProp.IMG_ENCHANTMENT, SourceFile.MANAICONS),
INSTANT (FSkinProp.IMG_INSTANT, SourceFile.MANAICONS), INSTANT (FSkinProp.IMG_INSTANT, SourceFile.MANAICONS),
LAND (FSkinProp.IMG_LAND, SourceFile.MANAICONS), LAND (FSkinProp.IMG_LAND, SourceFile.MANAICONS),
LANDLOGO (FSkinProp.IMG_LANDLOGO, SourceFile.MANAICONS),
MULTI (FSkinProp.IMG_MULTI, SourceFile.ICONS), MULTI (FSkinProp.IMG_MULTI, SourceFile.ICONS),
HDMULTI (FSkinProp.IMG_HDMULTI, SourceFile.MANAICONS),
PLANESWALKER (FSkinProp.IMG_PLANESWALKER, SourceFile.MANAICONS), PLANESWALKER (FSkinProp.IMG_PLANESWALKER, SourceFile.MANAICONS),
PACK (FSkinProp.IMG_PACK, SourceFile.ICONS), PACK (FSkinProp.IMG_PACK, SourceFile.ICONS),
SORCERY (FSkinProp.IMG_SORCERY, SourceFile.MANAICONS), SORCERY (FSkinProp.IMG_SORCERY, SourceFile.MANAICONS),

View File

@@ -6,6 +6,7 @@ import java.util.List;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import forge.Forge;
import forge.Graphics; import forge.Graphics;
import forge.assets.FImage; import forge.assets.FImage;
import forge.assets.FSkinFont; import forge.assets.FSkinFont;
@@ -27,7 +28,7 @@ public class GameEntityPicker extends TabPageScreen<GameEntityPicker> {
public GameEntityPicker(String title, Collection<? extends GameEntityView> choiceList, Collection<CardView> revealList, String revealListCaption, FImage revealListImage, boolean isOptional, final Callback<GameEntityView> callback) { public GameEntityPicker(String title, Collection<? extends GameEntityView> choiceList, Collection<CardView> revealList, String revealListCaption, FImage revealListImage, boolean isOptional, final Callback<GameEntityView> callback) {
super(new PickerTab[] { super(new PickerTab[] {
new PickerTab(choiceList, Localizer.getInstance().getMessage("lblChoices"), FSkinImage.DECKLIST, 1), new PickerTab(choiceList, Localizer.getInstance().getMessage("lblChoices"), Forge.hdbuttons ? FSkinImage.HDCHOICE : FSkinImage.DECKLIST, 1),
new PickerTab(revealList, revealListCaption, revealListImage, 0) new PickerTab(revealList, revealListCaption, revealListImage, 0)
}, false); }, false);

View File

@@ -44,8 +44,8 @@ import java.util.*;
import java.util.Map.Entry; import java.util.Map.Entry;
public class FDeckEditor extends TabPageScreen<FDeckEditor> { public class FDeckEditor extends TabPageScreen<FDeckEditor> {
public static FSkinImage MAIN_DECK_ICON = FSkinImage.DECKLIST; public static FSkinImage MAIN_DECK_ICON = Forge.hdbuttons ? FSkinImage.HDLIBRARY :FSkinImage.DECKLIST;
public static FSkinImage SIDEBOARD_ICON = FSkinImage.FLASHBACK; public static FSkinImage SIDEBOARD_ICON = Forge.hdbuttons ? FSkinImage.HDSIDEBOARD : FSkinImage.FLASHBACK;
private static final float HEADER_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.8f); private static final float HEADER_HEIGHT = Math.round(Utils.AVG_FINGER_HEIGHT * 0.8f);
public enum EditorType { public enum EditorType {
@@ -332,7 +332,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
protected void buildMenu() { protected void buildMenu() {
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();
addItem(new FMenuItem(localizer.getMessage("lblAddBasicLands"), FSkinImage.LAND, new FEventHandler() { addItem(new FMenuItem(localizer.getMessage("lblAddBasicLands"), FSkinImage.LANDLOGO, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
CardEdition defaultLandSet; CardEdition defaultLandSet;
@@ -365,7 +365,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
} }
})); }));
if (!isLimitedEditor()) { if (!isLimitedEditor()) {
addItem(new FMenuItem(localizer.getMessage("lblImportFromClipboard"), Forge.hdbuttons ? FSkinImage.HDOPEN : FSkinImage.OPEN, new FEventHandler() { addItem(new FMenuItem(localizer.getMessage("lblImportFromClipboard"), Forge.hdbuttons ? FSkinImage.HDIMPORT : FSkinImage.OPEN, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
FDeckImportDialog dialog = new FDeckImportDialog(!deck.isEmpty(), new Callback<Deck>() { FDeckImportDialog dialog = new FDeckImportDialog(!deck.isEmpty(), new Callback<Deck>() {
@@ -430,7 +430,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
} }
})); }));
} }
addItem(new FMenuItem(localizer.getMessage("btnCopyToClipboard"), new FEventHandler() { addItem(new FMenuItem(localizer.getMessage("btnCopyToClipboard"), Forge.hdbuttons ? FSkinImage.HDEXPORT : FSkinImage.BLANK, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
FDeckViewer.copyDeckToClipboard(deck); FDeckViewer.copyDeckToClipboard(deck);
@@ -1187,7 +1187,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
//if card has more than one art option, add item to change user's preferred art //if card has more than one art option, add item to change user's preferred art
final List<PaperCard> artOptions = FModel.getMagicDb().getCommonCards().getAllCards(card.getName()); final List<PaperCard> artOptions = FModel.getMagicDb().getCommonCards().getAllCards(card.getName());
if (artOptions != null && artOptions.size() > 1) { if (artOptions != null && artOptions.size() > 1) {
menu.addItem(new FMenuItem(localizer.getMessage("lblChangePreferredArt"), FSkinImage.SETTINGS, new FEventHandler() { menu.addItem(new FMenuItem(localizer.getMessage("lblChangePreferredArt"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
//sort options so current option is on top and selected by default //sort options so current option is on top and selected by default

View File

@@ -92,7 +92,7 @@ public abstract class ItemManager<T extends InventoryItem> extends FContainer im
.iconScaleFactor(0.9f).build(); //icon set later .iconScaleFactor(0.9f).build(); //icon set later
private final FLabel btnAdvancedSearchOptions = new FLabel.Builder() private final FLabel btnAdvancedSearchOptions = new FLabel.Builder()
.selectable(true).align(Align.center) .selectable(true).align(Align.center)
.icon(FSkinImage.SETTINGS).iconScaleFactor(0.9f) .icon(Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS).iconScaleFactor(0.9f)
.build(); .build();
private final FComboBox<ItemColumn> cbxSortOptions; private final FComboBox<ItemColumn> cbxSortOptions;

View File

@@ -69,6 +69,13 @@ public class PuzzleScreen extends LaunchScreen {
} }
}); });
hostedMatch.setEndGameHook((new Runnable() {
@Override
public void run() {
chosen.savePuzzleSolve(hostedMatch.getGame().getOutcome().isWinner(GamePlayerUtil.getGuiPlayer()));
}
}));
final List<RegisteredPlayer> players = new ArrayList<>(); final List<RegisteredPlayer> players = new ArrayList<>();
final RegisteredPlayer human = new RegisteredPlayer(new Deck()).setPlayer(GamePlayerUtil.getGuiPlayer()); final RegisteredPlayer human = new RegisteredPlayer(new Deck()).setPlayer(GamePlayerUtil.getGuiPlayer());
human.setStartingHand(0); human.setStartingHand(0);

View File

@@ -1,5 +1,6 @@
package forge.screens.match.views; package forge.screens.match.views;
import forge.Forge;
import forge.assets.FSkinImage; import forge.assets.FSkinImage;
import forge.deck.Deck; import forge.deck.Deck;
import forge.deck.FDeckViewer; import forge.deck.FDeckViewer;
@@ -85,7 +86,7 @@ public class VGameMenu extends FDropDownMenu {
autoYields.show(); autoYields.show();
} }
})); }));
addItem(new FMenuItem(localizer.getMessage("lblSettings"), FSkinImage.SETTINGS, new FEventHandler() { addItem(new FMenuItem(localizer.getMessage("lblSettings"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
SettingsScreen.show(false); SettingsScreen.show(false);

View File

@@ -56,7 +56,7 @@ public class ConquestMenu extends FPopupMenu {
setCurrentScreen(collectionScreen); setCurrentScreen(collectionScreen);
} }
}); });
private static final FMenuItem statsItem = new FMenuItem(Localizer.getInstance().getMessage("lblStatistics"), FSkinImage.MULTI, new FEventHandler() { private static final FMenuItem statsItem = new FMenuItem(Localizer.getInstance().getMessage("lblStatistics"), FSkinImage.HDMULTI, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
setCurrentScreen(statsScreen); setCurrentScreen(statsScreen);
@@ -68,7 +68,7 @@ public class ConquestMenu extends FPopupMenu {
setCurrentScreen(planeswalkScreen); setCurrentScreen(planeswalkScreen);
} }
}); });
private static final FMenuItem prefsItem = new FMenuItem(Localizer.getInstance().getMessage("Preferences"), FSkinImage.SETTINGS, new FEventHandler() { private static final FMenuItem prefsItem = new FMenuItem(Localizer.getInstance().getMessage("Preferences"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
setCurrentScreen(prefsScreen); setCurrentScreen(prefsScreen);
@@ -126,8 +126,8 @@ public class ConquestMenu extends FPopupMenu {
addItem(commandersItem); commandersItem.setSelected(currentScreen == commandersScreen); addItem(commandersItem); commandersItem.setSelected(currentScreen == commandersScreen);
addItem(planeswalkersItem); planeswalkersItem.setSelected(currentScreen == planeswalkersScreen); addItem(planeswalkersItem); planeswalkersItem.setSelected(currentScreen == planeswalkersScreen);
addItem(collectionItem); collectionItem.setSelected(currentScreen == collectionScreen); addItem(collectionItem); collectionItem.setSelected(currentScreen == collectionScreen);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
addItem(planeswalkItem); planeswalkItem.setSelected(currentScreen == planeswalkScreen); addItem(planeswalkItem); planeswalkItem.setSelected(currentScreen == planeswalkScreen);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
addItem(prefsItem); prefsItem.setSelected(currentScreen == prefsScreen); addItem(prefsItem); prefsItem.setSelected(currentScreen == prefsScreen);
} }
} }

View File

@@ -244,10 +244,7 @@ public class ConquestRewardDialog extends FScrollPane {
//ensure current card in view //ensure current card in view
if (getScrollHeight() > getHeight() && index < cardCount) { if (getScrollHeight() > getHeight() && index < cardCount) {
CardRevealer currentCard = cardRevealers.get(index); CardRevealer currentCard = cardRevealers.get(index);
if (!Forge.extrawide.equals("default")) scrollIntoView(currentCard, currentCard.getHeight() / (columnCount * PADDING) / 2);
scrollIntoView(currentCard, currentCard.getHeight() / (columnCount * PADDING) / 2);
else
scrollIntoView(currentCard, currentCard.getHeight() / 2 + PADDING); //show half of the card below
} }
} }

View File

@@ -43,7 +43,7 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
private static final QuestStatsScreen statsScreen = new QuestStatsScreen(); private static final QuestStatsScreen statsScreen = new QuestStatsScreen();
private static final QuestTournamentsScreen tournamentsScreen = new QuestTournamentsScreen(); private static final QuestTournamentsScreen tournamentsScreen = new QuestTournamentsScreen();
private static final FMenuItem duelsItem = new FMenuItem(Localizer.getInstance().getMessage("lblDuels"), FSkinImage.QUEST_GEAR, new FEventHandler() { private static final FMenuItem duelsItem = new FMenuItem(Localizer.getInstance().getMessage("lblDuels"), FSkinImage.QUEST_BIG_SWORD, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
setCurrentScreen(duelsScreen); setCurrentScreen(duelsScreen);
@@ -55,13 +55,13 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
setCurrentScreen(challengesScreen); setCurrentScreen(challengesScreen);
} }
}); });
private static final FMenuItem tournamentsItem = new FMenuItem(Localizer.getInstance().getMessage("lblTournaments"), FSkinImage.PACK, new FEventHandler() { private static final FMenuItem tournamentsItem = new FMenuItem(Localizer.getInstance().getMessage("lblTournaments"), FSkinImage.QUEST_BIG_SHIELD, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
setCurrentScreen(tournamentsScreen); setCurrentScreen(tournamentsScreen);
} }
}); });
private static final FMenuItem decksItem = new FMenuItem(Localizer.getInstance().getMessage("lblQuestDecks"), FSkinImage.DECKLIST, new FEventHandler() { private static final FMenuItem decksItem = new FMenuItem(Localizer.getInstance().getMessage("lblQuestDecks"), FSkinImage.QUEST_BIG_BAG, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
setCurrentScreen(decksScreen); setCurrentScreen(decksScreen);
@@ -79,7 +79,7 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
setCurrentScreen(bazaarScreen); setCurrentScreen(bazaarScreen);
} }
}); });
private static final FMenuItem statsItem = new FMenuItem(Localizer.getInstance().getMessage("lblStatistics"), FSkinImage.MULTI, new FEventHandler() { private static final FMenuItem statsItem = new FMenuItem(Localizer.getInstance().getMessage("lblStatistics"), FSkinImage.HDMULTI, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
setCurrentScreen(statsScreen); setCurrentScreen(statsScreen);
@@ -119,7 +119,7 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
}); });
} }
}); });
private static final FMenuItem prefsItem = new FMenuItem(Localizer.getInstance().getMessage("Preferences"), FSkinImage.SETTINGS, new FEventHandler() { private static final FMenuItem prefsItem = new FMenuItem(Localizer.getInstance().getMessage("Preferences"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS, new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
setCurrentScreen(prefsScreen); setCurrentScreen(prefsScreen);
@@ -243,9 +243,9 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
addItem(decksItem); decksItem.setSelected(currentScreen == decksScreen); addItem(decksItem); decksItem.setSelected(currentScreen == decksScreen);
addItem(spellShopItem); spellShopItem.setSelected(currentScreen == spellShopScreen); addItem(spellShopItem); spellShopItem.setSelected(currentScreen == spellShopScreen);
addItem(bazaarItem); bazaarItem.setSelected(currentScreen == bazaarScreen); addItem(bazaarItem); bazaarItem.setSelected(currentScreen == bazaarScreen);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
addItem(unlockSetsItem); addItem(unlockSetsItem);
addItem(travelItem); addItem(travelItem);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
addItem(prefsItem); prefsItem.setSelected(currentScreen == prefsScreen); addItem(prefsItem); prefsItem.setSelected(currentScreen == prefsScreen);
} }

View File

@@ -37,7 +37,7 @@ public class SettingsPage extends TabPage<SettingsScreen> {
private final FGroupList<Setting> lstSettings = add(new FGroupList<>()); private final FGroupList<Setting> lstSettings = add(new FGroupList<>());
public SettingsPage() { public SettingsPage() {
super(Localizer.getInstance().getMessage("lblSettings"), FSkinImage.SETTINGS); super(Localizer.getInstance().getMessage("lblSettings"), Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS);
final Localizer localizer = Localizer.getInstance(); final Localizer localizer = Localizer.getInstance();

View File

@@ -83,4 +83,5 @@ War of the Spark, 3/6/WAR, WAR
Modern Horizons, 3/6/WAR, MH1 Modern Horizons, 3/6/WAR, MH1
Core Set 2020, 3/6/M20, M20 Core Set 2020, 3/6/M20, M20
Throne of Eldraine, 3/6/ELD, ELD Throne of Eldraine, 3/6/ELD, ELD
Theros Beyond Death, 3/6/THB, THB Theros Beyond Death, 3/6/THB, THB
Mystery Booster, 3/6/MB1, MB1

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,10 @@
Name:Band Together Name:Band Together
ManaCost:2 G ManaCost:2 G
Types:Instant Types:Instant
A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | AILogic$ PowerDmg | SubAbility$ SoulsDamage | TargetMin$ 0 | TargetMax$ 2 | StackDescription$ None | SpellDescription$ Up to two target creatures you control each deal damage equal to their power to another target creature. A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select up to two target creatures you control | ImprintCards$ Targeted | AILogic$ PowerDmg | SubAbility$ DBPump | TargetMin$ 0 | TargetMax$ 2 | StackDescription$ SpellDescription | SpellDescription$ Up to two target creatures you control each deal damage equal to their power to another target creature.
SVar:SoulsDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | NumDmg$ X | References$ X | TargetUnique$ True | DamageSource$ ParentTarget SVar:DBPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | RememberObjects$ ThisTargetedCard | IsCurse$ True | SubAbility$ DBEachDamage | StackDescription$ None
SVar:X:ParentTargeted$CardPower SVar:DBEachDamage:DB$ EachDamage | ValidCards$ Creature.IsImprinted | NumDmg$ X | References$ X | DamageDesc$ damage equal to its power | DefinedCards$ Remembered | SubAbility$ DBCleanup | StackDescription$ None
#NumDmg isn't really used here. It is left for clarity. The AF pulls Damage straight from "X" hardcoded.
SVar:X:Count$CardPower
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
Oracle:Up to two target creatures you control each deal damage equal to their power to another target creature. Oracle:Up to two target creatures you control each deal damage equal to their power to another target creature.

View File

@@ -0,0 +1,10 @@
Name:Combo Attack
ManaCost:2 G
Types:Sorcery
A:SP$ Pump | Cost$ 2 G | ValidTgts$ Creature.YourTeamCtrl | TgtPrompt$ Select two target creatures your team controls | ImprintCards$ Targeted | TargetMin$ 2 | TargetMax$ 2 | AILogic$ PowerDmg | SubAbility$ DBPump | StackDescription$ SpellDescription | SpellDescription$ Two target creatures your team controls each deal damage equal to their power to target creature.
SVar:DBPump:DB$ Pump | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | RememberObjects$ ThisTargetedCard | IsCurse$ True | SubAbility$ DBEachDamage | StackDescription$ None
SVar:DBEachDamage:DB$ EachDamage | ValidCards$ Creature.IsImprinted | NumDmg$ X | References$ X | DefinedCards$ Remembered | SubAbility$ DBCleanup | StackDescription$ None
#NumDmg isn't really used here. It is left for clarity. The AF pulls Damage straight from "X" hardcoded.
SVar:X:Count$CardPower
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearImprinted$ True
Oracle:Two target creatures your team controls each deal damage equal to their power to target creature.

View File

@@ -2,8 +2,6 @@ Name:Crashing Boars
ManaCost:3 G G ManaCost:3 G G
Types:Creature Boar Types:Creature Boar
PT:4/4 PT:4/4
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigChoose | TriggerDescription$ Whenever CARDNAME attacks, defending player chooses an untapped creature they control. That creature blocks CARDNAME this turn if able. T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ DBMustBlock | TriggerDescription$ Whenever CARDNAME attacks, defending player chooses an untapped creature they control. That creature blocks CARDNAME this turn if able.
SVar:TrigChoose:DB$ ChooseCard | Defined$ DefendingPlayer | Amount$ 1 | Choices$ Creature.untapped+DefenderCtrl | Mandatory$ True | SubAbility$ DBMustBlock SVar:DBMustBlock:DB$ MustBlock | Choices$ Creature.untapped+DefenderCtrl | Chooser$ DefendingPlayer
SVar:DBMustBlock:DB$ MustBlock | Defined$ ChosenCard
SVar:Picture:http://www.wizards.com/global/images/magic/general/crashing_boars.jpg
Oracle:Whenever Crashing Boars attacks, defending player chooses an untapped creature they control. That creature blocks Crashing Boars this turn if able. Oracle:Whenever Crashing Boars attacks, defending player chooses an untapped creature they control. That creature blocks Crashing Boars this turn if able.

View File

@@ -7,5 +7,5 @@ S:Mode$ Continuous | Affected$ Creature.ChosenType+YouCtrl | AddPower$ 1 | AddTo
AI:RemoveDeck:Random AI:RemoveDeck:Random
SVar:PlayMain1:TRUE SVar:PlayMain1:TRUE
SVar:AIPreference:SacCost$Creature.ChosenType+Other SVar:AIPreference:SacCost$Creature.ChosenType+Other
A:AB$ Pump | Cost$ 1 W B Sac<1/Creature.ChosenType/creature of the chosen type> | ValidTgts$ Creature | TgtPrompt$ Select target creature you control | KW$ Indestructible | SpellDescription$ Target creature you control gains indestructible until end of turn. A:AB$ Pump | Cost$ 1 Sac<1/Creature.ChosenType/creature of the chosen type> | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | KW$ Indestructible | SpellDescription$ Target creature you control gains indestructible until end of turn.
Oracle:As Etchings of the Chosen enters the battlefield, choose a creature type.\nCreatures you control of the chosen type get +1/+1.\n{1}, Sacrifice a creature of the chosen type: Target creature you control gains indestructible until end of turn. Oracle:As Etchings of the Chosen enters the battlefield, choose a creature type.\nCreatures you control of the chosen type get +1/+1.\n{1}, Sacrifice a creature of the chosen type: Target creature you control gains indestructible until end of turn.

View File

@@ -4,8 +4,8 @@ Types:Creature Human Knight
PT:1/1 PT:1/1
K:First Strike K:First Strike
K:Haste K:Haste
T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks, another target creature you control gets +1/+0 until end of turn. T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks, another target attacking Knight you control gets +1/+0 until end of turn.
SVar:TrigPump:DB$Pump | ValidTgts$ Knight.YouCtrl+Other | TgtPrompt$ Select another target attacking Knight you control | NumAtt$ +1 SVar:TrigPump:DB$ Pump | ValidTgts$ Knight.YouCtrl+attacking+Other | TgtPrompt$ Select another target attacking Knight you control | NumAtt$ +1
SVar:HasAttackEffect:TRUE SVar:HasAttackEffect:TRUE
S:Mode$ ReduceCost | ValidTarget$ Card.Self | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 3 | Description$ Equip abilities you activate that target CARDNAME cost {3} less to activate. S:Mode$ ReduceCost | ValidTarget$ Card.Self | ValidSpell$ Activated.Equip | Activator$ You | Amount$ 3 | Description$ Equip abilities you activate that target CARDNAME cost {3} less to activate.
Oracle:First strike, haste\nWhenever Fervent Champion attacks, another target attacking Knight you control gets +1/+0 until end of turn.\nEquip abilities you activate that target Fervent Champion cost {3} less to activate. Oracle:First strike, haste\nWhenever Fervent Champion attacks, another target attacking Knight you control gets +1/+0 until end of turn.\nEquip abilities you activate that target Fervent Champion cost {3} less to activate.

View File

@@ -3,12 +3,11 @@ ManaCost:1 U R
Types:Creature Sliver Types:Creature Sliver
PT:2/2 PT:2/2
S:Mode$ Continuous | Affected$ Sliver | AddAbility$ Frenetic | AddSVar$ DBExile & DelTrig & MoveBack & DBSacSelf | Description$ All Slivers have "{0}: If this permanent is on the battlefield, flip a coin. If you win the flip, exile this permanent and return it to the battlefield under its owner's control at the beginning of the next end step. If you lose the flip, sacrifice it." S:Mode$ Continuous | Affected$ Sliver | AddAbility$ Frenetic | AddSVar$ DBExile & DelTrig & MoveBack & DBSacSelf | Description$ All Slivers have "{0}: If this permanent is on the battlefield, flip a coin. If you win the flip, exile this permanent and return it to the battlefield under its owner's control at the beginning of the next end step. If you lose the flip, sacrifice it."
SVar:Frenetic:DB$ FlipACoin | ConditionPresent$ Card.Self | ConditionCompare$ EQ1 | WinSubAbility$ DBExile | LoseSubAbility$ DBSacSelf | SpellDescription$ If this permanent is on the battlefield, flip a coin. If you win the flip, exile this permanent and return it to the battlefield under its owner's control at the beginning of the next end step. If you lose the flip, sacrifice it. SVar:Frenetic:AB$ FlipACoin | Cost$ 0 | ConditionPresent$ Card.Self | ConditionCompare$ EQ1 | WinSubAbility$ DBExile | LoseSubAbility$ DBSacSelf | SpellDescription$ If this permanent is on the battlefield, flip a coin. If you win the flip, exile this permanent and return it to the battlefield under its owner's control at the beginning of the next end step. If you lose the flip, sacrifice it.
SVar:DBExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ Self | SubAbility$ DelTrig SVar:DBExile:DB$ ChangeZone | Origin$ Battlefield | Destination$ Exile | Defined$ Self | SubAbility$ DelTrig
SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ MoveBack | Static$ True SVar:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ MoveBack | Static$ True
SVar:MoveBack:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ Self SVar:MoveBack:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ Self
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self
SVar:PlayMain1:TRUE SVar:PlayMain1:TRUE
AI:RemoveDeck:All AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/frenetic_sliver.jpg
Oracle:All Slivers have "{0}: If this permanent is on the battlefield, flip a coin. If you win the flip, exile this permanent and return it to the battlefield under its owner's control at the beginning of the next end step. If you lose the flip, sacrifice it." Oracle:All Slivers have "{0}: If this permanent is on the battlefield, flip a coin. If you win the flip, exile this permanent and return it to the battlefield under its owner's control at the beginning of the next end step. If you lose the flip, sacrifice it."

View File

@@ -0,0 +1,11 @@
Name:Glyph of Delusion
ManaCost:U
Types:Instant
A:SP$ Pump | Cost$ U | ValidTgts$ Wall.blockedThisTurn | TgtPrompt$ Select target Wall that blocked this turn | SubAbility$ DBPutCounter | StackDescription$ SpellDescription | SpellDescription$ Put X glyph counters on target creature that target Wall blocked this turn, where X is the power of that blocked creature. The creature gains “This creature doesnt untap during your untap step if it has a glyph counter on it” and “At the beginning of your upkeep, remove a glyph counter from this creature.”
SVar:DBPutCounter:DB$ PutCounter | CounterType$ GLYPH | CounterNum$ X | References$ X | ValidTgts$ Creature.blockedByValidThisTurn ParentTarget | TgtPrompt$ Select target creature blocked by target Wall this turn to put counters on | SubAbility$ Delude | IsCurse$ True
SVar:X:Targeted$CardPower
SVar:Delude:DB$ Animate | Defined$ ParentTarget | staticAbilities$ Delusional | Triggers$ TrigGlyphUpkeep | sVars$ LoseGlyph | Permanent$ True | StackDescription$ None
SVar:Delusional:Mode$ Continuous | Affected$ Card.Self+counters_GE1_GLYPH | AddHiddenKeyword$ CARDNAME doesn't untap during your untap step. | Description$ CARDNAME doesn't untap during your untap step if it has a glyph counter on it.
SVar:TrigGlyphUpkeep:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ LoseGlyph | TriggerDescription$ At the beginning of your upkeep, remove a glyph counter from CARDNAME.
SVar:LoseGlyph:DB$ RemoveCounter | CounterType$ GLYPH | CounterNum$ 1
Oracle:Put X glyph counters on target creature that target Wall blocked this turn, where X is the power of that blocked creature. The creature gains “This creature doesnt untap during your untap step if it has a glyph counter on it” and “At the beginning of your upkeep, remove a glyph counter from this creature.”

View File

@@ -1,7 +1,7 @@
Name:Joust Name:Joust
ManaCost:1 R ManaCost:1 R
Types:Sorcery Types:Sorcery
A:SP$ Pump | Cost$ 1 R | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | NumAtt$ +2 | NumDef$ +1 | ConditionDefined$ ThisTargetedCard | ConditionPresent$ Knight | SubAbility$ DBFight | SpellDescription$ Choose target creature you control and target creature you don't control. The creature you control gets +2/+1 until end of turn if it's a Knight. Then those creatures fight each other. (Each deals damage equal to its power to the other.) A:SP$ Pump | Cost$ 1 R | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature you control | NumAtt$ +2 | NumDef$ +1 | AILogic$ Fight | ConditionDefined$ ThisTargetedCard | ConditionPresent$ Knight | SubAbility$ DBFight | SpellDescription$ Choose target creature you control and target creature you don't control. The creature you control gets +2/+1 until end of turn if it's a Knight. Then those creatures fight each other. (Each deals damage equal to its power to the other.)
SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.YouDontCtrl | AILogic$ Always | TgtPrompt$ Choose target creature you don't control SVar:DBFight:DB$ Fight | Defined$ ParentTarget | ValidTgts$ Creature.YouDontCtrl | AILogic$ Always | TgtPrompt$ Choose target creature you don't control
DeckHints:Type$Knight DeckHints:Type$Knight
Oracle:Choose target creature you control and target creature you don't control. The creature you control gets +2/+1 until end of turn if it's a Knight. Then those creatures fight each other. (Each deals damage equal to its power to the other.) Oracle:Choose target creature you control and target creature you don't control. The creature you control gets +2/+1 until end of turn if it's a Knight. Then those creatures fight each other. (Each deals damage equal to its power to the other.)

View File

@@ -2,10 +2,10 @@ Name:Kenrith, the Returned King
ManaCost:4 W ManaCost:4 W
Types:Legendary Creature Human Noble Types:Legendary Creature Human Noble
PT:5/5 PT:5/5
A:AB$ PumpAll | Cost$ R | ValidCards$ Creature | KW$ Trample & Haste | SpellDescription$ All creatures gain trample and haste until end of turn. A:AB$ PumpAll | Cost$ R | ValidCards$ Creature | KW$ Trample & Haste | AILogic$ PumpForTrample | SpellDescription$ All creatures gain trample and haste until end of turn.
A:AB$ PutCounter | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature. A:AB$ PutCounter | Cost$ 1 G | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Put a +1/+1 counter on target creature.
A:AB$ GainLife | Cost$ 2 W | LifeAmount$ 5 | ValidTgts$ Player | TgtPrompt$ Choose a player | SpellDescription$ Target player gains 5 life. A:AB$ GainLife | Cost$ 2 W | LifeAmount$ 5 | ValidTgts$ Player | TgtPrompt$ Choose a player | SpellDescription$ Target player gains 5 life.
A:AB$ Draw | Cost$ 3 U | NumCards$ 1 | ValidTgts$ Player | TgtPrompt$ Choose a player | SpellDescription$ Target player draws a card. A:AB$ Draw | Cost$ 3 U | NumCards$ 1 | ValidTgts$ Player | TgtPrompt$ Choose a player | SpellDescription$ Target player draws a card.
A:AB$ ChangeZone | Cost$ 4 B | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature | ChangeNum$ 1 | SpellDescription$ Put target creature card from a graveyard onto the battlefield under its owner's control. A:AB$ ChangeZone | Cost$ 4 B | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature | AITgts$ Creature.YouOwn | ChangeNum$ 1 | SpellDescription$ Put target creature card from a graveyard onto the battlefield under its owner's control.
DeckHas:Ability$Counters & Ability$LifeGain DeckHas:Ability$Counters & Ability$LifeGain
Oracle:{R}: All creatures gain trample and haste until end of turn.\n{1}{G}: Put a +1/+1 counter on target creature.\n{2}{W}: Target player gains 5 life.\n{3}{U}: Target player draws a card.\n{4}{B}: Put target creature card from a graveyard onto the battlefield under its owner's control. Oracle:{R}: All creatures gain trample and haste until end of turn.\n{1}{G}: Put a +1/+1 counter on target creature.\n{2}{W}: Target player gains 5 life.\n{3}{U}: Target player draws a card.\n{4}{B}: Put target creature card from a graveyard onto the battlefield under its owner's control.

View File

@@ -1,6 +1,7 @@
Name:Legion's End Name:Legion's End
ManaCost:1 B ManaCost:1 B
Types:Sorcery Types:Sorcery
A:SP$ ChangeZone | Cost$ 1 B | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.OppCtrl+cmcLE2 | TgtPrompt$ Select target creature an opponent controls with converted mana cost 2 or less | SubAbility$ DBChangeZoneAll | SpellDescription$ Exile target creature an opponent controls with converted mana cost 2 or less and all other creatures that player controls with the same name as that creature. Then that player reveals their hand and exiles all cards with that name from their hand and graveyard. A:SP$ ChangeZone | Cost$ 1 B | Origin$ Battlefield | Destination$ Exile | ValidTgts$ Creature.OppCtrl+cmcLE2 | TgtPrompt$ Select target creature an opponent controls with converted mana cost 2 or less | SubAbility$ DBExileAll | StackDescription$ SpellDescription | SpellDescription$ Exile target creature an opponent controls with converted mana cost 2 or less and all other creatures that player controls with the same name as that creature. Then that player reveals their hand and exiles all cards with that name from their hand and graveyard.
SVar:DBChangeZoneAll:DB$ ChangeZoneAll | Defined$ TargetedController | ChangeType$ Targeted.sameName | Origin$ Battlefield,Graveyard,Hand | Destination$ Exile | Search$ True SVar:DBExileAll:DB$ ChangeZoneAll | Defined$ TargetedController | ChangeType$ Targeted.sameName+Creature | Origin$ Battlefield | Destination$ Exile | SubAbility$ DBChangeZoneAll | StackDescription$ None
SVar:DBChangeZoneAll:DB$ ChangeZoneAll | Defined$ TargetedController | ChangeType$ Targeted.sameName | Origin$ Graveyard,Hand | Destination$ Exile | Search$ True | StackDescription$ None
Oracle:Exile target creature an opponent controls with converted mana cost 2 or less and all other creatures that player controls with the same name as that creature. Then that player reveals their hand and exiles all cards with that name from their hand and graveyard. Oracle:Exile target creature an opponent controls with converted mana cost 2 or less and all other creatures that player controls with the same name as that creature. Then that player reveals their hand and exiles all cards with that name from their hand and graveyard.

View File

@@ -3,12 +3,11 @@ ManaCost:2 B
Types:Creature Imp Types:Creature Imp
PT:1/1 PT:1/1
K:Flying K:Flying
A:AB$ Effect | Cost$ T | Name$ Maddening Imp Effect | StaticAbilities$ KWPump | ActivationPhases$ Upkeep->Main1 | OpponentTurn$ True | SpellDescription$ Non-Wall creatures the active player controls attack this turn if able. At the beginning of the next end step, destroy each of those creatures that didn't attack this turn. Activate this ability only during an opponent's turn and only before combat. | SubAbility$ DestroyPacifist A:AB$ PumpAll | Cost$ T | ValidCards$ Creature.ActivePlayerCtrl+nonWall | KW$ HIDDEN CARDNAME attacks each combat if able. | ActivationPhases$ Upkeep->Main1 | OpponentTurn$ True | SubAbility$ DBEffect | StackDescription$ SpellDescription | SpellDescription$ Non-Wall creatures the active player controls attack this turn if able. At the beginning of the next end step, destroy each of those creatures that didn't attack this turn. Activate this ability only during an opponent's turn and only before combat.
SVar:KWPump:Mode$ Continuous | EffectZone$ Command | Affected$ Creature.ActivePlayerCtrl+nonWall | AffectedZone$ Battlefield | AddHiddenKeyword$ CARDNAME attacks each combat if able. | Description$ Non-Wall creatures the active player controls attack this turn if able. SVar:DBEffect:DB$ Effect | Name$ Maddening Imp Effect | Triggers$ EndofTurn | SVars$ TrigDestroy | RememberObjects$ Valid Creature.ActivePlayerCtrl+nonWall
SVar:DestroyPacifist:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ TrigDestroy | TriggerDescription$ At the beginning of the next end step, destroy each of those creatures that didn't attack this turn. SVar:EndofTurn:Mode$ Phase | Phase$ End of Turn | Execute$ TrigDestroy | TriggerDescription$ At the beginning of the next end step, destroy each of those creatures that didn't attack this turn.
SVar:TrigDestroy:DB$ DestroyAll | ValidCards$ Creature.ActivePlayerCtrl+notAttackedThisTurn+nonWall SVar:TrigDestroy:DB$ DestroyAll | ValidCards$ Creature.IsRemembered+notAttackedThisTurn
AI:RemoveDeck:All AI:RemoveDeck:All
AI:RemoveDeck:Random AI:RemoveDeck:Random
SVar:NonCombatPriority:5 SVar:NonCombatPriority:5
SVar:Picture:http://www.wizards.com/global/images/magic/general/maddening_imp.jpg
Oracle:Flying\n{T}: Non-Wall creatures the active player controls attack this turn if able. At the beginning of the next end step, destroy each of those creatures that didn't attack this turn. Activate this ability only during an opponent's turn and only before combat. Oracle:Flying\n{T}: Non-Wall creatures the active player controls attack this turn if able. At the beginning of the next end step, destroy each of those creatures that didn't attack this turn. Activate this ability only during an opponent's turn and only before combat.

View File

@@ -1,7 +1,7 @@
Name:Maelstrom Nexus Name:Maelstrom Nexus
ManaCost:W U B R G ManaCost:W U B R G
Types:Enchantment Types:Enchantment
S:Mode$ Continuous | Affected$ Card.YouCtrl | AffectedZone$ Exile,Graveyard,Hand,Library,Command | CheckSVar$ Y | SVarCompare$ EQ0 | AddKeyword$ Cascade | Description$ The first spell you cast each turn has cascade. (When you cast your first spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order.) S:Mode$ Continuous | Affected$ Card.YouCtrl | AffectedZone$ Stack | CheckSVar$ Y | SVarCompare$ EQ0 | AddKeyword$ Cascade | Description$ The first spell you cast each turn has cascade. (When you cast your first spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order.)
SVar:Y:Count$ThisTurnCast_Card.YouCtrl SVar:Y:Count$ThisTurnCast_Card.YouCtrl
SVar:Picture:http://www.wizards.com/global/images/magic/general/maelstrom_nexus.jpg SVar:Picture:http://www.wizards.com/global/images/magic/general/maelstrom_nexus.jpg
Oracle:The first spell you cast each turn has cascade. (When you cast your first spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order.) Oracle:The first spell you cast each turn has cascade. (When you cast your first spell, exile cards from the top of your library until you exile a nonland card that costs less. You may cast it without paying its mana cost. Put the exiled cards on the bottom of your library in a random order.)

View File

@@ -5,7 +5,7 @@ T:Mode$ ChangesZone | ValidCard$ Card.Self | Origin$ Any | Destination$ Battlefi
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_1_1_elemental | TokenOwner$ You | LegacyImage$ r 1 1 elemental m20 | RememberTokens$ True | SubAbility$ DBAttach SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_1_1_elemental | TokenOwner$ You | LegacyImage$ r 1 1 elemental m20 | RememberTokens$ True | SubAbility$ DBAttach
SVar:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup SVar:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
S:Mode$ Continuous | Affected$ Card.EquippedBy | AddAbility$ Damage | AddSVar$ ThorncasterSliverDamage | Description$ Equipped creature has flying and gets creature: It deals 1 damage to any target. S:Mode$ Continuous | Affected$ Card.EquippedBy | AddAbility$ Damage | Description$ Equipped creature has "Sacrifice this creature: It deals 1 damage to any target."
SVar:Damage:AB$DealDamage | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to any target. SVar:Damage:AB$DealDamage | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature,Player,Planeswalker | TgtPrompt$ Select any target | NumDmg$ 1 | SpellDescription$ CARDNAME deals 1 damage to any target.
SVar:NonStackingAttachEffect:True SVar:NonStackingAttachEffect:True
AI:RemoveDeck:All AI:RemoveDeck:All

View File

@@ -3,6 +3,9 @@ ManaCost:W U B
Types:Legendary Creature Human Types:Legendary Creature Human
PT:1/1 PT:1/1
K:CARDNAME doesn't untap during your untap step. K:CARDNAME doesn't untap during your untap step.
A:AB$ GainControl | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | LoseControl$ LeavesPlay,LoseControl | DestroyTgt$ LeavesPlay,LoseControl,Untap | NoRegen$ True | SpellDescription$ Gain control of target creature for as long as you control CARDNAME. When CARDNAME leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated. A:AB$ GainControl | Cost$ T | ValidTgts$ Creature | TgtPrompt$ Select target creature | LoseControl$ LeavesPlay,LoseControl | SubAbility$ DBEffect | SpellDescription$ Gain control of target creature for as long as you control CARDNAME. When CARDNAME leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated.
SVar:Picture:http://www.wizards.com/global/images/magic/general/merieke_ri_berit.jpg SVar:DBEffect:DB$ Effect | RememberObjects$ ParentTarget | ForgetOnMoved$ Battlefield | Triggers$ LeavesPlay,Untap | References$ LeavesPlay,Untap | Duration$ UntilHostLeavesPlay
SVar:LeavesPlay:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.EffectSource | Execute$ DBDestroy | TriggerDescription$ When EFFECTSOURCE leaves the battlefield, or becomes untapped, destroy that creature. It can't be regenerated.
SVar:Untap:Mode$ Untaps | ValidCard$ Card.EffectSource | Execute$ DBDestroy | Secondary$ True | TriggerDescription$ When EFFECTSOURCE leaves the battlefield, or becomes untapped, destroy that creature. It can't be regenerated.
SVar:DBDestroy:DB$ Destroy | Defined$ Remembered | NoRegen$ True
Oracle:Merieke Ri Berit doesn't untap during your untap step.\n{T}: Gain control of target creature for as long as you control Merieke Ri Berit. When Merieke Ri Berit leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated. Oracle:Merieke Ri Berit doesn't untap during your untap step.\n{T}: Gain control of target creature for as long as you control Merieke Ri Berit. When Merieke Ri Berit leaves the battlefield or becomes untapped, destroy that creature. It can't be regenerated.

View File

@@ -3,14 +3,13 @@ ManaCost:3 W W
Types:Legendary Planeswalker Nahiri Types:Legendary Planeswalker Nahiri
Loyalty:3 Loyalty:3
Text:CARDNAME can be your commander. Text:CARDNAME can be your commander.
A:AB$ Token | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | TokenAmount$ 1 | TokenScript$ w_1_1_kor_soldier | TokenOwner$ You | LegacyImage$ w 1 1 kor soldier c14 | RememberTokens$ True | SubAbility$ DBChooseTarget | SpellDescription$ Create a 1/1 white Kor Soldier creature token. You may attach an Equipment you control to it. A:AB$ Token | Cost$ AddCounter<2/LOYALTY> | Planeswalker$ True | TokenAmount$ 1 | TokenScript$ w_1_1_kor_soldier | TokenOwner$ You | LegacyImage$ w 1 1 kor soldier c14 | RememberTokens$ True | SubAbility$ DBChooseToken | SpellDescription$ Create a 1/1 white Kor Soldier creature token. You may attach an Equipment you control to it.
SVar:DBChooseTarget:DB$ ChooseCard | DefinedCards$ Remembered | Mandatory$ True | ChoiceTitle$ Choose a token: | SubAbility$ DBAttach SVar:DBChooseToken:DB$ ChooseCard | DefinedCards$ Remembered | Mandatory$ True | ChoiceTitle$ Choose a token | SubAbility$ DBAttach | StackDescription$ None
SVar:DBAttach:DB$ Attach | Optional$ True | Object$ Valid Equipment.YouCtrl | ChooseAnObject$ Choose an equipment you control | Defined$ ChosenCard | SubAbility$ DBCleanup SVar:DBAttach:DB$ Attach | Optional$ True | Object$ Valid Equipment.YouCtrl | ChooseAnObject$ Choose an Equipment you control | Defined$ ChosenCard | SubAbility$ DBCleanup | StackDescription$ None
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True | ClearChosenCard$ True
A:AB$ ChangeZone | Cost$ SubCounter<2/LOYALTY> | Origin$ Hand,Graveyard | Destination$ Battlefield | Hidden$ True | Planeswalker$ True | ChangeType$ Equipment.YouCtrl | Optional$ True | SpellDescription$ You may put an Equipment card from your hand or graveyard onto the battlefield. A:AB$ ChangeZone | Cost$ SubCounter<2/LOYALTY> | Origin$ Hand,Graveyard | Destination$ Battlefield | Hidden$ True | Planeswalker$ True | ChangeType$ Equipment.YouCtrl | Optional$ True | SpellDescription$ You may put an Equipment card from your hand or graveyard onto the battlefield.
A:AB$ Token | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | Ultimate$ True | TokenAmount$ 1 | TokenScript$ stoneforged_blade | LegacyImage$ stoneforged blade c14 | TokenOwner$ You | SpellDescription$ Create a colorless Equipment artifact token named Stoneforged Blade. It has indestructible, "Equipped creature gets +5/+5 and has double strike," and equip {0}. A:AB$ Token | Cost$ SubCounter<10/LOYALTY> | Planeswalker$ True | Ultimate$ True | TokenAmount$ 1 | TokenScript$ stoneforged_blade | LegacyImage$ stoneforged blade c14 | TokenOwner$ You | SpellDescription$ Create a colorless Equipment artifact token named Stoneforged Blade. It has indestructible, "Equipped creature gets +5/+5 and has double strike," and equip {0}.
DeckHas:Ability$Token DeckHas:Ability$Token
DeckNeeds:Type$Equipment DeckNeeds:Type$Equipment
AI:RemoveDeck:All AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/nahiri_the_lithomancer.jpg
Oracle:[+2]: Create a 1/1 white Kor Soldier creature token. You may attach an Equipment you control to it.\n[-2]: You may put an Equipment card from your hand or graveyard onto the battlefield.\n[-10]: Create a colorless Equipment artifact token named Stoneforged Blade. It has indestructible, "Equipped creature gets +5/+5 and has double strike," and equip {0}.\nNahiri, the Lithomancer can be your commander. Oracle:[+2]: Create a 1/1 white Kor Soldier creature token. You may attach an Equipment you control to it.\n[-2]: You may put an Equipment card from your hand or graveyard onto the battlefield.\n[-10]: Create a colorless Equipment artifact token named Stoneforged Blade. It has indestructible, "Equipped creature gets +5/+5 and has double strike," and equip {0}.\nNahiri, the Lithomancer can be your commander.

View File

@@ -1,11 +1,13 @@
Name:Quenchable Fire Name:Quenchable Fire
ManaCost:3 R ManaCost:3 R
Types:Sorcery Types:Sorcery
A:SP$ DealDamage | Cost$ 3 R | ValidTgts$ Player | TgtPrompt$ Select target player | NumDmg$ 3 | SubAbility$ DBEffect | SpellDescription$ CARDNAME deals 3 damage to target player. It deals an additional 3 damage to that player at the beginning of your next upkeep step unless they pay {U} before that step. A:SP$ DealDamage | Cost$ 3 R | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 3 | SubAbility$ DBEffect | StackDescription$ SpellDescription | SpellDescription$ CARDNAME deals 3 damage to target player or planeswalker. It deals an additional 3 damage to that player or planeswalker at the beginning of your next upkeep step unless that player or that planeswalker's controller pays {U} before that step.
SVar:DBEffect:DB$ Effect | Name$ Quenchable Fire Effect | EffectOwner$ Targeted | Duration$ Permanent | Triggers$ UpkeepTrig | Abilities$ PayUp | SVars$ Bleed,ExileEffect | RememberObjects$ SourceController | ImprintCards$ Self SVar:DBEffect:DB$ Effect | Name$ Quenchable Fire Effect | EffectOwner$ Targeted | Duration$ Permanent | Triggers$ UpkeepTrig | Abilities$ PayUp | SVars$ Bleed,ExileEffect | RememberObjects$ SourceController | ConditionDefined$ Targeted | ConditionPresent$ Planeswalker | ConditionCompare$ EQ0 | SubAbility$ DBEffect2
SVar:UpkeepTrig:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player.IsRemembered | TriggerZones$ Command | Execute$ Bleed | TriggerDescription$ It deals an additional 3 damage to you at the beginning of that player's next upkeep step unless you pay {U} before that step. SVar:DBEffect2:DB$ Effect | Name$ Quenchable Fire Effect | EffectOwner$ TargetedController | Duration$ Permanent | ForgetOnMoved$ Battlefield | Triggers$ UpkeepTrig2 | Abilities$ PayUp | SVars$ Bleed2,ExileEffect | RememberObjects$ SourceController,Targeted | ConditionDefined$ Targeted | ConditionPresent$ Planeswalker
SVar:Bleed:DB$ DealDamage | Defined$ You | NumDmg$ 3 | DamageSource$ Imprinted | SubAbility$ ExileEffect SVar:UpkeepTrig:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player.IsRemembered | TriggerZones$ Command | Execute$ Bleed | TriggerDescription$ EFFECTSOURCE deals an additional 3 damage to you at the beginning of that player's next upkeep step unless you pay {U} before that step.
SVar:Bleed:DB$ DealDamage | Defined$ You | NumDmg$ 3 | DamageSource$ EffectSource | SubAbility$ ExileEffect
SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile SVar:ExileEffect:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
SVar:PayUp:ST$ ChangeZone | Cost$ U | Defined$ Self | Origin$ Command | Destination$ Exile | ActivationZone$ Command | AILogic$ Always | SpellDescription$ Pay {U} to remove this effect. SVar:PayUp:ST$ ChangeZone | Cost$ U | Defined$ Self | Origin$ Command | Destination$ Exile | ActivationZone$ Command | AILogic$ Always | SpellDescription$ Pay {U} to remove this effect.
SVar:Picture:http://www.wizards.com/global/images/magic/general/quenchable_fire.jpg SVar:UpkeepTrig2:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player.IsRemembered | TriggerZones$ Command | Execute$ Bleed2 | TriggerDescription$ EFFECTSOURCE deals an additional 3 damage to that planeswalker at the beginning of that player's next upkeep step unless you pay {U} before that step.
Oracle:Quenchable Fire deals 3 damage to target player. It deals an additional 3 damage to that player at the beginning of your next upkeep step unless they pay {U} before that step. SVar:Bleed2:DB$ DamageAll | ValidCards$ Card.IsRemembered | NumDmg$ 3 | DamageSource$ EffectSource | SubAbility$ ExileEffect
Oracle:Quenchable Fire deals 3 damage to target player or planeswalker. It deals an additional 3 damage to that player or planeswalker at the beginning of your next upkeep step unless that player or that planeswalker's controller pays {U} before that step.

View File

@@ -195,15 +195,15 @@ AdditionalSetUnlockedInQuest=MPS_KLD
182 C Watchful Automaton 182 C Watchful Automaton
183 C Welder Automaton 183 C Welder Automaton
184 R Spire of Industry 184 R Spire of Industry
185 M Ajani, Valiant Protector 185 M Ajani, Valiant Protector
186 R Ajani's Aid 186 C Inspiring Roar
187 U Ajani's Comrade 187 U Ajani's Comrade
188 C Inspiring Roar 188 R Ajani's Aid
189 C Tranquil Expanse 189 C Tranquil Expanse
190 M Tezzeret, Master of Metal 190 M Tezzeret, Master of Metal
191 R Tezzeret's Betrayal 191 R Tezzeret's Betrayal
192 U Tezzeret's Simulacrum 192 C Pendulum of Patterns
193 C Pendulum of Patterns 193 U Tezzeret's Simulacrum
194 C Submerged Boneyard 194 C Submerged Boneyard
[tokens] [tokens]

View File

@@ -27,10 +27,10 @@ Foil=NotSupported
17 C Curfew 17 C Curfew
18 C Dark Ritual 18 C Dark Ritual
19 R Dirtcowl Wurm 19 R Dirtcowl Wurm
20 U Disenchant 20 C Disenchant
21 C Disruptive Student 21 C Disruptive Student
22 C Drifting Meadow 22 C Drifting Meadow
23 C Elvish Lyrist 23 U Elvish Lyrist
24 C Exhume 24 C Exhume
25 U Fecundity 25 U Fecundity
26 C Fertile Ground 26 C Fertile Ground
@@ -40,16 +40,16 @@ Foil=NotSupported
30 C Gorilla Warrior 30 C Gorilla Warrior
31 C Healing Salve 31 C Healing Salve
32 C Heat Ray 32 C Heat Ray
33 R Hurricane 33 U Hurricane
34 C Infantry Veteran 34 C Infantry Veteran
35 R Land Tax 35 U Land Tax
36 R Lhurgoyf 36 R Lhurgoyf
37 C Lightning Elemental 37 C Lightning Elemental
38 R Living Death 38 R Living Death
39 C Llanowar Elves 39 C Llanowar Elves
40 C Man-o'-War 40 C Man-o'-War
41 C Mana Leak 41 C Mana Leak
42 U Maniacal Rage 42 C Maniacal Rage
43 C Manta Riders 43 C Manta Riders
44 C Master Decoy 44 C Master Decoy
45 U Mogg Hollows 45 U Mogg Hollows
@@ -59,7 +59,7 @@ Foil=NotSupported
49 U Pestilence 49 U Pestilence
50 C Phyrexian Ghoul 50 C Phyrexian Ghoul
51 C Pincher Beetles 51 C Pincher Beetles
52 U Plated Rootwalla 52 C Plated Rootwalla
53 C Polluted Mire 53 C Polluted Mire
54 C Prodigal Sorcerer 54 C Prodigal Sorcerer
55 C Raging Goblin 55 C Raging Goblin
@@ -72,7 +72,7 @@ Foil=NotSupported
62 C Sanctum Custodian 62 C Sanctum Custodian
63 U Sanctum Guardian 63 U Sanctum Guardian
64 C Sandstorm 64 C Sandstorm
65 U Scaled Wurm 65 C Scaled Wurm
66 C Scryb Sprites 66 C Scryb Sprites
67 U Seasoned Marshal 67 U Seasoned Marshal
68 C Seeker of Skybreak 68 C Seeker of Skybreak
@@ -83,7 +83,7 @@ Foil=NotSupported
73 C Slippery Karst 73 C Slippery Karst
74 C Soltari Foot Soldier 74 C Soltari Foot Soldier
75 U Songstitcher 75 U Songstitcher
76 U Soul Warden 76 C Soul Warden
77 C Spike Colony 77 C Spike Colony
78 U Spike Feeder 78 U Spike Feeder
79 R Spike Weaver 79 R Spike Weaver

View File

@@ -135,7 +135,7 @@ Booster=10 Common, 3 Uncommon, 1 fromSheet("BBD RareMythic"), 1 BasicLand
125 C Omenspeaker 125 C Omenspeaker
126 U Opportunity 126 U Opportunity
127 U Oracle's Insight 127 U Oracle's Insight
128 C Peregrine Drake 128 U Peregrine Drake
129 U Phantom Warrior 129 U Phantom Warrior
130 U Reckless Scholar 130 U Reckless Scholar
131 R Sower of Temptation 131 R Sower of Temptation
@@ -203,7 +203,7 @@ Booster=10 Common, 3 Uncommon, 1 fromSheet("BBD RareMythic"), 1 BasicLand
193 C Cowl Prowler 193 C Cowl Prowler
194 C Daggerback Basilisk 194 C Daggerback Basilisk
195 M Doubling Season 195 M Doubling Season
196 U Elvish Visionary 196 C Elvish Visionary
197 U Feral Hydra 197 U Feral Hydra
198 C Fertile Ground 198 C Fertile Ground
199 U Fertilid 199 U Fertilid

View File

@@ -76,7 +76,7 @@ Foil=NotSupported
66 C Yavimaya Wurm 66 C Yavimaya Wurm
67 U Diabolic Vision 67 U Diabolic Vision
68 U Segmented Wurm 68 U Segmented Wurm
69 C Clockwork Avian 69 R Clockwork Avian
70 R Clockwork Beast 70 R Clockwork Beast
71 U Dwarven Ruins 71 U Dwarven Ruins
72 U Ebon Stronghold 72 U Ebon Stronghold
@@ -97,4 +97,4 @@ Foil=NotSupported
87 L Mountain 87 L Mountain
88 L Forest 88 L Forest
89 L Forest 89 L Forest
90 L Forest 90 L Forest

View File

@@ -230,6 +230,7 @@ Booster=10 Common:!fromSheet("CN2 Draft Matters"), 3 Uncommon:!fromSheet("CN2 Dr
219 R Exotic Orchard 219 R Exotic Orchard
220 U Rogue's Passage 220 U Rogue's Passage
221 U Shimmering Grotto 221 U Shimmering Grotto
222 M Kaya, Ghost Assassin
[tokens] [tokens]
w_1_1_soldier w_1_1_soldier

View File

@@ -184,14 +184,14 @@ Booster=10 Common:!land, 3 Uncommon, 1 RareMythic, 1 fromSheet("FRF Lands"), 0 f
174 C Tranquil Cove 174 C Tranquil Cove
175 C Wind-Scarred Crag 175 C Wind-Scarred Crag
176 L Plains 176 L Plains
176 L Plains 177 L Plains
179 L Island 178 L Island
179 L Island 179 L Island
180 L Swamp
181 L Swamp 181 L Swamp
181 L Swamp 182 L Mountain
183 L Mountain 183 L Mountain
183 L Mountain 184 L Forest
185 L Forest
185 L Forest 185 L Forest
[tokens] [tokens]

View File

@@ -0,0 +1,29 @@
[metadata]
Code=PGPX
Code2=PGPX
Date=2007-02-24
Name=Grand Prix Promos
MciCode=pgpx
Type=Other
[cards]
R Spiritmonger
R Call of the Herd
R Chrome Mox
R Umezawa's Jitte
R Maelstrom Pulse
R Goblin Guide
R Lotus Cobra
M Primeval Titan
R All Is Dust
M Batterskull
M Griselbrand
R Stoneforge Mystic
R Sword of Feast and Famine
M Progenitus
R Mutavault
L Plains
L Island
L Swamp
L Mountain
L Forest

View File

@@ -258,26 +258,26 @@ Booster=10 Common, 3 Uncommon, 1 RareMythic, 1 BasicLand KTK
247 C Wind-Scarred Crag 247 C Wind-Scarred Crag
248 R Windswept Heath 248 R Windswept Heath
249 R Wooded Foothills 249 R Wooded Foothills
269 L Forest
269 L Forest
269 L Forest
269 L Forest
257 L Island
257 L Island
257 L Island
257 L Island
263 L Mountain
263 L Mountain
263 L Mountain
263 L Mountain
250 L Plains
250 L Plains
250 L Plains
250 L Plains 250 L Plains
251 L Plains
252 L Plains
253 L Plains
254 L Island
255 L Island
256 L Island
257 L Island
258 L Swamp 258 L Swamp
258 L Swamp 259 L Swamp
258 L Swamp 260 L Swamp
258 L Swamp 261 L Swamp
262 L Mountain
263 L Mountain
264 L Mountain
265 L Mountain
266 L Forest
267 L Forest
268 L Forest
269 L Forest
[tokens] [tokens]
w_3_4_bird_flying w_3_4_bird_flying

View File

@@ -238,26 +238,26 @@ Booster=10 Common, 3 Uncommon, 1 RareMythic, 1 BasicLand
227 U Encroaching Wastes 227 U Encroaching Wastes
228 R Mutavault 228 R Mutavault
229 U Shimmering Grotto 229 U Shimmering Grotto
230 L Plains
231 L Plains 231 L Plains
231 L Plains 232 L Plains
231 L Plains 233 L Plains
231 L Plains
234 L Island
234 L Island
234 L Island
234 L Island 234 L Island
235 L Island
236 L Island
237 L Island
238 L Swamp
239 L Swamp
240 L Swamp
241 L Swamp 241 L Swamp
241 L Swamp 242 L Mountain
241 L Swamp 243 L Mountain
241 L Swamp
244 L Mountain
244 L Mountain
244 L Mountain
244 L Mountain 244 L Mountain
245 L Mountain
246 L Forest 246 L Forest
246 L Forest 247 L Forest
246 L Forest 248 L Forest
246 L Forest 249 L Forest
[tokens] [tokens]
c_1_1_sliver c_1_1_sliver

View File

@@ -258,26 +258,26 @@ Booster=10 Common:!fromSheet("M15 Sample Cards"), 3 Uncommon:!fromSheet("M15 Sam
247 R Sliver Hive 247 R Sliver Hive
248 R Urborg, Tomb of Yawgmoth 248 R Urborg, Tomb of Yawgmoth
249 R Yavimaya Coast 249 R Yavimaya Coast
250 L Plains
251 L Plains 251 L Plains
251 L Plains 252 L Plains
251 L Plains 253 L Plains
251 L Plains 254 L Island
255 L Island
255 L Island
255 L Island
255 L Island 255 L Island
256 L Island
257 L Island
258 L Swamp 258 L Swamp
258 L Swamp 259 L Swamp
258 L Swamp 260 L Swamp
258 L Swamp 261 L Swamp
263 L Mountain 262 L Mountain
263 L Mountain
263 L Mountain
263 L Mountain 263 L Mountain
264 L Mountain
265 L Mountain
266 L Forest 266 L Forest
266 L Forest 267 L Forest
266 L Forest 268 L Forest
266 L Forest 269 L Forest
270 R Aegis Angel 270 R Aegis Angel
271 C Divine Verdict 271 C Divine Verdict
272 C Inspired Charge 272 C Inspired Charge

View File

@@ -0,0 +1,128 @@
[metadata]
Code=FMB1
Date=2020-03-08
Name=Mystery Booster Retail Edition Foils
Type=Other
[cards]
1 U Not of This World
2 R Celestial Dawn
3 R Celestial Kirin
4 U Changeling Hero
5 U Council Guardian
6 U Eidolon of Rhetoric
7 R Isamaru, Hound of Konda
8 C Lapse of Certainty
9 C Lumithread Field
10 R Norn's Annex
11 R Proclamation of Rebirth
12 U Pull from Eternity
13 R Rune-Tail, Kitsune Ascendant
14 C Sinew Sliver
15 C Soul's Attendant
16 R Spelltithe Enforcer
17 U Springjack Shepherd
18 U Wall of Shards
19 U White Knight
20 C Blighted Agent
21 U Delay
22 R Fatespinner
23 U Frozen Aether
24 R Grand Architect
25 R Intruder Alarm
26 M Misthollow Griffin
27 U Paradox Haze
28 R Patron of the Moon
29 R Puca's Mischief
30 R Spellweaver Volute
31 C Storm Crow
32 R Zur's Weirding
33 R Bringer of the Black Dawn
34 C Chimney Imp
35 R Conspiracy
36 C Echoing Decay
37 R Funeral Charm
38 R Herald of Leshrac
39 R Marrow-Gnawer
40 R Nezumi Shortfang
41 R One with Nothing
42 U Ravenous Trap
43 U Rescue from the Underworld
44 R Undead Warchief
45 C Viscera Seer
46 U Balduvian Rage
47 R Braid of Fire
48 C Burning Inquiry
49 R Fiery Gambit
50 U Flamekin Harbinger
51 R Form of the Dragon
52 C Goblin Bushwhacker
53 U Guerrilla Tactics
54 U Lightning Storm
55 R Norin the Wary
56 C Ogre Gatecrasher
57 C Pyretic Ritual
58 M Scourge of the Throne
59 R Stigma Lasher
60 U Treasonous Ogre
61 R Allosaurus Rider
62 U Archetype of Endurance
63 C Boreal Druid
64 R Boundless Realms
65 U Bramblewood Paragon
66 R Fungusaur
67 C Game-Trail Changeling
68 C Gleeful Sabotage
69 C Greater Mossdog
70 R Helix Pinnacle
71 C Hornet Sting
72 U Manaweft Sliver
73 R Maro
74 R Myojin of Life's Web
75 R Panglacial Wurm
76 R Reki, the History of Kamigawa
77 R Rhox
78 C Sakura-Tribe Scout
79 U Scryb Ranger
80 U Sheltering Ancient
81 U Sosuke, Son of Seshiro
82 R Spike Feeder
83 M Aurelia's Fury
84 U Drogskol Captain
85 R Glittering Wish
86 U Harmonic Sliver
87 M Karrthus, Tyrant of Jund
88 M Maelstrom Nexus
89 U Mind Funeral
90 M Sarkhan the Mad
91 M Sen Triplets
92 R Yore-Tiller Nephilim
93 R Balefire Liege
94 U Gilder Bairn
95 U Kulrath Knight
96 C Noggle Bandit
97 U Wear // Tear
98 R Amulet of Vigor
99 U Blasting Station
100 U Codex Shredder
101 U Geth's Grimoire
102 C Iron Myr
103 R Knowledge Pool
104 U Lantern of Insight
105 R Leveler
106 M Lich's Mirror
107 U Magewright's Stone
108 U Memnite
109 R Mindslaver
110 C Pili-Pala
111 R Reaper King
112 R Sundial of the Infinite
113 R Teferi's Puzzle Box
114 U Trailblazer's Boots
115 R Triskelion
116 R Witchbane Orb
117 R Alchemist's Refuge
118 R Minamo, School at Water's Edge
119 U Mirrodin's Core
120 R Shizo, Death's Storehouse
121 U Stalking Stones

File diff suppressed because it is too large Load Diff

View File

@@ -36,6 +36,15 @@ Type=Other
34 R Marrow-Gnawer 34 R Marrow-Gnawer
35 R Pack Rat 35 R Pack Rat
36 R Rat Colony 36 R Rat Colony
37 R Thalia, Guardian of Thraben
38 R Thalia, Guardian of Thraben
39 R Thalia, Guardian of Thraben
40 R Thalia, Guardian of Thraben
51 M Captain Sisay
52 M Meren of Clan Nel Toth
53 M Narset, Enlightened Master
54 M Oona, Queen of the Fae
55 M Saskia, the Unyielding
68 M Heliod, God of the Sun 68 M Heliod, God of the Sun
69 M Karametra, God of Harvests 69 M Karametra, God of Harvests
70 M Iroas, God of Victory 70 M Iroas, God of Victory

View File

@@ -82,7 +82,7 @@ Prerelease=6 Boosters, 1 RareMythic+
71 M Thassa, Deep-Dwelling 71 M Thassa, Deep-Dwelling
72 R Thassa's Intervention 72 R Thassa's Intervention
73 R Thassa's Oracle 73 R Thassa's Oracle
74 C Thirst For Meaning 74 C Thirst for Meaning
75 U Threnody Singer 75 U Threnody Singer
76 R Thryx, the Sudden Storm 76 R Thryx, the Sudden Storm
77 C Towering-Wave Mystic 77 C Towering-Wave Mystic
@@ -233,7 +233,7 @@ Prerelease=6 Boosters, 1 RareMythic+
222 R Kunoros, Hound of Athreos 222 R Kunoros, Hound of Athreos
223 U Mischievous Chimera 223 U Mischievous Chimera
224 M Polukranos, Unchained 224 M Polukranos, Unchained
225 U Rise To Glory 225 U Rise to Glory
226 U Siona, Captain of the Pyleas 226 U Siona, Captain of the Pyleas
227 U Slaughter-Priest of Mogis 227 U Slaughter-Priest of Mogis
228 U Staggering Insight 228 U Staggering Insight
@@ -367,13 +367,13 @@ Prerelease=6 Boosters, 1 RareMythic+
350 R Temple of Malice 350 R Temple of Malice
351 R Temple of Plenty 351 R Temple of Plenty
#Bundle promo #Bundle promo
R Arasta of the Endless Web 352 R Arasta of the Endless Web
#Promo Pack #Promo Pack
U Alseid of Life's Bounty 353 U Alseid of Life's Bounty
C Thirst For Meaning 354 C Thirst for Meaning
U Gray Merchant of Asphodel 355 U Gray Merchant of Asphodel
C Thrill of Possibility 356 C Thrill of Possibility
U Wolfwillow Haven 357 U Wolfwillow Haven
[tokens] [tokens]
b_2_2_zombie b_2_2_zombie

View File

@@ -284,36 +284,36 @@ Prerelease=6 Boosters, 1 RareMythic+
271 M Oko, Thief of Crowns 271 M Oko, Thief of Crowns
272 M The Royal Scions 272 M The Royal Scions
#Storybook Frames #Storybook Frames
C Ardenvale Tactician 273 C Ardenvale Tactician
C Faerie Guidemother 274 C Faerie Guidemother
R Giant Killer 275 R Giant Killer
C Lonesome Unicorn 276 C Lonesome Unicorn
M Realm-Cloaked Giant 277 M Realm-Cloaked Giant
U Shepherd of the Flock 278 U Shepherd of the Flock
C Silverflame Squire 279 C Silverflame Squire
U Animating Faerie 280 U Animating Faerie
M Brazen Borrower 281 M Brazen Borrower
R Fae of Wishes 282 R Fae of Wishes
U Hypnotic Sprite 283 U Hypnotic Sprite
C Merfolk Secretkeeper 284 C Merfolk Secretkeeper
C Queen of Ice 285 C Queen of Ice
U Foulmire Knight 286 U Foulmire Knight
R Murderous Rider 287 R Murderous Rider
U Order of Midnight 288 U Order of Midnight
C Reaper of Night 289 C Reaper of Night
C Smitten Swordmaster 290 C Smitten Swordmaster
R Bonecrusher Giant 291 R Bonecrusher Giant
U Embereth Shieldbreaker 292 U Embereth Shieldbreaker
C Merchant of the Vale 293 C Merchant of the Vale
C Rimrock Knight 294 C Rimrock Knight
U Beanstalk Giant 295 U Beanstalk Giant
C Curious Pair 296 C Curious Pair
U Flaxen Intruder 297 U Flaxen Intruder
C Garenbrig Carver 298 C Garenbrig Carver
R Lovestruck Beast 299 R Lovestruck Beast
C Rosethorn Acolyte 300 C Rosethorn Acolyte
C Tuinvale Treefolk 301 C Tuinvale Treefolk
U Oakhame Ranger 302 U Oakhame Ranger
#Buy-A-Box Promo #Buy-A-Box Promo
303 M Kenrith, the Returned King 303 M Kenrith, the Returned King
#Planeswalker Deck Cards #Planeswalker Deck Cards
@@ -348,72 +348,72 @@ U Oakhame Ranger
332 R Tome of Legends 332 R Tome of Legends
333 C Command Tower 333 C Command Tower
#Borderless art rares and mythics #Borderless art rares and mythics
R Acclaimed Contender 334 R Acclaimed Contender
R Charming Prince 335 R Charming Prince
M The Circle of Loyalty 336 M The Circle of Loyalty
R Happily Ever After 337 R Happily Ever After
M Harmonious Archon 338 M Harmonious Archon
R Hushbringer 339 R Hushbringer
R Linden, the Steadfast Queen 340 R Linden, the Steadfast Queen
R Worthy Knight 341 R Worthy Knight
R Emry, Lurker of the Loch 342 R Emry, Lurker of the Loch
R Folio of Fancies 343 R Folio of Fancies
R Gadwick, the Wizened 344 R Gadwick, the Wizened
M The Magic Mirror 345 M The Magic Mirror
R Midnight Clock 346 R Midnight Clock
R Mirrormade 347 R Mirrormade
R Stolen by the Fae 348 R Stolen by the Fae
R Vantress Gargoyle 349 R Vantress Gargoyle
R Ayara, First of Locthwain 350 R Ayara, First of Locthwain
R Blacklance Paragon 351 R Blacklance Paragon
M The Cauldron of Eternity 352 M The Cauldron of Eternity
R Clackbridge Troll 353 R Clackbridge Troll
R Oathsworn Knight 354 R Oathsworn Knight
R Piper of the Swarm 355 R Piper of the Swarm
M Rankle, Master of Pranks 356 M Rankle, Master of Pranks
R Wishclaw Talisman 357 R Wishclaw Talisman
R Witch's Vengeance 358 R Witch's Vengeance
M Embercleave 359 M Embercleave
R Fervent Champion 360 R Fervent Champion
R Fires of Invention 361 R Fires of Invention
R Irencrag Feat 362 R Irencrag Feat
R Irencrag Pyromancer 363 R Irencrag Pyromancer
R Opportunistic Dragon 364 R Opportunistic Dragon
M Robber of the Rich 365 M Robber of the Rich
R Sundering Stroke 366 R Sundering Stroke
R Torbran, Thane of Red Fell 367 R Torbran, Thane of Red Fell
R Feasting Troll King 368 R Feasting Troll King
R Gilded Goose 369 R Gilded Goose
M The Great Henge 370 M The Great Henge
R Once Upon A Time 371 R Once Upon a Time
M Questing Beast 372 M Questing Beast
R Return of the Wildspeaker 373 R Return of the Wildspeaker
R Wicked Wolf 374 R Wicked Wolf
R Wildborn Preserver 375 R Wildborn Preserver
R Yorvo, Lord of Garenbrig 376 R Yorvo, Lord of Garenbrig
R Dance of the Manse 377 R Dance of the Manse
R Doom Foretold 378 R Doom Foretold
R Escape to the Wilds 379 R Escape to the Wilds
R Faeburrow Elder 380 R Faeburrow Elder
R Lochmere Serpent 381 R Lochmere Serpent
M Outlaws' Merriment 382 M Outlaws' Merriment
R Stormfist Crusader 383 R Stormfist Crusader
R Sorcerous Spyglass 384 R Sorcerous Spyglass
R Stonecoil Serpent 385 R Stonecoil Serpent
R Castle Ardenvale 386 R Castle Ardenvale
R Castle Embereth 387 R Castle Embereth
R Castle Garenbrig 388 R Castle Garenbrig
R Castle Locthwain 389 R Castle Locthwain
R Castle Vantress 390 R Castle Vantress
R Fabled Passage 391 R Fabled Passage
#Bundle promo #Bundle promo
R Piper of the Swarm 392 R Piper of the Swarm
#Promo Pack #Promo Pack
U Glass Casket 393 U Glass Casket
U Slaying Fire 394 U Slaying Fire
U Kenrith's Transformation 395 U Kenrith's Transformation
U Improbable Alliance 396 U Improbable Alliance
U Inspiring Veteran 397 U Inspiring Veteran
[tokens] [tokens]
w_0_1_goat w_0_1_goat

View File

@@ -0,0 +1,24 @@
[metadata]
Code=UND
Code2=UND
Date=2020-02-29
Name=Unsanctioned
MciCode=und
Type=Other
[cards]
87 L Plains
88 L Plains
89 L Island
90 L Island
91 L Swamp
92 L Swamp
93 L Mountain
94 L Mountain
95 L Forest
96 L Forest
[tokens]
u_1_1_beeble
r_1_1_goblin
g_1_1_squirrel

View File

@@ -34,8 +34,8 @@ b_2_2_vampire_flying
b_2_2_zombie b_2_2_zombie
b_2_2_zombie b_2_2_zombie
r_1_1_brainiac r_1_1_brainiac
r_3_1_elemental_haste r_1_1_elemental
r_3_1_elemental_haste r_1_1_elemental
r_1_1_goblin r_1_1_goblin
g_3_3_beast g_3_3_beast
g_3_3_beast g_3_3_beast

View File

@@ -285,6 +285,42 @@ BoosterMustContain=Planeswalker
273 R Jace's Ruse 273 R Jace's Ruse
274 C Simic Guildgate 274 C Simic Guildgate
275 M Tezzeret, Master of the Bridge 275 M Tezzeret, Master of the Bridge
1★ R Karn, the Great Creator
2★ R Ugin, the Ineffable
13★ M Gideon Blackblade
32★ U Teyo, the Shieldmage
37★ U The Wanderer
54★ R Jace, Wielder of Mysteries
56★ U Kasmina, Enigmatic Mentor
61★ U Narset, Parter of Veils
83★ U Davriel, Rogue Shadowmage
97★ M Liliana, Dreadhorde General
100★ U Ob Nixilis, the Hate-Twisted
119★ R Chandra, Fire Artisan
135★ U Jaya, Venerated Firemage
143★ R Sarkhan the Masterless
146★ U Tibalt, Rakish Instigator
150★ U Arlinn, Voice of the Pack
164★ U Jiang Yanggu, Wildcrafter
169★ R Nissa, Who Shakes the World
180★ R Vivien, Champion of the Wilds
184★ R Ajani, the Greathearted
191★ R Domri, Anarch of Bolas
207★ M Nicol Bolas, Dragon-God
211★ R Ral, Storm Conduit
217★ R Sorin, Vengeful Bloodlord
220★ R Tamiyo, Collector of Tales
221★ R Teferi, Time Raveler
227★ U Angrath, Captain of Chaos
228★ U Ashiok, Dream Render
229★ U Dovin, Hand of Control
230★ U Huatli, the Sun's Heart
231★ U Kaya, Bane of the Dead
232★ U Kiora, Behemoth Beckoner
233★ U Nahiri, Storm of Stone
234★ U Saheeli, Sublime Artificer
235★ U Samut, Tyrant Smasher
236★ U Vraska, Swarm's Eminence
[tokens] [tokens]
wubrg_2_2_citizen wubrg_2_2_citizen

View File

@@ -178,5 +178,5 @@ R Winding Canyons
R Xanthic Statue R Xanthic Statue
C Zombie Scavengers C Zombie Scavengers
[token] [tokens]
g_1_1_squirrel g_1_1_squirrel

View File

@@ -4,4 +4,4 @@ Order:103
Subtype:Modern Subtype:Modern
Type:Sanctioned Type:Sanctioned
Sets:8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, LRW, EVE, SHM, MOR, ALA, CFX, ARB, M10, ZEN, WWK, ROE, M11, SOM, MBS, NPH, M12, ISD, DKA, AVR, M13, RTR, GTC, DGM, M14, THS, BNG, JOU, M15, KTK, FRF, DTK, MM2, ORI, BFZ, OGW, SOI, EMN, KLD, AER, AKH, W17, HOU, XLN, RIX, DOM, M19, G18, GRN, RNA, WAR, MH1, M20, ELD, THB Sets:8ED, MRD, DST, 5DN, CHK, BOK, SOK, 9ED, RAV, GPT, DIS, CSP, TSP, TSB, PLC, FUT, 10E, LRW, EVE, SHM, MOR, ALA, CFX, ARB, M10, ZEN, WWK, ROE, M11, SOM, MBS, NPH, M12, ISD, DKA, AVR, M13, RTR, GTC, DGM, M14, THS, BNG, JOU, M15, KTK, FRF, DTK, MM2, ORI, BFZ, OGW, SOI, EMN, KLD, AER, AKH, W17, HOU, XLN, RIX, DOM, M19, G18, GRN, RNA, WAR, MH1, M20, ELD, THB
Banned:Ancient Den; Birthing Pod; Blazing Shoal; Bridge From Below; Chrome Mox; Cloudpost; Dark Depths; Deathrite Shaman; Dig Through Time; Dread Return; Eye of Ugin; Faithless Looting; Gitaxian Probe; Glimpse of Nature; Golgari Grave-Troll; Great Furnace; Green Sun's Zenith; Hogaak, Arisen Necropolis; Hypergenesis; Krark-Clan Ironworks; Mental Misstep; Ponder; Preordain; Punishing Fire; Rite of Flame; Seat of the Synod; Second Sunrise; Seething Song; Sensei's Divining Top; Skullclamp; Splinter Twin; Summer Bloom; Treasure Cruise; Tree of Tales; Umezawa's Jitte; Vault of Whispers Banned:Ancient Den; Birthing Pod; Blazing Shoal; Bridge from Below; Chrome Mox; Cloudpost; Dark Depths; Deathrite Shaman; Dig Through Time; Dread Return; Eye of Ugin; Faithless Looting; Gitaxian Probe; Glimpse of Nature; Golgari Grave-Troll; Great Furnace; Green Sun's Zenith; Hogaak, Arisen Necropolis; Hypergenesis; Krark-Clan Ironworks; Mental Misstep; Mox Opal; Mycosynth Lattice; Oko, Thief of Crowns; Ponder; Preordain; Punishing Fire; Rite of Flame; Seat of the Synod; Second Sunrise; Seething Song; Sensei's Divining Top; Skullclamp; Splinter Twin; Summer Bloom; Treasure Cruise; Tree of Tales; Umezawa's Jitte; Vault of Whispers

View File

@@ -4,4 +4,4 @@ Order:102
Subtype:Pioneer Subtype:Pioneer
Type:Sanctioned Type:Sanctioned
Sets:RTR, GTC, DGM, M14, THS, BNG, JOU, M15, KTK, FRF, DTK, ORI, BFZ, OGW, SOI, EMN, KLD, AER, AKH, HOU, XLN, RIX, DOM, M19, GRN, RNA, WAR, M20, ELD, THB Sets:RTR, GTC, DGM, M14, THS, BNG, JOU, M15, KTK, FRF, DTK, ORI, BFZ, OGW, SOI, EMN, KLD, AER, AKH, HOU, XLN, RIX, DOM, M19, GRN, RNA, WAR, M20, ELD, THB
Banned:Bloodstained Mire; Flooded Strand; Polluted Delta; Windswept Heath; Wooded Foothills; Felidar Guardian; Leyline of Abundance; Oath of Nissa; Veil of Summer; Field of the Dead; Once Upon a Time; Smugglers Copter Banned:Bloodstained Mire; Felidar Guardian; Field of the Dead; Flooded Strand; Leyline of Abundance; Nexus of Fate; Oath of Nissa; Oko, Thief of Crowns; Once Upon a Time; Polluted Delta; Smuggler's Copter; Veil of Summer; Windswept Heath; Wooded Foothills

View File

@@ -2126,6 +2126,7 @@ lblLoadingCurrentConquest=Loading current conquest...
lblSelectCommander=Select Commander lblSelectCommander=Select Commander
lblCantSelectDeckBecause=Can''t select {0} \nDeck {1} lblCantSelectDeckBecause=Can''t select {0} \nDeck {1}
#ConquestAEtherScreen.java #ConquestAEtherScreen.java
lblShardsAE=Shards: {0}
lblHaveNAEShards=Shards: {0} {1} lblHaveNAEShards=Shards: {0} {1}
lblTapToPullFromAE=Tap to pull from the Aether\n{0} lblTapToPullFromAE=Tap to pull from the Aether\n{0}
lblSelectCaptionFilter=Select {0} Filter lblSelectCaptionFilter=Select {0} Filter

View File

@@ -0,0 +1,17 @@
[metadata]
Name:Possibility Storm - Theros Beyond Death #05
URL:https://i2.wp.com/www.possibilitystorm.com/wp-content/uploads/2020/02/148.-THB5-scaled.jpg
Goal:Win
Turns:1
Difficulty:Rare
Description:Win this turn. You have eight cards remaining in your library. Assume these cards are not relevant to the solution.
[state]
humanlife=20
ailife=10
turn=1
activeplayer=human
activephase=MAIN1
humanhand=Devious Cover-Up;Dawn of Hope;Frogify;Phoenix of Ash;Sentinel's Eyes
humanlibrary=Opt;Opt;Opt;Opt;Opt;Opt;Opt;Opt
humanbattlefield=Fblthp, the Lost;Elspeth, Sun's Nemesis|Counters:LOYALTY=4;Glint-Horn Buccaneer|Id:1;Benthic Biomancer;Heliod, Sun-Crowned;Hallowed Fountain|NoETBTrigs;Hallowed Fountain|NoETBTrigs;Hallowed Fountain|NoETBTrigs;Sacred Foundry|NoETBTrigs;Sacred Foundry|NoETBTrigs;Sacred Foundry|NoETBTrigs
aibattlefield=Hushbringer|Tapped;Bishop of Wings;Gilded Goose;Setessan Champion;Arboreal Grazer;Demotion|AttachedTo:1

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" ?> <?xml version="1.0" ?>
<bazaar> <bazaar>
<options> <options>
<iconSize>80</iconSize> <iconSize>160</iconSize>
</options> </options>
<stalls> <stalls>
<stall name="Alchemist" displayName="Orim, Samite Healer" icon="ICO_QUEST_BOTTLES"> <stall name="Alchemist" displayName="Orim, Samite Healer" icon="ICO_QUEST_BOTTLES">
@@ -26,7 +26,7 @@
<string>Sleight</string> <string>Sleight</string>
</items> </items>
</stall> </stall>
<stall name="Gear" displayName="The Rope and Axe" icon="ICO_QUEST_GEAR"> <stall name="Gear" displayName="The Rope and Axe" icon="ICO_QUEST_BIG_ARMOR">
<description>This adventurer&apos;s market has a tool for every need ... or so the plaque on the wall claims.</description> <description>This adventurer&apos;s market has a tool for every need ... or so the plaque on the wall claims.</description>
<items> <items>
<string>Map</string> <string>Map</string>
@@ -53,22 +53,22 @@
</stall> </stall>
</stalls> </stalls>
<questItems> <questItems>
<item name="Sleight" purchaseName="Sleight of Hand Vol. I" maxLevel="1" basePrice="2000" itemType="SLEIGHT" icon="ICO_QUEST_BOOK"> <item name="Sleight" purchaseName="Sleight of Hand Vol. I" maxLevel="1" basePrice="2000" itemType="SLEIGHT" icon="ICO_QUEST_BIG_BOOK">
<description>These volumes explain how to perform the most difficult of sleights. <description>These volumes explain how to perform the most difficult of sleights.
Effect: Your first mulligan is free.</description> Effect: Your first mulligan is free.</description>
</item> </item>
<item name="Map" purchaseName="Adventurer&apos;s Map" maxLevel="1" basePrice="2000" itemType="MAP" icon="ICO_QUEST_MAP"> <item name="Map" purchaseName="Adventurer&apos;s Map" maxLevel="1" basePrice="2000" itemType="MAP" icon="ICO_QUEST_BIG_MAP">
<description>These ancient charts should facilitate navigation during your travels significantly. <description>These ancient charts should facilitate navigation during your travels significantly.
Effect: Quest challenges become available more frequently.</description> Effect: Quest challenges become available more frequently.</description>
</item> </item>
<item name="Lucky Coin" maxLevel="1" basePrice="2000" itemType="LUCKY_COIN" icon="ICO_QUEST_COIN"> <item name="Lucky Coin" maxLevel="1" basePrice="2000" itemType="LUCKY_COIN" icon="ICO_QUEST_BIG_COIN">
<description>This coin is believed to give good luck to its owner. <description>This coin is believed to give good luck to its owner.
Effect: Improves the chance of getting a random rare after each match by 15%.</description> Effect: Improves the chance of getting a random rare after each match by 15%.</description>
</item> </item>
<item name="Estates" maxLevel="3" basePrice="250" itemType="ESTATES" icon="ICO_QUEST_GOLD"> <item name="Estates" maxLevel="3" basePrice="250" itemType="ESTATES" icon="ICO_QUEST_BIG_HOUSE">
<description>Land owners have a strong voice in community matters. <description>Land owners have a strong voice in community matters.
Effect: Gives a bonus of %d%% to match winnings. Effect: Gives a bonus of %d%% to match winnings.
@@ -81,37 +81,37 @@ Effect: Quest challenges become available more frequently.
Effect: +3 life Effect: +3 life
Effect: Activate once for a new set of challenges (re-fuels after a challenge is attempted).</description> Effect: Activate once for a new set of challenges (re-fuels after a challenge is attempted).</description>
</item> </item>
<item name="Pound of Flesh" maxLevel="29" basePrice="250" itemType="POUND_FLESH" icon="ICO_QUEST_BREW"> <item name="Pound of Flesh" maxLevel="29" basePrice="250" itemType="POUND_FLESH" icon="ICO_QUEST_BIG_BREW">
<description>The Alchemist welcomes contributions to his famous Elixir. <description>The Alchemist welcomes contributions to his famous Elixir.
But beware, you may build an immunity to its effects... But beware, you may build an immunity to its effects...
Effect: Alchemist gives you %d credits. Effect: Alchemist gives you %d credits.
Effect: Reduces maximum life by 1.</description> Effect: Reduces maximum life by 1.</description>
</item> </item>
<item name="Elixir of Life" maxLevel="15" basePrice="250" itemType="ELIXIR_OF_LIFE" icon="ICO_QUEST_ELIXIR"> <item name="Elixir of Life" maxLevel="15" basePrice="250" itemType="ELIXIR_OF_LIFE" icon="ICO_QUEST_BIG_ELIXIR">
<description>A salty sweet smell rises from the vials bubbling behind the counter. <description>A salty sweet smell rises from the vials bubbling behind the counter.
Effect: Gives +1 to maximum life. Effect: Gives +1 to maximum life.
Fine Print: Loses effectiveness after 15 uses.</description> Fine Print: Loses effectiveness after 15 uses.</description>
</item> </item>
<item name="Charm of Vim" maxLevel="1" basePrice="1000" <item name="Charm of Vim" maxLevel="1" basePrice="1000"
itemType="CHARM_VIM" icon="ICO_QUEST_CHARM"> itemType="CHARM_VIM" icon="ICO_QUEST_BIG_BOOTS">
<description>A charm fills you with energy, speeding your movements. <description>A charm fills you with energy, speeding your movements.
Effect: You may have each match be best of 1 instead of 3.</description> Effect: You may have each match be best of 1 instead of 3.</description>
</item> </item>
<item name="Charm of Vigor" maxLevel="1" basePrice="1000" <item name="Charm of Vigor" maxLevel="1" basePrice="1000"
itemType="CHARM" icon="ICO_QUEST_CHARM"> itemType="CHARM" icon="ICO_QUEST_BIG_CHARM">
<description>A charm to ward off the fatigue of battle. <description>A charm to ward off the fatigue of battle.
Effect: You may have each match be best of 5 instead of 3.</description> Effect: You may have each match be best of 5 instead of 3.</description>
</item> </item>
<item name="Cash Stakes" maxLevel="1" basePrice="1500" itemType="CASH_STAKES" icon="ICO_QUEST_STAKES"> <item name="Cash Stakes" maxLevel="1" basePrice="1500" itemType="CASH_STAKES" icon="ICO_QUEST_BIG_STAKES">
<description>A written agreement with the Spell Shop to acquire cards you lose in an ante match from quest opponents. <description>A written agreement with the Spell Shop to acquire cards you lose in an ante match from quest opponents.
Effect: Cards lost in an ante match will be available immediately following the match in the Card Shop.</description> Effect: Cards lost in an ante match will be available immediately following the match in the Card Shop.</description>
</item> </item>
<item name="Bank Membership" maxLevel="3" basePrice="2500" itemType="MEMBERSHIP_TOKEN" icon="ICO_QUEST_GOLD"> <item name="Bank Membership" maxLevel="3" basePrice="2500" itemType="MEMBERSHIP_TOKEN" icon="ICO_QUEST_BIG_BM">
<description>A token certifying you as a member of the bank, giving you a greater selection of booster packs when you win. <description>A token certifying you as a member of the bank, giving you a greater selection of booster packs when you win.
Effect: Adds one more booster pack to the pack selection after you win.</description> Effect: Adds one more booster pack to the pack selection after you win.</description>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 523 KiB

After

Width:  |  Height:  |  Size: 534 KiB

View File

@@ -0,0 +1,6 @@
Name:Beeble
ManaCost:no cost
Types:Creature Beeble
Colors:blue
PT:1/1
Oracle:

View File

@@ -182,6 +182,15 @@ public enum FSkinProp {
ICO_ARCSON (new int[] {320, 800, 80, 80}, PropType.ICON), ICO_ARCSON (new int[] {320, 800, 80, 80}, PropType.ICON),
ICO_ARCSHOVER (new int[] {400, 800, 80, 80}, PropType.ICON), ICO_ARCSHOVER (new int[] {400, 800, 80, 80}, PropType.ICON),
//choice-search-misc
ICO_HDCHOICE (new int[] {2, 1792, 128, 128}, PropType.BUTTONS),
ICO_HDSIDEBOARD (new int[] {132, 1792, 128, 128}, PropType.BUTTONS),
ICO_HDPREFERENCE (new int[] {262, 1792, 128, 128}, PropType.BUTTONS),
ICO_HDIMPORT (new int[] {2, 1922, 128, 128}, PropType.BUTTONS),
ICO_HDEXPORT (new int[] {132, 1922, 128, 128}, PropType.BUTTONS),
ICO_BLANK (new int[] {2, 2, 2, 2}, PropType.ICON), //safe coords, lower than 2 will cause crash on desktop
IMG_LANDLOGO (new int[] {84, 822, 80, 80}, PropType.MANAICONS),
//quest icons //quest icons
ICO_QUEST_ZEP (new int[] {0, 480, 80, 80}, PropType.ICON), ICO_QUEST_ZEP (new int[] {0, 480, 80, 80}, PropType.ICON),
ICO_QUEST_GEAR (new int[] {80, 480, 80, 80}, PropType.ICON), ICO_QUEST_GEAR (new int[] {80, 480, 80, 80}, PropType.ICON),
@@ -204,6 +213,22 @@ public enum FSkinProp {
ICO_QUEST_MINUS (new int[] {560, 640, 80, 80}, PropType.ICON), ICO_QUEST_MINUS (new int[] {560, 640, 80, 80}, PropType.ICON),
ICO_QUEST_PLUS (new int[] {480, 640, 80, 80}, PropType.ICON), ICO_QUEST_PLUS (new int[] {480, 640, 80, 80}, PropType.ICON),
ICO_QUEST_PLUSPLUS (new int[] {480, 720, 80, 80}, PropType.ICON), ICO_QUEST_PLUSPLUS (new int[] {480, 720, 80, 80}, PropType.ICON),
ICO_QUEST_BIG_ELIXIR (new int[] {0, 880, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_BREW (new int[] {160, 880, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_BM (new int[] {320, 880, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_STAKES (new int[] {480, 880, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_HOUSE (new int[] {0, 1040, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_COIN (new int[] {160, 1040, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_BOOK (new int[] {320, 1040, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_MAP (new int[] {480, 1040, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_ZEP (new int[] {0, 1200, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_CHARM (new int[] {160, 1200, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_BOOTS (new int[] {320, 1200, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_SHIELD (new int[] {480, 1200, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_ARMOR (new int[] {0, 1360, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_AXE (new int[] {160, 1360, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_SWORD (new int[] {320, 1360, 160, 160}, PropType.ICON),
ICO_QUEST_BIG_BAG (new int[] {480, 1360, 160, 160}, PropType.ICON),
//interface icons //interface icons
ICO_QUESTION (new int[] {560, 800, 32, 32}, PropType.ICON), ICO_QUESTION (new int[] {560, 800, 32, 32}, PropType.ICON),
@@ -278,6 +303,7 @@ public enum FSkinProp {
IMG_INSTANT (new int[] {166, 740, 80, 80}, PropType.MANAICONS), IMG_INSTANT (new int[] {166, 740, 80, 80}, PropType.MANAICONS),
IMG_LAND (new int[] {248, 740, 80, 80}, PropType.MANAICONS), IMG_LAND (new int[] {248, 740, 80, 80}, PropType.MANAICONS),
IMG_MULTI (new int[] {80, 720, 40, 40}, PropType.IMAGE), IMG_MULTI (new int[] {80, 720, 40, 40}, PropType.IMAGE),
IMG_HDMULTI (new int[] {2, 822, 80, 80}, PropType.MANAICONS),
IMG_PLANESWALKER (new int[] {330, 740, 80, 80}, PropType.MANAICONS), IMG_PLANESWALKER (new int[] {330, 740, 80, 80}, PropType.MANAICONS),
IMG_PACK (new int[] {80, 760, 40, 40}, PropType.IMAGE), IMG_PACK (new int[] {80, 760, 40, 40}, PropType.IMAGE),
IMG_SORCERY (new int[] {412, 740, 80, 80}, PropType.MANAICONS), IMG_SORCERY (new int[] {412, 740, 80, 80}, PropType.MANAICONS),

View File

@@ -1,6 +1,7 @@
package forge.itemmanager; package forge.itemmanager;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import forge.GuiBase;
import forge.assets.FSkinProp; import forge.assets.FSkinProp;
import forge.assets.IHasSkinProp; import forge.assets.IHasSkinProp;
import forge.card.CardRules; import forge.card.CardRules;
@@ -35,7 +36,8 @@ public final class SItemManagerUtil {
RED (FSkinProp.IMG_MANA_R, CardRulesPredicates.Presets.IS_RED, "lblRedcards"), RED (FSkinProp.IMG_MANA_R, CardRulesPredicates.Presets.IS_RED, "lblRedcards"),
GREEN (FSkinProp.IMG_MANA_G, CardRulesPredicates.Presets.IS_GREEN, "lblGreencards"), GREEN (FSkinProp.IMG_MANA_G, CardRulesPredicates.Presets.IS_GREEN, "lblGreencards"),
COLORLESS (FSkinProp.IMG_MANA_COLORLESS, CardRulesPredicates.Presets.IS_COLORLESS, "lblColorlesscards"), COLORLESS (FSkinProp.IMG_MANA_COLORLESS, CardRulesPredicates.Presets.IS_COLORLESS, "lblColorlesscards"),
MULTICOLOR (FSkinProp.IMG_MULTI, CardRulesPredicates.Presets.IS_MULTICOLOR, "lblMulticolorcards"), MULTICOLOR (GuiBase.getInterface().isLibgdxPort() ? FSkinProp.IMG_HDMULTI :
FSkinProp.IMG_MULTI, CardRulesPredicates.Presets.IS_MULTICOLOR, "lblMulticolorcards"),
PACK_OR_DECK (FSkinProp.IMG_PACK, null, "lblPackordeck"), PACK_OR_DECK (FSkinProp.IMG_PACK, null, "lblPackordeck"),
LAND (FSkinProp.IMG_LAND, CardRulesPredicates.Presets.IS_LAND, "lblLands"), LAND (FSkinProp.IMG_LAND, CardRulesPredicates.Presets.IS_LAND, "lblLands"),
@@ -60,7 +62,8 @@ public final class SItemManagerUtil {
DECK_RED (FSkinProp.IMG_MANA_R, null, "lblReddecks"), DECK_RED (FSkinProp.IMG_MANA_R, null, "lblReddecks"),
DECK_GREEN (FSkinProp.IMG_MANA_G, null, "lblGreendecks"), DECK_GREEN (FSkinProp.IMG_MANA_G, null, "lblGreendecks"),
DECK_COLORLESS (FSkinProp.IMG_MANA_COLORLESS, null, "lblColorlessdecks"), DECK_COLORLESS (FSkinProp.IMG_MANA_COLORLESS, null, "lblColorlessdecks"),
DECK_MULTICOLOR (FSkinProp.IMG_MULTI, null, "lblMulticolordecks"), DECK_MULTICOLOR (GuiBase.getInterface().isLibgdxPort() ? FSkinProp.IMG_HDMULTI :
FSkinProp.IMG_MULTI, null, "lblMulticolordecks"),
FOIL_OLD (FSkinProp.FOIL_11, null, "lblOldstyleFoilcards"), FOIL_OLD (FSkinProp.FOIL_11, null, "lblOldstyleFoilcards"),
FOIL_NEW (FSkinProp.FOIL_01, null, "lblNewstyleFoilcards"), FOIL_NEW (FSkinProp.FOIL_01, null, "lblNewstyleFoilcards"),

View File

@@ -75,7 +75,7 @@ public enum ProtocolMethod {
clearSelectables (Mode.SERVER), clearSelectables (Mode.SERVER),
refreshField (Mode.SERVER), refreshField (Mode.SERVER),
// TODO case "setPlayerAvatar": // TODO case "setPlayerAvatar":
openZones (Mode.SERVER, PlayerZoneUpdates.class, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class), openZones (Mode.SERVER, PlayerZoneUpdates.class, PlayerView.class, Collection/*ZoneType*/.class, Map/*PlayerView,Object*/.class),
restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, PlayerZoneUpdates.class), restoreOldZones (Mode.SERVER, Void.TYPE, PlayerView.class, PlayerZoneUpdates.class),
isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class), isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class),
setRememberedActions(Mode.SERVER, Void.TYPE), setRememberedActions(Mode.SERVER, Void.TYPE),

View File

@@ -746,7 +746,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
endTempShowCards(); endTempShowCards();
} else { } else {
getGui().message(MessageUtil.formatMessage(localizer.getMessage("lblThereNoCardInPlayerZone", "{player's}", zone.getTranslatedName().toLowerCase()), getGui().message(MessageUtil.formatMessage(localizer.getMessage("lblThereNoCardInPlayerZone", "{player's}", zone.getTranslatedName().toLowerCase()),
player, owner), fm); getLocalPlayerView(), owner), fm);
} }
} }

View File

@@ -45,21 +45,21 @@ public abstract class ImageFetcher {
final String filename = ImageUtil.getImageKey(paperCard, backFace, true); final String filename = ImageUtil.getImageKey(paperCard, backFace, true);
destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR + "/" + filename + ".jpg"); destFile = new File(ForgeConstants.CACHE_CARD_PICS_DIR + "/" + filename + ".jpg");
// First try to download the LQ Set URL, then fetch from scryfall/magiccards.info // First try to download the LQ Set URL, then fetch from scryfall
StringBuilder setDownload = new StringBuilder(ForgeConstants.URL_PIC_DOWNLOAD); StringBuilder setDownload = new StringBuilder(ForgeConstants.URL_PIC_DOWNLOAD);
setDownload.append(ImageUtil.getDownloadUrl(paperCard, backFace)); setDownload.append(ImageUtil.getDownloadUrl(paperCard, backFace));
downloadUrls.add(setDownload.toString()); downloadUrls.add(setDownload.toString());
int artIndex = Integer.parseInt(imageKey.split("\\|")[2]);
final StaticData data = StaticData.instance(); final StaticData data = StaticData.instance();
final int cardNum = data.getCommonCards().getCardCollectorNumber(paperCard.getName(), paperCard.getEdition()); final String cardNum = data.getCommonCards().getCardCollectorNumber(paperCard.getName(), paperCard.getEdition(), artIndex);
if (cardNum != -1) { if (cardNum != null) {
String suffix = ""; String suffix = "";
if (paperCard.getRules().getOtherPart() != null) { if (paperCard.getRules().getOtherPart() != null) {
suffix = (backFace ? "b" : "a"); suffix = (backFace ? "b" : "a");
} }
final String editionMciCode = data.getEditions().getMciCodeByCode(paperCard.getEdition()); final String editionMciCode = data.getEditions().getMciCodeByCode(paperCard.getEdition());
downloadUrls.add(String.format("https://img.scryfall.com/cards/normal/en/%s/%d%s.jpg", editionMciCode, cardNum, suffix)); downloadUrls.add(String.format("https://img.scryfall.com/cards/normal/en/%s/%s%s.jpg", editionMciCode, cardNum, suffix));
downloadUrls.add(String.format("https://magiccards.info/scans/en/%s/%d%s.jpg", editionMciCode, cardNum, suffix));
} }
} else if (prefix.equals(ImageKeys.TOKEN_PREFIX)) { } else if (prefix.equals(ImageKeys.TOKEN_PREFIX)) {
if (tokenImages == null) { if (tokenImages == null) {