Merge pull request #263 from Northmoc/hiddenCZ

various getStackDescription improvements
This commit is contained in:
Anthony Calosa
2022-05-07 06:48:46 +08:00
committed by GitHub
11 changed files with 92 additions and 29 deletions

View File

@@ -206,8 +206,9 @@ public class AnimateEffect extends AnimateEffectBase {
protected String getStackDescription(SpellAbility sa) {
final Card host = sa.getHostCard();
final StringBuilder sb = new StringBuilder();
final List<Card> tgts = getCardsfromTargets(sa);
final boolean justOne = tgts.size() == 1;
final List<Card> tgts = getDefinedCardsOrTargeted(sa);
//possible to be building stack desc before Defined is populated... for now, 0 will default to singular
final boolean justOne = tgts.size() <= 1;
if (sa.hasParam("IfDesc")) {
if (sa.getParam("IfDesc").equals("True") && sa.hasParam("SpellDescription")) {
@@ -264,7 +265,7 @@ public class AnimateEffect extends AnimateEffectBase {
} else {
sb.append("toughness ").append(toughness).append(" ");
}
} else {
} else if (sb.length() > initial) {
sb.append(justOne ? "becomes " : "become ");
}
@@ -291,7 +292,8 @@ public class AnimateEffect extends AnimateEffectBase {
}
}
if (keywords.size() > 0) {
sb.append("and gains ").append(Lang.joinHomogenous(keywords).toLowerCase()).append(" ");
sb.append(sb.length() > initial ? "and " : "").append(" gains ");
sb.append(Lang.joinHomogenous(keywords).toLowerCase()).append(" ");
}
// sb.append(abilities)
// sb.append(triggers)
@@ -317,6 +319,20 @@ public class AnimateEffect extends AnimateEffectBase {
}
sb.append(".");
if (sa.hasParam("AtEOT")) {
sb.append(" ");
final String eot = sa.getParam("AtEOT");
final String pronoun = justOne ? "it" : "them";
if (eot.equals("Hand")) {
sb.append("Return ").append(pronoun).append(" to your hand");
} else if (eot.equals("SacrificeCtrl")) {
sb.append(justOne ? "Its controller sacrifices it" : "Their controllers sacrifice them");
} else { //Sacrifice,Exile
sb.append(eot).append(" ").append(pronoun);
}
sb.append(" at the beginning of the next end step.");
}
return sb.toString();
}

View File

@@ -293,15 +293,36 @@ public class ChangeZoneEffect extends SpellAbilityEffect {
// TODO Expand on this Description as more cards use it
// for the non-targeted SAs when you choose what is returned on resolution
sb.append("Return ").append(num).append(" ").append(type).append(" card(s) ");
sb.append(" to your ").append(destination);
sb.append(" to your ").append(destination).append(".");
} else if (origin.equals("Graveyard")) {
// for non-targeted SAs when you choose what is moved on resolution
// this will need expansion as more cards use it
sb.append(chooserNames).append(" puts ");
final String cardTag = type.contains("card") ? "" : " card";
sb.append(num != 0 ? Lang.nounWithNumeralExceptOne(num, type + cardTag) :
sa.getParamOrDefault("ChangeNumDesc", "") + " " + type + cardTag);
sb.append(" into their ").append(destination.toLowerCase()).append(".");
final boolean changeNumDesc = sa.hasParam("ChangeNumDesc");
final boolean mandatory = sa.hasParam("Mandatory");
String changed;
if (changeNumDesc) {
changed = sa.getParam("ChangeNumDesc") + " " + type + cardTag;
} else if (!mandatory) {
changed = Lang.nounWithNumeral(num, type + cardTag);
} else {
changed = Lang.nounWithNumeralExceptOne(num, type + cardTag);
}
final boolean battlefield = destination.equals("Battlefield");
sb.append(chooserNames).append(" returns ").append(mandatory || changeNumDesc ? "" : "up to ");
sb.append(changed);
// so far, it seems non-targeted only lets you return from your own graveyard
sb.append(" from their graveyard").append(choosers.size() > 1 ? "s" : "");
sb.append(battlefield ? " to the " : " into their ").append(destination.toLowerCase());
if (sa.hasParam("WithCountersType")) {
final CounterType cType = CounterType.getType(sa.getParam("WithCountersType"));
if (cType != null) {
sb.append(" with an additional ").append(cType.getName()).append(" counter on it");
} else {
sb.append(" [ChangeZoneEffect WithCountersType error]");
}
}
sb.append(".");
}
return sb.toString();

View File

@@ -11,6 +11,7 @@ import forge.game.card.Card;
import forge.game.card.CardCollectionView;
import forge.game.card.CardZoneTable;
import forge.game.player.Player;
import forge.game.player.PlayerCollection;
import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType;
import forge.util.Lang;
@@ -92,17 +93,40 @@ public class MillEffect extends SpellAbilityEffect {
protected String getStackDescription(SpellAbility sa) {
final StringBuilder sb = new StringBuilder();
final int numCards = sa.hasParam("NumCards") ? AbilityUtils.calculateAmount(sa.getHostCard(), sa.getParam("NumCards"), sa) : 1;
final boolean optional = sa.hasParam("Optional");
final boolean eachP = sa.hasParam("Defined") && sa.getParam("Defined").equals("Player");
String each = "Each player";
final PlayerCollection tgtPs = getTargetPlayers(sa);
sb.append(Lang.joinHomogenous(getTargetPlayers(sa))).append(" ");
if (sa.hasParam("IfDesc")) {
final String ifD = sa.getParam("IfDesc");
if (ifD.equals("True")) {
String ifDesc = sa.getDescription();
if (ifDesc.contains(",")) {
sb.append(ifDesc, 0, ifDesc.indexOf(",") + 1);
} else {
sb.append("[MillEffect IfDesc parsing error]");
}
} else {
sb.append(ifD);
}
sb.append(" ");
each = each.toLowerCase();
}
sb.append(eachP ? each : Lang.joinHomogenous(tgtPs));
sb.append(" ");
final ZoneType dest = ZoneType.smartValueOf(sa.getParam("Destination"));
sb.append(optional ? "may " : "");
if ((dest == null) || dest.equals(ZoneType.Graveyard)) {
sb.append("mills ");
sb.append("mill");
} else if (dest.equals(ZoneType.Exile)) {
sb.append("exiles ");
sb.append("exile");
} else if (dest.equals(ZoneType.Ante)) {
sb.append("antes ");
sb.append("ante");
}
sb.append((optional || tgtPs.size() > 1) && !eachP ? " " : "s ");
sb.append(Lang.nounWithNumeralExceptOne(numCards, "card")).append(".");

View File

@@ -1,8 +1,8 @@
Name:Blood for Bones
ManaCost:3 B
Types:Sorcery
A:SP$ ChangeZone | Cost$ 3 B Sac<1/Creature> | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn | RememberChanged$ True | SubAbility$ DBChangeZone | SpellDescription$ Return a creature card from your graveyard to the battlefield, then return another creature card from your graveyard to your hand.
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn+IsNotRemembered | SubAbility$ DBCleanup
A:SP$ ChangeZone | Cost$ 3 B Sac<1/Creature> | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn | PrimaryPrompt$ Choose a creature card to return to the battlefield | ChangeTypeDesc$ creature | RememberChanged$ True | SubAbility$ DBChangeZone | SpellDescription$ Return a creature card from your graveyard to the battlefield, then return another creature card from your graveyard to your hand.
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn+IsNotRemembered | PrimaryPrompt$ Choose another creature card to return to your hand | ChangeNumDesc$ another | ChangeTypeDesc$ creature | SubAbility$ DBCleanup
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
AI:RemoveDeck:Random
Oracle:As an additional cost to cast this spell, sacrifice a creature.\nReturn a creature card from your graveyard to the battlefield, then return another creature card from your graveyard to your hand.

View File

@@ -4,7 +4,7 @@ Types:Snow Sorcery
A:SP$ Charm | Cost$ 4 B B | Choices$ DestroyCtrs,DestroyPWs | CharmNum$ 1 | SpellDescription$ Then return a creature or planeswalker card with mana value X or less from your graveyard to the battlefield, where X is the amount of {S} spent to cast this spell. ({S} is mana from a snow source.)
SVar:DestroyCtrs:DB$ DestroyAll | ValidCards$ Creature | SubAbility$ DBReturn | SpellDescription$ Destroy all creatures.
SVar:DestroyPWs:DB$ DestroyAll | ValidCards$ Planeswalker | SubAbility$ DBReturn | SpellDescription$ Destroy all planeswalkers.
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn+cmcLEX,Planeswalker.YouOwn+cmcLEX | SpellDescription$ Then return a creature or planeswalker card with mana value X or less from your graveyard to the battlefield, where X is the amount of {S} spent to cast this spell. ({S} is mana from a snow source.)
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | Hidden$ True | Mandatory$ True | ChangeType$ Creature.YouOwn+cmcLEX,Planeswalker.YouOwn+cmcLEX | ChangeTypeDesc$ creature or planeswalker card with mana value X or less | SpellDescription$ Then return a creature or planeswalker card with mana value X or less from your graveyard to the battlefield, where X is the amount of {S} spent to cast this spell. ({S} is mana from a snow source.)
SVar:X:Count$CastTotalManaSpent Snow
SVar:AIPreference:ManaFrom$Snow
AI:RemoveDeck:Random

View File

@@ -1,8 +1,8 @@
Name:Bond of Insight
ManaCost:3 U
Types:Sorcery
A:SP$ Mill | Cost$ 3 U | NumCards$ 4 | Defined$ Player | SubAbility$ DBChangeZone | StackDescription$ Each player mills four cards. | SpellDescription$ Each player mills four cards. Return up to two instant and/or sorcery cards from your graveyard to your hand. Exile CARDNAME.
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeNum$ 2 | ChangeType$ Instant.YouOwn,Sorcery.YouOwn | SelectPrompt$ Select up to two instant and/or sorcery cards from your graveyard to return to your hand | Hidden$ True | SubAbility$ DBExile | StackDescription$ {p:You} returns up to two instant and/or sorcery cards from their graveyard to their hand.
A:SP$ Mill | NumCards$ 4 | Defined$ Player | SubAbility$ DBChangeZone | SpellDescription$ Each player mills four cards. Return up to two instant and/or sorcery cards from your graveyard to your hand. Exile CARDNAME.
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Hand | ChangeNum$ 2 | ChangeType$ Instant.YouOwn,Sorcery.YouOwn | ChangeTypeDesc$ instant and/or sorcery | SelectPrompt$ Select up to two instant and/or sorcery cards from your graveyard to return to your hand | Hidden$ True | SubAbility$ DBExile | StackDescription$ {p:You} returns up to two instant and/or sorcery cards from their graveyard to their hand.
SVar:DBExile:DB$ ChangeZone | Origin$ Stack | Destination$ Exile | StackDescription$ Exile CARDNAME.
DeckHas:Ability$Graveyard|Mill
DeckHints:Type$Instant|Sorcery

View File

@@ -1,8 +1,8 @@
Name:Cauldron's Gift
ManaCost:4 B
Types:Sorcery
A:SP$ Mill | Cost$ 4 B | NumCards$ 4 | Defined$ You | SubAbility$ DBChangeZone | ConditionCheckSVar$ X | AIManaPref$ B | SpellDescription$ Adamant — If at least three black mana was spent to cast this spell, mill four cards. You may choose a creature card in your graveyard. If you do, return it to the battlefield with an additional +1/+1 counter on it.
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.YouOwn | Hidden$ True | ChangeNum$ 1 | WithCountersType$ P1P1
A:SP$ Mill | NumCards$ 4 | SubAbility$ DBChangeZone | ConditionCheckSVar$ X | AIManaPref$ B | IfDesc$ True | SpellDescription$ Adamant — If at least three black mana was spent to cast this spell, mill four cards. You may choose a creature card in your graveyard. If you do, return it to the battlefield with an additional +1/+1 counter on it.
SVar:DBChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.YouOwn | ChangeTypeDesc$ creature | Hidden$ True | ChangeNum$ 1 | WithCountersType$ P1P1
SVar:X:Count$Adamant.Black.1.0
DeckHas:Ability$Counters|Graveyard
DeckHas:Ability$Counters|Graveyard|Mill
Oracle:Adamant — If at least three black mana was spent to cast this spell, mill four cards.\nYou may choose a creature card in your graveyard. If you do, return it to the battlefield with an additional +1/+1 counter on it.

View File

@@ -1,7 +1,7 @@
Name:Connive
ManaCost:2 U/B U/B
Types:Sorcery
A:SP$ GainControl | Cost$ 2 U/B U/B | ValidTgts$ Creature.powerLE2 | TgtPrompt$ Select target creature with power 2 or less. | SpellDescription$ Gain control of target creature with power 2 or less.
A:SP$ GainControl | ValidTgts$ Creature.powerLE2 | TgtPrompt$ Select target creature with power 2 or less | SpellDescription$ Gain control of target creature with power 2 or less.
AlternateMode:Split
Oracle:Gain control of target creature with power 2 or less.
@@ -10,7 +10,7 @@ ALTERNATE
Name:Concoct
ManaCost:3 U B
Types:Sorcery
A:SP$ Surveil | Cost$ 3 U B | Amount$ 3 | SubAbility$ DBReturn | SpellDescription$ Surveil 3, then return a creature card from your graveyard to the battlefield.
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.YouCtrl | ChangeNum$ 1 | Hidden$ True
A:SP$ Surveil | Amount$ 3 | SubAbility$ DBReturn | SpellDescription$ Surveil 3, then return a creature card from your graveyard to the battlefield.
SVar:DBReturn:DB$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.YouOwn | ChangeTypeDesc$ creature | ChangeNum$ 1 | Hidden$ True | Mandatory$ True
DeckHas:Ability$Surveil|Graveyard
Oracle:Surveil 3, then return a creature card from your graveyard to the battlefield.

View File

@@ -2,8 +2,9 @@ Name:Corpse Dance
ManaCost:2 B
Types:Instant
K:Buyback:2
A:SP$ ChangeZone | Cost$ 2 B | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.TopGraveyardCreature+YouCtrl | Hidden$ True | Mandatory$ True | RememberChanged$ True | SubAbility$ DBPump | SpellDescription$ Return the top creature card of your graveyard to the battlefield. That creature gains haste until end of turn. Exile it at the beginning of the next end step.
SVar:DBPump:DB$ Animate | Keywords$ Haste | Defined$ Remembered | AtEOT$ Exile | SubAbility$ DBCleanup
A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Creature.TopGraveyardCreature+YouOwn | Hidden$ True | Mandatory$ True | RememberChanged$ True | SubAbility$ DBPump | StackDescription$ {p:You} returns the top creature card of their graveyard to the battlefield. | SpellDescription$ Return the top creature card of your graveyard to the battlefield.
SVar:DBPump:DB$ Animate | Keywords$ Haste | Defined$ Remembered | AtEOT$ Exile | SubAbility$ DBCleanup | DefinedDesc$ That creature | SpellDescription$ That creature gains haste until end of turn. Exile it at the beginning of the next end step.
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
SVar:NeedsOrderedGraveyard:TRUE
DeckHas:Ability$Graveyard
Oracle:Buyback {2} (You may pay an additional {2} as you cast this spell. If you do, put this card into your hand as it resolves.)\nReturn the top creature card of your graveyard to the battlefield. That creature gains haste until end of turn. Exile it at the beginning of the next end step.

View File

@@ -1,7 +1,8 @@
Name:Eerie Ultimatum
ManaCost:W W B B B G G
Types:Sorcery
A:SP$ ChangeZone | Cost$ W W B B B G G | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Permanent.YouOwn | DifferentNames$ True | ChangeNum$ X | Hidden$ True | StackDescription$ SpellDescription | SpellDescription$ Return any number of permanent cards with different names from your graveyard to the battlefield.
A:SP$ ChangeZone | Origin$ Graveyard | Destination$ Battlefield | ChangeType$ Permanent.YouOwn | ChangeNumDesc$ any number of | ChangeTypeDesc$ permanent cards with different names | DifferentNames$ True | ChangeNum$ X | Hidden$ True | SpellDescription$ Return any number of permanent cards with different names from your graveyard to the battlefield.
SVar:X:Count$DifferentCardNames_Permanent.YouOwn+inZoneGraveyard
SVar:IsReanimatorCard:TRUE
DeckHas:Ability$Graveyard
Oracle:Return any number of permanent cards with different names from your graveyard to the battlefield.

View File

@@ -1,6 +1,6 @@
Name:Forbidden Friendship
ManaCost:1 R
Types:Sorcery
A:SP$ Token | Cost$ 1 R | TokenAmount$ 1 | TokenScript$ r_1_1_dinosaur_haste,w_1_1_human_soldier | TokenOwner$ You | SpellDescription$ Create a 1/1 red Dinosaur creature token with haste and a 1/1 white Human Soldier creature token.
DeckHas:Ability$Token
A:SP$ Token | TokenScript$ r_1_1_dinosaur_haste,w_1_1_human_soldier | SpellDescription$ Create a 1/1 red Dinosaur creature token with haste and a 1/1 white Human Soldier creature token.
DeckHas:Ability$Token & Type$Dinosaur|Human|Soldier
Oracle:Create a 1/1 red Dinosaur creature token with haste and a 1/1 white Human Soldier creature token.