mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 19:28:01 +00:00
Compare commits
23 Commits
migrate-tl
...
chooseColo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
82c9cd4ef5 | ||
|
|
4a35b51bf2 | ||
|
|
0faae58c1d | ||
|
|
6900bcb8dd | ||
|
|
7497e3e8cd | ||
|
|
93d9c78b8e | ||
|
|
0cd9126b5c | ||
|
|
ba47164862 | ||
|
|
0170f5fe56 | ||
|
|
b07428c02a | ||
|
|
24242aa908 | ||
|
|
07814d9e82 | ||
|
|
9bf45c2e62 | ||
|
|
31147739f1 | ||
|
|
74b1467837 | ||
|
|
a85dc13cd8 | ||
|
|
2ed01fb285 | ||
|
|
3621c02165 | ||
|
|
9e3f23315e | ||
|
|
1033a0b595 | ||
|
|
b49efb28f9 | ||
|
|
07ee5ccddf | ||
|
|
21e458237d |
2
.github/workflows/sync-wiki.yml
vendored
2
.github/workflows/sync-wiki.yml
vendored
@@ -18,7 +18,7 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: fix md links for Gollum
|
||||
run: find ${{ github.workspace }}/docs/ -type f -name "*.md" -exec sed -i -E 's|(\[[^]]+]\()([^)]+\/)*([^).]+).md(#)*([[:alnum:]]*)\)|\1\3\4\5)|g' '{}' \;
|
||||
run: find ${{ github.workspace }}/docs/ -type f -name "*.md" -exec sed -i -E 's|(\[[^]]+]\()([^)]+\/)*([^).]+).md\)|\1\3)|g' '{}' \;
|
||||
- name: fix image links for Gollum
|
||||
run: find ${{ github.workspace }}/docs/ -type f -name "*.png" -exec mv '{}' ${{ github.workspace }}/docs/ \;
|
||||
- uses: Andrew-Chen-Wang/github-wiki-action@v5
|
||||
|
||||
@@ -241,7 +241,8 @@ public class PlayerControllerAi extends PlayerController {
|
||||
public Map<Byte, Integer> specifyManaCombo(SpellAbility sa, ColorSet colorSet, int manaAmount, boolean different) {
|
||||
Map<Byte, Integer> result = new HashMap<>();
|
||||
for (int i = 0; i < manaAmount; ++i) {
|
||||
Byte chosen = chooseColor("", sa, colorSet);
|
||||
MagicColor.Color chosenColor = chooseColor("", sa, colorSet);
|
||||
Byte chosen = chosenColor == null ? (byte)0 : chosenColor.getColorMask();
|
||||
if (result.containsKey(chosen)) {
|
||||
result.put(chosen, result.get(chosen) + 1);
|
||||
} else {
|
||||
@@ -1022,19 +1023,22 @@ public class PlayerControllerAi extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte chooseColorAllowColorless(String message, Card card, ColorSet colors) {
|
||||
public MagicColor.Color chooseColorAllowColorless(String message, Card card, ColorSet colors) {
|
||||
final String c = ComputerUtilCard.getMostProminentColor(player.getCardsIn(ZoneType.Hand));
|
||||
byte chosenColorMask = MagicColor.fromName(c);
|
||||
if ((colors.getColor() & chosenColorMask) != 0) {
|
||||
return chosenColorMask;
|
||||
return MagicColor.Color.fromByte(chosenColorMask);
|
||||
}
|
||||
return Iterables.getFirst(colors, MagicColor.Color.COLORLESS).getColorMask();
|
||||
return Iterables.getFirst(colors, MagicColor.Color.COLORLESS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte chooseColor(String message, SpellAbility sa, ColorSet colors) {
|
||||
public MagicColor.Color chooseColor(String message, SpellAbility sa, ColorSet colors) {
|
||||
if (colors.countColors() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (colors.countColors() < 2) {
|
||||
return Iterables.getFirst(colors, MagicColor.Color.WHITE).getColorMask();
|
||||
return Iterables.getFirst(colors, MagicColor.Color.WHITE);
|
||||
}
|
||||
// You may switch on sa.getApi() here and use sa.getParam("AILogic")
|
||||
CardCollectionView hand = player.getCardsIn(ZoneType.Hand);
|
||||
@@ -1045,9 +1049,9 @@ public class PlayerControllerAi extends PlayerController {
|
||||
byte chosenColorMask = MagicColor.fromName(c);
|
||||
|
||||
if ((colors.getColor() & chosenColorMask) != 0) {
|
||||
return chosenColorMask;
|
||||
return MagicColor.Color.fromByte(chosenColorMask);
|
||||
}
|
||||
return Iterables.getFirst(colors, MagicColor.Color.WHITE).getColorMask();
|
||||
return Iterables.getFirst(colors, MagicColor.Color.WHITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
package forge.card;
|
||||
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.util.Lang;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
//
|
||||
@@ -187,25 +185,7 @@ final class CardFace implements ICardFace, Cloneable {
|
||||
}
|
||||
|
||||
void assignMissingFieldsToVariant(CardFace variant) {
|
||||
if(variant.oracleText == null) {
|
||||
if(variant.flavorName != null && this.oracleText != null) {
|
||||
try {
|
||||
Lang lang = Lang.getInstance();
|
||||
//Rudimentary name replacement. Can't do pronouns, ability words, or flavored keywords. Need to define variant text manually for that.
|
||||
//Regex here checks for the name following either a word boundary or a literal "\n" string, since those haven't yet been converted to line breaks.
|
||||
String flavoredText = this.oracleText.replaceAll("(?<=\\b|\\\\n)" + this.name + "\\b", variant.flavorName);
|
||||
flavoredText = flavoredText.replaceAll("(?<=\\b|\\\\n)" + lang.getNickName(this.name) + "\\b", lang.getNickName(variant.flavorName));
|
||||
variant.oracleText = flavoredText;
|
||||
}
|
||||
catch (PatternSyntaxException ignored) {
|
||||
// Old versions of Android are weird about patterns sometimes. I don't *think* this is such a case but
|
||||
// the documentation is unreliable. May be worth removing this once we're sure it's not a problem.
|
||||
variant.oracleText = this.oracleText;
|
||||
}
|
||||
}
|
||||
else
|
||||
variant.oracleText = this.oracleText;
|
||||
}
|
||||
if(variant.oracleText == null) variant.oracleText = this.oracleText;
|
||||
if(variant.manaCost == null) variant.manaCost = this.manaCost;
|
||||
if(variant.color == null) variant.color = ColorSet.fromManaCost(variant.manaCost);
|
||||
|
||||
|
||||
@@ -504,11 +504,16 @@ public final class CardRules implements ICardCharacteristics {
|
||||
|
||||
CardFace variantMain = ((CardFace) mainPart).getOrCreateFunctionalVariant(variantName);
|
||||
variantMain.setFlavorName(nameParts[0]);
|
||||
//Rudimentary name replacement. Can't do nicknames, pronouns, ability words, or flavored keywords. Need to define variants manually for that.
|
||||
if(mainPart.getOracleText().contains(mainPart.getName()))
|
||||
variantMain.setOracleText(mainPart.getOracleText().replace(mainPart.getName(), nameParts[0]));
|
||||
((CardFace) mainPart).assignMissingFieldsToVariant(variantMain);
|
||||
|
||||
if(otherPart != null) {
|
||||
CardFace variantOther = ((CardFace) otherPart).getOrCreateFunctionalVariant(variantName);
|
||||
variantOther.setFlavorName(nameParts[1]);
|
||||
if(otherPart.getOracleText().contains(otherPart.getName()))
|
||||
variantMain.setOracleText(otherPart.getOracleText().replace(otherPart.getName(), nameParts[1]));
|
||||
((CardFace) otherPart).assignMissingFieldsToVariant(variantOther);
|
||||
}
|
||||
|
||||
|
||||
@@ -1027,22 +1027,6 @@ public class DeckRecognizer {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the magic color by the localised/translated name.
|
||||
* @param localisedName String of localised color name.
|
||||
* @return The string of the magic color.
|
||||
*/
|
||||
public static String getColorNameByLocalisedName(String localisedName) {
|
||||
Localizer localizer = Localizer.getInstance();
|
||||
|
||||
if(localisedName.equals(localizer.getMessage("lblWhite"))) return MagicColor.Constant.WHITE;
|
||||
if(localisedName.equals(localizer.getMessage("lblBlue"))) return MagicColor.Constant.BLUE;
|
||||
if(localisedName.equals(localizer.getMessage("lblBlack"))) return MagicColor.Constant.BLACK;
|
||||
if(localisedName.equals(localizer.getMessage("lblRed"))) return MagicColor.Constant.RED;
|
||||
if(localisedName.equals(localizer.getMessage("lblGreen"))) return MagicColor.Constant.GREEN;
|
||||
|
||||
return "";
|
||||
}
|
||||
public static boolean isDeckName(final String lineAsIs) {
|
||||
if (lineAsIs == null)
|
||||
return false;
|
||||
|
||||
@@ -78,7 +78,7 @@ public class GameAction {
|
||||
private boolean holdCheckingStaticAbilities = false;
|
||||
|
||||
private final static Comparator<StaticAbility> effectOrder = Comparator.comparing(StaticAbility::isCharacteristicDefining).reversed()
|
||||
.thenComparing(StaticAbility::getTimestamp);
|
||||
.thenComparing(s -> s.getHostCard().getLayerTimestamp());
|
||||
|
||||
public GameAction(Game game0) {
|
||||
game = game0;
|
||||
@@ -1103,16 +1103,11 @@ public class GameAction {
|
||||
if (stAb.checkMode(StaticAbilityMode.Continuous) && stAb.zonesCheck()) {
|
||||
staticAbilities.add(stAb);
|
||||
}
|
||||
}
|
||||
if (!co.getStaticCommandList().isEmpty()) {
|
||||
staticList.add(co);
|
||||
}
|
||||
for (StaticAbility stAb : co.getHiddenStaticAbilities()) {
|
||||
if (stAb.checkMode(StaticAbilityMode.Continuous) && stAb.zonesCheck()) {
|
||||
staticAbilities.add(stAb);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (!co.getStaticCommandList().isEmpty()) {
|
||||
staticList.add(co);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}, true);
|
||||
|
||||
@@ -1338,7 +1333,7 @@ public class GameAction {
|
||||
|
||||
// now the earliest one left is the correct choice
|
||||
List<StaticAbility> statics = Lists.newArrayList(dependencyGraph.vertexSet());
|
||||
statics.sort(Comparator.comparing(StaticAbility::getTimestamp));
|
||||
statics.sort(Comparator.comparing(s -> s.getHostCard().getLayerTimestamp()));
|
||||
|
||||
return statics.get(0);
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import forge.game.card.Card;
|
||||
import forge.game.card.CardZoneTable;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.game.spellability.SpellAbilityStackInstance;
|
||||
import forge.game.trigger.TriggerType;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.util.Lang;
|
||||
@@ -48,7 +47,7 @@ public class AirbendEffect extends SpellAbilityEffect {
|
||||
|
||||
final CardZoneTable triggerList = CardZoneTable.getSimultaneousInstance(sa);
|
||||
|
||||
for (Card c : getCardsfromTargets(sa)) {
|
||||
for (Card c : getTargetCards(sa)) {
|
||||
final Card gameCard = game.getCardState(c, null);
|
||||
// gameCard is LKI in that case, the card is not in game anymore
|
||||
// or the timestamp did change
|
||||
@@ -56,27 +55,21 @@ public class AirbendEffect extends SpellAbilityEffect {
|
||||
if (gameCard == null || !c.equalsWithGameTimestamp(gameCard) || gameCard.isPhasedOut()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!gameCard.canExiledBy(sa, true)) {
|
||||
continue;
|
||||
}
|
||||
handleExiledWith(gameCard, sa);
|
||||
|
||||
Map<AbilityKey, Object> moveParams = AbilityKey.newMap();
|
||||
AbilityKey.addCardZoneTableParams(moveParams, triggerList);
|
||||
|
||||
SpellAbilityStackInstance si = null;
|
||||
if (gameCard.isInZone(ZoneType.Stack)) {
|
||||
SpellAbility stackSA = game.getStack().getSpellMatchingHost(gameCard);
|
||||
si = game.getStack().getInstanceMatchingSpellAbilityID(stackSA);
|
||||
}
|
||||
|
||||
Card movedCard = game.getAction().exile(gameCard, sa, moveParams);
|
||||
|
||||
if (movedCard == null || !movedCard.isInZone(ZoneType.Exile)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (si != null) {
|
||||
// GameAction.changeZone should really take care of cleaning up SASI when a card from the stack is removed.
|
||||
game.getStack().remove(si);
|
||||
}
|
||||
|
||||
// Effect to cast for 2 from exile
|
||||
Card eff = createEffect(sa, movedCard.getOwner(), "Airbend" + movedCard, hostCard.getImageKey());
|
||||
eff.addRemembered(movedCard);
|
||||
@@ -91,7 +84,6 @@ public class AirbendEffect extends SpellAbilityEffect {
|
||||
|
||||
game.getAction().moveToCommand(eff, sa);
|
||||
}
|
||||
|
||||
triggerList.triggerChangesZoneAll(game, sa);
|
||||
handleExiledWith(triggerList.allCards(), sa);
|
||||
|
||||
|
||||
@@ -30,27 +30,28 @@ public class ChangeTextEffect extends SpellAbilityEffect {
|
||||
|
||||
final String changedColorWordOriginal, changedColorWordNew;
|
||||
if (sa.hasParam("ChangeColorWord")) {
|
||||
byte originalColor = 0;
|
||||
// all instances are Choose Choose
|
||||
MagicColor.Color originalColor = null;
|
||||
final String[] changedColorWordsArray = sa.getParam("ChangeColorWord").split(" ");
|
||||
if (changedColorWordsArray[0].equals("Choose")) {
|
||||
originalColor = sa.getActivatingPlayer().getController().chooseColor(
|
||||
Localizer.getInstance().getMessage("lblChooseColorReplace"), sa, ColorSet.WUBRG);
|
||||
changedColorWordOriginal = TextUtil.capitalize(MagicColor.toLongString(originalColor));
|
||||
changedColorWordOriginal = TextUtil.capitalize(originalColor.getName());
|
||||
} else {
|
||||
changedColorWordOriginal = changedColorWordsArray[0];
|
||||
originalColor = MagicColor.fromName(changedColorWordOriginal);
|
||||
originalColor = MagicColor.Color.fromByte(MagicColor.fromName(changedColorWordOriginal));
|
||||
}
|
||||
|
||||
if (changedColorWordsArray[1].equals("Choose")) {
|
||||
final ColorSet possibleNewColors;
|
||||
if (originalColor == 0) { // no original color (ie. any or absent)
|
||||
if (originalColor == null) { // no original color (ie. any or absent)
|
||||
possibleNewColors = ColorSet.WUBRG;
|
||||
} else { // may choose any except original color
|
||||
possibleNewColors = ColorSet.fromMask(originalColor).inverse();
|
||||
possibleNewColors = ColorSet.fromEnums(originalColor).inverse();
|
||||
}
|
||||
final byte newColor = sa.getActivatingPlayer().getController().chooseColor(
|
||||
MagicColor.Color newColor = sa.getActivatingPlayer().getController().chooseColor(
|
||||
Localizer.getInstance().getMessage("lblChooseNewColor"), sa, possibleNewColors);
|
||||
changedColorWordNew = TextUtil.capitalize(MagicColor.toLongString(newColor));
|
||||
changedColorWordNew = TextUtil.capitalize(newColor.getName());
|
||||
} else {
|
||||
changedColorWordNew = changedColorWordsArray[1];
|
||||
}
|
||||
|
||||
@@ -114,15 +114,15 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
// just use the first possible color.
|
||||
choice = colorsProduced[differentChoice ? nMana : 0];
|
||||
} else {
|
||||
byte chosenColor = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa,
|
||||
MagicColor.Color chosenColor = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa,
|
||||
differentChoice && (colorsNeeded == null || colorsNeeded.length <= nMana) ? fullOptions : colorOptions);
|
||||
if (chosenColor == 0)
|
||||
if (chosenColor == null)
|
||||
throw new RuntimeException("ManaEffect::resolve() /*combo mana*/ - " + p + " color mana choice is empty for " + card.getName());
|
||||
|
||||
if (differentChoice) {
|
||||
fullOptions = ColorSet.fromMask(fullOptions.getColor() - chosenColor);
|
||||
fullOptions = ColorSet.fromMask(fullOptions.getColor() - chosenColor.getColorMask());
|
||||
}
|
||||
choice = MagicColor.toShortString(chosenColor);
|
||||
choice = chosenColor.getShortName();
|
||||
}
|
||||
|
||||
if (nMana > 0) {
|
||||
@@ -157,13 +157,13 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
mask |= MagicColor.fromName(colorsNeeded.charAt(nChar));
|
||||
}
|
||||
colorMenu = mask == 0 ? ColorSet.WUBRG : ColorSet.fromMask(mask);
|
||||
byte val = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, colorMenu);
|
||||
if (0 == val) {
|
||||
MagicColor.Color val = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, colorMenu);
|
||||
if (val == null) {
|
||||
throw new RuntimeException("ManaEffect::resolve() /*any mana*/ - " + p + " color mana choice is empty for " + card.getName());
|
||||
}
|
||||
|
||||
game.getAction().notifyOfValue(sa, card, MagicColor.toSymbol(val), p);
|
||||
abMana.setExpressChoice(MagicColor.toShortString(val));
|
||||
game.getAction().notifyOfValue(sa, card, val.getSymbol(), p);
|
||||
abMana.setExpressChoice(val.getShortName());
|
||||
}
|
||||
else if (abMana.isSpecialMana()) {
|
||||
String type = abMana.getOrigProduced().split("Special ")[1];
|
||||
@@ -178,22 +178,22 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
|
||||
for (ManaCostShard s : enchanted.getManaCost()) {
|
||||
ColorSet cs = ColorSet.fromMask(s.getColorMask());
|
||||
byte chosenColor;
|
||||
MagicColor.Color chosenColor;
|
||||
if (cs.isColorless())
|
||||
continue;
|
||||
if (s.isOr2Generic()) { // CR 106.8
|
||||
chosenColor = chooser.getController().chooseColorAllowColorless(Localizer.getInstance().getMessage("lblChooseSingleColorFromTarget", s.toString()), card, cs);
|
||||
if (chosenColor == MagicColor.COLORLESS) {
|
||||
if (chosenColor == MagicColor.Color.COLORLESS) {
|
||||
generic += 2;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (cs.isMonoColor())
|
||||
chosenColor = s.getColorMask();
|
||||
chosenColor = MagicColor.Color.fromByte(s.getColorMask());
|
||||
else /* (cs.isMulticolor()) */ {
|
||||
chosenColor = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblChooseSingleColorFromTarget", s.toString()), sa, cs);
|
||||
}
|
||||
sb.append(MagicColor.toShortString(chosenColor));
|
||||
sb.append(chosenColor.getShortName());
|
||||
sb.append(' ');
|
||||
}
|
||||
if (generic > 0) {
|
||||
@@ -239,8 +239,8 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
if (cs.isMonoColor())
|
||||
sb.append(MagicColor.toShortString(s.getColorMask()));
|
||||
else /* (cs.isMulticolor()) */ {
|
||||
byte chosenColor = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblChooseSingleColorFromTarget", s.toString()), sa, cs);
|
||||
sb.append(MagicColor.toShortString(chosenColor));
|
||||
MagicColor.Color chosenColor = chooser.getController().chooseColor(Localizer.getInstance().getMessage("lblChooseSingleColorFromTarget", s.toString()), sa, cs);
|
||||
sb.append(chosenColor.getShortName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
|
||||
}
|
||||
|
||||
if (mask == 0 && !expressChoiceColors.isEmpty() && colors.contains("colorless")) {
|
||||
baseMana = MagicColor.toShortString(player.getController().chooseColorAllowColorless(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa.getHostCard(), ColorSet.fromMask(mask)));
|
||||
baseMana = player.getController().chooseColorAllowColorless(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa.getHostCard(), ColorSet.fromMask(mask)).getShortName();
|
||||
} else {
|
||||
// Nothing set previously so ask player if needed
|
||||
if (mask == 0) {
|
||||
@@ -104,17 +104,17 @@ public class ManaReflectedEffect extends SpellAbilityEffect {
|
||||
} else if (colors.size() == 1) {
|
||||
baseMana = MagicColor.toShortString(colors.iterator().next());
|
||||
} else if (colors.contains("colorless")) {
|
||||
baseMana = MagicColor.toShortString(player.getController().chooseColorAllowColorless(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa.getHostCard(), ColorSet.fromNames(colors)));
|
||||
baseMana = player.getController().chooseColorAllowColorless(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa.getHostCard(), ColorSet.fromNames(colors)).getShortName();
|
||||
} else {
|
||||
baseMana = MagicColor.toShortString(player.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, ColorSet.fromNames(colors)));
|
||||
baseMana = player.getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, ColorSet.fromNames(colors)).getShortName();
|
||||
}
|
||||
} else {
|
||||
colorMenu = ColorSet.fromMask(mask);
|
||||
byte color = sa.getActivatingPlayer().getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, colorMenu);
|
||||
if (color == 0) {
|
||||
MagicColor.Color color = sa.getActivatingPlayer().getController().chooseColor(Localizer.getInstance().getMessage("lblSelectManaProduce"), sa, colorMenu);
|
||||
if (color == null) {
|
||||
System.err.println("Unexpected behavior in ManaReflectedEffect: " + sa.getActivatingPlayer() + " - color mana choice is empty for " + sa.getHostCard().getName());
|
||||
}
|
||||
baseMana = MagicColor.toShortString(color);
|
||||
baseMana = color.getShortName();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -34,15 +34,15 @@ public class ReplaceManaEffect extends SpellAbilityEffect {
|
||||
// replace type and amount
|
||||
replaced = sa.getParam("ReplaceMana");
|
||||
if ("Any".equals(replaced)) {
|
||||
byte rs = player.getController().chooseColor("Choose a color", sa, ColorSet.WUBRG);
|
||||
replaced = MagicColor.toShortString(rs);
|
||||
MagicColor.Color rs = player.getController().chooseColor("Choose a color", sa, ColorSet.WUBRG);
|
||||
replaced = rs.getShortName();
|
||||
}
|
||||
} else if (sa.hasParam("ReplaceType")) {
|
||||
// replace color and colorless
|
||||
String color = sa.getParam("ReplaceType");
|
||||
if ("Any".equals(color)) {
|
||||
byte rs = player.getController().chooseColor("Choose a color", sa, ColorSet.WUBRG);
|
||||
color = MagicColor.toShortString(rs);
|
||||
MagicColor.Color rs = player.getController().chooseColor("Choose a color", sa, ColorSet.WUBRG);
|
||||
color = rs.getShortName();
|
||||
} else {
|
||||
// convert in case Color Word used
|
||||
color = MagicColor.toShortString(color);
|
||||
|
||||
@@ -209,7 +209,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
private boolean renowned;
|
||||
private boolean solved;
|
||||
private boolean tributed;
|
||||
private StaticAbility suspectedStatic = null;
|
||||
private Card suspectedEffect = null;
|
||||
|
||||
private SpellAbility manifestedSA;
|
||||
private SpellAbility cloakedSA;
|
||||
@@ -6758,15 +6758,15 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
return true;
|
||||
}
|
||||
|
||||
public StaticAbility getSuspectedStatic() {
|
||||
return this.suspectedStatic;
|
||||
public Card getSuspectedEffect() {
|
||||
return this.suspectedEffect;
|
||||
}
|
||||
public void setSuspectedStatic(StaticAbility stAb) {
|
||||
this.suspectedStatic = stAb;
|
||||
public void setSuspectedEffect(Card effect) {
|
||||
this.suspectedEffect = effect;
|
||||
}
|
||||
|
||||
public final boolean isSuspected() {
|
||||
return suspectedStatic != null;
|
||||
return suspectedEffect != null;
|
||||
}
|
||||
|
||||
public final boolean setSuspected(final boolean suspected) {
|
||||
@@ -6779,15 +6779,23 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
return true;
|
||||
}
|
||||
|
||||
String s = "Mode$ Continuous | AffectedDefined$ Self | AddKeyword$ Menace | AddStaticAbility$ SuspectedCantBlockBy";
|
||||
suspectedStatic = StaticAbility.create(s, this, currentState, true);
|
||||
suspectedStatic.putParam("Timestamp", String.valueOf(getGame().getNextTimestamp()));
|
||||
suspectedEffect = SpellAbilityEffect.createEffect(null, this, this.getController(), "Suspected Effect", getImageKey(), getGame().getNextTimestamp());
|
||||
suspectedEffect.setRenderForUI(false);
|
||||
suspectedEffect.addRemembered(this);
|
||||
|
||||
String s = "Mode$ Continuous | AffectedDefined$ RememberedCard | EffectZone$ Command | AddKeyword$ Menace | AddStaticAbility$ SuspectedCantBlockBy";
|
||||
StaticAbility suspectedStatic = suspectedEffect.addStaticAbility(s);
|
||||
String effect = "Mode$ CantBlock | ValidCard$ Creature.Self | Description$ CARDNAME can't block.";
|
||||
suspectedStatic.setSVar("SuspectedCantBlockBy", effect);
|
||||
|
||||
GameCommand until = SpellAbilityEffect.exileEffectCommand(getGame(), suspectedEffect);
|
||||
addLeavesPlayCommand(until);
|
||||
getGame().getAction().moveToCommand(suspectedEffect, null);
|
||||
} else {
|
||||
suspectedStatic = null;
|
||||
if (isSuspected()) {
|
||||
getGame().getAction().exileEffect(suspectedEffect);
|
||||
suspectedEffect = null;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -7285,15 +7293,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
}
|
||||
}
|
||||
|
||||
public final FCollectionView<StaticAbility> getHiddenStaticAbilities() {
|
||||
FCollection<StaticAbility> result = new FCollection<>();
|
||||
// Suspected
|
||||
if (this.isInPlay() && this.isSuspected()) {
|
||||
result.add(suspectedStatic);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public final FCollectionView<Trigger> getTriggers() {
|
||||
return currentState.getTriggers();
|
||||
}
|
||||
|
||||
@@ -315,7 +315,7 @@ public class CardCopyService {
|
||||
newCopy.setSaddled(copyFrom.isSaddled());
|
||||
if (newCopy.isSaddled()) newCopy.setSaddledByThisTurn(copyFrom.getSaddledByThisTurn());
|
||||
if (copyFrom.isSuspected()) {
|
||||
newCopy.setSuspectedStatic(copyFrom.getSuspectedStatic().copy(newCopy, true));
|
||||
newCopy.setSuspectedEffect(getLKICopy(copyFrom.getSuspectedEffect(), cachedMap));
|
||||
}
|
||||
|
||||
newCopy.setDamageHistory(copyFrom.getDamageHistory());
|
||||
|
||||
@@ -3100,10 +3100,10 @@ public class Player extends GameEntity implements Comparable<Player> {
|
||||
Player p = cmd.getController();
|
||||
String prompt = Localizer.getInstance().getMessage("lblChooseAColorFor", cmd.getName());
|
||||
SpellAbility cmdColorsa = new SpellAbility.EmptySa(ApiType.ChooseColor, cmd, p);
|
||||
byte chosenColor = p.getController().chooseColor(prompt, cmdColorsa, ColorSet.WUBRG);
|
||||
cmd.setChosenColors(List.of(MagicColor.toLongString(chosenColor)));
|
||||
MagicColor.Color chosenColor = p.getController().chooseColor(prompt, cmdColorsa, ColorSet.WUBRG);
|
||||
cmd.setChosenColors(List.of(chosenColor.getName()));
|
||||
p.getGame().getAction().notifyOfValue(cmdColorsa, cmd,
|
||||
Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), MagicColor.toLongString(chosenColor)), p);
|
||||
Localizer.getInstance().getMessage("lblPlayerPickedChosen", p.getName(), chosenColor.getName()), p);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import com.google.common.collect.Multimap;
|
||||
import forge.LobbyPlayer;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.ICardFace;
|
||||
import forge.card.MagicColor;
|
||||
import forge.card.mana.ManaCost;
|
||||
import forge.card.mana.ManaCostShard;
|
||||
import forge.deck.Deck;
|
||||
@@ -265,8 +266,8 @@ public abstract class PlayerController {
|
||||
|
||||
public abstract boolean chooseFlipResult(SpellAbility sa, Player flipper, boolean[] results, boolean call);
|
||||
|
||||
public abstract byte chooseColor(String message, SpellAbility sa, ColorSet colors);
|
||||
public abstract byte chooseColorAllowColorless(String message, Card c, ColorSet colors);
|
||||
public abstract MagicColor.Color chooseColor(String message, SpellAbility sa, ColorSet colors);
|
||||
public abstract MagicColor.Color chooseColorAllowColorless(String message, Card c, ColorSet colors);
|
||||
public abstract List<String> chooseColors(String message, SpellAbility sa, int min, int max, List<String> options);
|
||||
|
||||
public abstract ICardFace chooseSingleCardFace(SpellAbility sa, String message, Predicate<ICardFace> cpp, String name);
|
||||
|
||||
@@ -297,9 +297,7 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
* conditions are fulfilled.
|
||||
*/
|
||||
private boolean shouldApplyContinuousAbility(final StaticAbilityLayer layer, final boolean previousRun) {
|
||||
return layers.contains(layer) && checkConditions(StaticAbilityMode.Continuous) && ( previousRun ||
|
||||
getHostCard().getStaticAbilities().contains(this) ||
|
||||
getHostCard().getHiddenStaticAbilities().contains(this));
|
||||
return layers.contains(layer) && checkConditions(StaticAbilityMode.Continuous) && (previousRun || getHostCard().getStaticAbilities().contains(this));
|
||||
}
|
||||
|
||||
public final Cost getAttackCost(final Card attacker, final GameEntity target, final List<Card> attackersWithOptionalCost) {
|
||||
@@ -585,13 +583,6 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
|
||||
.result();
|
||||
}
|
||||
|
||||
public long getTimestamp() {
|
||||
if (hasParam("Timestamp")) {
|
||||
return Long.valueOf(getParam("Timestamp"));
|
||||
}
|
||||
return getHostCard().getLayerTimestamp();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setHostCard(Card host) {
|
||||
super.setHostCard(host);
|
||||
|
||||
@@ -25,6 +25,7 @@ import forge.GameCommand;
|
||||
import forge.card.*;
|
||||
import forge.game.Game;
|
||||
import forge.game.StaticEffect;
|
||||
import forge.game.StaticEffects;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.ApiType;
|
||||
import forge.game.card.*;
|
||||
@@ -92,11 +93,12 @@ public final class StaticAbilityContinuous {
|
||||
final List<Player> affectedPlayers = StaticAbilityContinuous.getAffectedPlayers(stAb);
|
||||
final Game game = hostCard.getGame();
|
||||
|
||||
final StaticEffect se = game.getStaticEffects().getStaticEffect(stAb);
|
||||
final StaticEffects effects = game.getStaticEffects();
|
||||
final StaticEffect se = effects.getStaticEffect(stAb);
|
||||
se.setAffectedCards(affectedCards);
|
||||
se.setAffectedPlayers(affectedPlayers);
|
||||
se.setParams(params);
|
||||
se.setTimestamp(stAb.getTimestamp());
|
||||
se.setTimestamp(hostCard.getLayerTimestamp());
|
||||
|
||||
// nothing more to do
|
||||
if (stAb.hasParam("Affected") && affectedPlayers.isEmpty() && affectedCards.isEmpty()) {
|
||||
|
||||
@@ -470,13 +470,16 @@ public class PlayerControllerForTests extends PlayerController {
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte chooseColor(String message, SpellAbility sa, ColorSet colors) {
|
||||
return Iterables.getFirst(colors, MagicColor.Color.WHITE).getColorMask();
|
||||
public MagicColor.Color chooseColor(String message, SpellAbility sa, ColorSet colors) {
|
||||
if (colors.countColors() == 0) {
|
||||
return null;
|
||||
}
|
||||
return Iterables.getFirst(colors, MagicColor.Color.WHITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte chooseColorAllowColorless(String message, Card card, ColorSet colors) {
|
||||
return Iterables.getFirst(colors, MagicColor.Color.COLORLESS).getColorMask();
|
||||
public MagicColor.Color chooseColorAllowColorless(String message, Card card, ColorSet colors) {
|
||||
return Iterables.getFirst(colors, MagicColor.Color.COLORLESS);
|
||||
}
|
||||
|
||||
private CardCollection chooseItems(CardCollectionView items, int amount) {
|
||||
|
||||
@@ -1556,7 +1556,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Amulet of the Deceiver",
|
||||
"equipmentSlot": "Neck",
|
||||
"equipmentSlot": "Head",
|
||||
"iconName": "MoxJet",
|
||||
"effect": {
|
||||
"lifeModifier": -1,
|
||||
|
||||
@@ -1343,7 +1343,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Helm of Obedience",
|
||||
"equipmentSlot": "Neck",
|
||||
"equipmentSlot": "Head",
|
||||
"iconName": "MoxJet",
|
||||
"effect": {
|
||||
"lifeModifier": -1,
|
||||
|
||||
@@ -1556,7 +1556,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Amulet of the Deceiver",
|
||||
"equipmentSlot": "Neck",
|
||||
"equipmentSlot": "Head",
|
||||
"iconName": "MoxJet",
|
||||
"effect": {
|
||||
"lifeModifier": -1,
|
||||
|
||||
@@ -145,4 +145,3 @@ Final Fantasy, 3/6/FIN, FIN
|
||||
Alchemy: Innistrad, 3/6/ISD, YMID
|
||||
Edge of Eternities, 3/6/EOE, EOE
|
||||
Marvel's Spider-Man, 3/6/SPM, SPM
|
||||
Avatar: The Last Airbender, 3/6/TLA, TLA
|
||||
@@ -1,23 +0,0 @@
|
||||
Name:Aang, Swift Savior
|
||||
ManaCost:1 W U
|
||||
Types:Legendary Creature Human Avatar Ally
|
||||
PT:2/3
|
||||
K:Flash
|
||||
K:Flying
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigAirbend | TriggerDescription$ When NICKNAME enters, airbend up to one other target creature or spell. (Exile it. While it's exiled, its owner may cast it for {2} rather than its mana cost.)
|
||||
SVar:TrigAirbend:DB$ Airbend | ValidTgts$ Creature.Other,Card.inZoneStack | TgtPrompt$ Select up to another target creature or spell | TgtZone$ Battlefield,Stack | TargetMin$ 0
|
||||
A:AB$ SetState | Cost$ Waterbend<8> | Defined$ Self | Mode$ Transform | SpellDescription$ Transform NICKNAME.
|
||||
AlternateMode:DoubleFaced
|
||||
Oracle:Flash\nFlying\nWhen Aang enters, airbend up to one other target creature or spell. (Exile it. While it's exiled, its owner may cast it for {2} rather than its mana cost.)\nWaterbend {8}: Transform Aang.
|
||||
|
||||
ALTERNATE
|
||||
|
||||
Name:Aang and La, Ocean's Fury
|
||||
ManaCost:no cost
|
||||
Types:Legendary Creature Avatar Spirit Ally
|
||||
PT:5/5
|
||||
K:Reach
|
||||
K:Trample
|
||||
T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPutCounterAll | TriggerDescription$ Whenever NICKNAME attack, put a +1/+1 counter on each tapped creature you control.
|
||||
SVar:TrigPutCounterAll:DB$ PutCounterAll | ValidCards$ Creature.YouCtrl+tapped | CounterType$ P1P1 | CounterNum$ 1
|
||||
Oracle:Reach, trample\nWhenever Aang and La attack, put a +1/+1 counter on each tapped creature you control.
|
||||
@@ -1,10 +0,0 @@
|
||||
Name:Benevolent River Spirit
|
||||
ManaCost:U U
|
||||
Types:Creature Spirit
|
||||
PT:4/5
|
||||
S:Mode$ RaiseCost | ValidCard$ Card.Self | Activator$ You | Type$ Spell | Cost$ Waterbend<5> | EffectZone$ All | Description$ As an additional cost to cast this spell, waterbend {5}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)
|
||||
K:Flying
|
||||
K:Ward:2
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigScry | TriggerDescription$ When this creature enters, scry 2.
|
||||
SVar:TrigScry:DB$ Scry | ScryNum$ 2
|
||||
Oracle:As an additional cost to cast this spell, waterbend {5}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)\nFlying, ward {2} (Whenever this creature becomes the target of a spell or ability an opponent controls, counter it unless that player pays {2}.)\nWhen this creature enters, scry 2.
|
||||
@@ -1,8 +0,0 @@
|
||||
Name:Crashing Wave
|
||||
ManaCost:U U
|
||||
Types:Sorcery
|
||||
S:Mode$ RaiseCost | ValidCard$ Card.Self | Activator$ You | Type$ Spell | Cost$ Waterbend<X> | EffectZone$ All | Description$ As an additional cost to cast this spell, waterbend {X}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)
|
||||
A:SP$ Tap | TargetMin$ 0 | TargetMax$ X | TgtPrompt$ Select up to X target creatures to tap | ValidTgts$ Creature | SubAbility$ DBPutCounter
|
||||
SVar:DBPutCounter:DB$ PutCounter | Choices$ Creature.tapped+OppCtrl | ChoiceTitle$ Choose any number of tapped creatures your opponents control to distribute counters to | CounterType$ STUN | CounterNum$ 3 | ChoiceAmount$ 3 | DividedAsYouChoose$ 3
|
||||
SVar:X:Count$xPaid
|
||||
Oracle:As an additional cost to cast this spell, waterbend {X}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)\nTap up to X target creatures, then distribute three stun counters among tapped creatures your opponents control. (If a permanent with a stun counter would become untapped, remove one from it instead.)
|
||||
@@ -1,10 +0,0 @@
|
||||
Name:Foggy Swamp Visions
|
||||
ManaCost:1 B B
|
||||
Types:Sorcery
|
||||
S:Mode$ RaiseCost | ValidCard$ Card.Self | Activator$ You | Type$ Spell | Cost$ Waterbend<X> | EffectZone$ All | Description$ As an additional cost to cast this spell, waterbend {X}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)
|
||||
A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Exile | ValidTgts$ Creature | TgtPrompt$ Choose X target creature cards from graveyards | TargetMin$ X | TargetMax$ X | SubAbility$ DBClone | RememberChanged$ True | SpellDescription$ Exile X target creature cards from graveyards. For each creature card exiled this way, create a token that's a copy of it. At the beginning of your next end step, sacrifice those tokens.
|
||||
SVar:DBClone:DB$ CopyPermanent | Defined$ Remembered | NumCopies$ 1 | AtEOT$ YourSacrifice | SubAbility$ DBCleanup
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
SVar:X:Count$xPaid
|
||||
DeckHas:Ability$Token|Graveyard
|
||||
Oracle:As an additional cost to cast this spell, waterbend {X}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)\nExile X target creature cards from graveyards. For each creature card exiled this way, create a token that's a copy of it. At the beginning of your next end step, sacrifice those tokens.
|
||||
@@ -1,11 +0,0 @@
|
||||
Name:Hama, the Bloodbender
|
||||
ManaCost:2 UB UB UB
|
||||
Types:Legendary Creature Human Warlock
|
||||
PT:3/3
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigMill | TriggerDescription$ When NICKNAME enters, target opponent mills three cards. Exile up to one noncreature, nonland card from that player's graveyard. For as long as you control NICKNAME, you may cast the exiled card during your turn by waterbending {X} rather than paying its mana cost, where X is its mana value. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)
|
||||
SVar:TrigMill:DB$ Mill | NumCards$ 3 | ValidTgts$ Opponent | TgtPrompt$ Select target opponent to mill | SubAbility$ DBChangeZone
|
||||
SVar:DBChangeZone:DB$ ChangeZone | Optional$ True | Origin$ Graveyard | Destination$ Exile | DefinedPlayer$ Targeted | Chooser$ You | ChangeType$ Card.nonCreature+nonLand | ChangeNum$ 1 | IsCurse$ True | RememberChanged$ True | SubAbility$ DBEffect
|
||||
SVar:DBEffect:DB$ Effect | StaticAbilities$ STPlay | RememberObjects$ Remembered | Duration$ AsLongAsControl | ExileOnMoved$ Exile | SubAbility$ DBCleanup
|
||||
SVar:STPlay:Mode$ Continuous | MayPlay$ True | Condition$ PlayerTurn | Affected$ Card.IsRemembered | AffectedZone$ Exile | MayPlayAltManaCost$ Waterbend<ConvertedManaCost> | Description$ You may cast that card during your turn by waterbending {X} rather than paying its mana cost, where X is its mana value.
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
Oracle:When Hama enters, target opponent mills three cards. Exile up to one noncreature, nonland card from that player's graveyard. For as long as you control Hama, you may cast the exiled card during your turn by waterbending {X} rather than paying its mana cost, where X is its mana value. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)
|
||||
@@ -1,13 +0,0 @@
|
||||
Name:Katara, Seeking Revenge
|
||||
ManaCost:3 UB
|
||||
Types:Legendary Creature Human Warrior Ally
|
||||
PT:3/3
|
||||
S:Mode$ OptionalCost | EffectZone$ All | ValidCard$ Card.Self | ValidSA$ Spell | Cost$ Waterbend<2> | Description$ As an additional cost to cast this spell, you may waterbend {2}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigDraw | TriggerDescription$ When NICKNAME enters, draw a card, then discard a card unless her additional cost was paid.
|
||||
SVar:TrigDraw:DB$ Draw | Defined$ You | NumCards$ 1 | SubAbility$ DBDiscard
|
||||
SVar:DBDiscard:DB$ Discard | Defined$ You | NumCards$ X | Mode$ TgtChoose
|
||||
S:Mode$ Continuous | Affected$ Card.Self | AddPower$ Y | AddToughness$ Y | Description$ NICKNAME gets +1/+1 for each Lesson card in your graveyard.
|
||||
SVar:X:Count$OptionalGenericCostPaid.0.1
|
||||
SVar:Y:Count$ValidGraveyard Lesson.YouOwn
|
||||
DeckHas:Ability$Discard
|
||||
Oracle:As an additional cost to cast this spell, you may waterbend {2}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)\nWhen Katara enters, draw a card, then discard a card unless her additional cost was paid.\nKatara gets +1/+1 for each Lesson card in your graveyard.
|
||||
@@ -3,8 +3,8 @@ ManaCost:W
|
||||
Types:Legendary Creature Lemur Bat Ally
|
||||
PT:1/1
|
||||
K:Flying
|
||||
S:Mode$ ReduceCost | ValidCard$ Creature.nonLemur+withFlying+YouCtrl | Type$ Spell | Activator$ You | Amount$ 1 | Condition$ PlayerTurn | CheckSVar$ X | SVarCompare$ EQ0 | Description$ The first non-Lemur creature spell with flying you cast during each of your turns costs {1} less to cast.
|
||||
S:Mode$ ReduceCost | ValidCard$ Creature.nonLemur+hasFlying+YouCtrl | Type$ Spell | Activator$ You | Amount$ 1 | Condition$ PlayerTurn | CheckSVar$ X | SVarCompare$ EQ0 | Description$ The first non-Lemur creature spell with flying you cast during each of your turns costs {1} less to cast.
|
||||
T:Mode$ ChangesZone | ValidCard$ Creature.Other+YouCtrl+withFlying | Origin$ Any | Destination$ Battlefield | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ Whenever another creature you control with flying enters, NICKNAME gets +1/+1 until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ +1 | NumDef$ +1
|
||||
SVar:X:Count$ThisTurnCast_Creature.nonLemur+withFlying+YouCtrl
|
||||
SVar:X:Count$ThisTurnCast_Creature.nonLemur+hasFlying+YouCtrl
|
||||
Oracle:Flying\nThe first non-Lemur creature spell with flying you cast during each of your turns costs {1} less to cast.\nWhenever another creature you control with flying enters, Momo gets +1/+1 until end of turn.
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
Name:Planetarium of Wan Shi Tong
|
||||
ManaCost:6
|
||||
Types:Legendary Artifact
|
||||
A:AB$ Scry | Cost$ 1 T | ScryNum$ 2 | SpellDescription$ Scry 2.
|
||||
T:Mode$ Scry | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPeek | PresentDefined$ Remembered | IsPresent$ Card | PresentCompare$ EQ0 | TriggerDescription$ Whenever you scry or surveil, look at the top card of your library. You may cast that card without paying its mana cost. Do this only once each turn. (Look at the card after you scry or surveil.)
|
||||
T:Mode$ Surveil | ValidPlayer$ You | TriggerZones$ Battlefield | Execute$ TrigPeek | Secondary$ True | PresentDefined$ Remembered | IsPresent$ Card | PresentCompare$ EQ0 | TriggerDescription$ Whenever you scry or surveil, look at the top card of your library. You may cast that card without paying its mana cost. Do this only once each turn. (Look at the card after you scry or surveil.)
|
||||
SVar:TrigPeek:DB$ PeekAndReveal | NoReveal$ True | SubAbility$ TrigPlay
|
||||
SVar:TrigPlay:DB$ Play | Defined$ TopOfLibrary | WithoutManaCost$ True | ValidSA$ Spell | Optional$ True | RememberPlayed$ True | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Any | ValidCard$ Card.Self | Execute$ DBCleanup | Static$ True
|
||||
T:Mode$ TurnBegin | ValidPlayer$ Player | Execute$ DBCleanup | Static$ True
|
||||
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||
Oracle:{1}, {T}: Scry 2.\nWhenever you scry or surveil, look at the top card of your library. You may cast that card without paying its mana cost. Do this only once each turn. (Look at the card after you scry or surveil.)
|
||||
@@ -1,12 +0,0 @@
|
||||
Name:Spirit Water Revival
|
||||
ManaCost:1 U U
|
||||
Types:Sorcery
|
||||
S:Mode$ OptionalCost | EffectZone$ All | ValidCard$ Card.Self | ValidSA$ Spell | Cost$ Waterbend<6> | Description$ As an additional cost to cast this spell, you may waterbend {6}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)
|
||||
A:SP$ ChangeZoneAll | ChangeType$ Card.YouOwn | Origin$ Graveyard | Destination$ Library | Shuffle$ True | ConditionCheckSVar$ X | SubAbility$ DBDraw | SpellDescription$ Draw two cards. If this spell's additional cost was paid, instead shuffle your graveyard into your library, draw seven cards, and you have no maximum hand size for the rest of the game. Exile CARDNAME.
|
||||
SVar:DBDraw:DB$ Draw | NumCards$ Y | SubAbility$ DBEffect
|
||||
SVar:DBEffect:DB$ Effect | StaticAbilities$ STHandSize | Duration$ Permanent | ConditionCheckSVar$ X | SubAbility$ DBExile
|
||||
SVar:STHandSize:Mode$ Continuous | Affected$ You | SetMaxHandSize$ Unlimited | Description$ You have no maximum hand size for the rest of the game.
|
||||
SVar:DBExile:DB$ ChangeZone | Origin$ Stack | Destination$ Exile
|
||||
SVar:X:Count$OptionalGenericCostPaid.1.0
|
||||
SVar:Y:Count$OptionalGenericCostPaid.7.2
|
||||
Oracle:As an additional cost to cast this spell, you may waterbend {6}. (While paying a waterbend cost, you can tap your artifacts and creatures to help. Each one pays for {1}.)\nDraw two cards. If this spell's additional cost was paid, instead shuffle your graveyard into your library, draw seven cards, and you have no maximum hand size for the rest of the game.\nExile Spirit Water Revival.
|
||||
@@ -1,8 +0,0 @@
|
||||
Name:Tolls of War
|
||||
ManaCost:W B
|
||||
Types:Enchantment
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigClue | TriggerDescription$ When this enchantment enters, create a Clue token. (It's an artifact with "{2}, Sacrifice this token: Draw a card.")
|
||||
SVar:TrigClue:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_clue_draw | TokenOwner$ You
|
||||
T:Mode$ Sacrificed | ValidCard$ Permanent.YouCtrl | Execute$ TrigAlly | TriggerZones$ Battlefield | ValidPlayer$ You | PlayerTurn$ True | ActivationLimit$ 1 | TriggerDescription$ Whenever you sacrifice a permanent during your turn, create a 1/1 white Ally creature token. This ability triggers only once each turn.
|
||||
SVar:TrigAlly:DB$ Token | TokenScript$ w_1_1_ally
|
||||
Oracle:When this enchantment enters, create a Clue token. (It's an artifact with "{2}, Sacrifice this token: Draw a card.")\nWhenever you sacrifice a permanent during your turn, create a 1/1 white Ally creature token. This ability triggers only once each turn.
|
||||
@@ -1,7 +0,0 @@
|
||||
Name:True Ancestry
|
||||
ManaCost:1 G
|
||||
Types:Sorcery Lesson
|
||||
A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ValidTgts$ Permanent.YouOwn | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Choose up to one target creature card in your graveyard | SubAbility$ DBToken | SpellDescription$ Return up to one target permanent card from your graveyard to your hand. Create a Clue token. (It's an artifact with "{2}, Sacrifice this token: Draw a card.")
|
||||
SVar:DBToken:DB$ Token | TokenAmount$ 1 | TokenScript$ c_a_clue_draw | TokenOwner$ You
|
||||
DeckHints:Ability$Graveyard|Token
|
||||
Oracle:Return up to one target permanent card from your graveyard to your hand.\nCreate a Clue token. (It's an artifact with "{2}, Sacrifice this token: Draw a card.")
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user