mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 11:48:02 +00:00
Some support for Desert Cenote (#7505)
--------- Co-authored-by: tool4EvEr <tool4EvEr@>
This commit is contained in:
@@ -93,7 +93,6 @@ public enum AbilityKey {
|
||||
Mana("Mana"),
|
||||
MergedCards("MergedCards"),
|
||||
Mode("Mode"),
|
||||
Modifier("Modifier"),
|
||||
MonstrosityAmount("MonstrosityAmount"),
|
||||
NaturalResult("NaturalResult"),
|
||||
NewCard("NewCard"),
|
||||
|
||||
@@ -2220,7 +2220,7 @@ public class AbilityUtils {
|
||||
// Count$IfCastInOwnMainPhase.<numMain>.<numNotMain> // 7/10
|
||||
if (sq[0].contains("IfCastInOwnMainPhase")) {
|
||||
final PhaseHandler cPhase = game.getPhaseHandler();
|
||||
final boolean isMyMain = cPhase.getPhase().isMain() && cPhase.isPlayerTurn(player) && c.getCastFrom() != null;
|
||||
final boolean isMyMain = cPhase.getPhase().isMain() && cPhase.isPlayerTurn(player) && c.wasCast();
|
||||
return doXMath(Integer.parseInt(sq[isMyMain ? 1 : 2]), expr, c, ctb);
|
||||
}
|
||||
|
||||
@@ -2480,7 +2480,6 @@ public class AbilityUtils {
|
||||
// But these aren't really things you count so they'll show up in properties most likely
|
||||
}
|
||||
|
||||
|
||||
//Count$TypesSharedWith [defined]
|
||||
if (sq[0].startsWith("TypesSharedWith")) {
|
||||
Set<CardType.CoreType> thisTypes = Sets.newHashSet(c.getType().getCoreTypes());
|
||||
|
||||
@@ -1016,8 +1016,9 @@ public abstract class SpellAbilityEffect {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static Player getNewChooser(final SpellAbility sa, final Player activator, final Player loser) {
|
||||
public static Player getNewChooser(final SpellAbility sa, final Player loser) {
|
||||
// CR 800.4g
|
||||
final Player activator = sa.getActivatingPlayer();
|
||||
final PlayerCollection options;
|
||||
if (loser.isOpponentOf(activator)) {
|
||||
options = activator.getOpponents();
|
||||
|
||||
@@ -103,7 +103,7 @@ public class ChooseCardEffect extends SpellAbilityEffect {
|
||||
CardCollectionView pChoices = choices;
|
||||
CardCollection chosen = new CardCollection();
|
||||
if (!p.isInGame()) {
|
||||
p = getNewChooser(sa, activator, p);
|
||||
p = getNewChooser(sa, p);
|
||||
}
|
||||
if (sa.hasParam("ControlledByPlayer")) {
|
||||
final String param = sa.getParam("ControlledByPlayer");
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
package forge.game.ability.effects;
|
||||
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.MagicColor;
|
||||
import forge.deck.DeckRecognizer;
|
||||
import forge.game.ability.AbilityUtils;
|
||||
import forge.game.ability.SpellAbilityEffect;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.card.CardUtil;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.spellability.SpellAbility;
|
||||
import forge.util.Aggregates;
|
||||
@@ -41,6 +44,13 @@ public class ChooseColorEffect extends SpellAbilityEffect {
|
||||
String[] restrictedChoices = sa.getParam("Choices").split(",");
|
||||
colorChoices = Arrays.asList(restrictedChoices);
|
||||
}
|
||||
if (sa.hasParam("ColorsFrom")) {
|
||||
ColorSet cs = CardUtil.getColorsFromCards(AbilityUtils.getDefinedCards(card, sa.getParam("ColorsFrom"), sa));
|
||||
if (cs.isColorless()) {
|
||||
return;
|
||||
}
|
||||
colorChoices = cs.stream().map(Object::toString).collect(Collectors.toCollection(ArrayList::new));
|
||||
}
|
||||
if (sa.hasParam("Exclude")) {
|
||||
for (String s : sa.getParam("Exclude").split(",")) {
|
||||
colorChoices.remove(s);
|
||||
@@ -49,24 +59,22 @@ public class ChooseColorEffect extends SpellAbilityEffect {
|
||||
|
||||
for (Player p : getTargetPlayers(sa)) {
|
||||
if (!p.isInGame()) {
|
||||
p = getNewChooser(sa, sa.getActivatingPlayer(), p);
|
||||
p = getNewChooser(sa, p);
|
||||
}
|
||||
List<String> chosenColors = new ArrayList<>();
|
||||
int cntMin = sa.hasParam("TwoColors") ? 2 : 1;
|
||||
int cntMin = sa.hasParam("UpTo") ? 0 : sa.hasParam("TwoColors") ? 2 : 1;
|
||||
int cntMax = sa.hasParam("TwoColors") ? 2 : sa.hasParam("OrColors") ? colorChoices.size() : 1;
|
||||
String prompt = null;
|
||||
if (cntMax == 1) {
|
||||
prompt = Localizer.getInstance().getMessage("lblChooseAColor");
|
||||
} else {
|
||||
if (cntMax > cntMin) {
|
||||
if (cntMax >= MagicColor.NUMBER_OR_COLORS) {
|
||||
prompt = Localizer.getInstance().getMessage("lblAtLastChooseNumColors", Lang.getNumeral(cntMin));
|
||||
} else {
|
||||
prompt = Localizer.getInstance().getMessage("lblChooseSpecifiedRangeColors", Lang.getNumeral(cntMin), Lang.getNumeral(cntMax));
|
||||
}
|
||||
} else if (cntMax > cntMin) {
|
||||
if (cntMax >= MagicColor.NUMBER_OR_COLORS) {
|
||||
prompt = Localizer.getInstance().getMessage("lblAtLastChooseNumColors", Lang.getNumeral(cntMin));
|
||||
} else {
|
||||
prompt = Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(cntMax));
|
||||
prompt = Localizer.getInstance().getMessage("lblChooseSpecifiedRangeColors", Lang.getNumeral(cntMin), Lang.getNumeral(cntMax));
|
||||
}
|
||||
} else {
|
||||
prompt = Localizer.getInstance().getMessage("lblChooseNColors", Lang.getNumeral(cntMax));
|
||||
}
|
||||
Player noNotify = p;
|
||||
if (sa.hasParam("Random")) {
|
||||
|
||||
@@ -62,7 +62,7 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
|
||||
for (Player p : getDefinedPlayersOrTargeted(sa)) {
|
||||
if (!p.isInGame()) {
|
||||
p = getNewChooser(sa, sa.getActivatingPlayer(), p);
|
||||
p = getNewChooser(sa, p);
|
||||
}
|
||||
|
||||
// determine if any of the choices are not valid
|
||||
@@ -116,7 +116,6 @@ public class ChooseGenericEffect extends SpellAbilityEffect {
|
||||
} else if (secretly) {
|
||||
if (record.length() > 0) record.append("\r\n");
|
||||
record.append(Localizer.getInstance().getMessage("lblPlayerChooseValue", p, chosenValue));
|
||||
|
||||
}
|
||||
if (sa.hasParam("SetChosenMode")) {
|
||||
sa.getHostCard().setChosenMode(chosenValue);
|
||||
|
||||
@@ -22,7 +22,7 @@ public class EndTurnEffect extends SpellAbilityEffect {
|
||||
final List<Player> enders = getDefinedPlayersOrTargeted(sa, "Defined");
|
||||
Player ender = enders.isEmpty() ? sa.getActivatingPlayer() : enders.get(0);
|
||||
if (!ender.isInGame()) {
|
||||
ender = getNewChooser(sa, sa.getActivatingPlayer(), ender);
|
||||
ender = getNewChooser(sa, ender);
|
||||
}
|
||||
|
||||
if (sa.hasParam("Optional") && !ender.getController().confirmAction(sa, null, Localizer.getInstance().getMessage("lblDoYouWantEndTurn"), null)) {
|
||||
|
||||
@@ -60,18 +60,21 @@ public class ManaEffect extends SpellAbilityEffect {
|
||||
|
||||
if (abMana.isComboMana()) {
|
||||
int amount = sa.hasParam("Amount") ? AbilityUtils.calculateAmount(card, sa.getParam("Amount"), sa) : 1;
|
||||
if(amount <= 0)
|
||||
if (amount <= 0)
|
||||
continue;
|
||||
|
||||
String express = abMana.getExpressChoice();
|
||||
String[] colorsProduced = abMana.getComboColors(sa).split(" ");
|
||||
|
||||
final StringBuilder choiceString = new StringBuilder();
|
||||
final StringBuilder choiceSymbols = new StringBuilder();
|
||||
String combo = abMana.getComboColors(sa);
|
||||
if (combo.isBlank()) {
|
||||
return;
|
||||
}
|
||||
String[] colorsProduced = combo.split(" ");
|
||||
ColorSet colorOptions = ColorSet.fromNames(colorsProduced);
|
||||
String express = abMana.getExpressChoice();
|
||||
String[] colorsNeeded = express.isEmpty() ? null : express.split(" ");
|
||||
boolean differentChoice = abMana.getOrigProduced().contains("Different");
|
||||
ColorSet fullOptions = colorOptions;
|
||||
final StringBuilder choiceString = new StringBuilder();
|
||||
final StringBuilder choiceSymbols = new StringBuilder();
|
||||
// Use specifyManaCombo if possible
|
||||
if (colorsNeeded == null && amount > 1 && !sa.hasParam("TwoEach")) {
|
||||
Map<Byte, Integer> choices = chooser.getController().specifyManaCombo(sa, colorOptions, amount, differentChoice);
|
||||
|
||||
@@ -319,7 +319,6 @@ public class RollDiceEffect extends SpellAbilityEffect {
|
||||
for (DieRollResult roll : resultsList) {
|
||||
final Map<AbilityKey, Object> runParams = AbilityKey.mapFromPlayer(player);
|
||||
runParams.put(AbilityKey.Sides, sides);
|
||||
runParams.put(AbilityKey.Modifier, modifier);
|
||||
runParams.put(AbilityKey.Result, roll.getModifiedValue());
|
||||
runParams.put(AbilityKey.NaturalResult, roll.getNaturalValue());
|
||||
runParams.put(AbilityKey.RolledToVisitAttractions, toVisitAttractions);
|
||||
|
||||
@@ -2625,8 +2625,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
|| keyword.startsWith("Graft") || keyword.startsWith("Fading") || keyword.startsWith("Vanishing:")
|
||||
|| keyword.startsWith("Afterlife") || keyword.startsWith("Hideaway") || keyword.startsWith("Toxic")
|
||||
|| keyword.startsWith("Afflict") || keyword.startsWith ("Poisonous") || keyword.startsWith("Rampage")
|
||||
|| keyword.startsWith("Renown") || keyword.startsWith("Annihilator") || keyword.startsWith("Devour")
|
||||
|| keyword.startsWith("Mobilize")) {
|
||||
|| keyword.startsWith("Renown") || keyword.startsWith("Annihilator") || keyword.startsWith("Devour")) {
|
||||
final String[] k = keyword.split(":");
|
||||
sbLong.append(k[0]).append(" ").append(k[1]).append(" (").append(inst.getReminderText()).append(")");
|
||||
} else if (keyword.startsWith("Crew")) {
|
||||
@@ -2667,14 +2666,13 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
final String[] k = keyword.split(":");
|
||||
String desc = k.length > 2 ? k[2] : CardType.getPluralType(k[1]);
|
||||
sbLong.append(k[0]).append(" ").append(desc).append(" (").append(inst.getReminderText()).append(")");
|
||||
} else if (keyword.equals("Convoke") || keyword.equals("Dethrone")|| keyword.equals("Fear")
|
||||
|| keyword.equals("Melee") || keyword.equals("Improvise")|| keyword.equals("Shroud")
|
||||
|| keyword.equals("Banding") || keyword.equals("Intimidate")|| keyword.equals("Evolve")
|
||||
|| keyword.equals("Exalted") || keyword.equals("Extort")|| keyword.equals("Flanking")
|
||||
|| keyword.equals("Horsemanship") || keyword.equals("Infect")|| keyword.equals("Persist")
|
||||
|| keyword.equals("Phasing") || keyword.equals("Shadow")|| keyword.equals("Skulk")
|
||||
|| keyword.equals("Undying") || keyword.equals("Wither")
|
||||
|| keyword.equals("Bargain")
|
||||
} else if (keyword.equals("Convoke") || keyword.equals("Dethrone") || keyword.equals("Fear")
|
||||
|| keyword.equals("Melee") || keyword.equals("Improvise") || keyword.equals("Shroud")
|
||||
|| keyword.equals("Banding") || keyword.equals("Intimidate") || keyword.equals("Evolve")
|
||||
|| keyword.equals("Exalted") || keyword.equals("Extort") || keyword.equals("Flanking")
|
||||
|| keyword.equals("Horsemanship") || keyword.equals("Infect") || keyword.equals("Persist")
|
||||
|| keyword.equals("Phasing") || keyword.equals("Shadow") || keyword.equals("Skulk")
|
||||
|| keyword.equals("Undying") || keyword.equals("Wither") || keyword.equals("Bargain")
|
||||
|| keyword.equals("Mentor") || keyword.equals("Training")) {
|
||||
if (sb.length() != 0) {
|
||||
sb.append("\r\n");
|
||||
@@ -2738,7 +2736,7 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
|| keyword.startsWith("Class") || keyword.startsWith("Blitz")
|
||||
|| keyword.startsWith("Specialize") || keyword.equals("Ravenous")
|
||||
|| keyword.equals("For Mirrodin") || keyword.startsWith("Craft")
|
||||
|| keyword.startsWith("Landwalk") || keyword.startsWith("Visit")) {
|
||||
|| keyword.startsWith("Landwalk") || keyword.startsWith("Visit") || keyword.startsWith("Mobilize")) {
|
||||
// keyword parsing takes care of adding a proper description
|
||||
} else if (keyword.equals("Read ahead")) {
|
||||
sb.append(Localizer.getInstance().getMessage("lblReadAhead")).append(" (").append(Localizer.getInstance().getMessage("lblReadAheadDesc"));
|
||||
@@ -4817,29 +4815,6 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
perpetual.add(p);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public final void executePerpetual(Map<String, Object> p) {
|
||||
final String category = (String) p.get("Category");
|
||||
if (category.equals("NewPT")) {
|
||||
addNewPT((Integer) p.get("Power"), (Integer) p.get("Toughness"), (long)
|
||||
p.get("Timestamp"), (long) 0);
|
||||
} else if (category.equals("PTBoost")) {
|
||||
addPTBoost((Integer) p.get("Power"), (Integer) p.get("Toughness"), (long)
|
||||
p.get("Timestamp"), (long) 0);
|
||||
} else if (category.equals("Keywords")) {
|
||||
boolean removeAll = p.containsKey("RemoveAll") && (boolean) p.get("RemoveAll") == true;
|
||||
addChangedCardKeywords((List<String>) p.get("AddKeywords"), (List<String>) p.get("RemoveKeywords"),
|
||||
removeAll, (long) p.get("Timestamp"), null);
|
||||
} else if (category.equals("Types")) {
|
||||
addChangedCardTypes((CardType) p.get("AddTypes"), (CardType) p.get("RemoveTypes"),
|
||||
false, (Set<RemoveType>) p.get("RemoveXTypes"),
|
||||
(long) p.get("Timestamp"), (long) 0, true, false);
|
||||
} else if (category.equals("Colors")) {
|
||||
addColor((ColorSet) p.get("Colors"), !(boolean) p.get("Overwrite"), (long) p.get("Timestamp"),
|
||||
(long) 0, false);
|
||||
}
|
||||
}
|
||||
|
||||
public final void removePerpetual(final long timestamp) {
|
||||
Map<String, Object> toRemove = Maps.newHashMap();
|
||||
for (Map<String, Object> p : perpetual) {
|
||||
@@ -4852,14 +4827,14 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
}
|
||||
|
||||
public final void setPerpetual(final Card oldCard) {
|
||||
final List<Map<String, Object>> perp = oldCard.getPerpetual();
|
||||
perpetual = perp;
|
||||
for (Map<String, Object> p : perp) {
|
||||
if (p.get("Category").equals("Abilities")) {
|
||||
perpetual = oldCard.getPerpetual();
|
||||
for (Map<String, Object> p : perpetual) {
|
||||
final String category = (String) p.get("Category");
|
||||
if (category.equals("Abilities")) {
|
||||
long timestamp = (long) p.get("Timestamp");
|
||||
CardTraitChanges ctc = oldCard.getChangedCardTraits().get(timestamp, (long) 0).copy(this, false);
|
||||
addChangedCardTraits(ctc, timestamp, (long) 0);
|
||||
} else if (p.get("Category").equals("Incorporate")) {
|
||||
} else if (category.equals("Incorporate")) {
|
||||
long ts = (long) p.get("Timestamp");
|
||||
final ManaCost cCMC = oldCard.changedCardManaCost.get(ts, (long) 0);
|
||||
addChangedManaCost(cCMC, ts, (long) 0);
|
||||
@@ -4868,7 +4843,24 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars, ITr
|
||||
if (getFirstSpellAbility() != null) {
|
||||
getFirstSpellAbility().getPayCosts().add(new Cost((String) p.get("Incorporate"), false));
|
||||
}
|
||||
} else executePerpetual(p);
|
||||
} else if (category.equals("NewPT")) {
|
||||
addNewPT((Integer) p.get("Power"), (Integer) p.get("Toughness"), (long)
|
||||
p.get("Timestamp"), (long) 0);
|
||||
} else if (category.equals("PTBoost")) {
|
||||
addPTBoost((Integer) p.get("Power"), (Integer) p.get("Toughness"), (long)
|
||||
p.get("Timestamp"), (long) 0);
|
||||
} else if (category.equals("Keywords")) {
|
||||
boolean removeAll = p.containsKey("RemoveAll") && (boolean) p.get("RemoveAll") == true;
|
||||
addChangedCardKeywords((List<String>) p.get("AddKeywords"), (List<String>) p.get("RemoveKeywords"),
|
||||
removeAll, (long) p.get("Timestamp"), null);
|
||||
} else if (category.equals("Types")) {
|
||||
addChangedCardTypes((CardType) p.get("AddTypes"), (CardType) p.get("RemoveTypes"),
|
||||
false, (Set<RemoveType>) p.get("RemoveXTypes"),
|
||||
(long) p.get("Timestamp"), (long) 0, true, false);
|
||||
} else if (category.equals("Colors")) {
|
||||
addColor((ColorSet) p.get("Colors"), !(boolean) p.get("Overwrite"), (long) p.get("Timestamp"),
|
||||
(long) 0, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1529,7 +1529,7 @@ public class CardFactoryUtil {
|
||||
final String[] k = keyword.split(":");
|
||||
final String n = k[1];
|
||||
|
||||
final String trigStr = "Mode$ Attacks | ValidCard$ Card.Self | Secondary$ True"
|
||||
final String trigStr = "Mode$ Attacks | ValidCard$ Card.Self"
|
||||
+ " | TriggerDescription$ Mobilize " + n + " (" + inst.getReminderText() + ")";
|
||||
|
||||
final String effect = "DB$ Token | TokenAmount$ " + n + " | TokenScript$ r_1_1_warrior"
|
||||
|
||||
@@ -504,18 +504,6 @@ public class CardProperty {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (property.startsWith("NotEnchantedBy")) {
|
||||
if (property.substring(14).equals("Targeted")) {
|
||||
for (final Card c : AbilityUtils.getDefinedCards(source, "Targeted", spellAbility)) {
|
||||
if (card.isEnchantedBy(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (card.isEnchantedBy(source)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (property.startsWith("Enchanted")) {
|
||||
if (!source.equals(card.getEntityAttachedTo())) {
|
||||
return false;
|
||||
@@ -540,15 +528,6 @@ public class CardProperty {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (property.substring(16).equals("AllRemembered")) {
|
||||
for (final Object rem : source.getRemembered()) {
|
||||
if (rem instanceof Card) {
|
||||
final Card c = (Card) rem;
|
||||
if (!card.canBeAttached(c, null)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!card.canBeAttached(source, null)) {
|
||||
return false;
|
||||
@@ -556,12 +535,7 @@ public class CardProperty {
|
||||
}
|
||||
} else if (property.startsWith("EquippedBy") || property.startsWith("AttachedBy")) {
|
||||
String prop = property.substring(10);
|
||||
if (prop.equals("Enchanted")) {
|
||||
if (source.getEnchantingCard() == null ||
|
||||
!card.hasCardAttachment(source.getEnchantingCard())) {
|
||||
return false;
|
||||
}
|
||||
} else if (!StringUtils.isBlank(prop)) {
|
||||
if (!StringUtils.isBlank(prop)) {
|
||||
boolean found = false;
|
||||
for (final Card c : AbilityUtils.getDefinedCards(source, prop, spellAbility)) {
|
||||
if (card.hasCardAttachment(c)) {
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
*/
|
||||
package forge.game.spellability;
|
||||
|
||||
import com.google.common.base.Function;
|
||||
import com.google.common.collect.Iterators;
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.card.ColorSet;
|
||||
import forge.card.GamePieceType;
|
||||
@@ -48,6 +50,7 @@ import forge.game.zone.ZoneType;
|
||||
import forge.util.TextUtil;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -513,7 +516,7 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
}
|
||||
String produced = this.getOrigProduced();
|
||||
if (produced.contains("Chosen")) {
|
||||
produced = produced.replace("Chosen", this.getChosenColor(sa));
|
||||
produced = produced.replace("Chosen", getChosenColor(sa, sa.getHostCard().getChosenColors()));
|
||||
}
|
||||
return produced;
|
||||
}
|
||||
@@ -649,11 +652,18 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
}
|
||||
// replace Chosen for Combo colors
|
||||
if (origProduced.contains("Chosen")) {
|
||||
origProduced = origProduced.replace("Chosen", getChosenColor(sa));
|
||||
origProduced = origProduced.replace("Chosen", getChosenColor(sa, sa.getHostCard().getChosenColors()));
|
||||
}
|
||||
// replace Chosen for Spire colors
|
||||
if (origProduced.contains("ColorID")) {
|
||||
origProduced = origProduced.replace("ColorID", getChosenColorID(sa));
|
||||
Iterator<String> colors = Iterators.transform(sa.getHostCard().getMarkedColors().iterator(),
|
||||
new Function<>() {
|
||||
@Override
|
||||
public String apply(Byte b) {
|
||||
return MagicColor.toLongString(b);
|
||||
}
|
||||
});
|
||||
origProduced = origProduced.replace("ColorID", getChosenColor(sa, () -> colors));
|
||||
}
|
||||
if (origProduced.contains("NotedColors")) {
|
||||
// Should only be used for Paliano, the High City
|
||||
@@ -698,14 +708,14 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
return sb.length() == 0 ? "" : sb.substring(0, sb.length() - 1);
|
||||
}
|
||||
|
||||
public String getChosenColorID(SpellAbility sa) {
|
||||
public String getChosenColor(SpellAbility sa, Iterable<String> colors) {
|
||||
if (sa == null) {
|
||||
return "";
|
||||
}
|
||||
Card card = sa.getHostCard();
|
||||
if (card != null && card.hasMarkedColor()) {
|
||||
if (card != null) {
|
||||
StringBuilder values = new StringBuilder();
|
||||
for (byte c : card.getMarkedColors()) {
|
||||
for (String c : colors) {
|
||||
values.append(MagicColor.toShortString(c)).append(" ");
|
||||
}
|
||||
return values.toString();
|
||||
@@ -713,17 +723,6 @@ public class AbilityManaPart implements java.io.Serializable {
|
||||
return "";
|
||||
}
|
||||
|
||||
public String getChosenColor(SpellAbility sa) {
|
||||
if (sa == null) {
|
||||
return "";
|
||||
}
|
||||
Card card = sa.getHostCard();
|
||||
if (card != null && card.hasChosenColor()) {
|
||||
return MagicColor.toShortString(card.getChosenColor());
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public Card getSourceCard() {
|
||||
return sourceCard;
|
||||
}
|
||||
|
||||
@@ -175,7 +175,6 @@ public class StaticAbilityCantAttackBlock {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
public static boolean canBlockTapped(final Card card) {
|
||||
final Game game = card.getGame();
|
||||
for (final Card ca : game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)) {
|
||||
@@ -192,7 +191,6 @@ public class StaticAbilityCantAttackBlock {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private static boolean applyBlockTapped(final StaticAbility stAb, final Card card) {
|
||||
if (!stAb.matchesValidParam("ValidCard", card)) {
|
||||
return false;
|
||||
|
||||
@@ -450,7 +450,7 @@ public class WrappedAbility extends Ability {
|
||||
|
||||
if (decider != null) {
|
||||
if (!decider.isInGame()) {
|
||||
decider = SpellAbilityEffect.getNewChooser(sa, getActivatingPlayer(), decider);
|
||||
decider = SpellAbilityEffect.getNewChooser(sa, decider);
|
||||
}
|
||||
if (!decider.getController().confirmTrigger(this)) {
|
||||
return;
|
||||
|
||||
@@ -6,6 +6,6 @@ K:Indestructible
|
||||
S:Mode$ Continuous | Affected$ Card.Self | RemoveType$ Creature | CheckSVar$ X | SVarCompare$ LT7 | Description$ As long as your devotion to white and black is less than seven, NICKNAME isn't a creature.
|
||||
SVar:X:Count$DevotionDual.White.Black
|
||||
T:Mode$ ChangesZone | Origin$ Battlefield | Destination$ Graveyard | ValidCard$ Creature.YouOwn+Other | TriggerZones$ Battlefield | Execute$ TrigReturn | TriggerDescription$ Whenever another creature you own dies, return it to your hand unless target opponent pays 3 life.
|
||||
SVar:TrigReturn:DB$ ChangeZone | Defined$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Hand | UnlessCost$ PayLife<3> | UnlessPayer$ Targeted | ValidTgts$ Opponent | IsCurse$ True | Hidden$ True
|
||||
SVar:TrigReturn:DB$ ChangeZone | ThisDefinedAndTgts$ TriggeredNewCardLKICopy | Origin$ Graveyard | Destination$ Hand | UnlessCost$ PayLife<3> | UnlessPayer$ Targeted | ValidTgts$ Opponent | IsCurse$ True
|
||||
SVar:BuffedBy:Permanent.White,Permanent.Black
|
||||
Oracle:Indestructible\nAs long as your devotion to white and black is less than seven, Athreos isn't a creature.\nWhenever another creature you own dies, return it to your hand unless target opponent pays 3 life.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Enchantment Aura
|
||||
K:Enchant:Creature
|
||||
SVar:AttachAILogic:Pump
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ X | AddToughness$ X | Description$ Enchanted creature gets +1/+1 for each other creature you control.
|
||||
SVar:X:Count$Valid Creature.NotEnchantedBy+YouCtrl
|
||||
SVar:X:Count$Valid Creature.!EnchantedBy+YouCtrl
|
||||
SVar:BuffedBy:Creature
|
||||
Oracle:Enchant creature\nEnchanted creature gets +1/+1 for each other creature you control.
|
||||
|
||||
@@ -5,5 +5,5 @@ K:Convoke
|
||||
K:Enchant:Creature
|
||||
SVar:AttachAILogic:Pump
|
||||
S:Mode$ Continuous | Affected$ Card.AttachedBy | AddToughness$ X | Description$ Enchanted creature gets +0/+2 for each other creature you control.
|
||||
SVar:X:Count$Valid Creature.NotEnchantedBy+YouCtrl/Twice
|
||||
SVar:X:Count$Valid Creature.!EnchantedBy+YouCtrl/Twice
|
||||
Oracle:Convoke (Your creatures can help cast this spell. Each creature you tap while casting this spell pays for {1} or one mana of that creature's color.)\nEnchant creature\nEnchanted creature gets +0/+2 for each other creature you control.
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Enchantment Aura
|
||||
K:Enchant:Creature
|
||||
SVar:AttachAILogic:Pump
|
||||
T:Mode$ ChangesZone | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPump | TriggerZones$ Battlefield | TriggerDescription$ When CARDNAME enters, target creature you control other than enchanted creature gets +2/+2 and gains vigilance until end of turn.
|
||||
SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.YouCtrl+NotEnchantedBy | KW$ Vigilance | TgtPrompt$ Select target creature you control other than enchanted creature | NumAtt$ +2 | NumDef$ +2
|
||||
SVar:TrigPump:DB$ Pump | ValidTgts$ Creature.YouCtrl+!EnchantedBy | KW$ Vigilance | TgtPrompt$ Select target creature you control other than enchanted creature | NumAtt$ +2 | NumDef$ +2
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 2 | AddToughness$ 2 | AddKeyword$ Vigilance | Description$ Enchanted creature gets +2/+2 and has vigilance.
|
||||
Oracle:Enchant creature\nWhen Due Diligence enters, target creature you control other than enchanted creature gets +2/+2 and gains vigilance until end of turn.\nEnchanted creature gets +2/+2 and has vigilance.
|
||||
|
||||
@@ -5,5 +5,5 @@ K:Enchant:Creature
|
||||
SVar:AttachAILogic:Pump
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Vigilance | AddAbility$ ABBolster | AddPower$ X | AddToughness$ X | Description$ Enchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control. Enchanted creature has vigilance and "{W}, {T}: Bolster 1."
|
||||
SVar:ABBolster:AB$ PutCounter | Cost$ W T | Bolster$ True | CounterNum$ 1 | CounterType$ P1P1 | SpellDescription$ Bolster 1.
|
||||
SVar:X:Count$Valid Creature.YouCtrl+NotEnchantedBy$CardCounters.P1P1
|
||||
SVar:X:Count$Valid Creature.YouCtrl+!EnchantedBy$CardCounters.P1P1
|
||||
Oracle:Enchant creature\nEnchanted creature gets +1/+1 for each +1/+1 counter on other creatures you control.\nEnchanted creature has vigilance and "{W}, {T}: Bolster 1." (To bolster 1, choose a creature with the least toughness among creatures you control and put a +1/+1 counter on it.)
|
||||
|
||||
@@ -4,6 +4,6 @@ Types:Enchantment Aura
|
||||
K:Enchant:Creature
|
||||
SVar:AttachAILogic:Pump
|
||||
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddPower$ 1 | AddToughness$ 2 | Description$ Enchanted creature gets +1/+2.
|
||||
A:AB$ Attach | Cost$ 2 U | ValidTgts$ Creature.NotEnchantedBy | TgtPrompt$ Select target creature other than enchanted creature | AILogic$ Pump | SpellDescription$ Attach CARDNAME to target creature other than enchanted creature.
|
||||
A:AB$ Attach | Cost$ 2 U | ValidTgts$ Creature.!EnchantedBy | TgtPrompt$ Select target creature other than enchanted creature | AILogic$ Pump | SpellDescription$ Attach CARDNAME to target creature other than enchanted creature.
|
||||
AI:RemoveDeck:All
|
||||
Oracle:Enchant creature\nEnchanted creature gets +1/+2.\n{2}{U}: Attach Kjeldoran Pride to target creature other than enchanted creature.
|
||||
|
||||
@@ -2,7 +2,7 @@ Name:Lost Legacy
|
||||
ManaCost:1 B B
|
||||
Types:Sorcery
|
||||
A:SP$ NameCard | Defined$ You | ValidCards$ Card.nonLand+nonArtifact | ValidDescription$ nonartifact, nonland | SubAbility$ ExileHand | SpellDescription$ Choose a nonartifact, nonland card name. Search target player's graveyard, hand, and library for any number of cards with that name and exile them. That player shuffles, then draws a card for each card exiled from their hand this way. | StackDescription$ SpellDescription
|
||||
SVar:ExileHand:DB$ ChangeZone | ValidTgts$ Player | TgtPrompt$ Select target player | RememberTargets$ True | Origin$ Hand | Destination$ Exile | DefinedPlayer$ TargetedPlayer | ChangeType$ Card.NamedCard | ChangeNum$ NumInHand | Chooser$ You | SubAbility$ ExileLib | RememberChanged$ True | StackDescription$ None
|
||||
SVar:ExileHand:DB$ ChangeZone | ValidTgts$ Player | TgtPrompt$ Select target player | Origin$ Hand | Destination$ Exile | DefinedPlayer$ TargetedPlayer | ChangeType$ Card.NamedCard | ChangeNum$ NumInHand | Chooser$ You | SubAbility$ ExileLib | RememberChanged$ True | StackDescription$ None
|
||||
SVar:ExileLib:DB$ ChangeZone | Origin$ Library | Destination$ Exile | DefinedPlayer$ TargetedPlayer | ChangeType$ Card.NamedCard | ChangeNum$ NumInLib | Chooser$ You | Shuffle$ True | SubAbility$ ExileYard | StackDescription$ None
|
||||
SVar:ExileYard:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | DefinedPlayer$ TargetedPlayer | ChangeType$ Card.NamedCard | ChangeNum$ NumInYard | Chooser$ You | Hidden$ True | SubAbility$ Draw | StackDescription$ None
|
||||
SVar:Draw:DB$ Draw | Defined$ TargetedPlayer | NumCards$ X | SubAbility$ DBCleanup | StackDescription$ None
|
||||
|
||||
@@ -4,7 +4,7 @@ Types:Enchantment Aura
|
||||
K:Flash
|
||||
K:Enchant:Creature.YouCtrl:creature you control
|
||||
SVar:AttachAILogic:Pump
|
||||
T:Mode$ ChangesZone | ValidCard$ Creature.EnchantedBy,Creature.YouCtrl+modified+NotEnchantedBy | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigToken | TriggerDescription$ Whenever enchanted creature or another modified creature you control dies, create X 1/1 colorless Spirit creature tokens, where X is that creature's power. (Equipment, Auras you control, and counters are modifications.)
|
||||
T:Mode$ ChangesZone | ValidCard$ Creature.EnchantedBy,Creature.YouCtrl+modified+!EnchantedBy | Origin$ Battlefield | Destination$ Graveyard | Execute$ TrigToken | TriggerDescription$ Whenever enchanted creature or another modified creature you control dies, create X 1/1 colorless Spirit creature tokens, where X is that creature's power. (Equipment, Auras you control, and counters are modifications.)
|
||||
SVar:TrigToken:DB$ Token | TokenScript$ c_1_1_spirit | TokenAmount$ X
|
||||
SVar:X:TriggeredCard$CardPower
|
||||
DeckHas:Ability$Token & Type$Spirit
|
||||
|
||||
@@ -2,10 +2,9 @@ Name:Rumbling Ruin
|
||||
ManaCost:5 R
|
||||
Types:Creature Elemental
|
||||
PT:6/6
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigStore | TriggerDescription$ When CARDNAME enters, count the number of +1/+1 counters on creatures you control. Creatures your opponents control with power less than or equal to that number can't block this turn.
|
||||
SVar:TrigStore:DB$ StoreSVar | SVar$ X | Type$ CountSVar | Expression$ Y | SubAbility$ TrigEffect
|
||||
SVar:TrigEffect:DB$ Effect | StaticAbilities$ KWPump | SpellDescription$ Creatures your opponents control with power less than or equal to that number can't block this turn.
|
||||
SVar:KWPump:Mode$ Continuous | AffectedZone$ Battlefield | Affected$ Creature.OppCtrl+powerLEX | AddHiddenKeyword$ CARDNAME can't block. | Description$ Creatures your opponents control with power less than or equal to that number can't block this turn.
|
||||
SVar:X:Number$0
|
||||
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigEffect | TriggerDescription$ When CARDNAME enters, count the number of +1/+1 counters on creatures you control. Creatures your opponents control with power less than or equal to that number can't block this turn.
|
||||
SVar:TrigEffect:DB$ Effect | StaticAbilities$ KWPump | SetChosenNumber$ Y | SpellDescription$ Creatures your opponents control with power less than or equal to that number can't block this turn.
|
||||
SVar:KWPump:Mode$ CantBlock | ValidCard$ Creature.OppCtrl+powerLEX | Description$ Creatures your opponents control with power less than or equal to that number can't block this turn.
|
||||
SVar:X:Count$ChosenNumber
|
||||
SVar:Y:Count$Valid Creature.YouCtrl$CardCounters.P1P1
|
||||
Oracle:When Rumbling Ruin enters, count the number of +1/+1 counters on creatures you control. Creatures your opponents control with power less than or equal to that number can't block this turn.
|
||||
|
||||
@@ -3,6 +3,6 @@ ManaCost:U
|
||||
Types:Enchantment Aura
|
||||
K:Enchant:Creature
|
||||
SVar:AttachAILogic:Curiosity
|
||||
T:Mode$ DamageDone | ValidSource$ Creature.AttachedBy | ValidTarget$ Player | Execute$ TrigReturn | TriggerDescription$ Whenever enchanted creature deals damage to a player, return target creature that player controls to its owner's hand.
|
||||
T:Mode$ DamageDone | ValidSource$ Creature.AttachedBy | ValidTarget$ Player | Execute$ TrigReturn | TriggerZones$ Battlefield | TriggerDescription$ Whenever enchanted creature deals damage to a player, return target creature that player controls to its owner's hand.
|
||||
SVar:TrigReturn:DB$ ChangeZone | ValidTgts$ Creature | TargetsWithDefinedController$ TriggeredTarget | TgtPrompt$ Select target creature your opponent controls | IsCurse$ True | Origin$ Battlefield | Destination$ Hand
|
||||
Oracle:Enchant creature\nWhenever enchanted creature deals damage to a player, return target creature that player controls to its owner's hand.
|
||||
|
||||
@@ -5,6 +5,6 @@ K:Enchant:Creature
|
||||
SVar:AttachAITgts:Card.powerGE3
|
||||
SVar:AttachAILogic:Curse
|
||||
T:Mode$ Phase | Phase$ Upkeep | ValidPlayer$ Player.EnchantedController | TriggerZones$ Battlefield | Execute$ TrigDamage | TriggerDescription$ At the beginning of the upkeep of enchanted creature's controller, CARDNAME deals damage equal to that creature's power to that player unless they sacrifice another creature.
|
||||
SVar:TrigDamage:DB$ DealDamage | Defined$ TriggeredPlayer | NumDmg$ X | UnlessCost$ Sac<1/Creature.NotEnchantedBy> | UnlessPayer$ EnchantedController
|
||||
SVar:TrigDamage:DB$ DealDamage | Defined$ TriggeredPlayer | NumDmg$ X | UnlessCost$ Sac<1/Creature.!EnchantedBy> | UnlessPayer$ EnchantedController
|
||||
SVar:X:Enchanted$CardPower
|
||||
Oracle:Enchant creature\nAt the beginning of the upkeep of enchanted creature's controller, Unnatural Hunger deals damage equal to that creature's power to that player unless they sacrifice another creature.
|
||||
|
||||
@@ -3,7 +3,7 @@ ManaCost:R
|
||||
Types:Enchantment Aura
|
||||
K:Enchant:Creature.YouCtrl:creature you control
|
||||
SVar:AttachAILogic:Pump
|
||||
A:AB$ Pump | Cost$ tapXType<1/Creature.EnchantedBy/Enchanted Creature> | ValidTgts$ Creature.NotEnchantedBy | TgtPrompt$ Select target creature other than the creature tapped | NumAtt$ +2 | NumDef$ +1 | CostDesc$ Tap enchanted creature: | SpellDescription$ Target creature other than the creature tapped this way gets +2/+1 until end of turn. Activate only if enchanted creature is untapped.
|
||||
A:AB$ Pump | Cost$ tapXType<1/Creature.EnchantedBy/Enchanted Creature> | ValidTgts$ Creature.!EnchantedBy | TgtPrompt$ Select target creature other than the creature tapped | NumAtt$ +2 | NumDef$ +1 | CostDesc$ Tap enchanted creature: | SpellDescription$ Target creature other than the creature tapped this way gets +2/+1 until end of turn. Activate only if enchanted creature is untapped.
|
||||
AI:RemoveDeck:All
|
||||
SVar:NonStackingAttachEffect:True
|
||||
Oracle:Enchant creature you control\nTap enchanted creature: Target creature other than the creature tapped this way gets +2/+1 until end of turn. Activate only if enchanted creature is untapped.
|
||||
|
||||
@@ -449,8 +449,7 @@ public final class CardScriptParser {
|
||||
"AttachedBy", "Attached", "NameNotEnchantingEnchantedPlayer",
|
||||
"Enchanted", "CanEnchantRemembered",
|
||||
"CanEnchantSource", "CanBeEnchantedBy", "CanBeEnchantedByTargeted",
|
||||
"CanBeEnchantedByAllRemembered", "EquippedBy",
|
||||
"EquippedByTargeted", "EquippedByEnchanted", "FortifiedBy",
|
||||
"EquippedBy", "EquippedByTargeted", "EquippedByEnchanted", "FortifiedBy",
|
||||
"CanBeEquippedBy", "Equipped", "Fortified", "HauntedBy",
|
||||
"notTributed", "madness", "Paired", "PairedWith",
|
||||
"Above", "DirectlyAbove", "TopGraveyardCreature",
|
||||
@@ -488,7 +487,7 @@ public final class CardScriptParser {
|
||||
private static final Set<String> VALID_EXCLUSIVE_STARTSWITH = ImmutableSortedSet
|
||||
.of("named", "notnamed", "OwnedBy", "ControlledBy",
|
||||
"ControllerControls", "AttachedTo", "EnchantedBy",
|
||||
"NotEnchantedBy", "TopGraveyard", "SharesColorWith",
|
||||
"TopGraveyard", "SharesColorWith",
|
||||
"MostProminentColor", "notSharesColorWith",
|
||||
"sharesCreatureTypeWith", "sharesCardTypeWith", "sharesLandTypeWith",
|
||||
"sharesNameWith", "doesNotShareNameWith",
|
||||
|
||||
Reference in New Issue
Block a user