mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-20 20:58:03 +00:00
Merge branch 'master' into 'master'
STX: One Ward, two card See merge request core-developers/forge!4273
This commit is contained in:
@@ -2061,6 +2061,19 @@ public class Card extends GameEntity implements Comparable<Card>, IHasSVars {
|
|||||||
sb.append(" (").append(inst.getReminderText()).append(")");
|
sb.append(" (").append(inst.getReminderText()).append(")");
|
||||||
printedKW.add(keyword);
|
printedKW.add(keyword);
|
||||||
}
|
}
|
||||||
|
} else if (keyword.startsWith("Ward")) {
|
||||||
|
final String[] k = keyword.split(":");
|
||||||
|
final Cost cost = new Cost(k[1], false);
|
||||||
|
|
||||||
|
StringBuilder sbCost = new StringBuilder(k[0]);
|
||||||
|
if (!cost.isOnlyManaCost()) {
|
||||||
|
sbCost.append("—");
|
||||||
|
} else {
|
||||||
|
sbCost.append(" ");
|
||||||
|
}
|
||||||
|
sbCost.append(cost.toSimpleString());
|
||||||
|
sbLong.append(sbCost).append(" (").append(inst.getReminderText()).append(")");
|
||||||
|
sbLong.append("\r\n");
|
||||||
} else if (keyword.endsWith(" offering")) {
|
} else if (keyword.endsWith(" offering")) {
|
||||||
String offeringType = keyword.split(" ")[0];
|
String offeringType = keyword.split(" ")[0];
|
||||||
if (sb.length() != 0) {
|
if (sb.length() != 0) {
|
||||||
|
|||||||
@@ -3331,7 +3331,7 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
// sacrifice trigger
|
// sacrifice trigger
|
||||||
final StringBuilder sacTrig = new StringBuilder("Mode$ CounterRemoved | TriggerZones$ Battlefield" +
|
final StringBuilder sacTrig = new StringBuilder("Mode$ CounterRemoved | TriggerZones$ Battlefield" +
|
||||||
" | ValidCard$ Card.Self | NewCounterAmount$ 0 | CounterType$ TIME");
|
" | ValidCard$ Card.Self | NewCounterAmount$ 0 | CounterType$ TIME");
|
||||||
if (keyword.contains(":")) {
|
if (keyword.contains(":")) {
|
||||||
sacTrig.append("| Secondary$ True");
|
sacTrig.append("| Secondary$ True");
|
||||||
}
|
}
|
||||||
@@ -3343,6 +3343,21 @@ public class CardFactoryUtil {
|
|||||||
|
|
||||||
inst.addTrigger(parsedUpkeepTrig);
|
inst.addTrigger(parsedUpkeepTrig);
|
||||||
inst.addTrigger(parsedSacTrigger);
|
inst.addTrigger(parsedSacTrigger);
|
||||||
|
} else if (keyword.startsWith("Ward")) {
|
||||||
|
final String[] k = keyword.split(":");
|
||||||
|
final Cost cost = new Cost(k[1], false);
|
||||||
|
String costDesc = cost.toSimpleString();
|
||||||
|
|
||||||
|
String strTrig = "Mode$ BecomesTarget | ValidSource$ Card.OppCtrl | ValidTarget$ Card.Self "
|
||||||
|
+ " | Secondary$ True | TriggerDescription$ Ward " + costDesc + " ("
|
||||||
|
+ inst.getReminderText() + ")";
|
||||||
|
String effect = "DB$ Counter | Defined$ TriggeredSourceSA | UnlessCost$ " + k[1]
|
||||||
|
+ " | UnlessPayer$ TriggeredSourceSAController";
|
||||||
|
|
||||||
|
final Trigger trigger = TriggerHandler.parseTrigger(strTrig, card, intrinsic);
|
||||||
|
trigger.setOverridingAbility(AbilityFactory.getAbility(effect, card));
|
||||||
|
|
||||||
|
inst.addTrigger(trigger);
|
||||||
} else if (keyword.equals("MayFlashSac")) {
|
} else if (keyword.equals("MayFlashSac")) {
|
||||||
String strTrig = "Mode$ SpellCast | ValidCard$ Card.Self | ValidSA$ Spell.MayPlaySource | Static$ True | Secondary$ True "
|
String strTrig = "Mode$ SpellCast | ValidCard$ Card.Self | ValidSA$ Spell.MayPlaySource | Static$ True | Secondary$ True "
|
||||||
+ " | TriggerDescription$ If you cast it any time a sorcery couldn't have been cast, "
|
+ " | TriggerDescription$ If you cast it any time a sorcery couldn't have been cast, "
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ public final class CardUtil {
|
|||||||
"Fortify", "Transfigure", "Champion", "Evoke", "Prowl", "IfReach",
|
"Fortify", "Transfigure", "Champion", "Evoke", "Prowl", "IfReach",
|
||||||
"Reinforce", "Unearth", "Level up", "Miracle", "Overload",
|
"Reinforce", "Unearth", "Level up", "Miracle", "Overload",
|
||||||
"Scavenge", "Encore", "Bestow", "Outlast", "Dash", "Surge", "Emerge", "Hexproof:",
|
"Scavenge", "Encore", "Bestow", "Outlast", "Dash", "Surge", "Emerge", "Hexproof:",
|
||||||
"etbCounter", "Reflect").build();
|
"etbCounter", "Reflect", "Ward").build();
|
||||||
/** List of keyword endings of keywords that could be modified by text changes. */
|
/** List of keyword endings of keywords that could be modified by text changes. */
|
||||||
public static final ImmutableList<String> modifiableKeywordEndings = ImmutableList.<String>builder().add(
|
public static final ImmutableList<String> modifiableKeywordEndings = ImmutableList.<String>builder().add(
|
||||||
"walk", "cycling", "offering").build();
|
"walk", "cycling", "offering").build();
|
||||||
|
|||||||
@@ -161,6 +161,7 @@ public enum Keyword {
|
|||||||
UNLEASH("Unleash", SimpleKeyword.class, false, "You may have this creature enter the battlefield with a +1/+1 counter on it. It can't block as long as it has a +1/+1 counter on it."),
|
UNLEASH("Unleash", SimpleKeyword.class, false, "You may have this creature enter the battlefield with a +1/+1 counter on it. It can't block as long as it has a +1/+1 counter on it."),
|
||||||
VANISHING("Vanishing", KeywordWithAmount.class, false, "This permanent enters the battlefield with {%d:time counter} on it. At the beginning of your upkeep, remove a time counter from it. When the last is removed, sacrifice it."),
|
VANISHING("Vanishing", KeywordWithAmount.class, false, "This permanent enters the battlefield with {%d:time counter} on it. At the beginning of your upkeep, remove a time counter from it. When the last is removed, sacrifice it."),
|
||||||
VIGILANCE("Vigilance", SimpleKeyword.class, true, "Attacking doesn't cause this creature to tap."),
|
VIGILANCE("Vigilance", SimpleKeyword.class, true, "Attacking doesn't cause this creature to tap."),
|
||||||
|
WARD("Ward", KeywordWithCost.class, false, "Whenever this permanent becomes the target of a spell or ability an opponent controls, counter it unless that player pays %s."),
|
||||||
WITHER("Wither", SimpleKeyword.class, true, "This deals damage to creatures in the form of -1/-1 counters."),
|
WITHER("Wither", SimpleKeyword.class, true, "This deals damage to creatures in the form of -1/-1 counters."),
|
||||||
|
|
||||||
// mayflash additional cast
|
// mayflash additional cast
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
Name:Torrent Sculptor
|
||||||
|
ManaCost:2 U U
|
||||||
|
Types:Creature Merfolk Wizard
|
||||||
|
PT:2/2
|
||||||
|
K:Ward:2
|
||||||
|
T:Mode$ ChangesZone | ValidCard$ Card.Self | Destination$ Battlefield | Execute$ TrigChangeZone | TriggerDescription$ When CARDNAME enters the battlefield, exile an instant or sorcery card from your graveyard. Put a number of +1/+1 counters on Torrent Sculptor equal to half that card's mana value, rounded up.
|
||||||
|
SVar:TrigChangeZone:DB$ ChangeZone | Origin$ Graveyard | Destination$ Exile | ChangeType$ Instant.YouCtrl,Sorcery.YouCtrl | ChangeNum$ 1 | RememberChanged$ True | Hidden$ True | Mandatory$ True | SubAbility$ DBPutCounter
|
||||||
|
SVar:DBPutCounter:DB$ PutCounter | CounterType$ P1P1 | CounterNum$ X | SubAbility$ DBCleanup
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
SVar:X:Remembered$CardManaCost/HalfUp
|
||||||
|
AlternateMode:Modal
|
||||||
|
Oracle:Ward {2} (Whenever this creature becomes the target of a spell or ability an opponent controls, counter it unless that player pays {2}.)\nWhen Torrent Sculptor enters the battlefield, exile an instant or sorcery card from your graveyard. Put a number of +1/+1 counters on Torrent Sculptor equal to half that card's mana value, rounded up.
|
||||||
|
|
||||||
|
ALTERNATE
|
||||||
|
|
||||||
|
Name:Flamethrower Sonata
|
||||||
|
ManaCost:1 R
|
||||||
|
Types:Sorcery
|
||||||
|
A:SP$ Discard | Cost$ 1 R | Mode$ TgtChoose | SubAbility$ DBDraw | RememberDiscarded$ True | SpellDescription$ Discard a card, then draw a card. When you discard an instant or sorcery card this way, CARDNAME deals damage equal to that card's mana value to target creature or planeswalker you don't control.
|
||||||
|
SVar:DBDraw:DB$ Draw | SubAbility$ DBImmediateTrigger
|
||||||
|
SVar:DBImmediateTrigger:DB$ ImmediateTrigger | ConditionDefined$ Remembered | ConditionPresent$ Instant,Sorcery | Execute$ TrigDealDamage | RememberObjects$ RememberedCard | SubAbility$ DBCleanup | TriggerDescription$ When you discard an instant or sorcery card this way, CARDNAME deals damage equal to that card's mana value to target creature or planeswalker you don't control.
|
||||||
|
SVar:TrigDealDamage:DB$ DealDamage | ValidTgts$ Creature.YouDontCtrl,Planeswalker.YouDontCtrl | TgtPrompt$ Select target creature or planeswalker you don't control | NumDmg$ X
|
||||||
|
SVar:DBCleanup:DB$ Cleanup | ClearRemembered$ True
|
||||||
|
SVar:X:Remembered$CardManaCost
|
||||||
|
Oracle:Discard a card, then draw a card. When you discard an instant or sorcery card this way, Flamethrower Sonata deals damage equal to that card's mana value to target creature or planeswalker you don't control.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
Name:Waterfall Aerialist
|
||||||
|
ManaCost:3 U
|
||||||
|
Types:Creature Djinn Wizard
|
||||||
|
PT:3/1
|
||||||
|
K:Flying
|
||||||
|
K:Ward:2
|
||||||
|
Oracle:Flying\nWard {2} (Whenever this creature becomes the target of a spell or ability an opponent controls, counter it unless that player pays {2}.)
|
||||||
Reference in New Issue
Block a user