diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index cca0013b713..d3b8e20eb9b 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1261,12 +1261,12 @@ public class GameAction { return true; } - public final boolean sacrifice(final Card c, final SpellAbility source) { + public final Card sacrifice(final Card c, final SpellAbility source) { if (!c.canBeSacrificedBy(source)) { - return false; + return null; } - this.sacrificeDestroy(c); + final Card newCard = this.sacrificeDestroy(c); // Play the Sacrifice sound game.fireEvent(new GameEventCardSacrificed()); @@ -1276,7 +1276,7 @@ public class GameAction { runParams.put("Card", c); runParams.put("Cause", source); game.getTriggerHandler().runTrigger(TriggerType.Sacrificed, runParams, false); - return true; + return newCard; } /** @@ -1358,7 +1358,8 @@ public class GameAction { runParams.put("Causer", activator); game.getTriggerHandler().runTrigger(TriggerType.Destroyed, runParams, false); - return this.sacrificeDestroy(c); + final Card sacrificed = this.sacrificeDestroy(c); + return sacrificed != null; } /** @@ -1413,11 +1414,12 @@ public class GameAction { * * @param c * a {@link forge.game.card.Card} object. - * @return a boolean. + * @return the sacrificed Card in its new location, or {@code null} if the + * sacrifice wasn't successful. */ - public final boolean sacrificeDestroy(final Card c) { + public final Card sacrificeDestroy(final Card c) { if (!c.isInPlay()) { - return false; + return null; } boolean persist = (c.hasKeyword("Persist") && c.getCounters(CounterType.M1M1) == 0) && !c.isToken(); @@ -1464,7 +1466,7 @@ public class GameAction { game.getStack().addSimultaneousStackEntry(undyingAb); } - return true; + return newCard; } // sacrificeDestroy() public void reveal(Collection cards, Player cardOwner) { diff --git a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java index 0493d50609f..73c541cd417 100644 --- a/forge-game/src/main/java/forge/game/ability/AbilityUtils.java +++ b/forge-game/src/main/java/forge/game/ability/AbilityUtils.java @@ -241,22 +241,37 @@ public class AbilityUtils { } } else { List list = null; - if (defined.startsWith("Sacrificed")) { + if (defined.startsWith("SacrificedCards")) { + list = sa.getRootAbility().getPaidList("SacrificedCards"); + } + else if (defined.startsWith("Sacrificed")) { list = sa.getRootAbility().getPaidList("Sacrificed"); } + else if (defined.startsWith("DiscardedCards")) { + list = sa.getRootAbility().getPaidList("DiscardedCards"); + } else if (defined.startsWith("Discarded")) { list = sa.getRootAbility().getPaidList("Discarded"); } + else if (defined.startsWith("ExiledCards")) { + list = sa.getRootAbility().getPaidList("ExiledCards"); + } else if (defined.startsWith("Exiled")) { list = sa.getRootAbility().getPaidList("Exiled"); } + else if (defined.startsWith("TappedCards")) { + list = sa.getRootAbility().getPaidList("TappedCards"); + } else if (defined.startsWith("Tapped")) { list = sa.getRootAbility().getPaidList("Tapped"); } + else if (defined.startsWith("UntappedCards")) { + list = sa.getRootAbility().getPaidList("UntappedCards"); + } else if (defined.startsWith("Untapped")) { list = sa.getRootAbility().getPaidList("Untapped"); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java index 09ca278ae96..5cb78f645c0 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DestroyEffect.java @@ -96,7 +96,7 @@ public class DestroyEffect extends SpellAbilityEffect { boolean destroyed = false; final Card lki = CardUtil.getLKICopy(tgtC); if (sac) { - destroyed = game.getAction().sacrifice(tgtC, sa); + destroyed = game.getAction().sacrifice(tgtC, sa) != null; } else if (noRegen) { destroyed = game.getAction().destroyNoRegeneration(tgtC, sa); } else { @@ -115,7 +115,7 @@ public class DestroyEffect extends SpellAbilityEffect { if (unTgtC.isInPlay()) { boolean destroyed = false; if (sac) { - destroyed = game.getAction().sacrifice(unTgtC, sa); + destroyed = game.getAction().sacrifice(unTgtC, sa) != null; } else if (noRegen) { destroyed = game.getAction().destroyNoRegeneration(unTgtC, sa); } else { diff --git a/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java b/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java index e103e19b1e8..da0f8af14bd 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/DiscardEffect.java @@ -104,7 +104,7 @@ public class DiscardEffect extends SpellAbilityEffect { if (runDiscard) { final List toDiscard = AbilityUtils.getDefinedCards(source, sa.getParam("DefinedCards"), sa); for (final Card c : toDiscard) { - boolean hasDiscarded = p.discard(c, sa); + boolean hasDiscarded = p.discard(c, sa) != null; if (hasDiscarded) { discarded.add(c); } @@ -122,7 +122,7 @@ public class DiscardEffect extends SpellAbilityEffect { if (mode.equals("Hand")) { boolean shouldRemember = sa.hasParam("RememberDiscarded"); for(Card c : Lists.newArrayList(p.getCardsIn(ZoneType.Hand))) { // without copying will get concurrent modification exception - boolean hasDiscarded = p.discard(c, sa); + boolean hasDiscarded = p.discard(c, sa) != null; if( hasDiscarded && shouldRemember ) source.addRemembered(c); } @@ -161,7 +161,7 @@ public class DiscardEffect extends SpellAbilityEffect { break; final Card disc = Aggregates.random(list); - if ( p.discard(disc, sa) ) + if (p.discard(disc, sa) != null) discarded.add(disc); list.remove(disc); } diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java index 68b02e75a6f..1e951c49c66 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeAllEffect.java @@ -62,7 +62,7 @@ public class SacrificeAllEffect extends SpellAbilityEffect { } for (int i = 0; i < list.size(); i++) { - if (game.getAction().sacrifice(list.get(i), sa) && remSacrificed) { + if (game.getAction().sacrifice(list.get(i), sa) != null && remSacrificed) { card.addRemembered(list.get(i)); } } diff --git a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java index 9c8d3df6474..2eca6e53841 100644 --- a/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java +++ b/forge-game/src/main/java/forge/game/ability/effects/SacrificeEffect.java @@ -64,7 +64,7 @@ public class SacrificeEffect extends SpellAbilityEffect { if (valid.equals("Self")) { if (game.getZoneOf(card).is(ZoneType.Battlefield)) { - if (game.getAction().sacrifice(card, sa) && remSacrificed) { + if (game.getAction().sacrifice(card, sa) != null && remSacrificed) { card.addRemembered(card); } } @@ -89,7 +89,7 @@ public class SacrificeEffect extends SpellAbilityEffect { for(Card sac : choosenToSacrifice) { final Card lKICopy = CardUtil.getLKICopy(sac); - boolean wasSacrificed = !destroy && game.getAction().sacrifice(sac, sa); + boolean wasSacrificed = !destroy && game.getAction().sacrifice(sac, sa) != null; boolean wasDestroyed = destroy && game.getAction().destroy(sac, sa); // Run Devour Trigger if (devour) { diff --git a/forge-game/src/main/java/forge/game/cost/CostDiscard.java b/forge-game/src/main/java/forge/game/cost/CostDiscard.java index 1508b028a6a..df4bf50e126 100644 --- a/forge-game/src/main/java/forge/game/cost/CostDiscard.java +++ b/forge-game/src/main/java/forge/game/cost/CostDiscard.java @@ -150,17 +150,20 @@ public class CostDiscard extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { - targetCard.getController().discard(targetCard, ability); + protected Card doPayment(SpellAbility ability, Card targetCard) { + return targetCard.getController().discard(targetCard, ability); } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Discarded"; } + public String getHashForCardList() { + return "DiscardedCards"; + } @Override public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostExile.java b/forge-game/src/main/java/forge/game/cost/CostExile.java index 6033b7193e0..b777ee04fbd 100644 --- a/forge-game/src/main/java/forge/game/cost/CostExile.java +++ b/forge-game/src/main/java/forge/game/cost/CostExile.java @@ -194,23 +194,24 @@ public class CostExile extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { - Game game = targetCard.getGame(); - - game.getAction().exile(targetCard); + protected Card doPayment(SpellAbility ability, Card targetCard) { + final Game game = targetCard.getGame(); + return game.getAction().exile(targetCard); } - public static final String HashListKey = "Exiled"; + public static final String HashLKIListKey = "Exiled"; + public static final String HashCardListKey = "ExiledCards"; /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { - // TODO Auto-generated method stub - return HashListKey; + public String getHashForLKIList() { + return HashLKIListKey; + } + @Override + public String getHashForCardList() { + return HashCardListKey; } - - public T accept(ICostVisitor visitor) { return visitor.visit(this); diff --git a/forge-game/src/main/java/forge/game/cost/CostExiledMoveToGrave.java b/forge-game/src/main/java/forge/game/cost/CostExiledMoveToGrave.java index 8194795e093..9b12c0e61b7 100644 --- a/forge-game/src/main/java/forge/game/cost/CostExiledMoveToGrave.java +++ b/forge-game/src/main/java/forge/game/cost/CostExiledMoveToGrave.java @@ -69,9 +69,13 @@ public class CostExiledMoveToGrave extends CostPartWithList { * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "MovedToGrave"; } + @Override + public String getHashForCardList() { + return "MovedToGraveCards"; + } /* * (non-Javadoc) @@ -107,8 +111,8 @@ public class CostExiledMoveToGrave extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { - targetCard.getGame().getAction().moveToGraveyard(targetCard); + protected Card doPayment(SpellAbility ability, Card targetCard) { + return targetCard.getGame().getAction().moveToGraveyard(targetCard); } public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostFlipCoin.java b/forge-game/src/main/java/forge/game/cost/CostFlipCoin.java index 16199967055..5b5dfefd038 100644 --- a/forge-game/src/main/java/forge/game/cost/CostFlipCoin.java +++ b/forge-game/src/main/java/forge/game/cost/CostFlipCoin.java @@ -41,9 +41,13 @@ public class CostFlipCoin extends CostPartWithList { * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Flipped"; } + @Override + public String getHashForCardList() { + return "FlippedCards"; + } /* * (non-Javadoc) @@ -66,10 +70,11 @@ public class CostFlipCoin extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { + protected Card doPayment(SpellAbility ability, Card targetCard) { final Player activator = ability.getActivatingPlayer(); int i = FlipCoinEffect.getFilpMultiplier(activator); FlipCoinEffect.flipCoinCall(activator, ability, i); + return targetCard; } public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostGainControl.java b/forge-game/src/main/java/forge/game/cost/CostGainControl.java index e1b26f7170c..dd49095f33a 100644 --- a/forge-game/src/main/java/forge/game/cost/CostGainControl.java +++ b/forge-game/src/main/java/forge/game/cost/CostGainControl.java @@ -88,17 +88,22 @@ public class CostGainControl extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { + protected Card doPayment(SpellAbility ability, Card targetCard) { targetCard.setController(ability.getActivatingPlayer(), ability.getActivatingPlayer().getGame().getNextTimestamp()); + return targetCard; } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "ControllGained"; // why the hell double "L"? } + @Override + public String getHashForCardList() { + return "ControlGainedCards"; + } public T accept(ICostVisitor visitor) { return visitor.visit(this); diff --git a/forge-game/src/main/java/forge/game/cost/CostMill.java b/forge-game/src/main/java/forge/game/cost/CostMill.java index 198dae7211e..1094e68acb2 100644 --- a/forge-game/src/main/java/forge/game/cost/CostMill.java +++ b/forge-game/src/main/java/forge/game/cost/CostMill.java @@ -45,9 +45,13 @@ public class CostMill extends CostPartWithList { * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Milled"; } + @Override + public String getHashForCardList() { + return "MilledCards"; + } /* * (non-Javadoc) @@ -106,8 +110,8 @@ public class CostMill extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { - targetCard.getGame().getAction().moveToGraveyard(targetCard); + protected Card doPayment(SpellAbility ability, Card targetCard) { + return targetCard.getGame().getAction().moveToGraveyard(targetCard); } public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostPartMana.java b/forge-game/src/main/java/forge/game/cost/CostPartMana.java index 8a8664422aa..2db27008450 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPartMana.java +++ b/forge-game/src/main/java/forge/game/cost/CostPartMana.java @@ -116,8 +116,8 @@ public class CostPartMana extends CostPart { } public ManaCost getManaCostFor(SpellAbility sa) { - if ( isExiledCreatureCost() && !sa.getPaidList(CostExile.HashListKey).isEmpty()) // back from the brink - return sa.getPaidList(CostExile.HashListKey).get(0).getManaCost(); + if ( isExiledCreatureCost() && !sa.getPaidList(CostExile.HashLKIListKey).isEmpty()) // back from the brink + return sa.getPaidList(CostExile.HashLKIListKey).get(0).getManaCost(); else return getManaToPay(); } diff --git a/forge-game/src/main/java/forge/game/cost/CostPartWithList.java b/forge-game/src/main/java/forge/game/cost/CostPartWithList.java index 42d160432e8..08eabe9a674 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPartWithList.java +++ b/forge-game/src/main/java/forge/game/cost/CostPartWithList.java @@ -17,22 +17,25 @@ */ package forge.game.cost; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +import com.google.common.collect.Lists; + import forge.game.card.Card; import forge.game.card.CardUtil; import forge.game.player.Player; import forge.game.spellability.SpellAbility; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - /** * The Class CostPartWithList. */ public abstract class CostPartWithList extends CostPart { - /** The list. */ - private final List list = new ArrayList(); + /** The lists: one for LKI, one for the actual cards. */ + private final List lkiList = Lists.newArrayList(), + cardList = Lists.newArrayList(); // set is here because executePayment() adds card to list, while ai's decide payment does the same thing. // set allows to avoid duplication @@ -41,19 +44,20 @@ public abstract class CostPartWithList extends CostPart { * * @return the list */ - public final List getList() { - return this.list; + public final List getLKIList() { + return this.lkiList; + } + + public final List getCardList() { + return this.cardList; } /** * Reset list. */ - public final void resetList() { - this.list.clear(); - } - - protected final void addToList(final Card c) { - this.list.add(c); + public final void resetLists() { + this.lkiList.clear(); + this.cardList.clear(); } /** @@ -65,9 +69,13 @@ public abstract class CostPartWithList extends CostPart { * the hash */ public final void reportPaidCardsTo(final SpellAbility sa) { - final String paymentMethod = getHashForList(); - for (final Card card : this.list) { - sa.addCostToHashList(card, paymentMethod); + final String lkiPaymentMethod = getHashForLKIList(); + for (final Card card : this.lkiList) { + sa.addCostToHashList(card, lkiPaymentMethod); + } + final String cardPaymentMethod = getHashForCardList(); + for (final Card card : this.cardList) { + sa.addCostToHashList(card, cardPaymentMethod); } } @@ -94,16 +102,18 @@ public abstract class CostPartWithList extends CostPart { } public final boolean executePayment(SpellAbility ability, Card targetCard) { - this.list.add(CardUtil.getLKICopy(targetCard)); - doPayment(ability, targetCard); + this.lkiList.add(CardUtil.getLKICopy(targetCard)); + final Card newCard = doPayment(ability, targetCard); + this.cardList.add(newCard); return true; } // always returns true, made this to inline with return public final boolean executePayment(SpellAbility ability, Collection targetCards) { if(canPayListAtOnce()) { // This is used by reveal. Without it when opponent would reveal hand, you'll get N message boxes. - this.list.addAll(targetCards); - doListPayment(ability, targetCards); + this.lkiList.addAll(targetCards); + final Collection newCards = doListPayment(ability, targetCards); + this.cardList.addAll(newCards); return true; } for(Card c: targetCards) @@ -111,16 +121,23 @@ public abstract class CostPartWithList extends CostPart { return true; } - protected abstract void doPayment(SpellAbility ability, Card targetCard); + /** + * Do a payment with a single card. + * @param ability the {@link SpellAbility} to pay for. + * @param targetCard the {@link Card} to pay with. + * @return The physical card after the payment. + */ + protected abstract Card doPayment(SpellAbility ability, Card targetCard); // Overload these two only together, set to true and perform payment on list protected boolean canPayListAtOnce() { return false; } - protected void doListPayment(SpellAbility ability, Collection targetCards) { }; + protected Collection doListPayment(SpellAbility ability, Collection targetCards) { return Collections.emptyList(); }; /** * TODO: Write javadoc for this method. * @return */ - public abstract String getHashForList(); + public abstract String getHashForLKIList(); + public abstract String getHashForCardList(); @Override public boolean payAsDecided(Player ai, PaymentDecision decision, SpellAbility ability) { diff --git a/forge-game/src/main/java/forge/game/cost/CostPayment.java b/forge-game/src/main/java/forge/game/cost/CostPayment.java index 51dd671fbeb..d844d0a20ed 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPayment.java +++ b/forge-game/src/main/java/forge/game/cost/CostPayment.java @@ -144,7 +144,7 @@ public class CostPayment { // this clears lists used for undo. for (final CostPart part1 : this.paidCostParts) { if (part1 instanceof CostPartWithList) { - ((CostPartWithList) part1).resetList(); + ((CostPartWithList) part1).resetLists(); } } return true; @@ -176,7 +176,7 @@ public class CostPayment { } // abilities care what was used to pay for them if( part instanceof CostPartWithList ) { - ((CostPartWithList) part).resetList(); + ((CostPartWithList) part).resetLists(); } } return true; diff --git a/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java b/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java index f05a471ee88..4c09c6c3e15 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java +++ b/forge-game/src/main/java/forge/game/cost/CostPutCardToLib.java @@ -133,9 +133,13 @@ public class CostPutCardToLib extends CostPartWithList { * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "CardPutToLib"; } + @Override + public String getHashForCardList() { + return "CardPutToLibCards"; + } /* * (non-Javadoc) @@ -195,8 +199,8 @@ public class CostPutCardToLib extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { - targetCard.getGame().getAction().moveToLibrary(targetCard, Integer.parseInt(getLibPos())); + protected Card doPayment(SpellAbility ability, Card targetCard) { + return targetCard.getGame().getAction().moveToLibrary(targetCard, Integer.parseInt(getLibPos())); } diff --git a/forge-game/src/main/java/forge/game/cost/CostPutCounter.java b/forge-game/src/main/java/forge/game/cost/CostPutCounter.java index ba7f93d70c5..49ad73c9e8f 100644 --- a/forge-game/src/main/java/forge/game/cost/CostPutCounter.java +++ b/forge-game/src/main/java/forge/game/cost/CostPutCounter.java @@ -112,7 +112,7 @@ public class CostPutCounter extends CostPartWithList { if(this.payCostFromSource()) source.subtractCounter(this.counter, this.lastPaidAmount); else - for (final Card c : this.getList()) { + for (final Card c : this.getCardList()) { c.subtractCounter(this.counter, 1); } } @@ -177,8 +177,9 @@ public class CostPutCounter extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard){ + protected Card doPayment(SpellAbility ability, Card targetCard){ targetCard.addCounter(this.getCounter(), 1, false); + return targetCard; } protected void executePayment(SpellAbility ability, Card targetCard, int c) { @@ -196,9 +197,13 @@ public class CostPutCounter extends CostPartWithList { @Override - public String getHashForList() { + public String getHashForLKIList() { return "CounterPut"; } + @Override + public String getHashForCardList() { + return "CounterPutCards"; + } public T accept(ICostVisitor visitor) { return visitor.visit(this); diff --git a/forge-game/src/main/java/forge/game/cost/CostRemoveAnyCounter.java b/forge-game/src/main/java/forge/game/cost/CostRemoveAnyCounter.java index 636ad988b71..0cfa52f52e7 100644 --- a/forge-game/src/main/java/forge/game/cost/CostRemoveAnyCounter.java +++ b/forge-game/src/main/java/forge/game/cost/CostRemoveAnyCounter.java @@ -60,9 +60,13 @@ public class CostRemoveAnyCounter extends CostPartWithList { * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "CounterRemove"; } + @Override + public String getHashForCardList() { + return "CounterRemoveCards"; + } /** * Gets the counter. @@ -146,8 +150,9 @@ public class CostRemoveAnyCounter extends CostPartWithList { } @Override - protected void doPayment(SpellAbility ability, Card targetCard){ + protected Card doPayment(SpellAbility ability, Card targetCard){ targetCard.subtractCounter(this.getCounter(), 1); + return targetCard; } public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java b/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java index 157e708bdaf..aa42ab59a4b 100644 --- a/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java +++ b/forge-game/src/main/java/forge/game/cost/CostRemoveCounter.java @@ -18,6 +18,7 @@ package forge.game.cost; import com.google.common.collect.Lists; + import forge.game.card.Card; import forge.game.card.CardLists; import forge.game.card.CounterType; @@ -104,8 +105,8 @@ public class CostRemoveCounter extends CostPartWithList { */ @Override public final void refund(final Card source) { - int refund = this.getList().size() == 1 ? this.cntRemoved : 1; // is wrong for Ooze Flux and Novijen Sages - for (final Card c : this.getList()) { + int refund = this.getCardList().size() == 1 ? this.cntRemoved : 1; // is wrong for Ooze Flux and Novijen Sages + for (final Card c : this.getCardList()) { c.addCounter(this.counter, refund, false); } } @@ -162,17 +163,22 @@ public class CostRemoveCounter extends CostPartWithList { } @Override - protected void doPayment(SpellAbility ability, Card targetCard){ + protected Card doPayment(SpellAbility ability, Card targetCard){ targetCard.subtractCounter(this.counter, cntRemoved); + return targetCard; } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "CounterRemove"; } + @Override + public String getHashForCardList() { + return "CounterRemoveCards"; + } public T accept(ICostVisitor visitor) { return visitor.visit(this); diff --git a/forge-game/src/main/java/forge/game/cost/CostReturn.java b/forge-game/src/main/java/forge/game/cost/CostReturn.java index 39fb11309f3..3af826f71b4 100644 --- a/forge-game/src/main/java/forge/game/cost/CostReturn.java +++ b/forge-game/src/main/java/forge/game/cost/CostReturn.java @@ -110,17 +110,21 @@ public class CostReturn extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { - targetCard.getGame().getAction().moveToHand(targetCard); + protected Card doPayment(SpellAbility ability, Card targetCard) { + return targetCard.getGame().getAction().moveToHand(targetCard); } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Returned"; } + @Override + public String getHashForCardList() { + return "ReturnedCards"; + } public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostReveal.java b/forge-game/src/main/java/forge/game/cost/CostReveal.java index 134f08ad9ef..de2998cb5ad 100644 --- a/forge-game/src/main/java/forge/game/cost/CostReveal.java +++ b/forge-game/src/main/java/forge/game/cost/CostReveal.java @@ -19,6 +19,7 @@ package forge.game.cost; import com.google.common.base.Predicate; import com.google.common.collect.Lists; + import forge.game.card.Card; import forge.game.card.CardLists; import forge.game.player.Player; @@ -147,24 +148,30 @@ public class CostReveal extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { + protected Card doPayment(SpellAbility ability, Card targetCard) { targetCard.getGame().getAction().reveal(Lists.newArrayList(targetCard), ability.getActivatingPlayer()); + return targetCard; } @Override protected boolean canPayListAtOnce() { return true; } @Override - protected void doListPayment(SpellAbility ability, Collection targetCards) { + protected Collection doListPayment(SpellAbility ability, Collection targetCards) { ability.getActivatingPlayer().getGame().getAction().reveal(targetCards, ability.getActivatingPlayer()); + return targetCards; } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Revealed"; } + @Override + public String getHashForCardList() { + return "RevealedCards"; + } // Inputs public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostSacrifice.java b/forge-game/src/main/java/forge/game/cost/CostSacrifice.java index 88c1be7ce6b..b3cc28af4d4 100644 --- a/forge-game/src/main/java/forge/game/cost/CostSacrifice.java +++ b/forge-game/src/main/java/forge/game/cost/CostSacrifice.java @@ -116,17 +116,21 @@ public class CostSacrifice extends CostPartWithList { } @Override - protected void doPayment(SpellAbility ability, Card targetCard) { - targetCard.getGame().getAction().sacrifice(targetCard, ability); + protected Card doPayment(SpellAbility ability, Card targetCard) { + return targetCard.getGame().getAction().sacrifice(targetCard, ability); } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Sacrificed"; } + @Override + public String getHashForCardList() { + return "SacrificedCards"; + } // Inputs public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostTapType.java b/forge-game/src/main/java/forge/game/cost/CostTapType.java index cc0519e170e..a70020a9185 100644 --- a/forge-game/src/main/java/forge/game/cost/CostTapType.java +++ b/forge-game/src/main/java/forge/game/cost/CostTapType.java @@ -18,6 +18,7 @@ package forge.game.cost; import com.google.common.base.Predicate; + import forge.game.card.Card; import forge.game.card.CardLists; import forge.game.card.CardPredicates.Presets; @@ -89,11 +90,11 @@ public class CostTapType extends CostPartWithList { */ @Override public final void refund(final Card source) { - for (final Card c : this.getList()) { + for (final Card c : this.getCardList()) { c.setTapped(false); } - this.getList().clear(); + this.getCardList().clear(); } /* @@ -162,17 +163,22 @@ public class CostTapType extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { + protected Card doPayment(SpellAbility ability, Card targetCard) { targetCard.tap(); + return targetCard; } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Tapped"; } + @Override + public String getHashForCardList() { + return "TappedCards"; + } // Inputs public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostUnattach.java b/forge-game/src/main/java/forge/game/cost/CostUnattach.java index 2c5f732dc42..a03fc5e30bf 100644 --- a/forge-game/src/main/java/forge/game/cost/CostUnattach.java +++ b/forge-game/src/main/java/forge/game/cost/CostUnattach.java @@ -110,14 +110,19 @@ public class CostUnattach extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { + protected Card doPayment(SpellAbility ability, Card targetCard) { targetCard.unEquipCard(targetCard.getEquipping().get(0)); + return targetCard; } @Override - public String getHashForList() { + public String getHashForLKIList() { return "Unattached"; } + @Override + public String getHashForCardList() { + return "UnattachedCards"; + } public T accept(ICostVisitor visitor) { diff --git a/forge-game/src/main/java/forge/game/cost/CostUntapType.java b/forge-game/src/main/java/forge/game/cost/CostUntapType.java index 4707fcdc704..14e74a6105a 100644 --- a/forge-game/src/main/java/forge/game/cost/CostUntapType.java +++ b/forge-game/src/main/java/forge/game/cost/CostUntapType.java @@ -84,11 +84,11 @@ public class CostUntapType extends CostPartWithList { */ @Override public final void refund(final Card source) { - for (final Card c : this.getList()) { + for (final Card c : this.getCardList()) { c.setTapped(true); } - this.getList().clear(); + this.resetLists(); } /* @@ -123,17 +123,22 @@ public class CostUntapType extends CostPartWithList { * @see forge.card.cost.CostPartWithList#executePayment(forge.card.spellability.SpellAbility, forge.Card) */ @Override - protected void doPayment(SpellAbility ability, Card targetCard) { + protected Card doPayment(SpellAbility ability, Card targetCard) { targetCard.untap(); + return targetCard; } /* (non-Javadoc) * @see forge.card.cost.CostPartWithList#getHashForList() */ @Override - public String getHashForList() { + public String getHashForLKIList() { return "Untapped"; } + @Override + public String getHashForCardList() { + return "UntappedCards"; + } public T accept(ICostVisitor visitor) { return visitor.visit(this); 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 f022b9c8c88..6afb9857e83 100644 --- a/forge-game/src/main/java/forge/game/player/Player.java +++ b/forge-game/src/main/java/forge/game/player/Player.java @@ -1591,9 +1591,9 @@ public class Player extends GameEntity implements Comparable { * a {@link forge.game.card.Card} object. * @param sa * a {@link forge.game.spellability.SpellAbility} object. - * @return a {@link forge.CardList} object. + * @return the discarded {@link Card} in its new location. */ - public final boolean discard(final Card c, final SpellAbility sa) { + public final Card discard(final Card c, final SpellAbility sa) { // TODO: This line should be moved inside CostPayment somehow /*if (sa != null) { sa.addCostToHashList(c, "Discarded"); @@ -1608,19 +1608,20 @@ public class Player extends GameEntity implements Comparable { repRunParams.put("Affected", this); if (game.getReplacementHandler().run(repRunParams) != ReplacementResult.NotReplaced) { - return false; + return null; } boolean discardToTopOfLibrary = null != sa && sa.hasParam("DiscardToTopOfLibrary"); boolean discardMadness = sa != null && sa.hasParam("Madness"); + final Card newCard; if (discardToTopOfLibrary) { - game.getAction().moveToLibrary(c, 0); + newCard = game.getAction().moveToLibrary(c, 0); // Play the Discard sound } else if (discardMadness) { - game.getAction().exile(c); + newCard = game.getAction().exile(c); } else { - game.getAction().moveToGraveyard(c); + newCard = game.getAction().moveToGraveyard(c); // Play the Discard sound } this.numDiscardedThisTurn++; @@ -1635,8 +1636,8 @@ public class Player extends GameEntity implements Comparable { runParams.put("Cause", cause); runParams.put("IsMadness", (Boolean) discardMadness); game.getTriggerHandler().runTrigger(TriggerType.Discarded, runParams, false); - return true; + return newCard; } /**