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 ((!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;
}
}

View File

@@ -34,12 +34,12 @@ import forge.game.card.CardCollectionView;
import forge.game.card.CardLists;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.player.PlayerCollection;
import forge.game.player.PlayerPredicates;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
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
@@ -54,8 +54,6 @@ import forge.util.collect.FCollectionView;
// (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
// 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>
@@ -77,7 +75,7 @@ public class ControlGainAi extends SpellAbilityAi {
final TargetRestrictions tgt = sa.getTargetRestrictions();
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 (tgt == null) {
@@ -94,18 +92,19 @@ public class ControlGainAi extends SpellAbilityAi {
sa.setTargetingPlayer(targetingPlayer);
return targetingPlayer.getController().chooseTargetsFor(sa);
}
if (tgt.isRandomTarget()) {
sa.getTargets().add(Aggregates.random(tgt.getAllCandidates(sa, false)));
}
if (tgt.canOnlyTgtOpponent()) {
List<Player> oppList = Lists
.newArrayList(Iterables.filter(opponents, PlayerPredicates.isTargetableBy(sa)));
List<Player> oppList = opponents.filter(PlayerPredicates.isTargetableBy(sa));
if (oppList.isEmpty()) {
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;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import forge.ai.*;
import forge.game.Game;
@@ -12,11 +12,9 @@ import forge.game.card.CardPredicates;
import forge.game.combat.Combat;
import forge.game.combat.CombatUtil;
import forge.game.keyword.Keyword;
import forge.game.phase.PhaseHandler;
import forge.game.phase.PhaseType;
import forge.game.player.Player;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.TargetRestrictions;
import forge.game.zone.ZoneType;
import java.util.List;
@@ -28,7 +26,6 @@ public class MustBlockAi extends SpellAbilityAi {
final Card source = sa.getHostCard();
final Game game = aiPlayer.getGame();
final Combat combat = game.getCombat();
final PhaseHandler ph = game.getPhaseHandler();
final boolean onlyLethal = !"AllowNonLethal".equals(sa.getParam("AILogic"));
if (combat == null || !combat.isAttacking(source)) {
@@ -39,7 +36,6 @@ public class MustBlockAi extends SpellAbilityAi {
return false;
}
final TargetRestrictions abTgt = sa.getTargetRestrictions();
final List<Card> list = determineGoodBlockers(source, aiPlayer, combat.getDefenderPlayerByAttacker(source), sa, onlyLethal,false);
if (!list.isEmpty()) {
@@ -69,7 +65,6 @@ public class MustBlockAi extends SpellAbilityAi {
@Override
protected boolean doTriggerAINoCost(final Player ai, SpellAbility sa, boolean mandatory) {
final Card source = sa.getHostCard();
final TargetRestrictions abTgt = sa.getTargetRestrictions();
// only use on creatures that can attack
if (!ai.getGame().getPhaseHandler().getPhase().isBefore(PhaseType.MAIN2)) {
@@ -94,7 +89,7 @@ public class MustBlockAi extends SpellAbilityAi {
boolean chance = false;
if (abTgt != null) {
if (sa.usesTargeting()) {
final List<Card> list = determineGoodBlockers(definedAttacker, ai, ai.getWeakestOpponent(), sa, true,true);
if (list.isEmpty()) {
return false;
@@ -119,6 +114,9 @@ public class MustBlockAi extends SpellAbilityAi {
sa.getTargets().add(blocker);
chance = true;
} else if (sa.hasParam("Choices")) {
// currently choice is attacked player
return true;
} else {
return false;
}
@@ -126,16 +124,9 @@ public class MustBlockAi extends SpellAbilityAi {
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 Card source = sa.getHostCard();
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>() {
List<Card> list = CardLists.filter(options, new Predicate<Card>() {
@Override
public boolean apply(final Card c) {
boolean tapped = c.isTapped();
@@ -161,4 +152,40 @@ public class MustBlockAi extends SpellAbilityAi {
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);
}
public int getCardCollectorNumber(String cardName, String reqEdition) {
public String getCardCollectorNumber(String cardName, String reqEdition, int artIndex) {
cardName = getName(cardName);
CardEdition edition = editions.get(reqEdition);
if (edition == null)
return -1;
return null;
int numMatches = 0;
for (CardInSet card : edition.getCards()) {
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) {

View File

@@ -38,6 +38,8 @@ import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
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 final CardRarity rarity;
public final int collectorNumber;
public final String collectorNumber;
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.collectorNumber = collectorNumber;
this.rarity = rarity;
@@ -86,7 +88,7 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
public String toString() {
StringBuilder sb = new StringBuilder();
if (collectorNumber != -1) {
if (collectorNumber != null) {
sb.append(collectorNumber);
sb.append(' ');
}
@@ -266,24 +268,23 @@ public final class CardEdition implements Comparable<CardEdition> { // immutable
Map<String, Integer> tokenNormalized = new HashMap<>();
List<CardEdition.CardInSet> processedCards = new ArrayList<>();
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")) {
if (StringUtils.isBlank(line))
continue;
// Optional collector number at the start.
String[] split = line.split(" ", 2);
int collectorNumber = -1;
if (split.length >= 2 && StringUtils.isNumeric(split[0])) {
collectorNumber = Integer.parseInt(split[0]);
line = split[1];
Matcher matcher = pattern.matcher(line);
if (matcher.matches()) {
String collectorNumber = matcher.group("cnum");
CardRarity r = CardRarity.smartValueOf(matcher.group("rarity"));
String cardName = matcher.group("name");
CardInSet cis = new CardInSet(cardName, collectorNumber, r);
processedCards.add(cis);
}
// 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(
"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",
"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");
@Override

View File

@@ -375,7 +375,7 @@ public class GameAction {
// the LKI needs to be the Card itself,
// or it might not updated correctly
// TODO be reworked when ZoneTrigger Update is done
if (toBattlefield) {
if (toBattlefield || zoneTo.is(ZoneType.Stack)) {
lastKnownInfo = c;
}
@@ -565,16 +565,31 @@ public class GameAction {
public final void controllerChangeZoneCorrection(final Card c) {
System.out.println("Correcting zone for " + c.toString());
final Zone oldBattlefield = game.getZoneOf(c);
if (oldBattlefield == null || oldBattlefield.getZoneType() == ZoneType.Stack) {
if (oldBattlefield == null || oldBattlefield.is(ZoneType.Stack)) {
return;
}
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)) {
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);
for (Player p : game.getPlayers()) {
((PlayerZoneBattlefield) p.getZone(ZoneType.Battlefield)).setTriggers(false);

View File

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

View File

@@ -6,7 +6,6 @@ import java.util.List;
import com.google.common.collect.Lists;
import forge.GameCommand;
import forge.card.mana.ManaCost;
import forge.game.Game;
import forge.game.GameEntity;
import forge.game.ability.AbilityUtils;
@@ -18,7 +17,6 @@ import forge.game.combat.Combat;
import forge.game.event.GameEventCardStatsChanged;
import forge.game.event.GameEventCombatChanged;
import forge.game.player.Player;
import forge.game.spellability.Ability;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.collect.FCollectionView;
@@ -26,9 +24,7 @@ import forge.util.Localizer;
import forge.util.CardTranslation;
public class ControlGainEffect extends SpellAbilityEffect {
/* (non-Javadoc)
* @see forge.card.abilityfactory.SpellEffect#getStackDescription(java.util.Map, forge.card.spellability.SpellAbility)
*/
@Override
protected String getStackDescription(SpellAbility sa) {
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.")) {
return;
}
final Game game = host.getGame();
if (c.isInPlay()) {
c.removeTempController(tStamp);
game.getAction().controllerChangeZoneCorrection(c);
if (tapOnLose) {
c.tap();
}
} // if
host.removeGainControlTargets(c);
}
@Override
@@ -84,11 +82,9 @@ public class ControlGainEffect extends SpellAbilityEffect {
final boolean bUntap = sa.hasParam("Untap");
final boolean bTapOnLose = sa.hasParam("TapOnLose");
final boolean bNoRegen = sa.hasParam("NoRegen");
final boolean remember = sa.hasParam("RememberControlled");
final boolean forget = sa.hasParam("ForgetControlled");
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> 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) {
// Add keywords only until end of turn
final GameCommand untilKeywordEOT = new GameCommand() {
@@ -241,43 +225,6 @@ public class ControlGainEffect extends SpellAbilityEffect {
} // 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>
* getLoseControlCommand.

View File

@@ -1,34 +1,62 @@
package forge.game.ability.effects;
import forge.game.Game;
import forge.game.ability.AbilityUtils;
import forge.game.ability.SpellAbilityEffect;
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.TargetRestrictions;
import forge.game.zone.ZoneType;
import forge.util.Localizer;
import java.util.ArrayList;
import java.util.List;
import com.google.common.collect.Lists;
public class MustBlockEffect extends SpellAbilityEffect {
@Override
public void resolve(SpellAbility sa) {
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");
List<Card> cards;
if (sa.hasParam("DefinedAttacker")) {
cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("DefinedAttacker"), sa);
} else {
cards = new ArrayList<>();
cards.add(host);
cards = Lists.newArrayList(host);
}
for (final Card c : tgtCards) {
if ((tgt == null) || c.canBeTargetedBy(sa)) {
if ((!sa.usesTargeting()) || c.canBeTargetedBy(sa)) {
if (mustBlockAll) {
c.addMustBlockCards(cards);
} else {
@@ -48,8 +76,6 @@ public class MustBlockEffect extends SpellAbilityEffect {
// end standard pre-
final List<Card> tgtCards = getTargetCards(sa);
String attacker = null;
if (sa.hasParam("DefinedAttacker")) {
final List<Card> cards = AbilityUtils.getDefinedCards(sa.getHostCard(), sa.getParam("DefinedAttacker"), sa);
@@ -58,10 +84,13 @@ public class MustBlockEffect extends SpellAbilityEffect {
attacker = host.toString();
}
for (final Card c : tgtCards) {
sb.append(c).append(" must block ").append(attacker).append(" if able.");
if (sa.hasParam("Choices")) {
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();
}

View File

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

View File

@@ -100,17 +100,21 @@ public class TrackableTypes {
if (newCollection != null) {
//swap in objects in old collection for objects in new collection
for (int i = 0; i < newCollection.size(); i++) {
T newObj = newCollection.get(i);
if (newObj != null) {
T existingObj = from.getTracker().getObj(itemType, newObj.getId());
if (existingObj != null) { //if object exists already, update its changed properties
existingObj.copyChangedProps(newObj);
newCollection.remove(i);
newCollection.add(i, existingObj);
}
else { //if object is new, cache in object lookup
from.getTracker().putObj(itemType, newObj.getId(), newObj);
try {
T newObj = newCollection.get(i);
if (newObj != null) {
T existingObj = from.getTracker().getObj(itemType, newObj.getId());
if (existingObj != null) { //if object exists already, update its changed properties
existingObj.copyChangedProps(newObj);
newCollection.remove(i);
newCollection.add(i, existingObj);
}
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();
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.
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) {
preferredName = skinName.toLowerCase().replace(' ', '_');
//reset hd buttons/icons
Forge.hdbuttons = false;
Forge.hdstart = false;
//ensure skins directory exists
final FileHandle dir = Gdx.files.absolute(ForgeConstants.SKINS_DIR);
if (!dir.exists() || !dir.isDirectory()) {
@@ -205,21 +209,21 @@ public class FSkin {
textures.put(f6.path(), textures.get(f3.path()));
}
if (f7.exists()){
Texture t = new Texture(f7, true);
t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
Texture t = new Texture(f7, false);
//t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f7.path(), t);
}
//hdbuttons
if (f11.exists()) {
Texture tf11 = new Texture(f11, true);
tf11.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f11.path(), tf11);
Texture t = new Texture(f11, true);
t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f11.path(), t);
Forge.hdbuttons = true;
} else { Forge.hdbuttons = false; } //how to refresh buttons when a theme don't have hd buttons?
if (f12.exists()) {
Texture tf12 = new Texture(f12, true);
tf12.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f12.path(), tf12);
Texture t = new Texture(f12, true);
t.setFilter(Texture.TextureFilter.MipMapLinearLinear, Texture.TextureFilter.Linear);
textures.put(f12.path(), t);
Forge.hdstart = true;
} else { Forge.hdstart = false; }
//update colors

View File

@@ -28,7 +28,7 @@ public enum FSkinImage implements FImage {
HDEXILE (FSkinProp.IMG_HDZONE_EXILE, SourceFile.BUTTONS),
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),
HDGRAVEYARD (FSkinProp.IMG_HDZONE_GRAVEYARD, SourceFile.BUTTONS),
@@ -126,6 +126,14 @@ public enum FSkinImage implements FImage {
ARCSON (FSkinProp.ICO_ARCSON, 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
COMMON_TROPHY (FSkinProp.IMG_COMMON_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_PLUS (FSkinProp.ICO_QUEST_PLUS, 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
QUESTION (FSkinProp.ICO_QUESTION, SourceFile.ICONS),
@@ -241,7 +265,9 @@ public enum FSkinImage implements FImage {
ENCHANTMENT (FSkinProp.IMG_ENCHANTMENT, SourceFile.MANAICONS),
INSTANT (FSkinProp.IMG_INSTANT, SourceFile.MANAICONS),
LAND (FSkinProp.IMG_LAND, SourceFile.MANAICONS),
LANDLOGO (FSkinProp.IMG_LANDLOGO, SourceFile.MANAICONS),
MULTI (FSkinProp.IMG_MULTI, SourceFile.ICONS),
HDMULTI (FSkinProp.IMG_HDMULTI, SourceFile.MANAICONS),
PLANESWALKER (FSkinProp.IMG_PLANESWALKER, SourceFile.MANAICONS),
PACK (FSkinProp.IMG_PACK, SourceFile.ICONS),
SORCERY (FSkinProp.IMG_SORCERY, SourceFile.MANAICONS),

View File

@@ -6,6 +6,7 @@ import java.util.List;
import com.google.common.collect.ImmutableList;
import forge.Forge;
import forge.Graphics;
import forge.assets.FImage;
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) {
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)
}, false);

View File

@@ -44,8 +44,8 @@ import java.util.*;
import java.util.Map.Entry;
public class FDeckEditor extends TabPageScreen<FDeckEditor> {
public static FSkinImage MAIN_DECK_ICON = FSkinImage.DECKLIST;
public static FSkinImage SIDEBOARD_ICON = FSkinImage.FLASHBACK;
public static FSkinImage MAIN_DECK_ICON = Forge.hdbuttons ? FSkinImage.HDLIBRARY :FSkinImage.DECKLIST;
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);
public enum EditorType {
@@ -332,7 +332,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
protected void buildMenu() {
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
public void handleEvent(FEvent e) {
CardEdition defaultLandSet;
@@ -365,7 +365,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
}
}));
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
public void handleEvent(FEvent e) {
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
public void handleEvent(FEvent e) {
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
final List<PaperCard> artOptions = FModel.getMagicDb().getCommonCards().getAllCards(card.getName());
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
public void handleEvent(FEvent e) {
//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
private final FLabel btnAdvancedSearchOptions = new FLabel.Builder()
.selectable(true).align(Align.center)
.icon(FSkinImage.SETTINGS).iconScaleFactor(0.9f)
.icon(Forge.hdbuttons ? FSkinImage.HDPREFERENCE : FSkinImage.SETTINGS).iconScaleFactor(0.9f)
.build();
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 RegisteredPlayer human = new RegisteredPlayer(new Deck()).setPlayer(GamePlayerUtil.getGuiPlayer());
human.setStartingHand(0);

View File

@@ -1,5 +1,6 @@
package forge.screens.match.views;
import forge.Forge;
import forge.assets.FSkinImage;
import forge.deck.Deck;
import forge.deck.FDeckViewer;
@@ -85,7 +86,7 @@ public class VGameMenu extends FDropDownMenu {
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
public void handleEvent(FEvent e) {
SettingsScreen.show(false);

View File

@@ -56,7 +56,7 @@ public class ConquestMenu extends FPopupMenu {
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
public void handleEvent(FEvent e) {
setCurrentScreen(statsScreen);
@@ -68,7 +68,7 @@ public class ConquestMenu extends FPopupMenu {
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
public void handleEvent(FEvent e) {
setCurrentScreen(prefsScreen);
@@ -126,8 +126,8 @@ public class ConquestMenu extends FPopupMenu {
addItem(commandersItem); commandersItem.setSelected(currentScreen == commandersScreen);
addItem(planeswalkersItem); planeswalkersItem.setSelected(currentScreen == planeswalkersScreen);
addItem(collectionItem); collectionItem.setSelected(currentScreen == collectionScreen);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
addItem(planeswalkItem); planeswalkItem.setSelected(currentScreen == planeswalkScreen);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
addItem(prefsItem); prefsItem.setSelected(currentScreen == prefsScreen);
}
}

View File

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

View File

@@ -43,7 +43,7 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
private static final QuestStatsScreen statsScreen = new QuestStatsScreen();
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
public void handleEvent(FEvent e) {
setCurrentScreen(duelsScreen);
@@ -55,13 +55,13 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
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
public void handleEvent(FEvent e) {
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
public void handleEvent(FEvent e) {
setCurrentScreen(decksScreen);
@@ -79,7 +79,7 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
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
public void handleEvent(FEvent e) {
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
public void handleEvent(FEvent e) {
setCurrentScreen(prefsScreen);
@@ -243,9 +243,9 @@ public class QuestMenu extends FPopupMenu implements IVQuestStats {
addItem(decksItem); decksItem.setSelected(currentScreen == decksScreen);
addItem(spellShopItem); spellShopItem.setSelected(currentScreen == spellShopScreen);
addItem(bazaarItem); bazaarItem.setSelected(currentScreen == bazaarScreen);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
addItem(unlockSetsItem);
addItem(travelItem);
addItem(statsItem); statsItem.setSelected(currentScreen == statsScreen);
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<>());
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();

View File

@@ -84,3 +84,4 @@ Modern Horizons, 3/6/WAR, MH1
Core Set 2020, 3/6/M20, M20
Throne of Eldraine, 3/6/ELD, ELD
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
ManaCost:2 G
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.
SVar:SoulsDamage:DB$ DealDamage | ValidTgts$ Creature | TgtPrompt$ Select target creature to be dealt damage | NumDmg$ X | References$ X | TargetUnique$ True | DamageSource$ ParentTarget
SVar:X:ParentTargeted$CardPower
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: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 | 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.

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
Types:Creature Boar
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.
SVar:TrigChoose:DB$ ChooseCard | Defined$ DefendingPlayer | Amount$ 1 | Choices$ Creature.untapped+DefenderCtrl | Mandatory$ True | SubAbility$ DBMustBlock
SVar:DBMustBlock:DB$ MustBlock | Defined$ ChosenCard
SVar:Picture:http://www.wizards.com/global/images/magic/general/crashing_boars.jpg
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:DBMustBlock:DB$ MustBlock | Choices$ Creature.untapped+DefenderCtrl | Chooser$ DefendingPlayer
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
SVar:PlayMain1:TRUE
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.

View File

@@ -4,8 +4,8 @@ Types:Creature Human Knight
PT:1/1
K:First Strike
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.
SVar:TrigPump:DB$Pump | ValidTgts$ Knight.YouCtrl+Other | TgtPrompt$ Select another target attacking Knight you control | NumAtt$ +1
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+attacking+Other | TgtPrompt$ Select another target attacking Knight you control | NumAtt$ +1
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.
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
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."
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:DelTrig:DB$ DelayedTrigger | Mode$ Phase | Phase$ End of Turn | Execute$ MoveBack | Static$ True
SVar:MoveBack:DB$ ChangeZone | Origin$ Exile | Destination$ Battlefield | Defined$ Self
SVar:DBSacSelf:DB$ Sacrifice | Defined$ Self
SVar:PlayMain1:TRUE
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."

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
ManaCost:1 R
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
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.)

View File

@@ -2,10 +2,10 @@ Name:Kenrith, the Returned King
ManaCost:4 W
Types:Legendary Creature Human Noble
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$ 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$ 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
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
ManaCost:1 B
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.
SVar:DBChangeZoneAll:DB$ ChangeZoneAll | Defined$ TargetedController | ChangeType$ Targeted.sameName | Origin$ Battlefield,Graveyard,Hand | Destination$ Exile | Search$ True
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: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.

View File

@@ -3,12 +3,11 @@ ManaCost:2 B
Types:Creature Imp
PT:1/1
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
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: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:TrigDestroy:DB$ DestroyAll | ValidCards$ Creature.ActivePlayerCtrl+notAttackedThisTurn+nonWall
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:DBEffect:DB$ Effect | Name$ Maddening Imp Effect | Triggers$ EndofTurn | SVars$ TrigDestroy | RememberObjects$ Valid Creature.ActivePlayerCtrl+nonWall
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.IsRemembered+notAttackedThisTurn
AI:RemoveDeck:All
AI:RemoveDeck:Random
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.

View File

@@ -1,7 +1,7 @@
Name:Maelstrom Nexus
ManaCost:W U B R G
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: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.)

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:DBAttach:DB$ Attach | Defined$ Remembered | SubAbility$ DBCleanup
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:NonStackingAttachEffect:True
AI:RemoveDeck:All

View File

@@ -3,6 +3,9 @@ ManaCost:W U B
Types:Legendary Creature Human
PT:1/1
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.
SVar:Picture:http://www.wizards.com/global/images/magic/general/merieke_ri_berit.jpg
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: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.

View File

@@ -3,14 +3,13 @@ ManaCost:3 W W
Types:Legendary Planeswalker Nahiri
Loyalty:3
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.
SVar:DBChooseTarget:DB$ ChooseCard | DefinedCards$ Remembered | Mandatory$ True | ChoiceTitle$ Choose a token: | SubAbility$ DBAttach
SVar:DBAttach:DB$ Attach | Optional$ True | Object$ Valid Equipment.YouCtrl | ChooseAnObject$ Choose an equipment you control | Defined$ ChosenCard | SubAbility$ DBCleanup
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: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 | StackDescription$ None
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$ 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
DeckNeeds:Type$Equipment
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.

View File

@@ -1,11 +1,13 @@
Name:Quenchable Fire
ManaCost:3 R
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.
SVar:DBEffect:DB$ Effect | Name$ Quenchable Fire Effect | EffectOwner$ Targeted | Duration$ Permanent | Triggers$ UpkeepTrig | Abilities$ PayUp | SVars$ Bleed,ExileEffect | RememberObjects$ SourceController | ImprintCards$ Self
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:Bleed:DB$ DealDamage | Defined$ You | NumDmg$ 3 | DamageSource$ Imprinted | SubAbility$ ExileEffect
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 | ConditionDefined$ Targeted | ConditionPresent$ Planeswalker | ConditionCompare$ EQ0 | SubAbility$ DBEffect2
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: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: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
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: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.
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

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

View File

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

View File

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

View File

@@ -76,7 +76,7 @@ Foil=NotSupported
66 C Yavimaya Wurm
67 U Diabolic Vision
68 U Segmented Wurm
69 C Clockwork Avian
69 R Clockwork Avian
70 R Clockwork Beast
71 U Dwarven Ruins
72 U Ebon Stronghold

View File

@@ -230,6 +230,7 @@ Booster=10 Common:!fromSheet("CN2 Draft Matters"), 3 Uncommon:!fromSheet("CN2 Dr
219 R Exotic Orchard
220 U Rogue's Passage
221 U Shimmering Grotto
222 M Kaya, Ghost Assassin
[tokens]
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
175 C Wind-Scarred Crag
176 L Plains
176 L Plains
179 L Island
177 L Plains
178 L Island
179 L Island
180 L Swamp
181 L Swamp
181 L Swamp
182 L Mountain
183 L Mountain
183 L Mountain
185 L Forest
184 L Forest
185 L Forest
[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
248 R Windswept Heath
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
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
258 L Swamp
259 L Swamp
260 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]
w_3_4_bird_flying

View File

@@ -238,26 +238,26 @@ Booster=10 Common, 3 Uncommon, 1 RareMythic, 1 BasicLand
227 U Encroaching Wastes
228 R Mutavault
229 U Shimmering Grotto
230 L Plains
231 L Plains
231 L Plains
231 L Plains
231 L Plains
234 L Island
234 L Island
234 L Island
232 L Plains
233 L Plains
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
241 L Swamp
244 L Mountain
244 L Mountain
244 L Mountain
242 L Mountain
243 L Mountain
244 L Mountain
245 L Mountain
246 L Forest
246 L Forest
246 L Forest
246 L Forest
247 L Forest
248 L Forest
249 L Forest
[tokens]
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
248 R Urborg, Tomb of Yawgmoth
249 R Yavimaya Coast
250 L Plains
251 L Plains
251 L Plains
251 L Plains
251 L Plains
255 L Island
255 L Island
255 L Island
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
258 L Swamp
263 L Mountain
263 L Mountain
263 L Mountain
259 L Swamp
260 L Swamp
261 L Swamp
262 L Mountain
263 L Mountain
264 L Mountain
265 L Mountain
266 L Forest
266 L Forest
266 L Forest
266 L Forest
267 L Forest
268 L Forest
269 L Forest
270 R Aegis Angel
271 C Divine Verdict
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
35 R Pack Rat
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
69 M Karametra, God of Harvests
70 M Iroas, God of Victory

View File

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

View File

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

View File

@@ -285,6 +285,42 @@ BoosterMustContain=Planeswalker
273 R Jace's Ruse
274 C Simic Guildgate
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]
wubrg_2_2_citizen

View File

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

View File

@@ -4,4 +4,4 @@ Order:103
Subtype:Modern
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
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
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
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
lblCantSelectDeckBecause=Can''t select {0} \nDeck {1}
#ConquestAEtherScreen.java
lblShardsAE=Shards: {0}
lblHaveNAEShards=Shards: {0} {1}
lblTapToPullFromAE=Tap to pull from the Aether\n{0}
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" ?>
<bazaar>
<options>
<iconSize>80</iconSize>
<iconSize>160</iconSize>
</options>
<stalls>
<stall name="Alchemist" displayName="Orim, Samite Healer" icon="ICO_QUEST_BOTTLES">
@@ -26,7 +26,7 @@
<string>Sleight</string>
</items>
</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>
<items>
<string>Map</string>
@@ -53,22 +53,22 @@
</stall>
</stalls>
<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.
Effect: Your first mulligan is free.</description>
</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.
Effect: Quest challenges become available more frequently.</description>
</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.
Effect: Improves the chance of getting a random rare after each match by 15%.</description>
</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.
Effect: Gives a bonus of %d%% to match winnings.
@@ -81,37 +81,37 @@ Effect: Quest challenges become available more frequently.
Effect: +3 life
Effect: Activate once for a new set of challenges (re-fuels after a challenge is attempted).</description>
</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.
But beware, you may build an immunity to its effects...
Effect: Alchemist gives you %d credits.
Effect: Reduces maximum life by 1.</description>
</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.
Effect: Gives +1 to maximum life.
Fine Print: Loses effectiveness after 15 uses.</description>
</item>
<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.
Effect: You may have each match be best of 1 instead of 3.</description>
</item>
<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.
Effect: You may have each match be best of 5 instead of 3.</description>
</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.
Effect: Cards lost in an ante match will be available immediately following the match in the Card Shop.</description>
</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.
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_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
ICO_QUEST_ZEP (new int[] {0, 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_PLUS (new int[] {480, 640, 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
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_LAND (new int[] {248, 740, 80, 80}, PropType.MANAICONS),
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_PACK (new int[] {80, 760, 40, 40}, PropType.IMAGE),
IMG_SORCERY (new int[] {412, 740, 80, 80}, PropType.MANAICONS),

View File

@@ -1,6 +1,7 @@
package forge.itemmanager;
import com.google.common.base.Predicate;
import forge.GuiBase;
import forge.assets.FSkinProp;
import forge.assets.IHasSkinProp;
import forge.card.CardRules;
@@ -35,7 +36,8 @@ public final class SItemManagerUtil {
RED (FSkinProp.IMG_MANA_R, CardRulesPredicates.Presets.IS_RED, "lblRedcards"),
GREEN (FSkinProp.IMG_MANA_G, CardRulesPredicates.Presets.IS_GREEN, "lblGreencards"),
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"),
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_GREEN (FSkinProp.IMG_MANA_G, null, "lblGreendecks"),
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_NEW (FSkinProp.FOIL_01, null, "lblNewstyleFoilcards"),

View File

@@ -75,7 +75,7 @@ public enum ProtocolMethod {
clearSelectables (Mode.SERVER),
refreshField (Mode.SERVER),
// 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),
isUiSetToSkipPhase (Mode.SERVER, Boolean.TYPE, PlayerView.class, PhaseType.class),
setRememberedActions(Mode.SERVER, Void.TYPE),

View File

@@ -746,7 +746,7 @@ public class PlayerControllerHuman extends PlayerController implements IGameCont
endTempShowCards();
} else {
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);
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);
setDownload.append(ImageUtil.getDownloadUrl(paperCard, backFace));
downloadUrls.add(setDownload.toString());
int artIndex = Integer.parseInt(imageKey.split("\\|")[2]);
final StaticData data = StaticData.instance();
final int cardNum = data.getCommonCards().getCardCollectorNumber(paperCard.getName(), paperCard.getEdition());
if (cardNum != -1) {
final String cardNum = data.getCommonCards().getCardCollectorNumber(paperCard.getName(), paperCard.getEdition(), artIndex);
if (cardNum != null) {
String suffix = "";
if (paperCard.getRules().getOtherPart() != null) {
suffix = (backFace ? "b" : "a");
}
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://magiccards.info/scans/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));
}
} else if (prefix.equals(ImageKeys.TOKEN_PREFIX)) {
if (tokenImages == null) {