diff --git a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java
index 78d32d576f7..539125293db 100644
--- a/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java
+++ b/forge-game/src/main/java/forge/game/card/CardFactoryUtil.java
@@ -2170,6 +2170,9 @@ public class CardFactoryUtil {
else if (keyword.startsWith("Awaken")) {
card.addSpellAbility(makeAwakenSpell(card, keyword));
}
+ else if (keyword.startsWith("Surge")) {
+ card.addSpellAbility(makeSurgeSpell(card, keyword));
+ }
else if (keyword.startsWith("Monstrosity")) {
final String[] k = keyword.split(":");
final String magnitude = k[0].substring(12);
@@ -3167,6 +3170,32 @@ public class CardFactoryUtil {
return awakenSpell;
}
+ /**
+ * make Surge keyword
+ * @param card
+ * @param surgeKeyword
+ * @return
+ */
+ private static SpellAbility makeSurgeSpell(final Card card, final String surgeKeyword) {
+ final String[] k = surgeKeyword.split(":");
+ final Cost surgeCost = new Cost(k[1], false);
+ card.removeIntrinsicKeyword(surgeKeyword);
+ final SpellAbility surgeSpell = card.getFirstSpellAbility().copy();
+
+ surgeSpell.setPayCosts(surgeCost);
+ surgeSpell.setBasicSpell(false);
+ surgeSpell.addOptionalCost(OptionalCost.Surge);
+
+ final SpellAbilityRestriction restriction = new SpellAbilityRestriction();
+ restriction.setVariables(card.getFirstSpellAbility().getRestrictions());
+ restriction.setSurge(true);
+ surgeSpell.setRestrictions(restriction);
+ String desc = "Surge " + surgeCost.toSimpleString() + " (You may cast this spell for its "
+ + "surge cost if you or a teammate has cast another spell this turn.)";
+ surgeSpell.setDescription(desc);
+ return surgeSpell;
+ }
+
/**
*
* hasKeyword.
diff --git a/forge-game/src/main/java/forge/game/card/CardUtil.java b/forge-game/src/main/java/forge/game/card/CardUtil.java
index b3c354c01e1..61f39558d36 100644
--- a/forge-game/src/main/java/forge/game/card/CardUtil.java
+++ b/forge-game/src/main/java/forge/game/card/CardUtil.java
@@ -60,7 +60,7 @@ public final class CardUtil {
"Transmute", "Replicate", "Recover", "Suspend", "Aura swap",
"Fortify", "Transfigure", "Champion", "Evoke", "Prowl",
"Reinforce", "Unearth", "Level up", "Miracle", "Overload",
- "Scavenge", "Bestow", "Outlast", "Dash", "Renown").build();
+ "Scavenge", "Bestow", "Outlast", "Dash", "Renown", "Surge").build();
/** List of keyword endings of keywords that could be modified by text changes. */
public static final ImmutableList modifiableKeywordEndings = ImmutableList.builder().add(
"walk", "cycling", "offering").build();
diff --git a/forge-game/src/main/java/forge/game/player/Player.java b/forge-game/src/main/java/forge/game/player/Player.java
index d9ca1dd1f4e..e0c6e9d2fab 100644
--- a/forge-game/src/main/java/forge/game/player/Player.java
+++ b/forge-game/src/main/java/forge/game/player/Player.java
@@ -1867,6 +1867,12 @@ public class Player extends GameEntity implements Comparable {
return blood;
}
+ public final boolean hasSurge() {
+ FCollection list = getAllies();
+ list.add(this);
+ return !CardLists.filterControlledBy(game.getStack().getSpellsCastThisTurn(), list).isEmpty();
+ }
+
public final boolean hasProwl(final String type) {
if (prowl.contains("AllCreatureTypes")) {
return true;
diff --git a/forge-game/src/main/java/forge/game/spellability/OptionalCost.java b/forge-game/src/main/java/forge/game/spellability/OptionalCost.java
index 0c274373fbd..604f1b5e703 100644
--- a/forge-game/src/main/java/forge/game/spellability/OptionalCost.java
+++ b/forge-game/src/main/java/forge/game/spellability/OptionalCost.java
@@ -9,7 +9,8 @@ public enum OptionalCost {
Buyback,
Entwine,
Kicker1,
- Kicker2,
+ Kicker2,
+ Surge,
AltCost, // used by prowl
Generic, // used by "Dragon Presence" and pseudo-kicker cards
}
diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java
index 3f51f16a431..023cf0049e3 100644
--- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java
+++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java
@@ -417,6 +417,10 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
return isOptionalCostPaid(OptionalCost.Kicker1) || isOptionalCostPaid(OptionalCost.Kicker2);
}
+ public boolean isSurged() {
+ return isOptionalCostPaid(OptionalCost.Surge);
+ }
+
public boolean isOptionalCostPaid(OptionalCost cost) {
SpellAbility saRoot = getRootAbility();
return saRoot.optionalCosts.contains(cost);
diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java
index 14ed36c367c..84eae6a79b1 100644
--- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java
+++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityCondition.java
@@ -95,7 +95,10 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
}
if (value.equals("Kicked 2")) {
this.kicked2 = true;
- }
+ }
+ if (value.equals("Surge")) {
+ this.surgeCostPaid = true;
+ }
if (value.equals("AllTargetsLegal")) {
this.setAllTargetsLegal(true);
}
@@ -223,6 +226,7 @@ public class SpellAbilityCondition extends SpellAbilityVariables {
if (this.kicked1 && !sa.isOptionalCostPaid(OptionalCost.Kicker1)) return false;
if (this.kicked2 && !sa.isOptionalCostPaid(OptionalCost.Kicker2)) return false;
if (this.altCostPaid && !sa.isOptionalCostPaid(OptionalCost.AltCost)) return false;
+ if (this.surgeCostPaid && !sa.isSurged()) return false;
if (this.optionalCostPaid && this.optionalBoolean && !sa.isOptionalCostPaid(OptionalCost.Generic)) return false;
if (this.optionalCostPaid && !this.optionalBoolean && sa.isOptionalCostPaid(OptionalCost.Generic)) return false;
diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java
index 0886f1ac989..114dd8c2ee7 100644
--- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java
+++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java
@@ -332,6 +332,11 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
return false;
}
}
+ if (this.isSurge()) {
+ if (!activator.hasSurge()) {
+ return false;
+ }
+ }
if (this.getProwlTypes() != null && !this.getProwlTypes().isEmpty()) {
// only true if the activating player has damaged the opponent with
// one of the specified types
diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityVariables.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityVariables.java
index 65d2e12ab7e..6e2c1dd8db5 100644
--- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityVariables.java
+++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityVariables.java
@@ -70,6 +70,7 @@ public class SpellAbilityVariables {
this.cardsInHand = sav.getCardsInHand();
this.chosenColors = sav.getColorToCheck();
this.threshold = sav.isThreshold();
+ this.surge = sav.isSurge();
this.metalcraft = sav.isThreshold();
this.hellbent = sav.isHellbent();
this.allTargetsLegal = sav.isAllTargetsLegal();
@@ -153,6 +154,9 @@ public class SpellAbilityVariables {
/** The hellbent. */
private boolean hellbent = false;
+ /** The surge. */
+ private boolean surge = false;
+
private boolean allTargetsLegal = false;
/** The prowl. */
@@ -486,6 +490,18 @@ public class SpellAbilityVariables {
this.metalcraft = bMetalcraft;
}
+ /**
+ *
+ * Setter for the field surge.
+ *
+ *
+ * @param bSurge
+ * a boolean.
+ */
+ public final void setSurge(final boolean bSurge) {
+ this.surge = bSurge;
+ }
+
/** Optional Costs */
protected boolean kicked = false;
protected boolean kicked1 = false; // http://magiccards.info/query?q=o%3A%22kicker%22+not+o%3A%22multikicker%22+o%3A%22and%2For+{%22
@@ -494,6 +510,7 @@ public class SpellAbilityVariables {
protected boolean optionalCostPaid = false; // Undergrowth other Pseudo-kickers
protected boolean optionalBoolean = true; // Just in case you need to check if something wasn't kicked, etc
protected boolean dragonPresence = false;
+ protected boolean surgeCostPaid = false;
/**
* @return the allTargetsLegal
@@ -709,6 +726,15 @@ public class SpellAbilityVariables {
return this.hellbent;
}
+ /**
+ * Checks if is surge.
+ *
+ * @return the surge
+ */
+ public final boolean isSurge() {
+ return this.surge;
+ }
+
public String getShareAllColors() {
return shareAllColors;
}