Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions forge-game/src/main/java/forge/game/ability/AbilityUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -2781,6 +2781,22 @@ public static int xCount(Card c, final String s, final CardTraitBase ctb) {
someCards = CardUtil.getLastTurnCast(validFilter, c, ctb, player);
}
}

// Count$DifferentManaValuesAmongSpellsAndLandsThisTurn <Valid> -- distinct mana values among cards matching
// <Valid> cast this turn, combined with lands you've played this turn. Built for the Coststorm keyword.
if (sq[0].startsWith("DifferentManaValuesAmongSpellsAndLandsThisTurn")) {
final String[] workingCopy = paidparts[0].split("_");
final String validFilter = workingCopy[1];
final Set<Integer> manaValues = Sets.newHashSet();
for (final Card castCard : CardUtil.getThisTurnCast(validFilter, c, ctb, player)) {
manaValues.add(castCard.getCMC());
}
for (final Card landCard : player.getLandsPlayedThisTurnCards()) {
manaValues.add(landCard.getCMC());
}
return doXMath(manaValues.size(), expr, c, ctb);
}

if (sq[0].startsWith("ThisTurnActivated")) {
final String[] workingCopy = paidparts[0].split("_");
final String validFilter = workingCopy[1];
Expand Down
10 changes: 10 additions & 0 deletions forge-game/src/main/java/forge/game/card/Card.java
Original file line number Diff line number Diff line change
Expand Up @@ -3266,6 +3266,16 @@ private StringBuilder abilityTextInstantSorcery(CardState state) {
sbAfter.append(" You may choose new targets for the copies.");
}

sbAfter.append(")");
sbAfter.append("\r\n");
} else if (keyword.equals("Coststorm")) {
sbAfter.append("Coststorm (");
sbAfter.append("When you cast this spell, copy it for each different mana value among other spells and lands you've played this turn.");

if (strSpell.contains("Target") || strSpell.contains("target")) {
sbAfter.append(" You may choose new targets for the copies.");
}

sbAfter.append(")");
sbAfter.append("\r\n");
} else if (keyword.startsWith("Replicate")) {
Expand Down
14 changes: 14 additions & 0 deletions forge-game/src/main/java/forge/game/card/CardFactoryUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -1181,6 +1181,20 @@ public void resolve() {
trigger.setOverridingAbility(copySa);

inst.addTrigger(trigger);
} else if (keyword.equals("Coststorm")) {
final String actualTrigger = "Mode$ SpellCast | ValidCard$ Card.Self | TriggerZones$ Stack | Secondary$ True"
+ "| TriggerDescription$ Coststorm (" + inst.getReminderText() + ")";

String effect = "DB$ CopySpellAbility | Defined$ TriggeredSpellAbility | Amount$ CoststormCount | MayChooseTarget$ True";

final Trigger parsedTrigger = TriggerHandler.parseTrigger(actualTrigger, card, intrinsic);

final SpellAbility sa = AbilityFactory.getAbility(effect, card);
sa.setSVar("CoststormCount", "Count$DifferentManaValuesAmongSpellsAndLandsThisTurn_Card.YouCtrl+!CastSaSource");

parsedTrigger.setOverridingAbility(sa);

inst.addTrigger(parsedTrigger);
} else if (keyword.startsWith("Haunt")) {
final String[] k = keyword.split(":");
final String hauntSVarName = k[1];
Expand Down
1 change: 1 addition & 0 deletions forge-game/src/main/java/forge/game/keyword/Keyword.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public enum Keyword {
COMPLEATED("Compleated", Compleated.class, true, "This planeswalker enters with two fewer loyalty counters for each Phyrexian mana symbol life was paid for."),
CONSPIRE("Conspire", SimpleKeyword.class, false, "As an additional cost to cast this spell, you may tap two untapped creatures you control that each share a color with it. If you do, copy it."),
CONVOKE("Convoke", SimpleKeyword.class, true, "Your creatures can help cast this spell. Each creature you tap while playing this spell reduces its cost by {1} or by one mana of that creature's color."),
COSTSTORM("Coststorm", SimpleKeyword.class, false, "When you cast this spell, copy it for each different mana value among other spells and lands you've played this turn."),
CRAFT("Craft", Craft.class, false, "%s, Exile this artifact, %s: Return this card transformed under its owner's control. Craft only as a sorcery."),
CREW("Crew", KeywordWithAmount.class, false, "Tap any number of creatures you control with total power %1$d or more: This Vehicle becomes an artifact creature until end of turn."),
CUMULATIVE_UPKEEP("Cumulative upkeep", KeywordWithCost.class, false, "At the beginning of your upkeep, put an age counter on this permanent, then sacrifice it unless you pay its upkeep cost for each age counter on it."),
Expand Down
6 changes: 6 additions & 0 deletions forge-game/src/main/java/forge/game/player/Player.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public class Player extends GameEntity implements Comparable<Player> {
private int numForetoldThisTurn;
private int landsPlayedThisTurn;
private int landsPlayedLastTurn;
private final CardCollection landsPlayedThisTurnCards = new CardCollection(); //Used for Coststorm. Needed because a land's mana value isn't always 0 (Glade of the Pump Spells)
private int numPowerSurgeLands;
private int spellsCastThisGame;
private int spellsCastLastTurn;
Expand Down Expand Up @@ -1651,6 +1652,7 @@ public final Card playLand(final Card land, SpellAbility cause) {

game.getStack().unfreezeStack();
addLandPlayedThisTurn();
landsPlayedThisTurnCards.add(c);

// play a sound
game.fireEvent(new GameEventLandPlayed(PlayerView.get(this), CardView.get(c)));
Expand Down Expand Up @@ -2235,6 +2237,9 @@ public final int getLandsPlayedThisTurn() {
public final int getLandsPlayedLastTurn() {
return landsPlayedLastTurn;
}
public final List<Card> getLandsPlayedThisTurnCards() {
return landsPlayedThisTurnCards;
}
public final void addLandPlayedThisTurn() {
landsPlayedThisTurn++;
achievementTracker.landsPlayed++;
Expand Down Expand Up @@ -2479,6 +2484,7 @@ public void onCleanupPhase() {
setTappedLandForManaThisTurn(false);
setLandsPlayedLastTurn(getLandsPlayedThisTurn());
resetLandsPlayedThisTurn();
landsPlayedThisTurnCards.clear();
resetInvestigatedThisTurn();
resetSurveilThisTurn();
resetDiscardedThisTurn();
Expand Down
6 changes: 6 additions & 0 deletions forge-gui/res/cardsfolder/f/friarball.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Name:Friarball
ManaCost:3 W
Types:Sorcery
K:Coststorm
A:SP$ Token | TokenScript$ w_2_2_monk | TokenOwner$ You | SpellDescription$ Create a 2/2 white Monk creature token.
Oracle:Create a 2/2 white Monk creature token.\nCoststorm (When you cast this spell, copy it for each different mana value among other spells and lands you've played this turn.)
6 changes: 6 additions & 0 deletions forge-gui/res/tokenscripts/w_2_2_monk.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Name:Monk Token
ManaCost:no cost
Colors:white
Types:Creature Monk
PT:2/2
Oracle: