mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
Merge branch 'master' into master2
This commit is contained in:
@@ -106,6 +106,14 @@ public final class MagicColor {
|
||||
}
|
||||
}
|
||||
|
||||
public static String toSymbol(final byte color) {
|
||||
return MagicColor.Color.fromByte(color).getSymbol();
|
||||
}
|
||||
|
||||
public static String toSymbol(final String color) {
|
||||
return toSymbol(fromName(color));
|
||||
}
|
||||
|
||||
/**
|
||||
* The Interface Color.
|
||||
*/
|
||||
@@ -165,6 +173,17 @@ public final class MagicColor {
|
||||
symbol = symbol0;
|
||||
}
|
||||
|
||||
public static Color fromByte(final byte color) {
|
||||
switch (color) {
|
||||
case MagicColor.WHITE: return WHITE;
|
||||
case MagicColor.BLUE: return BLUE;
|
||||
case MagicColor.BLACK: return BLACK;
|
||||
case MagicColor.RED: return RED;
|
||||
case MagicColor.GREEN: return GREEN;
|
||||
default: return COLORLESS;
|
||||
}
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ package forge.game.ability;
|
||||
import com.google.common.base.Functions;
|
||||
import com.google.common.collect.*;
|
||||
import com.google.common.math.IntMath;
|
||||
|
||||
import forge.card.CardStateName;
|
||||
import forge.card.CardType;
|
||||
import forge.card.ColorSet;
|
||||
@@ -2510,6 +2509,19 @@ public class AbilityUtils {
|
||||
return doXMath(CardLists.getValidCardCount(game.getLeftGraveyardThisTurn(), validFilter, player, c, ctb), expr, c, ctb);
|
||||
}
|
||||
|
||||
// Count$UnlockedDoors <Valid>
|
||||
if (sq[0].startsWith("UnlockedDoors")) {
|
||||
final String[] workingCopy = l[0].split(" ", 2);
|
||||
final String validFilter = workingCopy[1];
|
||||
|
||||
int unlocked = 0;
|
||||
for (Card doorCard : CardLists.getValidCards(player.getCardsIn(ZoneType.Battlefield), validFilter, player, c, ctb)) {
|
||||
unlocked += doorCard.getUnlockedRooms().size();
|
||||
}
|
||||
|
||||
return doXMath(unlocked, expr, c, ctb);
|
||||
}
|
||||
|
||||
// Manapool
|
||||
if (sq[0].startsWith("ManaPool")) {
|
||||
final String color = l[0].split(":")[1];
|
||||
|
||||
@@ -55,11 +55,14 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
|
||||
if (abMana.isComboMana()) {
|
||||
int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(card, sa.getParam("Amount"), sa) : 1;
|
||||
if(amount <= 0)
|
||||
continue;
|
||||
|
||||
String express = abMana.getExpressChoice();
|
||||
String[] colorsProduced = abMana.getComboColors(sa).split(" ");
|
||||
|
||||
final StringBuilder choiceString = new StringBuilder();
|
||||
final StringBuilder choiceSymbols = new StringBuilder();
|
||||
ColorSet colorOptions = ColorSet.fromNames(colorsProduced);
|
||||
String[] colorsNeeded = express.isEmpty() ? null : express.split(" ");
|
||||
boolean differentChoice = abMana.getOrigProduced().contains("Different");
|
||||
@@ -70,12 +73,14 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
for (Map.Entry<Byte, Integer> e : choices.entrySet()) {
|
||||
Byte chosenColor = e.getKey();
|
||||
String choice = MagicColor.toShortString(chosenColor);
|
||||
String symbol = MagicColor.toSymbol(chosenColor);
|
||||
Integer count = e.getValue();
|
||||
while (count > 0) {
|
||||
if (choiceString.length() > 0) {
|
||||
choiceString.append(" ");
|
||||
}
|
||||
choiceString.append(choice);
|
||||
choiceSymbols.append(symbol);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
@@ -106,25 +111,26 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
choiceString.append(" ");
|
||||
}
|
||||
choiceString.append(choice);
|
||||
choiceSymbols.append(MagicColor.toSymbol(choice));
|
||||
if (sa.hasParam("TwoEach")) {
|
||||
choiceString.append(" ").append(choice);
|
||||
choiceSymbols.append(MagicColor.toSymbol(choice));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (choiceString.toString().isEmpty() && "Combo ColorIdentity".equals(abMana.getOrigProduced())) {
|
||||
// No mana could be produced here (non-EDH match?), so cut short
|
||||
return;
|
||||
continue;
|
||||
}
|
||||
|
||||
game.getAction().notifyOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), choiceString), p);
|
||||
game.getAction().notifyOfValue(sa, p, choiceSymbols.toString(), p);
|
||||
abMana.setExpressChoice(choiceString.toString());
|
||||
}
|
||||
else if (abMana.isAnyMana()) {
|
||||
// AI color choice is set in ComputerUtils so only human players need to make a choice
|
||||
|
||||
String colorsNeeded = abMana.getExpressChoice();
|
||||
String choice = "";
|
||||
|
||||
ColorSet colorMenu = null;
|
||||
byte mask = 0;
|
||||
@@ -137,10 +143,9 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
if (0 == val) {
|
||||
throw new RuntimeException("ManaEffect::resolve() /*any mana*/ - " + p + " color mana choice is empty for " + card.getName());
|
||||
}
|
||||
choice = MagicColor.toShortString(val);
|
||||
|
||||
game.getAction().notifyOfValue(sa, card, Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), choice), p);
|
||||
abMana.setExpressChoice(choice);
|
||||
game.getAction().notifyOfValue(sa, card, MagicColor.toSymbol(val), p);
|
||||
abMana.setExpressChoice(MagicColor.toShortString(val));
|
||||
}
|
||||
else if (abMana.isSpecialMana()) {
|
||||
String type = abMana.getOrigProduced().split("Special ")[1];
|
||||
@@ -183,7 +188,7 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
int nMana = 0;
|
||||
for (Object o : card.getRemembered()) {
|
||||
if (o instanceof String) {
|
||||
sb.append(o.toString());
|
||||
sb.append(o);
|
||||
nMana++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ import forge.game.cost.Cost;
|
||||
import forge.game.keyword.Keyword;
|
||||
import forge.game.keyword.KeywordInterface;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.replacement.ReplacementEffect;
|
||||
import forge.game.replacement.ReplacementHandler;
|
||||
import forge.game.spellability.*;
|
||||
import forge.game.staticability.StaticAbility;
|
||||
@@ -268,6 +269,11 @@ public class CardFactory {
|
||||
original.addStaticAbility(st.copy(card, false));
|
||||
}
|
||||
}
|
||||
for (ReplacementEffect re : card.getCurrentState().getReplacementEffects()) {
|
||||
if (re.isIntrinsic()) {
|
||||
original.addReplacementEffect(re.copy(card, false));
|
||||
}
|
||||
}
|
||||
original.getSVars().putAll(card.getCurrentState().getSVars()); // Unfortunately need to copy these to (Effect looks for sVars on execute)
|
||||
} else if (state != CardStateName.Original) {
|
||||
CardFactoryUtil.setupKeywordedAbilities(card);
|
||||
|
||||
@@ -41,6 +41,7 @@ public class MessageUtil {
|
||||
case Seek:
|
||||
return value;
|
||||
case ChooseColor:
|
||||
case Mana:
|
||||
return sa.hasParam("Random")
|
||||
? Localizer.getInstance().getMessage("lblRandomColorChosen", value)
|
||||
: Localizer.getInstance().getMessage("lblPlayerPickedChosen", choser, value);
|
||||
|
||||
@@ -6,15 +6,15 @@ import java.awt.FontMetrics;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.concurrent.FutureTask;
|
||||
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.StyleConstants;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import forge.gui.FThreads;
|
||||
import forge.localinstance.skin.FSkinProp;
|
||||
import forge.toolbox.FSkin.SkinImage;
|
||||
import forge.util.Localizer;
|
||||
@@ -87,20 +87,25 @@ public class FOptionPane extends FDialog {
|
||||
if (FView.SINGLETON_INSTANCE.getSplash() != null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
final FOptionPane optionPane = new FOptionPane(message, title, icon, null, options, defaultOption);
|
||||
optionPane.setVisible(true);
|
||||
final int dialogResult = optionPane.result;
|
||||
optionPane.dispose();
|
||||
return dialogResult;
|
||||
return showOptionDialog(message, title, icon, null, options, defaultOption);
|
||||
}
|
||||
|
||||
public static int showOptionDialog(final String message, final String title, final SkinImage icon, final Component comp, final List<String> options, final int defaultOption) {
|
||||
final FOptionPane optionPane = new FOptionPane(message, title, icon, comp, options, defaultOption);
|
||||
optionPane.setVisible(true);
|
||||
final int dialogResult = optionPane.result;
|
||||
optionPane.dispose();
|
||||
return dialogResult;
|
||||
final Callable<Integer> showChoice = () -> {
|
||||
final FOptionPane optionPane = new FOptionPane(message, title, icon, comp, options, defaultOption);
|
||||
optionPane.setVisible(true);
|
||||
final int dialogResult = optionPane.result;
|
||||
optionPane.dispose();
|
||||
return dialogResult;
|
||||
};
|
||||
final FutureTask<Integer> future = new FutureTask<>(showChoice);
|
||||
FThreads.invokeInEdtAndWait(future);
|
||||
try {
|
||||
return future.get();
|
||||
} catch (final Exception e) { // should be no exception here
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static String showInputDialog(final String message, final String title) {
|
||||
@@ -117,45 +122,56 @@ public class FOptionPane extends FDialog {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> T showInputDialog(final String message, final String title, final SkinImage icon, final String initialInput, final List<T> inputOptions) {
|
||||
final JComponent inputField;
|
||||
FTextField txtInput = null;
|
||||
FComboBox<T> cbInput = null;
|
||||
if (inputOptions == null) {
|
||||
txtInput = new FTextField.Builder().text(initialInput).build();
|
||||
inputField = txtInput;
|
||||
} else {
|
||||
cbInput = new FComboBox<>(inputOptions);
|
||||
cbInput.setSelectedItem(initialInput);
|
||||
inputField = cbInput;
|
||||
}
|
||||
final Callable<T> showChoice = () -> {
|
||||
final JComponent inputField;
|
||||
FTextField txtInput = null;
|
||||
FComboBox<T> cbInput = null;
|
||||
if (inputOptions == null) {
|
||||
txtInput = new FTextField.Builder().text(initialInput).build();
|
||||
inputField = txtInput;
|
||||
} else {
|
||||
cbInput = new FComboBox<>(inputOptions);
|
||||
cbInput.setSelectedItem(initialInput);
|
||||
inputField = cbInput;
|
||||
}
|
||||
|
||||
final FOptionPane optionPane = new FOptionPane(message, title, icon, inputField, ImmutableList.of(Localizer.getInstance().getMessage("lblOK"), Localizer.getInstance().getMessage("lblCancel")), -1);
|
||||
optionPane.setDefaultFocus(inputField);
|
||||
inputField.addKeyListener(new KeyAdapter() { //hook so pressing Enter on field accepts dialog
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
optionPane.setResult(0);
|
||||
final FOptionPane optionPane = new FOptionPane(message, title, icon, inputField, ImmutableList.of(Localizer.getInstance().getMessage("lblOK"), Localizer.getInstance().getMessage("lblCancel")), -1);
|
||||
optionPane.setDefaultFocus(inputField);
|
||||
inputField.addKeyListener(new KeyAdapter() { //hook so pressing Enter on field accepts dialog
|
||||
@Override
|
||||
public void keyPressed(final KeyEvent e) {
|
||||
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
|
||||
optionPane.setResult(0);
|
||||
}
|
||||
}
|
||||
});
|
||||
optionPane.setVisible(true);
|
||||
final int dialogResult = optionPane.result;
|
||||
optionPane.dispose();
|
||||
if (dialogResult == 0) {
|
||||
if (inputOptions == null) {
|
||||
return (T)txtInput.getText();
|
||||
} else {
|
||||
return cbInput.getSelectedItem();
|
||||
}
|
||||
}
|
||||
});
|
||||
optionPane.setVisible(true);
|
||||
final int dialogResult = optionPane.result;
|
||||
optionPane.dispose();
|
||||
if (dialogResult == 0) {
|
||||
if (inputOptions == null) {
|
||||
return (T)txtInput.getText();
|
||||
} else {
|
||||
return cbInput.getSelectedItem();
|
||||
}
|
||||
return null;
|
||||
};
|
||||
final FutureTask<T> future = new FutureTask<>(showChoice);
|
||||
FThreads.invokeInEdtAndWait(future);
|
||||
try {
|
||||
return future.get();
|
||||
} catch (final Exception e) { // should be no exception here
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private int result = -1; //default result to -1, indicating dialog closed without choosing option
|
||||
private final FButton[] buttons;
|
||||
|
||||
public FOptionPane(final String message, final String title, final SkinImage icon, final Component comp, final List<String> options, final int defaultOption) {
|
||||
FThreads.assertExecutedByEdt(true);
|
||||
this.setTitle(title);
|
||||
|
||||
final int padding = 10;
|
||||
@@ -163,7 +179,7 @@ public class FOptionPane extends FDialog {
|
||||
final int gapAboveButtons = padding * 3 / 2;
|
||||
final int gapBottom = comp == null ? gapAboveButtons : padding;
|
||||
FLabel centeredLabel = null;
|
||||
FTextPane centeredPrompt = null;
|
||||
FTextPane prompt = null;
|
||||
|
||||
if (icon != null) {
|
||||
if (icon.getWidth() < 100) {
|
||||
@@ -179,23 +195,16 @@ public class FOptionPane extends FDialog {
|
||||
}
|
||||
}
|
||||
if (message != null) {
|
||||
if (centeredLabel == null) {
|
||||
final FTextArea prompt = new FTextArea(message);
|
||||
prompt.setFont(FSkin.getFont(14));
|
||||
prompt.setAutoSize(true);
|
||||
final Dimension parentSize = JOptionPane.getRootFrame().getSize();
|
||||
prompt.setMaximumSize(new Dimension(parentSize.width / 2, parentSize.height - 100));
|
||||
this.add(prompt, "x " + x + ", ay top, wrap, gaptop " + (icon == null ? 0 : 7) + ", gapbottom " + gapBottom);
|
||||
}
|
||||
else {
|
||||
final FTextPane prompt = new FTextPane(message);
|
||||
prompt.setFont(FSkin.getFont(14));
|
||||
prompt = new FTextPane();
|
||||
prompt.setContentType("text/html");
|
||||
prompt.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
|
||||
prompt.setText(FSkin.encodeSymbols(message, false));
|
||||
prompt.setFont(FSkin.getFont(14));
|
||||
if(centeredLabel != null)
|
||||
prompt.setTextAlignment(StyleConstants.ALIGN_CENTER);
|
||||
final Dimension parentSize = JOptionPane.getRootFrame().getSize();
|
||||
prompt.setMaximumSize(new Dimension(parentSize.width / 2, parentSize.height - 100));
|
||||
this.add(prompt, "x " + x + ", ay top, wrap, gapbottom " + gapBottom);
|
||||
centeredPrompt = prompt;
|
||||
}
|
||||
final Dimension parentSize = JOptionPane.getRootFrame().getSize();
|
||||
prompt.setMaximumSize(new Dimension(parentSize.width / 2, parentSize.height - 100));
|
||||
this.add(prompt, "x " + x + ", ay top, wrap, gaptop " + (icon == null ? 0 : 7) + ", gapbottom " + gapBottom);
|
||||
x = padding;
|
||||
}
|
||||
if (comp != null) {
|
||||
@@ -277,7 +286,8 @@ public class FOptionPane extends FDialog {
|
||||
|
||||
if (centeredLabel != null) {
|
||||
centeredLabel.setPreferredSize(new Dimension(width - 2 * padding, centeredLabel.getMinimumSize().height));
|
||||
centeredPrompt.setPreferredSize(new Dimension(width - 2 * padding, centeredPrompt.getPreferredSize().height));
|
||||
if(prompt != null)
|
||||
prompt.setPreferredSize(new Dimension(width - 2 * padding, prompt.getPreferredSize().height));
|
||||
}
|
||||
|
||||
this.setSize(width, this.getHeight() + buttonHeight); //resize dialog again to account for buttons
|
||||
|
||||
@@ -39,7 +39,7 @@ public class SpellSmithScene extends UIScene {
|
||||
|
||||
private List<PaperCard> cardPool = new ArrayList<>();
|
||||
private TextraLabel playerGold, playerShards, poolSize;
|
||||
private final TextraButton pullUsingGold, pullUsingShards;
|
||||
private final TextraButton pullUsingGold, pullUsingShards, acceptReward, declineReward, exitSmith;
|
||||
private final ScrollPane rewardDummy;
|
||||
private RewardActor rewardActor;
|
||||
SelectBox<CardEdition> editionList;
|
||||
@@ -47,6 +47,7 @@ public class SpellSmithScene extends UIScene {
|
||||
final private HashMap<String, TextraButton> rarityButtons = new HashMap<>();
|
||||
final private HashMap<String, TextraButton> costButtons = new HashMap<>();
|
||||
final private HashMap<String, TextraButton> colorButtons = new HashMap<>();
|
||||
|
||||
//Filter variables.
|
||||
private String edition = "";
|
||||
private String rarity = "";
|
||||
@@ -57,20 +58,28 @@ public class SpellSmithScene extends UIScene {
|
||||
private int currentPrice = 0;
|
||||
private int currentShardPrice = 0;
|
||||
private List<CardEdition> editions = null;
|
||||
private Reward currentReward = null;
|
||||
private boolean paidInShards = false;
|
||||
|
||||
private SpellSmithScene() {
|
||||
super(Forge.isLandscapeMode() ? "ui/spellsmith.json" : "ui/spellsmith_portrait.json");
|
||||
|
||||
|
||||
editionList = ui.findActor("BSelectPlane");
|
||||
rewardDummy = ui.findActor("RewardDummy");
|
||||
rewardDummy.setVisible(false);
|
||||
|
||||
|
||||
pullUsingGold = ui.findActor("pullUsingGold");
|
||||
pullUsingGold.setDisabled(true);
|
||||
pullUsingShards = ui.findActor("pullUsingShards");
|
||||
pullUsingShards.setDisabled(true);
|
||||
|
||||
exitSmith = ui.findActor("done");
|
||||
|
||||
acceptReward = ui.findActor("accept");
|
||||
acceptReward.setVisible(false);
|
||||
declineReward = ui.findActor("decline");
|
||||
declineReward.setVisible(false);
|
||||
|
||||
playerGold = Controls.newAccountingLabel(ui.findActor("playerGold"), false);
|
||||
playerShards = Controls.newAccountingLabel(ui.findActor("playerShards"), true);
|
||||
poolSize = ui.findActor("poolSize");
|
||||
@@ -114,6 +123,8 @@ public class SpellSmithScene extends UIScene {
|
||||
}
|
||||
}
|
||||
|
||||
ui.onButtonPress("accept", SpellSmithScene.this::acceptSmithing);
|
||||
ui.onButtonPress("decline", SpellSmithScene.this::declineSmithing);
|
||||
ui.onButtonPress("done", SpellSmithScene.this::done);
|
||||
ui.onButtonPress("pullUsingGold", () -> SpellSmithScene.this.pullCard(false));
|
||||
ui.onButtonPress("pullUsingShards", () -> SpellSmithScene.this.pullCard(true));
|
||||
@@ -122,6 +133,7 @@ public class SpellSmithScene extends UIScene {
|
||||
filterResults();
|
||||
});
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
edition = "";
|
||||
cost_low = -1;
|
||||
@@ -160,6 +172,10 @@ public class SpellSmithScene extends UIScene {
|
||||
}
|
||||
|
||||
public boolean done() {
|
||||
if (currentReward != null) {
|
||||
acceptSmithing();
|
||||
}
|
||||
|
||||
if (rewardActor != null) rewardActor.remove();
|
||||
cardPool.clear(); //Get rid of cardPool, filtering is fast enough to justify keeping it cached.
|
||||
Forge.switchToLast();
|
||||
@@ -380,29 +396,74 @@ public class SpellSmithScene extends UIScene {
|
||||
}
|
||||
|
||||
public void pullCard(boolean usingShards) {
|
||||
paidInShards = usingShards;
|
||||
PaperCard P = cardPool.get(MyRandom.getRandom().nextInt(cardPool.size())); //Don't use the standard RNG.
|
||||
Reward R = null;
|
||||
currentReward = null;
|
||||
if (Config.instance().getSettingData().useAllCardVariants) {
|
||||
if (!edition.isEmpty()) {
|
||||
R = new Reward(CardUtil.getCardByNameAndEdition(P.getCardName(), edition));
|
||||
currentReward = new Reward(CardUtil.getCardByNameAndEdition(P.getCardName(), edition));
|
||||
} else {
|
||||
R = new Reward(CardUtil.getCardByName(P.getCardName())); // grab any random variant if no set preference is specified
|
||||
currentReward = new Reward(CardUtil.getCardByName(P.getCardName())); // grab any random variant if no set preference is specified
|
||||
}
|
||||
} else {
|
||||
R = new Reward(P);
|
||||
currentReward = new Reward(P);
|
||||
}
|
||||
Current.player().addReward(R);
|
||||
if (usingShards) {
|
||||
if (rewardActor != null) rewardActor.remove();
|
||||
rewardActor = new RewardActor(currentReward, true, null, true);
|
||||
rewardActor.flip(); //Make it flip so it draws visual attention, why not.
|
||||
rewardActor.setBounds(rewardDummy.getX(), rewardDummy.getY(), rewardDummy.getWidth(), rewardDummy.getHeight());
|
||||
stage.addActor(rewardActor);
|
||||
|
||||
acceptReward.setVisible(true);
|
||||
declineReward.setVisible(true);
|
||||
exitSmith.setDisabled(true);
|
||||
disablePullButtons();
|
||||
}
|
||||
|
||||
private void acceptSmithing() {
|
||||
if (paidInShards) {
|
||||
Current.player().takeShards(currentShardPrice);
|
||||
} else {
|
||||
Current.player().takeGold(currentPrice);
|
||||
}
|
||||
if (Current.player().getGold() < currentPrice) pullUsingGold.setDisabled(true);
|
||||
if (Current.player().getShards() < currentShardPrice) pullUsingShards.setDisabled(true);
|
||||
|
||||
Current.player().addReward(currentReward);
|
||||
|
||||
clearReward();
|
||||
updatePullButtons();
|
||||
}
|
||||
|
||||
private void declineSmithing() {
|
||||
// Decline the smith reward for 10% of original price
|
||||
float priceAdjustment = .10f;
|
||||
if (paidInShards) {
|
||||
Current.player().takeShards((int)(currentShardPrice * priceAdjustment));
|
||||
} else {
|
||||
Current.player().takeGold((int)(currentPrice * priceAdjustment));
|
||||
}
|
||||
|
||||
clearReward();
|
||||
updatePullButtons();
|
||||
}
|
||||
|
||||
private void clearReward() {
|
||||
if (rewardActor != null) rewardActor.remove();
|
||||
rewardActor = new RewardActor(R, true, null, true);
|
||||
rewardActor.flip(); //Make it flip so it draws visual attention, why not.
|
||||
rewardActor.setBounds(rewardDummy.getX(), rewardDummy.getY(), rewardDummy.getWidth(), rewardDummy.getHeight());
|
||||
stage.addActor(rewardActor);
|
||||
currentReward = null;
|
||||
}
|
||||
|
||||
|
||||
private void updatePullButtons() {
|
||||
pullUsingGold.setDisabled(Current.player().getGold() < currentPrice);
|
||||
pullUsingShards.setDisabled(Current.player().getShards() < currentShardPrice);
|
||||
|
||||
acceptReward.setVisible(false);
|
||||
declineReward.setVisible(false);
|
||||
|
||||
exitSmith.setDisabled(false);
|
||||
}
|
||||
|
||||
private void disablePullButtons() {
|
||||
pullUsingGold.setDisabled(true);
|
||||
pullUsingShards.setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
"options": [
|
||||
{
|
||||
"name": "Am I allowed to enter the aerie ?",
|
||||
"text": "I'm afraid to say to you that you are not allowed to do that. Our guild is very protective of it's breeding practices, which have been developed over a span of more than thousands of years. Because of that, we don't want our competitors peeking into our business. If anyone without permission enters the aerie, that person will be repremanded by the various guards and even the birds, who have been trained to attack unwanted intruders.'",
|
||||
"text": "I'm afraid to say to you that you are not allowed to do that. Our guild is very protective of it's breeding practices, which have been developed over a span of more than thousands of years. Because of that, we don't want our competitors peeking into our business. If anyone without permission enters the aerie, that person will be reprimanded by the various guards and even the birds, who have been trained to attack unwanted intruders.'",
|
||||
"options": [
|
||||
{
|
||||
"name": "Thanks for the information, goodbye",
|
||||
|
||||
@@ -169,12 +169,34 @@
|
||||
"y": 5,
|
||||
"width": 90,
|
||||
"height": 20
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"selectable": true,
|
||||
"name": "accept",
|
||||
"text": "tr(lblTake)",
|
||||
"binding": "Use",
|
||||
"x": 343,
|
||||
"y": 173,
|
||||
"width": 60,
|
||||
"height": 20
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"selectable": true,
|
||||
"name": "decline",
|
||||
"text": "tr(lblRefund)",
|
||||
"binding": "Back",
|
||||
"x": 405,
|
||||
"y": 173,
|
||||
"width": 60,
|
||||
"height": 20
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"name": "poolSize",
|
||||
"x": 360,
|
||||
"y": 180,
|
||||
"y": 192,
|
||||
"width": 90,
|
||||
"height": 20
|
||||
},
|
||||
|
||||
@@ -174,12 +174,34 @@
|
||||
"y": 75,
|
||||
"width": 90,
|
||||
"height": 20
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"selectable": true,
|
||||
"name": "accept",
|
||||
"text": "tr(lblTake)",
|
||||
"binding": "Use",
|
||||
"x": 2,
|
||||
"y": 142,
|
||||
"width": 60,
|
||||
"height": 20
|
||||
},
|
||||
{
|
||||
"type": "TextButton",
|
||||
"selectable": true,
|
||||
"name": "decline",
|
||||
"text": "tr(lblRefund)",
|
||||
"binding": "Back",
|
||||
"x": 70,
|
||||
"y": 142,
|
||||
"width": 60,
|
||||
"height": 20
|
||||
},
|
||||
{
|
||||
"type": "Label",
|
||||
"name": "poolSize",
|
||||
"x": 16,
|
||||
"y": 150,
|
||||
"y": 163,
|
||||
"width": 97,
|
||||
"height": 20
|
||||
},
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Enchantment Creature Demon
|
||||
PT:6/6
|
||||
K:Flying
|
||||
K:Trample
|
||||
S:Mode$ Continuous | Affected$ Card.Enchantment+YouCtrl+nonLand | MayPlayLimit$ 1 | MayPlay$ True | MayPlayAltManaCost$ PayLife<ConvertedManaCost> | MayPlayDontGrantZonePermissions$ True | AffectedZone$ Hand,Graveyard,Exile,Library,Command | Description$ Once during each of your turns, you may cast an enchantment spell by paying life equal to its mana value rather than paying its mana cost.
|
||||
S:Mode$ Continuous | Condition$ PlayerTurn | Affected$ Card.Enchantment+YouCtrl+nonLand | MayPlayLimit$ 1 | MayPlay$ True | MayPlayAltManaCost$ PayLife<ConvertedManaCost> | MayPlayDontGrantZonePermissions$ True | AffectedZone$ Hand,Graveyard,Exile,Library,Command | Description$ Once during each of your turns, you may cast an enchantment spell by paying life equal to its mana value rather than paying its mana cost.
|
||||
A:AB$ Pump | Cost$ 2 B Sac<1/Enchantment.Other> | NumAtt$ X | SpellDescription$ CARDNAME gets +X/+0 until end of turn, where X is the sacrificed enchantment's mana value.
|
||||
SVar:X:Sacrificed$CardManaCost
|
||||
DeckHints:Type$Enchantment
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Name:Snakeskin Veil
|
||||
ManaCost:G
|
||||
Types:Instant
|
||||
A:SP$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on target creature you control.
|
||||
A:SP$ PutCounter | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1 | SubAbility$ DBPump | SpellDescription$ Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn.
|
||||
SVar:DBPump:DB$ Pump | Defined$ Targeted | KW$ Hexproof
|
||||
DeckHas:Ability$Counters
|
||||
Oracle:Put a +1/+1 counter on target creature you control. It gains hexproof until end of turn.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 B
|
||||
Types:Creature Leech
|
||||
PT:2/2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigLoseLife | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, each opponent loses 1 life.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigLoseLife| TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, each opponent loses 1 life.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigLoseLife| TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, each opponent loses 1 life.
|
||||
SVar:TrigLoseLife:DB$ LoseLife | Defined$ Player.Opponent | LifeAmount$ 1
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, each opponent loses 1 life.
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, each opponent loses 1 life.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:2 W
|
||||
Types:Creature Human Doctor
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gains lifelink until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gains lifelink until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gains lifelink until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ Self | KW$ Lifelink
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Cult Healer gains lifelink until end of turn.
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Cult Healer gains lifelink until end of turn.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:3 B
|
||||
Types:Creature Vampire Warrior
|
||||
PT:2/5
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 and gains lifelink until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ $ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 and gains lifelink until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ $ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 and gains lifelink until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 2 | KW$ Lifelink
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Dashing Bloodsucker gets +2/+0 and gains lifelink until end of turn.
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Dashing Bloodsucker gets +2/+0 and gains lifelink until end of turn.
|
||||
|
||||
14
forge-gui/res/cardsfolder/upcoming/disorienting_choice.txt
Normal file
14
forge-gui/res/cardsfolder/upcoming/disorienting_choice.txt
Normal file
@@ -0,0 +1,14 @@
|
||||
Name:Disorienting Choice
|
||||
ManaCost:3 G
|
||||
Types:Sorcery
|
||||
A:SP$ Pump | ValidTgts$ Artifact.OppCtrl,Enchantment.OppCtrl | TgtPrompt$ Choose up to one target artifact or enchantment each opponent controls | TargetMin$ 0 | TargetMax$ OneEach | TargetsForEachPlayer$ True | SubAbility$ DBRepeat | SpellDescription$ For each opponent, choose up to one target artifact or enchantment that player controls. For each permanent chosen this way, its controller may exile it. Then if one or more of the chosen permanents are still on the battlefield, you search your library for up to that many land cards, put them onto the battlefield tapped, then shuffle.
|
||||
SVar:DBRepeat:DB$ RepeatEach | RepeatPlayers$ TargetedController | RepeatSubAbility$ DBChoice | SubAbility$ DBExile
|
||||
SVar:DBChoice:DB$ GenericChoice | Choices$ DBDoNotKeep,DBIncrease | Defined$ Remembered | AILogic$ Random | ShowChoice$ ExceptSelf
|
||||
SVar:DBDoNotKeep:DB$ Pump | Defined$ Targeted.RememberedPlayerCtrl | RememberPumped$ True | SpellDescription$ Exile targeted card
|
||||
SVar:DBIncrease:DB$ StoreSVar | SVar$ X | Type$ CountSVar | Expression$ X/Plus.1 | SpellDescription$ Keep targeted card
|
||||
SVar:DBExile:DB$ ChangeZoneAll | Origin$ Battlefield | Destination$ Exile | ChangeType$ Card.IsRemembered | SubAbility$ DBSearchLibrary
|
||||
SVar:DBSearchLibrary:DB$ ChangeZone | Origin$ Library | Destination$ Battlefield | ChangeType$ Land | Tapped$ True | ChangeNum$ X | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Number$0
|
||||
SVar:OneEach:PlayerCountOpponents$Amount
|
||||
Oracle:For each opponent, choose up to one target artifact or enchantment that player controls. For each permanent chosen this way, its controller may exile it. Then if one or more of the chosen permanents are still on the battlefield, you search your library for up to that many land cards, put them onto the battlefield tapped, then shuffle.
|
||||
@@ -5,7 +5,7 @@ PT:1/3
|
||||
K:Flying
|
||||
K:Vigilance
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +1/+1 until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +1/+1 until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +1/+1 until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 1 | NumDef$ 1
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Flying, vigilance\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Erratic Apparition gets +1/+1 until end of turn.
|
||||
|
||||
9
forge-gui/res/cardsfolder/upcoming/fear_my_authority.txt
Normal file
9
forge-gui/res/cardsfolder/upcoming/fear_my_authority.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
Name:Fear My Authority
|
||||
ManaCost:no cost
|
||||
Types:Ongoing Scheme
|
||||
S:Mode$ Continuous | EffectZone$ Command | Affected$ Creature.YouCtrl | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Fear | Description$ Creatures you control get +2/+2 and have fear.
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You | TriggerZones$ Command | Execute$ DBAbandonCheck | TriggerDescription$ At the beginning of your upkeep, abandon this scheme unless you discard a card or pay 3 life.
|
||||
SVar:DBAbandonCheck:DB$ GenericChoice | Choices$ DBPayLife,DBDiscard
|
||||
SVar:DBPayLife:DB$ Abandon | UnlessCost$ PayLife<3> | UnlessPayer$ You | SpellDescription$ Pay 3 life or abandon this scheme
|
||||
SVar:DBDiscard:DB$ Abandon | UnlessCost$ Discard<1/Card> | UnlessPayer$ You | SpellDescription$ Discard a card or abandon this scheme
|
||||
Oracle:(An ongoing scheme remains face up until it's abandoned.)\nCreatures you control get +2/+2 and have fear. (They can't be blocked except by artifact creatures and/or black creatures.)\nAt the beginning of your upkeep, abandon this scheme unless you discard a card or pay 3 life.
|
||||
@@ -6,6 +6,6 @@ K:Flying
|
||||
K:Lifelink
|
||||
K:CARDNAME can't block.
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | OptionalDecider$ You | TriggerZones$ Graveyard | Execute$ TrigChange | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, you may return CARDNAME from your graveyard to your hand.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | OptionalDecider$ You | TriggerZones$ Graveyard | Execute$ TrigChange | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, you may return CARDNAME from your graveyard to your hand.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | OptionalDecider$ You | TriggerZones$ Graveyard | Execute$ TrigChange | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, you may return CARDNAME from your graveyard to your hand.
|
||||
SVar:TrigChange:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand
|
||||
Oracle:Flying, lifelink\nFear of Infinity can't block.\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, you may return Fear of Infinity from your graveyard to your hand.
|
||||
|
||||
@@ -3,8 +3,8 @@ ManaCost:W U
|
||||
Types:Creature Human Scout
|
||||
PT:2/2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigToken | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigToken | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigToken | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ r_1_1_gremlin | TokenOwner$ You
|
||||
DeckHas:Ability$Token
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token.
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, create a 1/1 red Gremlin creature token.
|
||||
|
||||
6
forge-gui/res/cardsfolder/upcoming/i_am_never_alone.txt
Normal file
6
forge-gui/res/cardsfolder/upcoming/i_am_never_alone.txt
Normal file
@@ -0,0 +1,6 @@
|
||||
Name:I Am Never Alone
|
||||
ManaCost:no cost
|
||||
Types:Scheme
|
||||
T:Mode$ SetInMotion | ValidCard$ Card.Self | Execute$ DBCopyCommander | TriggerZones$ Command | TriggerDescription$ When you set this scheme in motion, create a token that's a copy of your commander, except it's not legendary.
|
||||
SVar:DBCopyCommander:DB$ CopyPermanent | Choices$ Card.IsCommander+YouOwn | Defined$ ValidAll Card.IsCommander+YouOwn | ChoiceTitle$ Choose a commander you own | NonLegendary$ True
|
||||
Oracle:When you set this scheme in motion, create a token that's a copy of your commander, except it's not legendary.\n"This is but a pale shadow of my true form. Cower before it, and despair."
|
||||
@@ -3,10 +3,10 @@ ManaCost:3 R
|
||||
Types:Creature Spirit
|
||||
PT:2/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 until end of turn.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME gets +2/+0 until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ 2
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigDamage | TriggerDescription$ When CARDNAME dies, it deals damage equal to its power to any target.
|
||||
SVar:TrigDamage:DB$ DealDamage | ValidTgts$ Any | NumDmg$ X
|
||||
SVar:X:TriggeredCard$CardPower
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Infernal Phantom gets +2/+0 until end of turn.\nWhen Infernal Phantom dies, it deals damage equal to its power to any target.
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, Infernal Phantom gets +2/+0 until end of turn.\nWhen Infernal Phantom dies, it deals damage equal to its power to any target.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:W
|
||||
Types:Creature Human Scout
|
||||
PT:1/1
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a +1/+1 counter on target creature.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a +1/+1 counter on target creature.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a +1/+1 counter on target creature.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | ValidTgts$ Creature | TgtPrompt$ Select target creature | CounterType$ P1P1 | CounterNum$ 1
|
||||
DeckHas:Ability$Counters
|
||||
DeckNeeds:Type$Enchantment
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
Name:Rampaging Soulrager
|
||||
ManaCost:2 R
|
||||
Types:Creature Spirit
|
||||
PT:1/4
|
||||
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ 3 | CheckSVar$ X | SVarCompare$ GE2 | Description$ CARDNAME gets +3/+0 as long as there are two or more unlocked doors among Rooms you control.
|
||||
SVar:X:Count$UnlockedDoors Card.Room+YouCtrl
|
||||
Oracle:Rampaging Soulrager gets +3/+0 as long as there are two or more unlocked doors among Rooms you control.
|
||||
@@ -3,7 +3,7 @@ ManaCost:U
|
||||
Types:Creature Crab Skeleton
|
||||
PT:0/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigMill | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.)
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigMill | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.)
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigMill | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.)
|
||||
SVar:TrigMill:DB$ Mill | NumCards$ 2 | ValidTgts$ Player | TgtPrompt$ Select target player
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.)
|
||||
Oracle:Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, target player mills two cards. (They put the top two cards of their library into their graveyard.)
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Insect Skeleton
|
||||
PT:1/4
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.)
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.).
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigSurveil | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.).
|
||||
SVar:TrigSurveil:DB$ Surveil | Amount$ 1
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Flying\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.)
|
||||
Oracle:Flying\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 1. (Look at the top card of your library. You may put it into your graveyard.)
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Creature Human Wizard
|
||||
PT:3/3
|
||||
K:Defender
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigEffect | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME can attack this turn as though it didn't have defender.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigEffect | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME can attack this turn as though it didn't have defender.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigEffect | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, CARDNAME can attack this turn as though it didn't have defender.
|
||||
SVar:TrigEffect:DB$ Effect | StaticAbilities$ CanAttack | ForgetOnMoved$ Battlefield
|
||||
SVar:CanAttack:Mode$ CanAttackDefender | ValidCard$ Card.EffectSource | Description$ EFFECTSOURCE can attack this turn as though it didn't have defender.
|
||||
DeckNeeds:Type$Enchantment
|
||||
|
||||
@@ -4,11 +4,11 @@ Types:Creature Human Wizard
|
||||
PT:3/2
|
||||
K:Vigilance
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on CARDNAME.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPutCounter | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on CARDNAME.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigPutCounter | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on CARDNAME.
|
||||
SVar:TrigPutCounter:DB$ PutCounter | Defined$ Self | CounterType$ POSSESSION | CounterNum$ 1
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Card.Self | Execute$ TrigToken | TriggerDescription$ When CARDNAME dies, create an X/X blue Spirit creature token with flying, where X is the number of counters on CARDNAME.
|
||||
SVar:TrigToken:DB$ Token | TokenAmount$ 1 | TokenScript$ u_x_x_spirit_flying | TokenPower$ X | TokenToughness$ X | TokenOwner$ You
|
||||
SVar:X:TriggeredCard$CardCounters.ALL
|
||||
DeckHas:Ability$Token & Type$Spirit
|
||||
DeckNeeds:Type$Enchantment
|
||||
Oracle:Vigilance\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on Unwilling Vessel.\nWhen Unwilling Vessel dies, create an X/X blue Spirit creature token with flying, where X is the number of counters on Unwilling Vessel.
|
||||
Oracle:Vigilance\nEerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, put a possession counter on Unwilling Vessel.\nWhen Unwilling Vessel dies, create an X/X blue Spirit creature token with flying, where X is the number of counters on Unwilling Vessel.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 W B
|
||||
Types:Legendary Creature Human Warlock
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Enchantment.YouCtrl | TriggerZones$ Battlefield | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigSurveil | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.
|
||||
T:Mode$ FullyUnlock | ValidCard$ Card.Room | ValidPlayer$ You | Secondary$ True | Execute$ TrigSurveil | TriggerZones$ Battlefield | TriggerDescription$ Eerie — Whenever an enchantment you control enters and whenever you fully unlock a Room, surveil 2 if this is the first time this ability has resolved this turn. If it's the second time, each opponent discards a card. If it's the third time, put a creature card from a graveyard onto the battlefield under your control.
|
||||
SVar:TrigSurveil:DB$ Surveil | Amount$ 2 | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ1 | SubAbility$ DBDiscard
|
||||
SVar:DBDiscard:DB$ Discard | Defined$ Player.Opponent | Mode$ TgtChoose | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ2 | SubAbility$ DBChangeZone
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature | ChangeNum$ 1 | Mandatory$ True | GainControl$ True | ConditionCheckSVar$ X | ConditionSVarCompare$ EQ3 | SelectPrompt$ Select a creature card to return to the battlefield | Hidden$ True | SubAbility$ DBLog
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:1 G U
|
||||
Types:Legendary Creature Human Wizard
|
||||
PT:1/1
|
||||
T:Mode$ Phase | Phase$ End of Turn | TriggerZones$ Battlefield | Execute$ TrigToken | CheckSVar$ X | TriggerDescription$ At the beginning of your end step, if a land entered the battlefield under your control this turn and you control a prime number of lands, create Primo, the Indivisible, a legendary 0/0 green and blue Fractal creature token, then put that many +1/+1 counters on it. (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, and 31 are prime numbers.)
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ primo_the_invisible | RememberTokens$ True | SubAbility$ DBCounters
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ primo_the_indivisible | RememberTokens$ True | SubAbility$ DBCounters
|
||||
SVar:DBCounters:DB$ PutCounter | Defined$ Remembered | CounterNum$ Y | CounterType$ P1P1 | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$IsPrime Y.Z.0
|
||||
|
||||
9
forge-gui/res/editions/Alchemy Duskmourn.txt
Normal file
9
forge-gui/res/editions/Alchemy Duskmourn.txt
Normal file
@@ -0,0 +1,9 @@
|
||||
[metadata]
|
||||
Code=YDSK
|
||||
Date=2024-10-15
|
||||
Name=Alchemy: Duskmourn
|
||||
Type=Online
|
||||
ScryfallCode=YDSK
|
||||
|
||||
[cards]
|
||||
0 R Solitary Study // Endless Corridor @Leon Tukker
|
||||
@@ -796,6 +796,8 @@ F798 M Discord, Lord of Disharmony @Narendra Bintara Adi
|
||||
827 R Norin the Wary @Jarel Threat
|
||||
827b R Norin the Wary @Jarel Threat
|
||||
828 R Keen Duelist @Thanh Tuấn
|
||||
871 R Soul-Guide Lantern @
|
||||
872 R Yargle and Multani @Warren Mahy
|
||||
873 R Dark Deal @Tyler Jacobson
|
||||
874 R Archivist of Oghma @Cory Trego-Erdner
|
||||
875 M Battle Angels of Tyr @Raymond Swanland
|
||||
@@ -803,6 +805,7 @@ F798 M Discord, Lord of Disharmony @Narendra Bintara Adi
|
||||
877 R Druid of Purification @Alexander Mokhov
|
||||
878 R Prosperous Innkeeper @Tyler Jacobson
|
||||
879 M Minsc & Boo, Timeless Heroes @Justin Gerard
|
||||
880 R Stuffy Doll @Robin Olausson
|
||||
900 M The Scarab God @Barely Human
|
||||
901 R Lightning Bolt @Christopher Rush
|
||||
903 M The Locust God @See Machine
|
||||
|
||||
@@ -3434,4 +3434,6 @@ lblShowNoSell=No-Sell Anzeigen
|
||||
lblShowAll=Alle Anzeigen
|
||||
lblHideCollection=Sammlung Ausblenden
|
||||
lblShowCollection=Sammlung Anzeigen
|
||||
lblCracked=Geknackt!
|
||||
lblCracked=Geknackt!
|
||||
lblTake=Nehmen
|
||||
lblRefund=Erstattung
|
||||
@@ -3167,4 +3167,6 @@ lblShowNoSell=Show No-Sell
|
||||
lblShowAll=Show All
|
||||
lblHideCollection=Hide Collection
|
||||
lblShowCollection=Show Collection
|
||||
lblCracked=Cracked!
|
||||
lblCracked=Cracked!
|
||||
lblTake=Take
|
||||
lblRefund=Refund
|
||||
@@ -3448,4 +3448,6 @@ lblShowNoSell=Mostrar No Vender
|
||||
lblShowAll=Mostrar Todo
|
||||
lblHideCollection=Ocultar Colección
|
||||
lblShowCollection=Mostrar Colección
|
||||
lblCracked=¡Agrietado!
|
||||
lblCracked=¡Agrietado!
|
||||
lblTake=Llevar
|
||||
lblRefund=Reembolso
|
||||
@@ -3442,4 +3442,6 @@ lblShowNoSell=Afficher Non-Vente
|
||||
lblShowAll=Afficher Tout
|
||||
lblHideCollection=Masquer la Collection
|
||||
lblShowCollection=Afficher la Collection
|
||||
lblCracked=Fissuré!
|
||||
lblCracked=Fissuré!
|
||||
lblTake=Prendre
|
||||
lblRefund=Remboursement
|
||||
@@ -3441,3 +3441,5 @@ lblShowAll=Mostra Tutto
|
||||
lblHideCollection=Nascondi Collezione
|
||||
lblShowCollection=Mostra Collezione
|
||||
lblCracked=Incrinato!
|
||||
lblTake=Prendere
|
||||
lblRefund=Rimborso
|
||||
@@ -3436,4 +3436,6 @@ lblShowNoSell=ノーセールを表示
|
||||
lblShowAll=すべて表示
|
||||
lblHideCollection=コレクションを非表示にする
|
||||
lblShowCollection=ショーコレクション
|
||||
lblCracked=ひび割れた!
|
||||
lblCracked=ひび割れた!
|
||||
lblTake=取る
|
||||
lblRefund=返金
|
||||
@@ -3526,4 +3526,6 @@ lblShowNoSell=Mostrar Não-Venda
|
||||
lblShowAll=Mostrar Tudo
|
||||
lblHideCollection=Ocultar Coleção
|
||||
lblShowCollection=Mostrar Coleção
|
||||
lblCracked=Rachado!
|
||||
lblCracked=Rachado!
|
||||
lblTake=Pegar
|
||||
lblRefund=Reembolso
|
||||
@@ -3427,4 +3427,6 @@ lblShowNoSell=显示不卖
|
||||
lblShowAll=显示全部
|
||||
lblHideCollection=隐藏收藏
|
||||
lblShowCollection=展会系列
|
||||
lblCracked=破裂了!
|
||||
lblCracked=破裂了!
|
||||
lblTake=拿
|
||||
lblRefund=退款
|
||||
@@ -1,4 +1,4 @@
|
||||
Name:Primo, the Invisible
|
||||
Name:Primo, the Indivisible
|
||||
ManaCost:no cost
|
||||
Colors:green, blue
|
||||
Types:Legendary Creature Fractal
|
||||
Reference in New Issue
Block a user