mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 19:58:00 +00:00
Merge branch 'master' of https://github.com/Card-Forge/forge into adventure
This commit is contained in:
@@ -25,6 +25,11 @@ public final class ImageKeys {
|
||||
public static final String FORETELL_IMAGE = "foretell";
|
||||
|
||||
public static final String BACKFACE_POSTFIX = "$alt";
|
||||
public static final String SPECFACE_W = "$wspec";
|
||||
public static final String SPECFACE_U = "$uspec";
|
||||
public static final String SPECFACE_B = "$bspec";
|
||||
public static final String SPECFACE_R = "$rspec";
|
||||
public static final String SPECFACE_G = "$gspec";
|
||||
|
||||
private static String CACHE_CARD_PICS_DIR, CACHE_TOKEN_PICS_DIR, CACHE_ICON_PICS_DIR, CACHE_BOOSTER_PICS_DIR,
|
||||
CACHE_FATPACK_PICS_DIR, CACHE_BOOSTERBOX_PICS_DIR, CACHE_PRECON_PICS_DIR, CACHE_TOURNAMENTPACK_PICS_DIR;
|
||||
|
||||
@@ -803,7 +803,7 @@ public class StaticData {
|
||||
}
|
||||
|
||||
// check the front image
|
||||
imagePath = ImageUtil.getImageRelativePath(cp, false, true, false);
|
||||
imagePath = ImageUtil.getImageRelativePath(cp, "", true, false);
|
||||
if (imagePath != null) {
|
||||
File file = ImageKeys.getImageFile(imagePath);
|
||||
if (file == null && ImageKeys.hasSetLookup(imagePath))
|
||||
@@ -820,7 +820,7 @@ public class StaticData {
|
||||
|
||||
// check the back face
|
||||
if (cp.hasBackFace()) {
|
||||
imagePath = ImageUtil.getImageRelativePath(cp, true, true, false);
|
||||
imagePath = ImageUtil.getImageRelativePath(cp, "back", true, false);
|
||||
if (imagePath != null) {
|
||||
File file = ImageKeys.getImageFile(imagePath);
|
||||
if (file == null && ImageKeys.hasSetLookup(imagePath))
|
||||
|
||||
@@ -240,5 +240,10 @@ public interface IPaperCard extends InventoryItem, Serializable {
|
||||
boolean hasBackFace();
|
||||
String getCardImageKey();
|
||||
String getCardAltImageKey();
|
||||
String getCardWSpecImageKey();
|
||||
String getCardUSpecImageKey();
|
||||
String getCardBSpecImageKey();
|
||||
String getCardRSpecImageKey();
|
||||
String getCardGSpecImageKey();
|
||||
|
||||
}
|
||||
@@ -320,7 +320,7 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
||||
@Override
|
||||
public String getCardImageKey() {
|
||||
if (this.cardImageKey == null)
|
||||
this.cardImageKey = ImageUtil.getImageKey(this, false, true);
|
||||
this.cardImageKey = ImageUtil.getImageKey(this, "", true);
|
||||
return cardImageKey;
|
||||
}
|
||||
|
||||
@@ -329,13 +329,73 @@ public final class PaperCard implements Comparable<IPaperCard>, InventoryItemFro
|
||||
public String getCardAltImageKey() {
|
||||
if (this.cardAltImageKey == null){
|
||||
if (this.hasBackFace())
|
||||
this.cardAltImageKey = ImageUtil.getImageKey(this, true, true);
|
||||
this.cardAltImageKey = ImageUtil.getImageKey(this, "back", true);
|
||||
else // altImageKey will be the same as cardImageKey
|
||||
this.cardAltImageKey = ImageUtil.getImageKey(this, false, true);
|
||||
this.cardAltImageKey = ImageUtil.getImageKey(this, "", true);
|
||||
}
|
||||
return cardAltImageKey;
|
||||
}
|
||||
|
||||
private String cardWSpecImageKey = null;
|
||||
@Override
|
||||
public String getCardWSpecImageKey() {
|
||||
if (this.cardWSpecImageKey == null) {
|
||||
if (this.rules.getSplitType() == CardSplitType.Specialize)
|
||||
this.cardWSpecImageKey = ImageUtil.getImageKey(this, "white", true);
|
||||
else // just use cardImageKey
|
||||
this.cardWSpecImageKey = ImageUtil.getImageKey(this, "", true);
|
||||
}
|
||||
return cardWSpecImageKey;
|
||||
}
|
||||
|
||||
private String cardUSpecImageKey = null;
|
||||
@Override
|
||||
public String getCardUSpecImageKey() {
|
||||
if (this.cardUSpecImageKey == null) {
|
||||
if (this.rules.getSplitType() == CardSplitType.Specialize)
|
||||
this.cardUSpecImageKey = ImageUtil.getImageKey(this, "blue", true);
|
||||
else // just use cardImageKey
|
||||
this.cardUSpecImageKey = ImageUtil.getImageKey(this, "", true);
|
||||
}
|
||||
return cardUSpecImageKey;
|
||||
}
|
||||
|
||||
private String cardBSpecImageKey = null;
|
||||
@Override
|
||||
public String getCardBSpecImageKey() {
|
||||
if (this.cardBSpecImageKey == null) {
|
||||
if (this.rules.getSplitType() == CardSplitType.Specialize)
|
||||
this.cardBSpecImageKey = ImageUtil.getImageKey(this, "black", true);
|
||||
else // just use cardImageKey
|
||||
this.cardBSpecImageKey = ImageUtil.getImageKey(this, "", true);
|
||||
}
|
||||
return cardBSpecImageKey;
|
||||
}
|
||||
|
||||
private String cardRSpecImageKey = null;
|
||||
@Override
|
||||
public String getCardRSpecImageKey() {
|
||||
if (this.cardRSpecImageKey == null) {
|
||||
if (this.rules.getSplitType() == CardSplitType.Specialize)
|
||||
this.cardRSpecImageKey = ImageUtil.getImageKey(this, "red", true);
|
||||
else // just use cardImageKey
|
||||
this.cardRSpecImageKey = ImageUtil.getImageKey(this, "", true);
|
||||
}
|
||||
return cardRSpecImageKey;
|
||||
}
|
||||
|
||||
private String cardGSpecImageKey = null;
|
||||
@Override
|
||||
public String getCardGSpecImageKey() {
|
||||
if (this.cardGSpecImageKey == null) {
|
||||
if (this.rules.getSplitType() == CardSplitType.Specialize)
|
||||
this.cardGSpecImageKey = ImageUtil.getImageKey(this, "green", true);
|
||||
else // just use cardImageKey
|
||||
this.cardGSpecImageKey = ImageUtil.getImageKey(this, "", true);
|
||||
}
|
||||
return cardGSpecImageKey;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasBackFace(){
|
||||
CardSplitType cst = this.rules.getSplitType();
|
||||
|
||||
@@ -169,6 +169,27 @@ public class PaperToken implements InventoryItemFromSet, IPaperCard {
|
||||
return getImageKey(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCardWSpecImageKey() {
|
||||
return getImageKey(false);
|
||||
}
|
||||
@Override
|
||||
public String getCardUSpecImageKey() {
|
||||
return getImageKey(false);
|
||||
}
|
||||
@Override
|
||||
public String getCardBSpecImageKey() {
|
||||
return getImageKey(false);
|
||||
}
|
||||
@Override
|
||||
public String getCardRSpecImageKey() {
|
||||
return getImageKey(false);
|
||||
}
|
||||
@Override
|
||||
public String getCardGSpecImageKey() {
|
||||
return getImageKey(false);
|
||||
}
|
||||
|
||||
// InventoryItem
|
||||
@Override
|
||||
public String getImageKey(boolean altState) {
|
||||
|
||||
@@ -26,8 +26,8 @@ public class ImageUtil {
|
||||
return cp;
|
||||
}
|
||||
|
||||
public static String getImageRelativePath(PaperCard cp, boolean backFace, boolean includeSet, boolean isDownloadUrl) {
|
||||
final String nameToUse = cp == null ? null : getNameToUse(cp, backFace);
|
||||
public static String getImageRelativePath(PaperCard cp, String face, boolean includeSet, boolean isDownloadUrl) {
|
||||
final String nameToUse = cp == null ? null : getNameToUse(cp, face);
|
||||
if (nameToUse == null) {
|
||||
return null;
|
||||
}
|
||||
@@ -80,36 +80,55 @@ public class ImageUtil {
|
||||
}
|
||||
}
|
||||
|
||||
public static String getNameToUse(PaperCard cp, boolean backFace) {
|
||||
public static String getNameToUse(PaperCard cp, String face) {
|
||||
final CardRules card = cp.getRules();
|
||||
if (backFace) {
|
||||
if (face.equals("back")) {
|
||||
if (cp.hasBackFace())
|
||||
if (card.getOtherPart() != null) {
|
||||
return card.getOtherPart().getName();
|
||||
} else if (!card.getMeldWith().isEmpty()) {
|
||||
final CardDb db = StaticData.instance().getCommonCards();
|
||||
final CardDb db = StaticData.instance().getCommonCards();
|
||||
return db.getRules(card.getMeldWith()).getOtherPart().getName();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
else
|
||||
return null;
|
||||
} else if(CardSplitType.Split == cp.getRules().getSplitType()) {
|
||||
} else if (face.equals("white")) {
|
||||
if (card.getWSpecialize() != null) {
|
||||
return card.getWSpecialize().getName();
|
||||
}
|
||||
} else if (face.equals("blue")) {
|
||||
if (card.getUSpecialize() != null) {
|
||||
return card.getUSpecialize().getName();
|
||||
}
|
||||
} else if (face.equals("black")) {
|
||||
if (card.getBSpecialize() != null) {
|
||||
return card.getBSpecialize().getName();
|
||||
}
|
||||
} else if (face.equals("red")) {
|
||||
if (card.getRSpecialize() != null) {
|
||||
return card.getRSpecialize().getName();
|
||||
}
|
||||
} else if (face.equals("green")) {
|
||||
if (card.getGSpecialize() != null) {
|
||||
return card.getGSpecialize().getName();
|
||||
}
|
||||
} else if (CardSplitType.Split == cp.getRules().getSplitType()) {
|
||||
return card.getMainPart().getName() + card.getOtherPart().getName();
|
||||
} else {
|
||||
return cp.getName();
|
||||
}
|
||||
return cp.getName();
|
||||
}
|
||||
|
||||
public static String getImageKey(PaperCard cp, boolean backFace, boolean includeSet) {
|
||||
return getImageRelativePath(cp, backFace, includeSet, false);
|
||||
public static String getImageKey(PaperCard cp, String face, boolean includeSet) {
|
||||
return getImageRelativePath(cp, face, includeSet, false);
|
||||
}
|
||||
|
||||
public static String getDownloadUrl(PaperCard cp, boolean backFace) {
|
||||
return getImageRelativePath(cp, backFace, true, true);
|
||||
public static String getDownloadUrl(PaperCard cp, String face) {
|
||||
return getImageRelativePath(cp, face, true, true);
|
||||
}
|
||||
|
||||
public static String getScryfallDownloadUrl(PaperCard cp, boolean backFace, String setCode, String langCode, boolean useArtCrop){
|
||||
public static String getScryfallDownloadUrl(PaperCard cp, String face, String setCode, String langCode, boolean useArtCrop){
|
||||
String editionCode;
|
||||
if ((setCode != null) && (setCode.length() > 0))
|
||||
editionCode = setCode;
|
||||
@@ -121,7 +140,7 @@ public class ImageUtil {
|
||||
String versionParam = useArtCrop ? "art_crop" : "normal";
|
||||
String faceParam = "";
|
||||
if (cp.getRules().getOtherPart() != null) {
|
||||
faceParam = (backFace ? "&face=back" : "&face=front");
|
||||
faceParam = (face.equals("back") ? "&face=back" : "&face=front");
|
||||
}
|
||||
return String.format("%s/%s/%s?format=image&version=%s%s", editionCode, cardCollectorNumber,
|
||||
langCode, versionParam, faceParam);
|
||||
|
||||
@@ -17,53 +17,19 @@
|
||||
*/
|
||||
package forge.game;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import forge.util.*;
|
||||
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.ComparisonChain;
|
||||
import com.google.common.collect.Iterables;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Multimaps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.Table;
|
||||
|
||||
import com.google.common.collect.*;
|
||||
import forge.GameCommand;
|
||||
import forge.StaticData;
|
||||
import forge.card.CardStateName;
|
||||
import forge.card.MagicColor;
|
||||
import forge.deck.DeckSection;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.ability.AbilityKey;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardCollection;
|
||||
import forge.game.card.CardCollectionView;
|
||||
import forge.game.card.CardDamageMap;
|
||||
import forge.game.card.CardFactory;
|
||||
import forge.game.card.CardLists;
|
||||
import forge.game.card.CardPredicates;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.card.CardZoneTable;
|
||||
import forge.game.card.CounterEnumType;
|
||||
import forge.game.card.CounterType;
|
||||
import forge.game.event.GameEventCardChangeZone;
|
||||
import forge.game.event.GameEventCardDestroyed;
|
||||
import forge.game.event.GameEventCardStatsChanged;
|
||||
import forge.game.event.GameEventCardTapped;
|
||||
import forge.game.event.GameEventFlipCoin;
|
||||
import forge.game.event.GameEventGameStarted;
|
||||
import forge.game.event.GameEventScry;
|
||||
import forge.game.card.*;
|
||||
import forge.game.event.*;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.keyword.KeywordsChange;
|
||||
@@ -87,8 +53,12 @@ import forge.game.zone.PlayerZoneBattlefield;
|
||||
import forge.game.zone.Zone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.PaperCard;
|
||||
import forge.util.*;
|
||||
import forge.util.collect.FCollection;
|
||||
import forge.util.collect.FCollectionView;
|
||||
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Methods for common actions performed during a game.
|
||||
@@ -2148,6 +2118,13 @@ public class GameAction {
|
||||
return input.getName().equals("Emissary's Ploy");
|
||||
}
|
||||
});
|
||||
CardCollectionView all = CardLists.filterControlledBy(game.getCardsInGame(), takesAction);
|
||||
List<Card> spires = CardLists.filter(all, new Predicate<Card>() {
|
||||
@Override
|
||||
public boolean apply(Card input) {
|
||||
return input.getName().equals("Cryptic Spires");
|
||||
}
|
||||
});
|
||||
|
||||
int chosen = 1;
|
||||
List<Integer> cmc = Lists.newArrayList(1, 2, 3);
|
||||
@@ -2160,6 +2137,17 @@ public class GameAction {
|
||||
|
||||
c.setChosenNumber(chosen);
|
||||
}
|
||||
for (Card c : spires) {
|
||||
if (!c.hasChosenColor()) {
|
||||
List<String> colorChoices = new ArrayList<>(MagicColor.Constant.ONLY_COLORS);
|
||||
String prompt = CardTranslation.getTranslatedName(c.getName()) + ": " +
|
||||
Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(2));
|
||||
SpellAbility sa = new SpellAbility.EmptySa(ApiType.ChooseColor, c, takesAction);
|
||||
sa.putParam("AILogic", "MostProminentInComputerDeck");
|
||||
List<String> chosenColors = takesAction.getController().chooseColors(prompt, sa, 2, 2, colorChoices);
|
||||
c.setChosenColors(chosenColors);
|
||||
}
|
||||
}
|
||||
takesAction = game.getNextPlayerAfter(takesAction);
|
||||
} while (takesAction != first);
|
||||
}
|
||||
|
||||
@@ -101,6 +101,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
for (final Player p : tgtPlayers) {
|
||||
boolean dontRevealToOwner = true;
|
||||
if (sa.hasParam("EachBasicType")) {
|
||||
// Get all lands,
|
||||
List<Card> land = CardLists.filter(game.getCardsIn(ZoneType.Battlefield), Presets.LANDS);
|
||||
@@ -220,6 +221,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
||||
} else if ((tgt == null) || p.canBeTargetedBy(sa)) {
|
||||
if (sa.hasParam("AtRandom") && !choices.isEmpty()) {
|
||||
Aggregates.random(choices, validAmount, chosen);
|
||||
dontRevealToOwner = false;
|
||||
} else {
|
||||
String title = sa.hasParam("ChoiceTitle") ? sa.getParam("ChoiceTitle") : Localizer.getInstance().getMessage("lblChooseaCard") + " ";
|
||||
if (sa.hasParam ("ChoiceTitleAppendDefined")) {
|
||||
@@ -248,12 +250,14 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
||||
}
|
||||
}
|
||||
if (sa.hasParam("Reveal") && !sa.hasParam("SecretlyChoose")) {
|
||||
game.getAction().reveal(chosen, p, true, sa.hasParam("RevealTitle") ? sa.getParam("RevealTitle") : Localizer.getInstance().getMessage("lblChosenCards") + " ");
|
||||
game.getAction().reveal(chosen, p, dontRevealToOwner, sa.hasParam("RevealTitle") ?
|
||||
sa.getParam("RevealTitle") : Localizer.getInstance().getMessage("lblChosenCards") + " ");
|
||||
}
|
||||
}
|
||||
if(sa.hasParam("Reveal") && sa.hasParam("SecretlyChoose")) {
|
||||
if (sa.hasParam("Reveal") && sa.hasParam("SecretlyChoose")) {
|
||||
for (final Player p : tgtPlayers) {
|
||||
game.getAction().reveal(chosen, p, true, sa.hasParam("RevealTitle") ? sa.getParam("RevealTitle") : Localizer.getInstance().getMessage("lblChosenCards") + " ");
|
||||
game.getAction().reveal(chosen, p, true, sa.hasParam("RevealTitle") ?
|
||||
sa.getParam("RevealTitle") : Localizer.getInstance().getMessage("lblChosenCards") + " ");
|
||||
}
|
||||
}
|
||||
host.setChosenCards(chosen);
|
||||
|
||||
@@ -27,7 +27,7 @@ public class ChooseTypeEffect extends SpellAbilityEffect {
|
||||
for (final Player p : getTargetPlayers(sa)) {
|
||||
sb.append(p);
|
||||
}
|
||||
sb.append(" chooses a type.");
|
||||
sb.append(" chooses a ").append(sa.getParam("Type").toLowerCase()).append(" type.");
|
||||
} else {
|
||||
sb.append("Please improve the stack description.");
|
||||
}
|
||||
|
||||
@@ -360,10 +360,15 @@ public class PlayEffect extends SpellAbilityEffect {
|
||||
tgtSA = tgtSA.copyWithNoManaCost();
|
||||
} else if (sa.hasParam("PlayCost")) {
|
||||
Cost abCost;
|
||||
if ("ManaCost".equals(sa.getParam("PlayCost"))) {
|
||||
String cost = sa.getParam("PlayCost");
|
||||
if (cost.equals("ManaCost")) {
|
||||
abCost = new Cost(source.getManaCost(), false);
|
||||
} else {
|
||||
abCost = new Cost(sa.getParam("PlayCost"), false);
|
||||
if (cost.contains("ConvertedManaCost")) {
|
||||
final String costcmc = Integer.toString(tgtCard.getCMC());
|
||||
cost = cost.replace("ConvertedManaCost", costcmc);
|
||||
}
|
||||
abCost = new Cost(cost, false);
|
||||
}
|
||||
|
||||
tgtSA = tgtSA.copyWithDefinedCost(abCost);
|
||||
|
||||
@@ -280,6 +280,27 @@ public class CardFactory {
|
||||
} else if (c.isAdventureCard()) {
|
||||
c.setState(CardStateName.Adventure, false);
|
||||
c.setImageKey(originalPicture);
|
||||
} else if (c.canSpecialize()) {
|
||||
c.setState(CardStateName.SpecializeW, false);
|
||||
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_W);
|
||||
c.setSetCode(cp.getEdition());
|
||||
c.setRarity(cp.getRarity());
|
||||
c.setState(CardStateName.SpecializeU, false);
|
||||
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_U);
|
||||
c.setSetCode(cp.getEdition());
|
||||
c.setRarity(cp.getRarity());
|
||||
c.setState(CardStateName.SpecializeB, false);
|
||||
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_B);
|
||||
c.setSetCode(cp.getEdition());
|
||||
c.setRarity(cp.getRarity());
|
||||
c.setState(CardStateName.SpecializeR, false);
|
||||
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_R);
|
||||
c.setSetCode(cp.getEdition());
|
||||
c.setRarity(cp.getRarity());
|
||||
c.setState(CardStateName.SpecializeG, false);
|
||||
c.setImageKey(cp.getImageKey(false) + ImageKeys.SPECFACE_G);
|
||||
c.setSetCode(cp.getEdition());
|
||||
c.setRarity(cp.getRarity());
|
||||
}
|
||||
|
||||
c.setSetCode(cp.getEdition());
|
||||
|
||||
@@ -26,6 +26,7 @@ import forge.game.card.CardPredicates.Presets;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Lang;
|
||||
import forge.util.TextUtil;
|
||||
|
||||
/**
|
||||
@@ -114,7 +115,7 @@ public class CostTapType extends CostPartWithList {
|
||||
sb.append(" you control");
|
||||
}
|
||||
} else {
|
||||
sb.append(Cost.convertAmountTypeToWords(i, this.getAmount(), "untapped " + desc)).append(" you control");
|
||||
sb.append(Lang.nounWithNumeralExceptOne(this.getAmount(), "untapped " + desc)).append(" you control");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
@@ -172,12 +172,48 @@ public class ImageCache {
|
||||
|
||||
IPaperCard ipc = null;
|
||||
boolean altState = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX);
|
||||
String specColor = "";
|
||||
if (imageKey.endsWith(ImageKeys.SPECFACE_W)) {
|
||||
specColor = "white";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_U)) {
|
||||
specColor = "blue";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_B)) {
|
||||
specColor = "black";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_R)) {
|
||||
specColor = "red";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_G)) {
|
||||
specColor = "green";
|
||||
}
|
||||
if (altState)
|
||||
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length());
|
||||
if (!specColor.equals(""))
|
||||
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.SPECFACE_W.length());
|
||||
if (imageKey.startsWith(ImageKeys.CARD_PREFIX)) {
|
||||
ipc = ImageUtil.getPaperCardFromImageKey(imageKey);
|
||||
if (ipc != null) {
|
||||
imageKey = altState ? ipc.getCardAltImageKey() : ipc.getCardImageKey();
|
||||
if (altState) {
|
||||
imageKey = ipc.getCardAltImageKey();
|
||||
} else if (!specColor.equals("")) {
|
||||
switch (specColor) {
|
||||
case "white":
|
||||
imageKey = ipc.getCardWSpecImageKey();
|
||||
break;
|
||||
case "blue":
|
||||
imageKey = ipc.getCardUSpecImageKey();
|
||||
break;
|
||||
case "black":
|
||||
imageKey = ipc.getCardBSpecImageKey();
|
||||
break;
|
||||
case "red":
|
||||
imageKey = ipc.getCardRSpecImageKey();
|
||||
break;
|
||||
case "green":
|
||||
imageKey = ipc.getCardGSpecImageKey();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
imageKey = ipc.getCardImageKey();
|
||||
}
|
||||
if (StringUtils.isBlank(imageKey))
|
||||
return Pair.of(_defaultImage, true);
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ public class DeckHtmlSerializer {
|
||||
// System.out.println(card.getSets().get(card.getSets().size() - 1).URL);
|
||||
for (int i = card.getValue(); i > 0; --i ) {
|
||||
final PaperCard r = card.getKey();
|
||||
final String url = ForgeConstants.URL_PIC_DOWNLOAD + ImageUtil.getDownloadUrl(r, false);
|
||||
final String url = ForgeConstants.URL_PIC_DOWNLOAD + ImageUtil.getDownloadUrl(r, "");
|
||||
list.add(url);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,15 +77,51 @@ public final class FImageUtil {
|
||||
}
|
||||
|
||||
boolean altState = key.endsWith(ImageKeys.BACKFACE_POSTFIX);
|
||||
String specColor = "";
|
||||
if (key.endsWith(ImageKeys.SPECFACE_W)) {
|
||||
specColor = "white";
|
||||
} else if (key.endsWith(ImageKeys.SPECFACE_U)) {
|
||||
specColor = "blue";
|
||||
} else if (key.endsWith(ImageKeys.SPECFACE_B)) {
|
||||
specColor = "black";
|
||||
} else if (key.endsWith(ImageKeys.SPECFACE_R)) {
|
||||
specColor = "red";
|
||||
} else if (key.endsWith(ImageKeys.SPECFACE_G)) {
|
||||
specColor = "green";
|
||||
}
|
||||
String imageKey = key;
|
||||
if (prefix.equals(ImageKeys.CARD_PREFIX)) {
|
||||
PaperCard card = ImageUtil.getPaperCardFromImageKey(key);
|
||||
if (card != null)
|
||||
imageKey = altState ? card.getCardAltImageKey() : card.getCardImageKey();
|
||||
if (altState) {
|
||||
imageKey = card.getCardAltImageKey();
|
||||
} else if (!specColor.equals("")) {
|
||||
switch (specColor) {
|
||||
case "white":
|
||||
imageKey = card.getCardWSpecImageKey();
|
||||
break;
|
||||
case "blue":
|
||||
imageKey = card.getCardUSpecImageKey();
|
||||
break;
|
||||
case "black":
|
||||
imageKey = card.getCardBSpecImageKey();
|
||||
break;
|
||||
case "red":
|
||||
imageKey = card.getCardRSpecImageKey();
|
||||
break;
|
||||
case "green":
|
||||
imageKey = card.getCardGSpecImageKey();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
imageKey = card.getCardImageKey();
|
||||
}
|
||||
}
|
||||
if(altState) {
|
||||
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.BACKFACE_POSTFIX.length());
|
||||
imageKey += "full.jpg";
|
||||
} else if (!specColor.equals("")) {
|
||||
imageKey = imageKey.substring(0, imageKey.length() - ImageKeys.SPECFACE_W.length());
|
||||
imageKey += "full.jpg";
|
||||
}
|
||||
|
||||
File file = ImageKeys.getImageFile(imageKey);
|
||||
|
||||
@@ -92,7 +92,7 @@ public class NewGameScene extends UIScene {
|
||||
mode.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent changeEvent, Actor actor) {
|
||||
colorLabel.setText(mode.getCurrentIndex() < 2 ? colorIdLabel : Forge.getLocalizer().getMessage("lblDeck")+":");
|
||||
colorLabel.setText(mode.getCurrentIndex() < 2 ? colorIdLabel : "[BLACK]"+Forge.getLocalizer().getMessage("lblDeck")+":");
|
||||
if (mode.getCurrentIndex() == 3)
|
||||
colorId.setTextList(custom);
|
||||
if (mode.getCurrentIndex() == 2)
|
||||
|
||||
@@ -107,13 +107,8 @@ public class SaveLoadScene extends UIScene {
|
||||
difficulty.setSelectedIndex(1);
|
||||
difficulty.setAlignment(Align.center);
|
||||
difficulty.getStyle().fontColor = Color.GOLD;
|
||||
if (Forge.isLandscapeMode()) {
|
||||
difficulty.setX(280);
|
||||
difficulty.setY(220);
|
||||
} else {
|
||||
difficulty.setX(190);
|
||||
difficulty.setY(336);
|
||||
}
|
||||
difficulty.setX(scrollPane.getWidth()-difficulty.getWidth()+5);
|
||||
difficulty.setY(scrollPane.getTop()-difficulty.getHeight()-5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ public class RewardActor extends Actor implements Disposable, ImageFetcher.Callb
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String imagePath = ImageUtil.getImageRelativePath(reward.getCard(), false, true, false);
|
||||
String imagePath = ImageUtil.getImageRelativePath(reward.getCard(), "", true, false);
|
||||
File lookup = ImageKeys.hasSetLookup(imagePath) ? ImageKeys.setLookUpFile(imagePath, imagePath+"border") : null;
|
||||
int count = 0;
|
||||
if (lookup != null) {
|
||||
|
||||
@@ -711,13 +711,26 @@ public class World implements Disposable, SaveFileContent {
|
||||
}
|
||||
for(Map.Entry<String, Pair<Pixmap, HashMap<String, Pixmap>>> entry:pixmapHash.entrySet())
|
||||
{
|
||||
entry.getValue().getLeft().dispose();
|
||||
try {
|
||||
entry.getValue().getLeft().dispose();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
for(Map.Entry<String, Pixmap> pairEntry:entry.getValue().getRight().entrySet())
|
||||
{
|
||||
pairEntry.getValue().dispose();
|
||||
try {
|
||||
pairEntry.getValue().dispose();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
drawPixmapNow(pix);
|
||||
pixmapHash.clear();
|
||||
try {
|
||||
drawPixmapNow(pix);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
currentTime[0] = measureGenerationTime("mini map", currentTime[0]);
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,16 @@
|
||||
"width": 64,
|
||||
"height": 16,
|
||||
"x": 442,
|
||||
"y": 64
|
||||
"y": 56
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"name": "mana",
|
||||
"font": "default",
|
||||
"width": 64,
|
||||
"height": 16,
|
||||
"x": 442,
|
||||
"y": 73
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
@@ -71,7 +80,7 @@
|
||||
"width": 64,
|
||||
"height": 16,
|
||||
"x": 442,
|
||||
"y": 82
|
||||
"y": 90
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
|
||||
@@ -5,5 +5,5 @@ PT:1/3
|
||||
K:Flying
|
||||
S:Mode$ Continuous | Affected$ Creature.attacking ChosenPlayer | AddPower$ 1 | Description$ Creatures attacking the last chosen player get +1/+0.
|
||||
T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigChoose | TriggerZones$ Battlefield | TriggerDescription$ Lure the Unwary — At the beginning of combat on your turn, choose an opponent.
|
||||
SVar:TrigChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent | SetChosenPlayer$ True
|
||||
SVar:TrigChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent
|
||||
Oracle:Flying\nLure the Unwary — At the beginning of combat on your turn, choose an opponent.\nCreatures attacking the last chosen player get +1/+0.
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Artifact Creature Griffin
|
||||
PT:3/2
|
||||
K:Flying
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDestroy | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, destroy target nonland permanent of that player's choice that one of your opponents controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | TargetingPlayer$ TriggeredTarget | ValidTgts$ Permanent.nonLand+OppCtrl
|
||||
SVar:TrigDestroy:DB$ Destroy | TargetingPlayer$ TriggeredTarget | ValidTgts$ Permanent.nonLand+OppCtrl | TgtPrompt$ Select target nonland permanent controlled by opponent of damaging player
|
||||
Oracle:Flying\nWhenever Bladegriff Prototype deals combat damage to a player, destroy target nonland permanent of that player's choice that one of your opponents controls.
|
||||
|
||||
@@ -4,5 +4,6 @@ Types:Creature Phyrexian Human Cleric
|
||||
PT:2/2
|
||||
K:Intimidate
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDestroy | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may sacrifice it. If you do, destroy target creature that player controls.
|
||||
SVar:TrigDestroy:AB$ Destroy | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature.ControlledBy TriggeredDefendingPlayer | AITgts$ BetterThanSource | TgtPrompt$ Select target creature defending player controls
|
||||
SVar:TrigDestroy:AB$ Destroy | Cost$ Sac<1/CARDNAME> | ValidTgts$ Creature.ControlledBy TriggeredTarget | AITgts$ BetterThanSource | TgtPrompt$ Select target creature damaged player controls
|
||||
DeckHas:Ability$Sacrifice
|
||||
Oracle:Intimidate (This creature can't be blocked except by artifact creatures and/or creatures that share a color with it.)\nWhenever Blind Zealot deals combat damage to a player, you may sacrifice it. If you do, destroy target creature that player controls.
|
||||
|
||||
@@ -3,10 +3,9 @@ ManaCost:4 R R
|
||||
Types:Creature Efreet
|
||||
PT:6/4
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ At the beginning of your upkeep, choose target nonland permanent you control and up to two target nonland permanents you don't control. Destroy one of them at random.
|
||||
SVar:TrigPump:DB$ Pump | ValidTgts$ Permanent.nonLand+YouCtrl | TgtPrompt$ Select target nonland permanent you control | Mandatory$ True | RememberObjects$ Targeted | IsCurse$ True | SubAbility$ DBPump | StackDescription$ None
|
||||
SVar:DBPump:DB$ Pump | ValidTgts$ Permanent.nonLand+YouDontCtrl | TgtPrompt$ Select target nonland permanent you don't control | TargetMin$ 0 | TargetMax$ 1 | RememberObjects$ Targeted | IsCurse$ True | SubAbility$ DBPump2 | StackDescription$ None
|
||||
SVar:DBPump2:DB$ Pump | ValidTgts$ Permanent.nonLand+YouDontCtrl | TgtPrompt$ Select another target nonland permanent you don't control | TargetMin$ 0 | TargetMax$ 1 | TargetUnique$ True | RememberObjects$ Targeted | IsCurse$ True | SubAbility$ DBChooseRandom | StackDescription$ None
|
||||
SVar:DBChooseRandom:DB$ ChooseCard | Defined$ You | Amount$ 1 | AtRandom$ True | Choices$ Card.IsRemembered | SubAbility$ DBDestroy
|
||||
SVar:TrigPump:DB$ Pump | ValidTgts$ Permanent.nonLand+YouCtrl | TgtPrompt$ Select target nonland permanent you control | Mandatory$ True | IsCurse$ True | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | ValidTgts$ Permanent.nonLand+YouDontCtrl | TgtPrompt$ Select up to two target nonland permanents you don't control | TargetMin$ 0 | TargetMax$ 2 | IsCurse$ True | SubAbility$ DBChooseRandom
|
||||
SVar:DBChooseRandom:DB$ ChooseCard | AtRandom$ True | Reveal$ True | RevealTitle$ OVERRIDE Randomly chosen permanent: | DefinedCards$ TargetedCard | SubAbility$ DBDestroy
|
||||
SVar:DBDestroy:DB$ Destroy | Defined$ ChosenCard | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearChosenCard$ True
|
||||
Oracle:At the beginning of your upkeep, choose target nonland permanent you control and up to two target nonland permanents you don't control. Destroy one of them at random.
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Creature Insect
|
||||
PT:1/1
|
||||
K:Flying
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDestroy | CombatDamage$ True | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may destroy target artifact that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select an artifact your opponent controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredTarget | TgtPrompt$ Select target artifact damaged player controls
|
||||
Oracle:Flying\nWhenever Caustic Wasps deals combat damage to a player, you may destroy target artifact that player controls.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:3 B R G
|
||||
Types:Legendary Creature Dragon
|
||||
PT:6/6
|
||||
K:Flying
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | OptionalDecider$ You | Execute$ TrigChooseColor | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may pay {2}{R}. If you do, choose a color, then that player reveals their hand and Darigaaz deals damage to the player equal to the number of cards of that color revealed this way.
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | OptionalDecider$ You | Execute$ TrigChooseColor | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may pay {2}{R}. If you do, choose a color, then that player reveals their hand and NICKNAME deals damage to the player equal to the number of cards of that color revealed this way.
|
||||
SVar:TrigChooseColor:AB$ ChooseColor | Cost$ 2 R | Defined$ You | AILogic$ MostProminentInHumanDeck | SubAbility$ DBRevealHand
|
||||
SVar:DBRevealHand:DB$ RevealHand | Defined$ TriggeredTarget | RememberRevealed$ True | SubAbility$ DBDamage
|
||||
SVar:DBDamage:DB$ DealDamage | Defined$ TriggeredTarget | NumDmg$ X | SubAbility$ DBCleanup
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Creature Human Cleric
|
||||
PT:2/2
|
||||
K:Morph:1 W
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDestroy | CombatDamage$ True | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may destroy target enchantment that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Enchantment.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select an enchantment your opponent controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Enchantment.ControlledBy TriggeredTarget | TgtPrompt$ Select target artifact damaged player controls
|
||||
Oracle:Whenever Dawning Purist deals combat damage to a player, you may destroy target enchantment that player controls.\nMorph {1}{W} (You may cast this card face down as a 2/2 creature for {3}. Turn it face up any time for its morph cost.)
|
||||
|
||||
@@ -5,7 +5,7 @@ PT:2/1
|
||||
K:Ninjutsu:1 B
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigImmediateTrig | CombatDamage$ True | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may discard a creature card. When you do, destroy target creature or planeswalker that player controls.
|
||||
SVar:TrigImmediateTrig:AB$ ImmediateTrigger | Cost$ Discard<1/Creature> | Execute$ TrigDestroy | CopyTriggeringObjects$ True | TriggerDescription$ When you do, destroy target creature or planeswalker that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature.ControlledBy TriggeredDefendingPlayer,Planeswalker.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target creature or planeswalker that player controls
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature.ControlledBy TriggeredTarget,Planeswalker.ControlledBy TriggeredTarget | TgtPrompt$ Select target creature or planeswalker damaged player controls
|
||||
DeckHas:Ability$Discard
|
||||
SVar:AIPreference:DiscardCost$Creature.cmcLE3
|
||||
Oracle:Ninjutsu {1}{B} ({1}{B}, Return an unblocked attacker you control to hand: Put this card onto the battlefield from your hand tapped and attacking.)\nWhenever Dokuchi Silencer deals combat damage to a player, you may discard a creature card. When you do, destroy target creature or planeswalker that player controls.
|
||||
|
||||
@@ -7,5 +7,5 @@ T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.S
|
||||
SVar:TrigToken:AB$ Token | Cost$ 2 | TokenScript$ g_1_1_elf_warrior | RememberTokens$ True | SubAbility$ DBAttach
|
||||
SVar:DBAttach:DB$ Attach | Object$ TriggeredCard | Defined$ Remembered | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
DeckHas:Ability$Token
|
||||
DeckHas:Ability$Token & Type$Elf|Warrior
|
||||
Oracle:When Elven Bow enters the battlefield, you may pay {2}. If you do, create a 1/1 green Elf Warrior creature token, then attach Elven Bow to it.\nEquipped creature gets +1/+2 and has reach.\nEquip {3}
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Artifact Equipment
|
||||
K:Equip:2
|
||||
S:Mode$ Continuous | Affected$ Creature.EquippedBy | AddPower$ 2 | Description$ Equipped creature gets +2/+0.
|
||||
T:Mode$ DamageDone | ValidSource$ Creature.EquippedBy | ValidTarget$ Player | CombatDamage$ True | OptionalDecider$ You | Execute$ TrigDestroy | TriggerZones$ Battlefield | TriggerDescription$ Whenever equipped creature deals combat damage to a player, you may destroy target Equipment that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Equipment.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target equipment defending player controls
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Equipment.ControlledBy TriggeredTarget | TgtPrompt$ Select target Equipment damaged player controls
|
||||
Oracle:Equipped creature gets +2/+0.\nWhenever equipped creature deals combat damage to a player, you may destroy target Equipment that player controls.\nEquip {2}
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 R
|
||||
Types:Enchantment Aura
|
||||
K:Flash
|
||||
K:Enchant creature
|
||||
A:SP$ Attach | Cost$ 1 R | ValidTgts$ Creature | AITgts$ Card.powerGE1 | AILogic$ Pump
|
||||
A:SP$ Attach | ValidTgts$ Creature | AITgts$ Card.powerGE1 | AILogic$ Pump
|
||||
T:Mode$ DamageDone | ValidSource$ Card.AttachedBy | ValidTarget$ Player.TriggeredDefendingPlayer | CombatDamage$ True | Execute$ TrigDestroy | OptionalDecider$ You | TriggerDescription$ Whenever enchanted creature deals combat damage to defending player, you may destroy target artifact that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredTarget | TgtPrompt$ Select target artifact damaged player controls
|
||||
Oracle:Flash\nEnchant creature\nWhenever enchanted creature deals combat damage to defending player, you may destroy target artifact that player controls.
|
||||
|
||||
@@ -4,9 +4,9 @@ Types:Legendary Creature Avatar Minion
|
||||
PT:4/4
|
||||
T:Mode$ ChangesZone | ValidCard$ Card.wasNotCastFromYourHandByYou+Self | Destination$ Battlefield | Execute$ TrigYouLose | TriggerDescription$ When CARDNAME enters the battlefield, if you didn't cast it from your hand, you lose the game.
|
||||
SVar:TrigYouLose:DB$ LosesGame | Defined$ You
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | Execute$ TrigDestroy | TriggerDescription$ Whenever CARDNAME deals combat damage to a creature, destroy that creature. It can't be regenerated.
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Creature | CombatDamage$ True | Execute$ TrigDestroy | TriggerDescription$ Whenever NICKNAME deals combat damage to a creature, destroy that creature. It can't be regenerated.
|
||||
SVar:TrigDestroy:DB$ Destroy | Defined$ TriggeredTargetLKICopy | NoRegen$ True
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigTheyLose | TriggerDescription$ Whenever Phage deals combat damage to a player, that player loses the game.
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigTheyLose | TriggerDescription$ Whenever NICKNAME deals combat damage to a player, that player loses the game.
|
||||
SVar:TrigTheyLose:DB$ LosesGame | Defined$ TriggeredTarget
|
||||
SVar:MustBeBlocked:True
|
||||
Oracle:When Phage the Untouchable enters the battlefield, if you didn't cast it from your hand, you lose the game.\nWhenever Phage deals combat damage to a creature, destroy that creature. It can't be regenerated.\nWhenever Phage deals combat damage to a player, that player loses the game.
|
||||
|
||||
@@ -6,6 +6,6 @@ K:Trample
|
||||
K:Protection from enchantments
|
||||
K:Monstrosity:3:4 R G
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | IsPresent$ Card.Self+IsMonstrous | Execute$ TrigDestroy | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, if CARDNAME is monstrous, destroy target enchantment that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment that player controls | TargetsWithDefinedController$ TriggeredTarget
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Enchantment | TgtPrompt$ Select target enchantment damaged player controls | TargetsWithDefinedController$ TriggeredTarget
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Trample, protection from enchantments\n{4}{R}{G}: Monstrosity 3. (If this creature isn't monstrous, put three +1/+1 counters on it and it becomes monstrous.)\nWhenever Polis Crusher deals combat damage to a player, if Polis Crusher is monstrous, destroy target enchantment that player controls.
|
||||
|
||||
@@ -3,5 +3,5 @@ ManaCost:4 R R
|
||||
Types:Creature Ogre
|
||||
PT:5/4
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDestroy | CombatDamage$ True | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may destroy target artifact that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select an artifact your opponent controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredTarget | TgtPrompt$ Select target artifact damaged player controls
|
||||
Oracle:Whenever Rustmouth Ogre deals combat damage to a player, you may destroy target artifact that player controls.
|
||||
|
||||
@@ -7,7 +7,7 @@ K:Trample
|
||||
K:Haste
|
||||
K:etbCounter:P1P1:1:CheckSVar$ WasKicked:If CARDNAME was kicked, it enters the battlefield with a +1/+1 counter on it.
|
||||
SVar:WasKicked:Count$Kicked.1.0
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ TrigReturn | IsPresent$ Card.Self+counters_EQ0_P1P1 | TriggerDescription$ At the beginning of your end step, return Shatterskull Charger to its owner's hand unless it has a +1/+1 counter on it.
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | Execute$ TrigReturn | IsPresent$ Card.Self+counters_EQ0_P1P1 | TriggerDescription$ At the beginning of your end step, return CARDNAME to its owner's hand unless it has a +1/+1 counter on it.
|
||||
SVar:TrigReturn:DB$ ChangeZone | Origin$ Battlefield | Destination$ Hand | Defined$ Self
|
||||
SVar:PlayMain1:TRUE
|
||||
DeckHas:Ability$Counters
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Creature Giant Shaman
|
||||
PT:5/5
|
||||
S:Mode$ MinMaxBlocker | ValidCard$ Card.Self | Max$ 1 | Description$ CARDNAME can't be blocked by more than one creature.
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | CombatDamage$ True | Execute$ TrigDestroy | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, destroy target artifact or enchantment that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer,Enchantment.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact or enchantment that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredTarget,Enchantment.ControlledBy TriggeredTarget | TgtPrompt$ Select target artifact or enchantment damaged player controls
|
||||
Oracle:Sunder Shaman can't be blocked by more than one creature.\nWhenever Sunder Shaman deals combat damage to a player, destroy target artifact or enchantment that player controls.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Name:Syndicate Recruiter
|
||||
ManaCost: 2 U B
|
||||
Types:Creature Vampire Assassin
|
||||
Types:Creature Vampire Rogue
|
||||
PT:4/5
|
||||
K:Flying
|
||||
K:Ward:1
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Creature Rat Ninja
|
||||
PT:2/2
|
||||
K:Ninjutsu:2 B
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigDestroy | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, destroy target nonblack creature that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature.nonBlack+ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target nonblack creature defending player controls
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature.nonBlack+ControlledBy TriggeredTarget | TgtPrompt$ Select target nonblack creature damaged player controls
|
||||
SVar:MustBeBlocked:True
|
||||
Oracle:Ninjutsu {2}{B} ({2}{B}, Return an unblocked attacker you control to hand: Put this card onto the battlefield from your hand tapped and attacking.)\nWhenever Throat Slitter deals combat damage to a player, destroy target nonblack creature that player controls.
|
||||
|
||||
@@ -4,5 +4,5 @@ Types:Creature Beast
|
||||
PT:2/3
|
||||
K:Flying
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | OptionalDecider$ You | CombatDamage$ True | Execute$ TrigDestroy | TriggerZones$ Battlefield | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, you may destroy target artifact or enchantment that player controls.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredDefendingPlayer,Enchantment.ControlledBy TriggeredDefendingPlayer | TgtPrompt$ Select target artifact or enchantment you don't control.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Artifact.ControlledBy TriggeredTarget,Enchantment.ControlledBy TriggeredTarget | TgtPrompt$ Select target artifact or enchantment damaged player controls
|
||||
Oracle:Flying\nWhenever Trygon Predator deals combat damage to a player, you may destroy target artifact or enchantment that player controls.
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
Name:And They Shall Know No Fear
|
||||
ManaCost:1 W
|
||||
Types:Instant
|
||||
A:SP$ ChooseType | Type$ Creature | SubAbility$ DBPumpAll | AILogic$ MostProminentComputerControls | SpellDescription$ Choose a creature type.
|
||||
SVar:DBPumpAll:DB$ PumpAll | ValidCards$ Creature.YouCtrl+ChosenType | NumAtt$ +1 | KW$ Indestructible | SpellDescription$ Creatures you control of the chosen type get +1/+0 and gain indestructible until end of turn.
|
||||
Oracle:Choose a creature type. Creatures you control of the chosen type get +1/+0 and gain indestructible until end of turn.
|
||||
10
forge-gui/res/cardsfolder/upcoming/anrakyr_the_traveller.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/anrakyr_the_traveller.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Anrakyr the Traveller
|
||||
ManaCost:4 B
|
||||
Types:Legendary Artifact Creature Necron
|
||||
PT:4/4
|
||||
T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigCast | OptionalDecider$ You | TriggerDescription$ Whenever CARDNAME attacks, you may cast an artifact spell from your hand or graveyard by paying life equal to its mana value rather than paying its mana cost.
|
||||
SVar:TrigCast:DB$ Play | ValidZone$ Hand | Valid$ Artifact.YouOwn | ValidSA$ Spell | Controller$ You | ValidZone$ Hand,Graveyard | Optional$ True | Amount$ 1 | PlayCost$ PayLife<ConvertedManaCost>
|
||||
SVar:HasAttackEffect:TRUE
|
||||
DeckHas:Ability$Graveyard
|
||||
DeckHints:Type$Artifact
|
||||
Oracle:Lord of the Pyrrhian Legions — Whenever Anrakyr the Traveller attacks, you may cast an artifact spell from your hand or graveyard by paying life equal to its mana value rather than paying its mana cost.
|
||||
@@ -0,0 +1,9 @@
|
||||
Name:Assault Intercessor
|
||||
ManaCost:1 W B
|
||||
Types:Creature Astartes Warrior
|
||||
PT:3/2
|
||||
K:First strike
|
||||
K:Menace
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.OppCtrl | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Chainsword — Whenever a creature an opponent controls dies, that player loses 2 life.
|
||||
SVar:TrigLoseLife:DB$ LoseLife | LifeAmount$ 2 | Defined$ TriggeredCardController
|
||||
Oracle:First strike, menace\nChainsword — Whenever a creature an opponent controls dies, that player loses 2 life.
|
||||
10
forge-gui/res/cardsfolder/upcoming/belisarius_cawl.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/belisarius_cawl.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Belisarius Cawl
|
||||
ManaCost:2 W U
|
||||
Types:Legendary Artifact Creature Human
|
||||
PT:2/4
|
||||
A:AB$ Token | PrecostDesc$ Ultima Founding — | Cost$ T tapXType<2/Artifact> | TokenScript$ w_2_2_astartes_warrior_vigilance | SpellDescription$ Create a 2/2 white Astartes Warrior creature token with vigilance.
|
||||
A:AB$ Dig | PrecostDesc$ Master of Machines — | Cost$ T tapXType<X/Creature> | DigNum$ X | ChangeNum$ 1 | Optional$ True | ChangeValid$ Artifact | ForceRevealToController$ True | RestRandomOrder$ True | SpellDescription$ Look at the top X cards of your library. You may reveal an artifact card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||
SVar:X:Count$xPaid
|
||||
DeckHas:Ability$Token & Type$Astartes|Warrior
|
||||
DeckNeeds:Type$Artifact
|
||||
Oracle:Ultima Founding — {T}, Tap two untapped artifacts you control: Create a 2/2 white Astartes Warrior creature token with vigilance.\nMaster of Machines — {T}, Tap X untapped creatures you control: Look at the top X cards of your library. You may reveal an artifact card from among them and put it into your hand. Put the rest on the bottom of your library in a random order.
|
||||
11
forge-gui/res/cardsfolder/upcoming/birth_of_the_imperium.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/birth_of_the_imperium.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Name:Birth of the Imperium
|
||||
ManaCost:2 W U B
|
||||
Types:Enchantment Saga
|
||||
K:Saga:3:DBToken,DBSacrifice,DBDraw
|
||||
SVar:DBToken:DB$ Token | TokenScript$ w_2_2_astartes_warrior_vigilance | TokenAmount$ X | SpellDescription$ Create a 2/2 white Astartes Warrior creature token with vigilance for each opponent you have.
|
||||
SVar:X:PlayerCountOpponents$Amount
|
||||
SVar:DBSacrifice:DB$ Sacrifice | Defined$ Opponent | SacValid$ Creature | SacMessage$ creature | SpellDescription$ Each opponent sacrifices a creature.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ Y | NumCardsDesc$ two cards for each opponent who controls fewer creatures than you | SpellDescription$ Draw two cards for each opponent who controls fewer creatures than you.
|
||||
SVar:Y:PlayerCountOpponents$HasPropertyhasFewerCreaturesInPlayThanYou/Times.2
|
||||
DeckHas:Ability$Token & Type$Astartes|Warrior
|
||||
Oracle:(As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)\nI — Create a 2/2 white Astartes Warrior creature token with vigilance for each opponent you have.\nII — Each opponent sacrifices a creature.\nIII — Draw two cards for each opponent who controls fewer creatures than you.
|
||||
@@ -0,0 +1,9 @@
|
||||
Name:Chaos Terminator Lord
|
||||
ManaCost:3 R
|
||||
Types:Creature Astartes Warrior
|
||||
PT:3/3
|
||||
T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Lord of Chaos — At the beginning of combat on your turn, another target creature you control gains double strike until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.Other+YouCtrl | TgtPrompt$ Select another target creature you control | KW$ Double Strike
|
||||
SVar:PlayMain1:TRUE
|
||||
DeckHas:Keyword$DoubleStrike
|
||||
Oracle:Lord of Chaos — At the beginning of combat on your turn, another target creature you control gains double strike until end of turn.
|
||||
10
forge-gui/res/cardsfolder/upcoming/chronomancer.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/chronomancer.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Chronomancer
|
||||
ManaCost:1 B
|
||||
Types:Artifact Creature Necron Wizard
|
||||
PT:1/1
|
||||
K:Flying
|
||||
A:AB$ Draw | PrecostDesc$ Atomic Transmutation — | Cost$ 1 T Sac<1/Artifact.Other/another artifact> | SpellDescription$ Draw a card.
|
||||
K:Unearth:2 B
|
||||
DeckHas:Ability$Sacrifice|Graveyard
|
||||
DeckHints:Type$Artifact
|
||||
Oracle:Flying\nAtomic Transmutation — {1}, {T}, Sacrifice another artifact: Draw a card.\nUnearth {2}{B} ({2}{B}: Return this card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step or if it would leave the battlefield. Unearth only as a sorcery.)
|
||||
7
forge-gui/res/cardsfolder/upcoming/cryptic_spires.txt
Normal file
7
forge-gui/res/cardsfolder/upcoming/cryptic_spires.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Name:Cryptic Spires
|
||||
ManaCost:no cost
|
||||
Types:Land
|
||||
Text:As you create your deck, circle two of the colors below.
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
A:AB$ Mana | Cost$ T | Produced$ Combo Chosen | SpellDescription$ Add mana of either of the circled colors.
|
||||
Oracle:As you create your deck, circle two of the colors below.\nCryptic Spires enters the battlefield tapped.\n{T}: Add one mana of either of the circled colors.
|
||||
6
forge-gui/res/cardsfolder/upcoming/exterminatus.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/exterminatus.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Name:Exterminatus
|
||||
ManaCost:5 W B
|
||||
Types:Sorcery
|
||||
A:SP$ AnimateAll | ValidCards$ Permanent.nonLand+OppCtrl | RemoveKeywords$ Indestructible | SubAbility$ DBDestroyAll | SpellDescription$ Nonland permanents your opponents control lose indestructible until end of turn. Destroy all nonland permanents.
|
||||
SVar:DBDestroyAll:DB$ DestroyAll | ValidCards$ Permanent.nonLand
|
||||
Oracle:Nonland permanents your opponents control lose indestructible until end of turn.\nDestroy all nonland permanents.
|
||||
11
forge-gui/res/cardsfolder/upcoming/grey_knight_paragon.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/grey_knight_paragon.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Name:Grey Knight Paragon
|
||||
ManaCost:4 W
|
||||
Types:Creature Astartes Knight
|
||||
PT:4/4
|
||||
K:Flash
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigBranch | TriggerDescription$ Rites of Banishment — When CARDNAME enters the battlefield, destroy target attacking creature. If that creature is a Demon, exile it instead.
|
||||
SVar:TrigBranch:DB$ Branch | ValidTgts$ Creature.attacking | TgtPrompt$ Select target attacking creature | BranchConditionSVar$ X | BranchConditionSVarCompare$ EQ1 | TrueSubAbility$ ExileDemon | FalseSubAbility$ DestroyAttacker
|
||||
SVar:DestroyAttacker:DB$ Destroy | Defined$ Targeted
|
||||
SVar:ExileDemon:DB$ ChangeZone | Defined$ Targeted | Origin$ Battlefield | Destination$ Exile
|
||||
SVar:X:Targeted$Valid Creature.Demon
|
||||
Oracle:Flash\nRites of Banishment — When Grey Knight Paragon enters the battlefield, destroy target attacking creature. If that creature is a Demon, exile it instead.
|
||||
8
forge-gui/res/cardsfolder/upcoming/helbrute.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/helbrute.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Name:Helbrute
|
||||
ManaCost:3 B R
|
||||
Types:Artifact Creature Astartes Dreadnought
|
||||
PT:5/4
|
||||
K:Haste
|
||||
SVar:AltCost:Cost$ 3 B R ExileFromGrave<1/Creature.Other/another creature card> | PrecostDesc$ Sarcophagus — | ActivationZone$ Graveyard | Description$ You may cast CARDNAME from your graveyard by exiling another creature card from your graveyard in addition to paying its other costs.
|
||||
DeckHas:Ability$Graveyard
|
||||
Oracle:Haste\nSarcophagus — You may cast Helbrute from your graveyard by exiling another creature card from your graveyard in addition to paying its other costs.
|
||||
9
forge-gui/res/cardsfolder/upcoming/lord_of_change.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/lord_of_change.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Name:Lord of Change
|
||||
ManaCost:6 U
|
||||
Types:Creature Demon
|
||||
PT:6/6
|
||||
K:Flying
|
||||
K:Ward:3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ Architect of Deception — When CARDNAME enters the battlefield, draw three cards.
|
||||
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 3
|
||||
Oracle:Flying, ward {3}\nArchitect of Deception — When Lord of Change enters the battlefield, draw three cards.
|
||||
10
forge-gui/res/cardsfolder/upcoming/necron_deathmark.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/necron_deathmark.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Necron Deathmark
|
||||
ManaCost:3 B B
|
||||
Types:Artifact Creature Necron
|
||||
PT:5/3
|
||||
K:Flash
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDestroy | TriggerDescription$ Synaptic Disintegrator — When CARDNAME enters the battlefield, destroy up to one target creature and target player mills three cards.
|
||||
SVar:TrigDestroy:DB$ Destroy | ValidTgts$ Creature | TgtPrompt$ Select up to one target creature | TargetMin$ 0 | TargetMax$ 1 | SubAbility$ DBMill
|
||||
SVar:DBMill:DB$ Mill | ValidTgts$ Player | NumCards$ 3
|
||||
DeckHas:Ability$Mill
|
||||
Oracle:Flash\nSynaptic Disintegrator — When Necron Deathmark enters the battlefield, destroy up to one target creature and target player mills three cards.
|
||||
15
forge-gui/res/cardsfolder/upcoming/necron_monolith.txt
Normal file
15
forge-gui/res/cardsfolder/upcoming/necron_monolith.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
Name:Necron Monolith
|
||||
ManaCost:7
|
||||
Types:Artifact Vehicle
|
||||
PT:7/7
|
||||
K:Flying
|
||||
K:Indestructible
|
||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ Eternity Gate — Whenever CARDNAME attacks, mill three cards. For each creature card milled this way, create a 2/2 black Necron Warrior artifact creature token.
|
||||
SVar:TrigMill:DB$ Mill | NumCards$ 3 | RememberMilled$ True | SubAbility$ DBToken
|
||||
SVar:DBToken:DB$ Token | TokenAmount$ X | TokenScript$ b_2_2_a_necron_warrior | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
K:Crew:4
|
||||
SVar:X:Remembered$Valid Creature
|
||||
DeckHas:Ability$Mill|Token & Type$Necron|Warrior
|
||||
SVar:HasAttackEffect:TRUE
|
||||
Oracle:Flying, indestructible\nEternity Gate — Whenever Necron Monolith attacks, mill three cards. For each creature card milled this way, create a 2/2 black Necron Warrior artifact creature token.\nCrew 4 (Tap any number of creatures you control with total power 4 or more: This Vehicle becomes an artifact creature until end of turn.)
|
||||
8
forge-gui/res/cardsfolder/upcoming/necron_overlord.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/necron_overlord.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Name:Necron Overlord
|
||||
ManaCost:2 B B
|
||||
Types:Artifact Creature Necron Noble
|
||||
PT:2/5
|
||||
A:AB$ LoseLife | PrecostDesc$ Relentless Mind — | Cost$ X T tapXType<X/Artifact> | ValidTgts$ Opponent | LifeAmount$ X | SpellDescription$ Target opponent loses X life.
|
||||
SVar:X:Count$xPaid
|
||||
DeckHints:Type$Artifact
|
||||
Oracle:Relentless Mind — {X}, {T}, Tap X untapped artifacts you control: Target opponent loses X life.
|
||||
10
forge-gui/res/cardsfolder/upcoming/night_scythe.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/night_scythe.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Night Scythe
|
||||
ManaCost:3
|
||||
Types:Artifact Vehicle
|
||||
PT:3/1
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ Invasion Beams — When CARDNAME enters the battlefield, create a 2/2 black Necron Warrior artifact creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ b_2_2_a_necron_warrior
|
||||
K:Crew:2
|
||||
DeckHas:Type$Necron|Warrior & Ability$Token
|
||||
Oracle:Flying\nInvasion Beams — When Night Scythe enters the battlefield, create a 2/2 black Necron Warrior artifact creature token.\nCrew 2 (Tap any number of creatures you control with total power 2 or more: This Vehicle becomes an artifact creature until end of turn.)
|
||||
@@ -0,0 +1,80 @@
|
||||
Name:Shadowheart, Sharran Cleric
|
||||
ManaCost:1 B
|
||||
Types:Legendary Creature Human Elf Cleric
|
||||
PT:2/2
|
||||
K:Deathtouch
|
||||
K:Specialize:2::Activate only if a player has 13 or less life.:CheckSVar$ X | SVarCompare$ LE13
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your end step, CARDNAME deals 1 damage to each player.
|
||||
SVar:TrigDealDamage:DB$ DealDamage | Defined$ Player | NumDmg$ 1
|
||||
SVar:X:PlayerCountPlayers$LowestLifeTotal
|
||||
AlternateMode:Specialize
|
||||
DeckHas:Ability$Discard
|
||||
Oracle:Deathtouch\nSpecialize {2}. Activate only if a player has 13 or less life.\nAt the beginning of your end step, Shadowheart, Sharran Cleric deals 1 damage to each player.
|
||||
|
||||
SPECIALIZE:WHITE
|
||||
|
||||
Name:Shadowheart, Cleric of Order
|
||||
ManaCost:1 W B
|
||||
Types:Legendary Creature Human Elf Cleric
|
||||
PT:4/4
|
||||
K:Deathtouch
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your end step, CARDNAME deals 1 damage to each player.
|
||||
SVar:TrigDealDamage:DB$ DealDamage | Defined$ Player | NumDmg$ 1
|
||||
T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | PlayerTurn$ True | Execute$ TrigToken | TriggerDescription$ Whenever you lose life during your turn, create a 2/2 white Knight creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ w_2_2_knight
|
||||
DeckHas:Ability$Token & Type$Knight
|
||||
Oracle:Deathtouch\nAt the beginning of your end step, Shadowheart, Cleric of Order deals 1 damage to each player.\nWhenever you lose life during your turn, create a 2/2 white Knight creature token.
|
||||
|
||||
SPECIALIZE:BLUE
|
||||
|
||||
Name:Shadowheart, Cleric of Trickery
|
||||
ManaCost:1 U B
|
||||
Types:Legendary Creature Human Elf Cleric
|
||||
PT:4/4
|
||||
K:Deathtouch
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your end step, CARDNAME deals 1 damage to each player.
|
||||
SVar:TrigDealDamage:DB$ DealDamage | Defined$ Player | NumDmg$ 1
|
||||
T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | PlayerTurn$ True | Execute$ TrigDraw | TriggerDescription$ Whenever you lose life during your turn, draw a card.
|
||||
SVar:TrigDraw:DB$ Draw
|
||||
Oracle:Deathtouch\nAt the beginning of your end step, Shadowheart, Cleric of Trickery deals 1 damage to each player.\nWhenever you lose life during your turn, draw a card.
|
||||
|
||||
SPECIALIZE:BLACK
|
||||
|
||||
Name:Shadowheart, Cleric of Graves
|
||||
ManaCost:1 B B
|
||||
Types:Legendary Creature Human Elf Cleric
|
||||
PT:4/4
|
||||
K:Deathtouch
|
||||
K:Lifelink
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your end step, CARDNAME deals 1 damage to each player.
|
||||
SVar:TrigDealDamage:DB$ DealDamage | Defined$ Player | NumDmg$ 1
|
||||
DeckHas:Ability$LifeGain
|
||||
Oracle:Deathtouch, lifelink\nAt the beginning of your end step, Shadowheart, Cleric of Graves deals 1 damage to each player.
|
||||
|
||||
SPECIALIZE:RED
|
||||
|
||||
Name:Shadowheart, Cleric of War
|
||||
ManaCost:1 B R
|
||||
Types:Legendary Creature Human Elf Cleric
|
||||
PT:4/4
|
||||
K:Deathtouch
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDamageAll | TriggerDescription$ At the beginning of your end step, CARDNAME deals 1 damage to each player.
|
||||
SVar:TrigDamageAll:DB$ DealDamage | Defined$ Player | NumDmg$ 1
|
||||
T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | PlayerTurn$ True | Execute$ TrigDamageOpp | TriggerDescription$ Whenever you lose life during your turn, NICKNAME deals that much damage to each opponent.
|
||||
SVar:TrigDamageOpp:DB$ DealDamage | NumDmg$ X | Defined$ Opponent
|
||||
SVar:X:TriggerCount$LifeAmount
|
||||
Oracle:Deathtouch\nAt the beginning of your end step, Shadowheart, Cleric of War deals 1 damage to each player.\nWhenever you lose life during your turn, Shadowheart deals that much damage to each opponent.
|
||||
|
||||
SPECIALIZE:GREEN
|
||||
|
||||
Name:Shadowheart, Cleric of Twilight
|
||||
ManaCost:1 B G
|
||||
Types:Legendary Creature Human Elf Cleric
|
||||
PT:4/4
|
||||
K:Deathtouch
|
||||
S:Mode$ CantBlockBy | ValidAttacker$ Creature.Self | ValidBlocker$ Creature.powerLE2 | Description$ CARDNAME can't be blocked by creatures with power 2 or less.
|
||||
T:Mode$ Phase | Phase$ End of Turn | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigDealDamage | TriggerDescription$ At the beginning of your end step, NICKNAME deals 1 damage to each player.
|
||||
SVar:TrigDealDamage:DB$ DealDamage | Defined$ Player | NumDmg$ 1
|
||||
T:Mode$ LifeLost | ValidPlayer$ You | TriggerZones$ Battlefield | PlayerTurn$ True | Execute$ TrigPutCounter | TriggerDescription$ Whenever you lose life during your turn, put a +1/+1 counter on NICKNAME.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | CounterType$ P1P1
|
||||
Oracle:Deathtouch\nShadowheart, Cleric of Twilight can't be blocked by creatures with power 2 or less.\nAt the beginning of your end step, Shadowheart deals 1 damage to each player.\nWhenever you lose life during your turn, put a +1/+1 counter on Shadowheart.
|
||||
10
forge-gui/res/cardsfolder/upcoming/sister_hostpitaller.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/sister_hostpitaller.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Sister Hospitaller
|
||||
ManaCost:4 W B
|
||||
Types:Creature Human Cleric
|
||||
PT:3/2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigChangeZone | TriggerDescription$ Medicus Ministorum - When CARDNAME enters the battlefield, return target creature card from your graveyard to the battlefield. You gain life equal to that card's mana value.
|
||||
SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ValidTgts$ Creature.YouOwn | TgtPrompt$ Choose target creature card in your graveyard | ChangeNum$ 1 | SubAbility$ DBGainLife
|
||||
SVar:DBGainLife:DB$ GainLife | Defined$ You | LifeAmount$ X
|
||||
SVar:X:Targeted$CardManaCost
|
||||
DeckHas:Ability$Graveyard|Lifegain
|
||||
Oracle:Medicus Ministorum — When Sister Hospitaller enters the battlefield, return target creature card from your graveyard to the battlefield. You gain life equal to its mana value.
|
||||
@@ -0,0 +1,9 @@
|
||||
Name:Thunderwolf Cavalry
|
||||
ManaCost:4 W
|
||||
Types:Creature Astartes Warrior
|
||||
PT:4/4
|
||||
K:First Strike
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigPutCounter | CombatDamage$ True | TriggerDescription$ Crushing Teeth — Whenever CARDNAME deals combat damage to a player, put a +1/+1 counter on each other creature you control.
|
||||
SVar:TrigPutCounter:DB$ PutCounterAll | ValidCards$ Creature.YouCtrl+Other | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:First strike\nCrushing Teeth — Whenever Thunderwolf Cavalry deals combat damage to a player, put a +1/+1 counter on each other creature you control.
|
||||
12
forge-gui/res/cardsfolder/upcoming/tomb_blade.txt
Normal file
12
forge-gui/res/cardsfolder/upcoming/tomb_blade.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Name:Tomb Blade
|
||||
ManaCost:4 B B
|
||||
Types:Artifact Creature Necron
|
||||
PT:5/4
|
||||
K:Flying
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self | ValidTarget$ Player | Execute$ TrigLoseLife | CombatDamage$ True | TriggerDescription$ Whenever CARDNAME deals combat damage to a player, that player loses life equal to the number of creatures they control unless they sacrifice a creature.
|
||||
SVar:TrigLoseLife:DB$ LoseLife | Defined$ TriggeredTarget | UnlessCost$ Sac<1/Creature> | UnlessPayer$ TriggeredTarget | LifeAmount$ X
|
||||
SVar:X:TriggeredTarget$Valid Creature.YouCtrl
|
||||
K:Unearth:6 B B
|
||||
DeckHas:Ability$Sacrifice|Graveyard
|
||||
SVar:HasAttackEffect:TRUE
|
||||
Oracle:Flying\nWhenever Tomb Blade deals combat damage to a player, that player loses life equal to the number of creatures they control unless they sacrifice a creature.\nUnearth {6}{B}{B}
|
||||
9
forge-gui/res/cardsfolder/upcoming/tomb_fortress.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/tomb_fortress.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Name:Tomb Fortress
|
||||
ManaCost:no cost
|
||||
Types:Land
|
||||
K:CARDNAME enters the battlefield tapped.
|
||||
A:AB$ Mana | Cost$ T | Produced$ B | SpellDescription$ Add {B}.
|
||||
A:AB$ Mill | Cost$ 2 B B B T Exile<1/CARDNAME> | Defined$ You | SorcerySpeed$ True | NumCards$ 4 | SubAbility$ DBReturn | SpellDescription$ Mill four cards, then return a creature card from your graveyard to the battlefield. Activate only as a sorcery.
|
||||
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.YouOwn | ChangeNum$ 1 | Hidden$ True
|
||||
DeckHas:Ability$Graveyard|Mill
|
||||
Oracle:Tomb Fortress enters the battlefield tapped.\n{T}: Add {B}.\n{2}{B}{B}{B}, {T}, Exile Tomb Fortress: Mill four cards, then return a creature card from your graveyard to the battlefield. Activate only as a sorcery.
|
||||
@@ -0,0 +1,7 @@
|
||||
Name:Trazyn the Infinite
|
||||
ManaCost:4 B B
|
||||
Types:Legendary Artifact Creature Necron
|
||||
PT:4/6
|
||||
S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ Battlefield | GainsAbilitiesOf$ Artifact.YouOwn | GainsAbilitiesOfZones$ Graveyard | Description$ As long as Trazyn the Infinite is on the battlefield, it has all activated abilities of all artifact cards in your graveyard.
|
||||
DeckHints:Type$Artifact & Ability$Graveyard
|
||||
Oracle:As long as Trazyn the Infinite is on the battlefield, it has all activated abilities of all artifact cards in your graveyard.
|
||||
11
forge-gui/res/cardsfolder/upcoming/triarch_praetorian.txt
Normal file
11
forge-gui/res/cardsfolder/upcoming/triarch_praetorian.txt
Normal file
@@ -0,0 +1,11 @@
|
||||
Name:Triarch Praetorian
|
||||
ManaCost:1 B
|
||||
Types:Artifact Creature Necron
|
||||
PT:2/1
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Graveyard | Destination$ Battlefield | TriggerZones$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ Dynastic Codes — When CARDNAME enters the battlefield from a graveyard, you draw two cards and you lose 2 life.
|
||||
SVar:TrigDraw:DB$ Draw | NumCards$ 2 | SubAbility$ DBLoseLife
|
||||
SVar:DBLoseLife:DB$ LoseLife | LifeAmount$ 2
|
||||
K:Unearth:4 B
|
||||
DeckHas:Ability$Graveyard
|
||||
Oracle:Flying\nDynastic Codes — When Triarch Praetorian enters the battlefield from a graveyard, you draw two cards and you lose 2 life.\nUnearth {4}{B} ({4}{B}: Return this card from your graveyard to the battlefield. It gains haste. Exile it at the beginning of the next end step or if it would leave the battlefield. Unearth only as a sorcery.)
|
||||
9
forge-gui/res/cardsfolder/upcoming/triarch_stalker.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/triarch_stalker.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Name:Triarch Stalker
|
||||
ManaCost:3 B B
|
||||
Types:Artifact Creature Necron
|
||||
PT:4/5
|
||||
S:Mode$ Continuous | Affected$ Creature.attacking ChosenPlayer | AddKeyword$ Menace | Description$ Creatures attacking the last chosen player have menace.
|
||||
T:Mode$ Phase | Phase$ BeginCombat | ValidPlayer$ You | Execute$ TrigChoose | TriggerZones$ Battlefield | TriggerDescriptionLure the Unwary — At the beginning of combat on your turn, choose an opponent.
|
||||
SVar:TrigChoose:DB$ ChoosePlayer | Defined$ You | Choices$ Player.Opponent
|
||||
DeckHas:Keyword$Menace
|
||||
Oracle:Targeting Relay — At the beginning of combat on your turn, choose an opponent.\nCreatures attacking the last chosen player have menace.
|
||||
12
forge-gui/res/cardsfolder/upcoming/trygon_prime.txt
Normal file
12
forge-gui/res/cardsfolder/upcoming/trygon_prime.txt
Normal file
@@ -0,0 +1,12 @@
|
||||
Name:Trygon Prime
|
||||
ManaCost:2 G U
|
||||
Types:Creature Tyranid
|
||||
PT:4/4
|
||||
K:Vigilance
|
||||
T:Mode$ Attacks | ValidCard$ Creature.Self | Execute$ TrigCounters | TriggerDescription$ Subterranean Assault — Whenever cardname attacks, put a +1/+1 counter on it and a +1/+1 counter on up to one other target attacking creature. That creature can't be blocked this turn.
|
||||
SVar:TrigCounters:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBCounter
|
||||
SVar:DBCounter:DB$ PutCounter | ValidTgts$ Creature.attacking+Other | TargetMin$ 0 | TargetMax$ 1 | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump
|
||||
SVar:DBPump:DB$ Pump | Defined$ ParentTarget | KW$ HIDDEN Unblockable
|
||||
DeckHas:Ability$Counters
|
||||
SVar:HasAttackEffect:TRUE
|
||||
Oracle:Subterranean Assault — Whenever Trygon Prime attacks, put a +1/+1 counter on it and a +1/+1 counter on up to one other target attacking creature. That creature can't be blocked this turn.
|
||||
10
forge-gui/res/cardsfolder/upcoming/tyranid_harridan.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/tyranid_harridan.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Tyranid Harridan
|
||||
ManaCost:4 G U
|
||||
Types:Creature Tyranid
|
||||
K:Flying
|
||||
K:Ward:4
|
||||
PT:4/4
|
||||
T:Mode$ DamageDone | ValidSource$ Card.Self,Tyranid.YouCtrl | ValidTarget$ Player | CombatDamage$ True | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Shrieking Gargoyles — Whenever CARDNAME or another Tyranid you control deals combat damage to a player, create a 1/1 blue Tyranid Gargoyle creature token with flying.
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ u_1_1_tyranid_gargoyle_flying
|
||||
DeckHas:Type$Gargoyle & Ability$Token
|
||||
Oracle:Flying, ward {4}\nShrieking Gargoyles — Whenever Tyranid Harridan or another Tyranid you control deals combat damage to a player, create a 1/1 blue Tyranid Gargoyle creature token with flying.
|
||||
10
forge-gui/res/cardsfolder/upcoming/tzaangor_shaman.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/tzaangor_shaman.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Tzaangor Shaman
|
||||
ManaCost:2 U R
|
||||
Types:Creature Mutant Shaman
|
||||
PT:3/3
|
||||
K:Flying
|
||||
T:Mode$ DamageDone | CombatDamage$ True | ValidTarget$ Player | ValidSource$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigDelayedTrigger | TriggerDescription$ Sorcerous Elixir — Whenever CARDNAME deals combat damage to a player, copy the next instant or sorcery spell you cast this turn when you cast it. You may choose new targets for the copy.
|
||||
SVar:TrigDelayedTrigger:DB$ DelayedTrigger | AILogic$ SpellCopy | Execute$ EffTrigCopy | ThisTurn$ True | Mode$ SpellCast | ValidCard$ Instant,Sorcery | ValidActivatingPlayer$ You | SpellDescription$ When you cast your next instant or sorcery spell this turn, copy that spell. You may choose new targets for the copy.
|
||||
SVar:EffTrigCopy:DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | MayChooseTarget$ True
|
||||
DeckHints:Type$Instant|Sorcery
|
||||
Oracle:Flying\nSorcerous Elixir — Whenever Tzaangor Shaman deals combat damage to a player, copy the next instant or sorcery spell you cast this turn when you cast it. You may choose new targets for the copy.
|
||||
9
forge-gui/res/cardsfolder/upcoming/venomcrawler.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/venomcrawler.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Name:Venomcrawler
|
||||
ManaCost:3 B
|
||||
Types:Artifact Creature Demon
|
||||
PT:2/2
|
||||
K:Lifelink
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | ValidCard$ Creature.Other | Destination$ Graveyard | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Devourer of Souls — Whenever another creature dies, put a +1/+1 counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Lifelink\nDevourer of Souls — Whenever another creature dies, put a +1/+1 counter on Venomcrawler.
|
||||
8
forge-gui/res/cardsfolder/upcoming/venomthrope.txt
Normal file
8
forge-gui/res/cardsfolder/upcoming/venomthrope.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
Name:Venomthrope
|
||||
ManaCost:1 G U
|
||||
Types:Creature Tyranid
|
||||
PT:2/2
|
||||
K:Flying
|
||||
K:Deathtouch
|
||||
K:Hexproof
|
||||
Oracle:Flying, deathtouch, hexproof
|
||||
10
forge-gui/res/cardsfolder/upcoming/vexilus_praetor.txt
Normal file
10
forge-gui/res/cardsfolder/upcoming/vexilus_praetor.txt
Normal file
@@ -0,0 +1,10 @@
|
||||
Name:Vexilus Praetor
|
||||
ManaCost:3 W
|
||||
Types:Creature Custodes Warrior
|
||||
PT:3/4
|
||||
K:Flash
|
||||
K:Vilance
|
||||
S:Mode$ Continuous | Affected$ Card.IsCommander+YouCtrl | AddKeyword$ Protection from everything | Description$ Aegis of the Emperor — Commanders you control have protection from everything.
|
||||
SVar:PlayMain1:TRUE
|
||||
AI:RemoveDeck:Random
|
||||
Oracle:Flash\nVigilance\nAegis of the Emperor — Commanders you control have protection from everything.
|
||||
@@ -46,14 +46,14 @@ public class GuiDownloadPicturesHQ extends GuiDownloadService {
|
||||
existingSets = retrieveManifestDirectory();
|
||||
|
||||
for (final PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
|
||||
addDLObject(c, false);
|
||||
addDLObject(c, "");
|
||||
if (c.hasBackFace()) {
|
||||
addDLObject(c, true);
|
||||
addDLObject(c, "back");
|
||||
}
|
||||
}
|
||||
|
||||
for (final PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
|
||||
addDLObject(c, false);
|
||||
addDLObject(c, "");
|
||||
}
|
||||
|
||||
// Add missing tokens to the list of things to download.
|
||||
@@ -62,8 +62,8 @@ public class GuiDownloadPicturesHQ extends GuiDownloadService {
|
||||
return downloads;
|
||||
}
|
||||
|
||||
private void addDLObject(final PaperCard c, final boolean backFace) {
|
||||
final String imageKey = ImageUtil.getImageKey(c, backFace, false);
|
||||
private void addDLObject(final PaperCard c, final String face) {
|
||||
final String imageKey = ImageUtil.getImageKey(c, face, false);
|
||||
final String destPath = ForgeConstants.CACHE_CARD_PICS_DIR + imageKey + ".jpg";
|
||||
|
||||
if (existingImages.contains(imageKey + ".jpg")) {
|
||||
@@ -98,7 +98,7 @@ public class GuiDownloadPicturesHQ extends GuiDownloadService {
|
||||
cardname = cardname.replace("'", "");
|
||||
String scryfallurl = ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + "named?fuzzy=" + cardname;
|
||||
if(!setCode.equals("???")) scryfallurl += "&set=" + setCode.toLowerCase();
|
||||
if(backFace) scryfallurl += "&face=back";
|
||||
if(face.equals("back")) scryfallurl += "&face=back";
|
||||
scryfallurl += "&format=image";
|
||||
|
||||
downloads.put(destPath, scryfallurl);
|
||||
|
||||
@@ -40,14 +40,14 @@ public class GuiDownloadPicturesLQ extends GuiDownloadService {
|
||||
existingSets = retrieveManifestDirectory();
|
||||
|
||||
for (final PaperCard c : FModel.getMagicDb().getCommonCards().getAllCards()) {
|
||||
addDLObject(c, false);
|
||||
addDLObject(c, "");
|
||||
if (c.hasBackFace()) {
|
||||
addDLObject(c, true);
|
||||
addDLObject(c, "back");
|
||||
}
|
||||
}
|
||||
|
||||
for (final PaperCard c : FModel.getMagicDb().getVariantCards().getAllCards()) {
|
||||
addDLObject(c, false);
|
||||
addDLObject(c, "");
|
||||
}
|
||||
|
||||
// Add missing tokens to the list of things to download.
|
||||
@@ -56,8 +56,8 @@ public class GuiDownloadPicturesLQ extends GuiDownloadService {
|
||||
return downloads;
|
||||
}
|
||||
|
||||
private void addDLObject(final PaperCard c, final boolean backFace) {
|
||||
final String imageKey = ImageUtil.getImageKey(c, backFace, false);
|
||||
private void addDLObject(final PaperCard c, final String face) {
|
||||
final String imageKey = ImageUtil.getImageKey(c, face, false);
|
||||
final String destPath = ForgeConstants.CACHE_CARD_PICS_DIR + imageKey + ".jpg";
|
||||
|
||||
if (ImageKeys.getImageFile(imageKey) != null) {
|
||||
@@ -76,6 +76,6 @@ public class GuiDownloadPicturesLQ extends GuiDownloadService {
|
||||
return;
|
||||
}
|
||||
|
||||
downloads.put(destPath, ForgeConstants.URL_PIC_DOWNLOAD + ImageUtil.getDownloadUrl(c, backFace));
|
||||
downloads.put(destPath, ForgeConstants.URL_PIC_DOWNLOAD + ImageUtil.getDownloadUrl(c, face));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,10 +72,10 @@ public class GuiDownloadSetPicturesLQ extends GuiDownloadService {
|
||||
continue;
|
||||
}
|
||||
|
||||
addDLObject(ImageUtil.getDownloadUrl(c, false), ImageUtil.getImageKey(c, false, true), downloads);
|
||||
addDLObject(ImageUtil.getDownloadUrl(c, ""), ImageUtil.getImageKey(c, "", true), downloads);
|
||||
|
||||
if (c.hasBackFace()) {
|
||||
addDLObject(ImageUtil.getDownloadUrl(c, true), ImageUtil.getImageKey(c, true, true), downloads);
|
||||
addDLObject(ImageUtil.getDownloadUrl(c, "back"), ImageUtil.getImageKey(c, "back", true), downloads);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ public abstract class ImageFetcher {
|
||||
private HashMap<String, HashSet<Callback>> currentFetches = new HashMap<>();
|
||||
private HashMap<String, String> tokenImages;
|
||||
|
||||
private String getScryfallDownloadURL(PaperCard c, boolean backFace, boolean useArtCrop, boolean hasSetLookup, String imagePath, ArrayList<String> downloadUrls) {
|
||||
private String getScryfallDownloadURL(PaperCard c, String face, boolean useArtCrop, boolean hasSetLookup, String imagePath, ArrayList<String> downloadUrls) {
|
||||
StaticData data = StaticData.instance();
|
||||
CardEdition edition = data.getEditions().get(c.getEdition());
|
||||
if (edition == null) // edition does not exist - some error occurred with card data
|
||||
@@ -53,7 +53,7 @@ public abstract class ImageFetcher {
|
||||
if (ed != null) {
|
||||
String setCode =ed.getScryfallCode();
|
||||
String langCode = ed.getCardsLangCode();
|
||||
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(pc, backFace, setCode, langCode, useArtCrop));
|
||||
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(pc, face, setCode, langCode, useArtCrop));
|
||||
}
|
||||
}
|
||||
} else {// original from set
|
||||
@@ -61,7 +61,7 @@ public abstract class ImageFetcher {
|
||||
if (ed != null) {
|
||||
String setCode =ed.getScryfallCode();
|
||||
String langCode = ed.getCardsLangCode();
|
||||
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(pc, backFace, setCode, langCode, useArtCrop));
|
||||
downloadUrls.add(ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD + ImageUtil.getScryfallDownloadUrl(pc, face, setCode, langCode, useArtCrop));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public abstract class ImageFetcher {
|
||||
String setCode = edition.getScryfallCode();
|
||||
String langCode = edition.getCardsLangCode();
|
||||
return ForgeConstants.URL_PIC_SCRYFALL_DOWNLOAD +
|
||||
ImageUtil.getScryfallDownloadUrl(c, backFace, setCode, langCode, useArtCrop);
|
||||
ImageUtil.getScryfallDownloadUrl(c, face, setCode, langCode, useArtCrop);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,10 +105,46 @@ public abstract class ImageFetcher {
|
||||
// Skip fetching if artist info is not available for art crop
|
||||
if (useArtCrop && paperCard.getArtist().isEmpty())
|
||||
return;
|
||||
String imagePath = ImageUtil.getImageRelativePath(paperCard, false, true, false);
|
||||
String imagePath = ImageUtil.getImageRelativePath(paperCard, "", true, false);
|
||||
final boolean hasSetLookup = ImageKeys.hasSetLookup(imagePath);
|
||||
final boolean backFace = imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX);
|
||||
String filename = backFace ? paperCard.getCardAltImageKey() : paperCard.getCardImageKey();
|
||||
String face = "";
|
||||
if (imageKey.endsWith(ImageKeys.BACKFACE_POSTFIX)) {
|
||||
face = "back";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_W)) {
|
||||
face = "white";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_U)) {
|
||||
face = "blue";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_B)) {
|
||||
face = "black";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_R)) {
|
||||
face = "red";
|
||||
} else if (imageKey.endsWith(ImageKeys.SPECFACE_G)) {
|
||||
face = "green";
|
||||
}
|
||||
String filename = "";
|
||||
switch (face) {
|
||||
case "back":
|
||||
filename = paperCard.getCardAltImageKey();
|
||||
break;
|
||||
case "white":
|
||||
filename = paperCard.getCardWSpecImageKey();
|
||||
break;
|
||||
case "blue":
|
||||
filename = paperCard.getCardUSpecImageKey();
|
||||
break;
|
||||
case "black":
|
||||
filename = paperCard.getCardBSpecImageKey();
|
||||
break;
|
||||
case "red":
|
||||
filename = paperCard.getCardRSpecImageKey();
|
||||
break;
|
||||
case "green":
|
||||
filename = paperCard.getCardGSpecImageKey();
|
||||
break;
|
||||
default:
|
||||
filename = paperCard.getCardImageKey();
|
||||
break;
|
||||
}
|
||||
if (useArtCrop) {
|
||||
filename = TextUtil.fastReplace(filename, ".full", ".artcrop");
|
||||
}
|
||||
@@ -119,7 +155,7 @@ public abstract class ImageFetcher {
|
||||
//move priority of ftp image here
|
||||
StringBuilder setDownload = new StringBuilder(ForgeConstants.URL_PIC_DOWNLOAD);
|
||||
if (!hasSetLookup) {
|
||||
setDownload.append(ImageUtil.getDownloadUrl(paperCard, backFace));
|
||||
setDownload.append(ImageUtil.getDownloadUrl(paperCard, face));
|
||||
downloadUrls.add(setDownload.toString());
|
||||
} else {
|
||||
List<PaperCard> clones = StaticData.instance().getCommonCards().getAllCards(paperCard.getName());
|
||||
@@ -127,12 +163,12 @@ public abstract class ImageFetcher {
|
||||
if (clones.size() > 1) {//clones only
|
||||
if (!paperCard.getEdition().equalsIgnoreCase(pc.getEdition())) {
|
||||
StringBuilder set = new StringBuilder(ForgeConstants.URL_PIC_DOWNLOAD);
|
||||
set.append(ImageUtil.getDownloadUrl(pc, backFace));
|
||||
set.append(ImageUtil.getDownloadUrl(pc, face));
|
||||
downloadUrls.add(set.toString());
|
||||
}
|
||||
} else {// original from set
|
||||
StringBuilder set = new StringBuilder(ForgeConstants.URL_PIC_DOWNLOAD);
|
||||
set.append(ImageUtil.getDownloadUrl(pc, backFace));
|
||||
set.append(ImageUtil.getDownloadUrl(pc, face));
|
||||
downloadUrls.add(set.toString());
|
||||
}
|
||||
}
|
||||
@@ -140,7 +176,7 @@ public abstract class ImageFetcher {
|
||||
}
|
||||
final String cardCollectorNumber = paperCard.getCollectorNumber();
|
||||
if (!cardCollectorNumber.equals(IPaperCard.NO_COLLECTOR_NUMBER)) {
|
||||
final String scryfallURL = this.getScryfallDownloadURL(paperCard, backFace, useArtCrop, hasSetLookup, imagePath, downloadUrls);
|
||||
final String scryfallURL = this.getScryfallDownloadURL(paperCard, face, useArtCrop, hasSetLookup, filename, downloadUrls);
|
||||
if (scryfallURL != null && !hasSetLookup)
|
||||
downloadUrls.add(scryfallURL);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user