diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java
index b54c727370f..6d9ed807964 100644
--- a/forge-game/src/main/java/forge/game/GameActionUtil.java
+++ b/forge-game/src/main/java/forge/game/GameActionUtil.java
@@ -22,8 +22,10 @@ import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
+import forge.card.MagicColor;
import forge.card.mana.ManaCost;
import forge.card.mana.ManaCostParser;
+import forge.game.ability.AbilityFactory;
import forge.game.ability.AbilityUtils;
import forge.game.ability.ApiType;
import forge.game.card.*;
@@ -32,9 +34,15 @@ import forge.game.cost.Cost;
import forge.game.keyword.KeywordInterface;
import forge.game.player.Player;
import forge.game.player.PlayerController;
+import forge.game.replacement.ReplacementEffect;
+import forge.game.replacement.ReplacementHandler;
+import forge.game.replacement.ReplacementLayer;
import forge.game.spellability.*;
import forge.game.trigger.Trigger;
+import forge.game.trigger.TriggerHandler;
+import forge.game.trigger.TriggerType;
import forge.game.zone.ZoneType;
+import forge.util.Lang;
import forge.util.TextUtil;
import org.apache.commons.lang3.StringUtils;
@@ -363,10 +371,11 @@ public final class GameActionUtil {
}
SpellAbility result = null;
final Card host = sa.getHostCard();
+ final Game game = host.getGame();
final Player activator = sa.getActivatingPlayer();
final PlayerController pc = activator.getController();
- host.getGame().getAction().checkStaticAbilities(false);
+ game.getAction().checkStaticAbilities(false);
boolean reset = false;
@@ -429,7 +438,60 @@ public final class GameActionUtil {
int v = pc.chooseNumberForKeywordCost(sa, cost, ki, str, Integer.MAX_VALUE);
if (v > 0) {
- host.addReplacementEffect(CardFactoryUtil.makeEtbCounter("etbCounter:P1P1:" + v, host, false));
+
+ final Card eff = new Card(game.nextCardId(), game);
+ eff.setTimestamp(game.getNextTimestamp());
+ eff.setName(c.getName() + "'s Effect");
+ eff.addType("Effect");
+ eff.setToken(true); // Set token to true, so when leaving play it gets nuked
+ eff.setOwner(activator);
+
+ eff.setImageKey(c.getImageKey());
+ eff.setColor(MagicColor.COLORLESS);
+ eff.setImmutable(true);
+ // try to get the SpellAbility from the mana ability
+ //eff.setEffectSource((SpellAbility)null);
+
+ eff.addRemembered(host);
+
+ String abStr = "DB$ PutCounter | Defined$ ReplacedCard | CounterType$ P1P1 | ETB$ True | CounterNum$ " + v;
+
+ SpellAbility saAb = AbilityFactory.getAbility(abStr, c);
+
+ CardFactoryUtil.setupETBReplacementAbility(saAb);
+
+ String desc = "It enters the battlefield with ";
+ desc += Lang.nounWithNumeral(v, CounterType.P1P1.getName() + " counter");
+ desc += " on it.";
+
+ String repeffstr = "Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Battlefield | Description$ " + desc;
+
+ ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true);
+ re.setLayer(ReplacementLayer.Other);
+ re.setOverridingAbility(saAb);
+
+ eff.addReplacementEffect(re);
+
+ // Forgot Trigger
+ String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Stack | Destination$ Any | TriggerZones$ Command | Static$ True";
+ String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard";
+ String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile"
+ + " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0";
+
+ SpellAbility saForget = AbilityFactory.getAbility(forgetEffect, eff);
+ AbilitySub saExile = (AbilitySub) AbilityFactory.getAbility(exileEffect, eff);
+ saForget.setSubAbility(saExile);
+
+ final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, eff, true);
+ parsedTrigger.setOverridingAbility(saForget);
+ eff.addTrigger(parsedTrigger);
+ eff.updateStateForView();
+
+ // TODO: Add targeting to the effect so it knows who it's dealing with
+ game.getTriggerHandler().suppressMode(TriggerType.ChangesZone);
+ game.getAction().moveTo(ZoneType.Command, eff, null);
+ game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone);
+
if (result == null) {
result = sa.copy();
}
diff --git a/forge-game/src/main/java/forge/game/mana/ManaPool.java b/forge-game/src/main/java/forge/game/mana/ManaPool.java
index e90e6eb9b50..d11afbe776c 100644
--- a/forge-game/src/main/java/forge/game/mana/ManaPool.java
+++ b/forge-game/src/main/java/forge/game/mana/ManaPool.java
@@ -254,7 +254,7 @@ public class ManaPool extends ManaConversionMatrix implements Iterable
* Abstract AbilityMana class.
*
* Constructor for AbilityMana.
*
* produceMana.
*
* getKeywords. *
- * + * * @return a {@link java.lang.String} object. */ public String getKeywords() { @@ -218,7 +221,7 @@ public class AbilityManaPart implements java.io.Serializable { * addsCounters. * * @param saBeingPaid - * + * * @return a {@link java.lang.String} object. */ public boolean addsCounters(SpellAbility saBeingPaid) { @@ -228,10 +231,26 @@ public class AbilityManaPart implements java.io.Serializable { /** * createETBCounters */ - public void createETBCounters(Card c) { + public void createETBCounters(Card c, Player controller) { String[] parse = this.addsCounters.split("_"); // Convert random SVars if there are other cards with this effect if (c.isValid(parse[0], c.getController(), c, null)) { + final Game game = this.sourceCard.getGame(); + final Card eff = new Card(game.nextCardId(), game); + eff.setTimestamp(game.getNextTimestamp()); + eff.setName(sourceCard.getName() + "'s Effect"); + eff.addType("Effect"); + eff.setToken(true); // Set token to true, so when leaving play it gets nuked + eff.setOwner(controller); + + eff.setImageKey(sourceCard.getImageKey()); + eff.setColor(MagicColor.COLORLESS); + eff.setImmutable(true); + // try to get the SpellAbility from the mana ability + //eff.setEffectSource((SpellAbility)null); + + eff.addRemembered(c); + String abStr = "DB$ PutCounter | Defined$ ReplacedCard | CounterType$ " + parse[1] + " | ETB$ True | CounterNum$ " + parse[2]; @@ -241,15 +260,37 @@ public class AbilityManaPart implements java.io.Serializable { } CardFactoryUtil.setupETBReplacementAbility(sa); - String repeffstr = "Event$ Moved | ValidCard$ Card.Self | Destination$ Battlefield " - + " | Secondary$ True | Description$ CARDNAME" - + " enters the battlefield with " + CounterType.valueOf(parse[1]).getName() + " counters."; + String desc = "It enters the battlefield with "; + desc += Lang.nounWithNumeral(parse[2], CounterType.valueOf(parse[1]).getName() + " counter"); + desc += " on it."; - ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, c, false); + String repeffstr = "Event$ Moved | ValidCard$ Card.IsRemembered | Destination$ Battlefield | Description$ " + desc; + + ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, eff, true); re.setLayer(ReplacementLayer.Other); re.setOverridingAbility(sa); - c.addChangedCardTraits(null, null, null, ImmutableList.of(re), null, false, false, false, sa.getHostCard().getGame().getNextTimestamp()); + eff.addReplacementEffect(re); + + // Forgot Trigger + String trig = "Mode$ ChangesZone | ValidCard$ Card.IsRemembered | Origin$ Stack | Destination$ Any | TriggerZones$ Command | Static$ True"; + String forgetEffect = "DB$ Pump | ForgetObjects$ TriggeredCard"; + String exileEffect = "DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile" + + " | ConditionDefined$ Remembered | ConditionPresent$ Card | ConditionCompare$ EQ0"; + + SpellAbility saForget = AbilityFactory.getAbility(forgetEffect, eff); + AbilitySub saExile = (AbilitySub) AbilityFactory.getAbility(exileEffect, eff); + saForget.setSubAbility(saExile); + + final Trigger parsedTrigger = TriggerHandler.parseTrigger(trig, eff, true); + parsedTrigger.setOverridingAbility(saForget); + eff.addTrigger(parsedTrigger); + eff.updateStateForView(); + + // TODO: Add targeting to the effect so it knows who it's dealing with + game.getTriggerHandler().suppressMode(TriggerType.ChangesZone); + game.getAction().moveTo(ZoneType.Command, eff, null); + game.getTriggerHandler().clearSuppression(TriggerType.ChangesZone); } } @@ -270,7 +311,7 @@ public class AbilityManaPart implements java.io.Serializable { ** getManaRestrictions. *
- * + * * @return a {@link java.lang.String} object. */ public String getManaRestrictions() { @@ -281,7 +322,7 @@ public class AbilityManaPart implements java.io.Serializable { ** meetsManaRestrictions. *
- * + * * @param sa * a {@link forge.game.spellability.SpellAbility} object. * @return a boolean. @@ -297,7 +338,7 @@ public class AbilityManaPart implements java.io.Serializable { if (restriction.equals("nonSpell")) { return !sa.isSpell(); } - + if (restriction.equals("CumulativeUpkeep")) { if (sa.isCumulativeupkeep()) { return true; @@ -350,7 +391,7 @@ public class AbilityManaPart implements java.io.Serializable { ** mana. *
- * + * * @return a {@link java.lang.String} object. */ public final String mana() { @@ -439,7 +480,7 @@ public class AbilityManaPart implements java.io.Serializable { ** canProduce. *
- * + * * @param s * a {@link java.lang.String} object. * @return a boolean. @@ -469,7 +510,7 @@ public class AbilityManaPart implements java.io.Serializable { ** isBasic. *
- * + * * @return a boolean. */ public final boolean isBasic() { @@ -542,7 +583,7 @@ public class AbilityManaPart implements java.io.Serializable { public Card getSourceCard() { return sourceCard; } - + public void setSourceCard(final Card host) { sourceCard = host; }