Rebound: make it a ReplacementEffect as it should be

check for Fizzle in ReplaceMoved, so it only works when it resolved from Stack
This commit is contained in:
Hanmac
2017-10-02 13:42:14 +00:00
parent e40f3cb34d
commit 70b0e7d6c0
5 changed files with 52 additions and 22 deletions

View File

@@ -71,7 +71,7 @@ public class DelayedTriggerEffect extends SpellAbilityEffect {
} }
} }
if (mapParams.containsKey("Execute")) { if (mapParams.containsKey("Execute") || sa.hasAdditonalAbility("Execute")) {
SpellAbility overridingSA = sa.getAdditonalAbility("Execute"); SpellAbility overridingSA = sa.getAdditonalAbility("Execute");
overridingSA.setActivatingPlayer(sa.getActivatingPlayer()); overridingSA.setActivatingPlayer(sa.getActivatingPlayer());
overridingSA.setDeltrigActivatingPlayer(sa.getActivatingPlayer()); // ensure that the original activator can be restored later overridingSA.setDeltrigActivatingPlayer(sa.getActivatingPlayer()); // ensure that the original activator can be restored later

View File

@@ -2124,7 +2124,7 @@ public class Card extends GameEntity implements Comparable<Card> {
sb.delete(sb.lastIndexOf("\r\n"), sb.lastIndexOf("\r\n") + 3); sb.delete(sb.lastIndexOf("\r\n"), sb.lastIndexOf("\r\n") + 3);
} }
sb.append("Remove CARDNAME from your deck before playing if you're not playing for ante.\r\n"); sb.append("Remove CARDNAME from your deck before playing if you're not playing for ante.\r\n");
} else if (keyword.equals("Rebound") || keyword.equals("Retrace") || keyword.equals("Changeling")) { } else if (keyword.equals("Retrace") || keyword.equals("Changeling")) {
sb.append(keyword + " (" + Keyword.getInstance(keyword).getReminderText() + ")"); sb.append(keyword + " (" + Keyword.getInstance(keyword).getReminderText() + ")");
} else if (keyword.startsWith("Presence")) { } else if (keyword.startsWith("Presence")) {
sb.append(Keyword.getInstance(keyword).getReminderText()); sb.append(Keyword.getInstance(keyword).getReminderText());

View File

@@ -2195,6 +2195,9 @@ public class CardFactoryUtil {
else if (keyword.equals("Persist")) { else if (keyword.equals("Persist")) {
addTriggerAbility(keyword, card, null); addTriggerAbility(keyword, card, null);
} }
else if (keyword.equals("Rebound")) {
addReplacementEffect(keyword, card, null);
}
else if (keyword.equals("Undying")) { else if (keyword.equals("Undying")) {
addTriggerAbility(keyword, card, null); addTriggerAbility(keyword, card, null);
} }
@@ -3497,6 +3500,42 @@ public class CardFactoryUtil {
if (!intrinsic) { if (!intrinsic) {
kws.addReplacement(re); kws.addReplacement(re);
} }
} else if (keyword.equals("Rebound")) {
String repeffstr = "Event$ Moved | ValidCard$ Card.Self+wasCastFromHand+YouOwn+YouCtrl "
+ " | Origin$ Stack | Destination$ Graveyard | Fizzle$ False "
+ " | Description$ " + Keyword.REBOUND.getDescription();
String abExile = "DB$ ChangeZone | Defined$ Self | Origin$ Stack | Destination$ Exile";
String delTrig = "DB$ DelayedTrigger | Mode$ Phase | Phase$ Upkeep | ValidPlayer$ You " +
" | OptionalDecider$ You | RememberObjects$ Self | TriggerDescription$"
+ " At the beginning of your next upkeep, you may cast " + card.toString() + " without paying it's manacost.";
// TODO add check for still in exile
String abPlay = "DB$ Play | Defined$ Self | WithoutManaCost$ True | Optional$ True";
SpellAbility saExile = AbilityFactory.getAbility(abExile, card);
final AbilitySub delsub = (AbilitySub) AbilityFactory.getAbility(delTrig, card);
final AbilitySub saPlay = (AbilitySub) AbilityFactory.getAbility(abPlay, card);
delsub.setAdditionalAbility("Execute", saPlay);
saExile.setSubAbility(delsub);
if (!intrinsic) {
saExile.setIntrinsic(false);
}
ReplacementEffect re = ReplacementHandler.parseReplacement(repeffstr, card, intrinsic);
re.setLayer(ReplacementLayer.Other);
re.setOverridingAbility(saExile);
ReplacementEffect cardre = card.addReplacementEffect(re);
if (!intrinsic) {
kws.addReplacement(cardre);
}
} else if (keyword.equals("Unleash")) { } else if (keyword.equals("Unleash")) {
String effect = "DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Unleash (" + Keyword.getInstance(keyword).getReminderText() + ")"; String effect = "DB$ PutCounter | Defined$ Self | CounterType$ P1P1 | CounterNum$ 1 | SpellDescription$ Unleash (" + Keyword.getInstance(keyword).getReminderText() + ")";

View File

@@ -84,6 +84,17 @@ public class ReplaceMoved extends ReplacementEffect {
} }
} }
if (hasParam("Fizzle")) {
// if Replacement look for Fizzle
if (!runParams.containsKey("Fizzle")) {
return false;
}
Boolean val = (Boolean) runParams.get("Fizzle");
if ("True".equals(getParam("Fizzle")) != val) {
return false;
}
}
if (hasParam("Cause")) { if (hasParam("Cause")) {
if (!runParams.containsKey("Cause")) { if (!runParams.containsKey("Cause")) {
return false; return false;

View File

@@ -595,26 +595,6 @@ public class MagicStack /* extends MyObservable */ implements Iterable<SpellAbil
else if (sa.isAftermath()) { else if (sa.isAftermath()) {
game.getAction().exile(source, sa, Maps.newHashMap()); game.getAction().exile(source, sa, Maps.newHashMap());
} }
else if (source.hasKeyword("Rebound")
&& !fizzle
&& source.getCastFrom() == ZoneType.Hand
&& game.getZoneOf(source).is(ZoneType.Stack)
&& source.getOwner().equals(source.getController())) //"If you cast this spell from your hand"
{
//Move rebounding card to exile
source = game.getAction().exile(source, null, Maps.newHashMap());
source.setSVar("ReboundAbilityTrigger", "DB$ Play | Defined$ Self "
+ "| WithoutManaCost$ True | Optional$ True");
//Setup a Rebound-trigger
final Trigger reboundTrigger = forge.game.trigger.TriggerHandler.parseTrigger("Mode$ Phase "
+ "| Phase$ Upkeep | ValidPlayer$ You | OptionalDecider$ You | Execute$ ReboundAbilityTrigger "
+ "| TriggerDescription$ At the beginning of your next upkeep, you may cast " + source.toString()
+ " without paying it's manacost.", source, true);
game.getTriggerHandler().registerDelayedTrigger(reboundTrigger);
}
else if (!source.isCopiedSpell() && else if (!source.isCopiedSpell() &&
(source.isInstant() || source.isSorcery() || fizzle) && (source.isInstant() || source.isSorcery() || fizzle) &&
source.isInZone(ZoneType.Stack)) { source.isInZone(ZoneType.Stack)) {