diff --git a/forge-game/src/main/java/forge/game/cost/CostExileFromStack.java b/forge-game/src/main/java/forge/game/cost/CostExileFromStack.java index d04501e37f3..196c3a9c793 100644 --- a/forge-game/src/main/java/forge/game/cost/CostExileFromStack.java +++ b/forge-game/src/main/java/forge/game/cost/CostExileFromStack.java @@ -112,6 +112,7 @@ public class CostExileFromStack extends CostPart { if (si != null) { game.getStack().remove(si); } + game.getAction().exile(sa.getHostCard(), null); } return true; } diff --git a/forge-gui/res/cardsfolder/upcoming/dragons_approach.txt b/forge-gui/res/cardsfolder/upcoming/dragons_approach.txt new file mode 100644 index 00000000000..3e2ce2cc117 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/dragons_approach.txt @@ -0,0 +1,7 @@ +Name:Dragon's Approach +ManaCost:2 R +Types:Sorcery +K:A deck can have any number of cards named CARDNAME. +A:SP$ DealDamage | Cost$ 2 R | Defined$ Player.Opponent | NumDmg$ 3 | SubAbility$ DBSearch | SpellDescription$ CARDNAME deals 3 damage to each opponent. You may exile CARDNAME and four cards named Dragon's Approach from your graveyard. If you do, search your library for a Dragon creature card, put it onto the battlefield, then shuffle. +SVar:DBSearch:DB$ ChangeZone | UnlessCost$ ExileFromGrave<4/Card.namedDragon's Approach> ExileFromStack<1/Card.Self> | UnlessSwitched$ True | UnlessPayer$ You | Origin$ Library | Destination$ Battlefield | ChangeType$ Creature.Dragon | ChangeNum$ 1 | SpellDescription$ Search your library for a Dragon creature card, put it onto the battlefield, then shuffle. +Oracle:Dragon’s Approach deals 3 damage to each opponent. You may exile Dragon’s Approach and four cards named Dragon’s Approach from your graveyard. If you do, search your library for a Dragon creature card, put it onto the battlefield, then shuffle.\nA deck can have any number of cards named Dragon’s Approach. diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 7f5fcc3ba2b..d116656f420 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -5,6 +5,8 @@ import java.util.ArrayList; import java.util.List; import forge.ImageKeys; +import forge.game.cost.*; +import forge.game.spellability.SpellAbilityStackInstance; import org.apache.commons.lang3.StringUtils; import com.google.common.collect.Iterables; @@ -27,31 +29,6 @@ import forge.game.card.CardView; import forge.game.card.CardZoneTable; import forge.game.card.CounterEnumType; import forge.game.card.CounterType; -import forge.game.cost.Cost; -import forge.game.cost.CostAddMana; -import forge.game.cost.CostAdjustment; -import forge.game.cost.CostDamage; -import forge.game.cost.CostDiscard; -import forge.game.cost.CostDraw; -import forge.game.cost.CostExile; -import forge.game.cost.CostFlipCoin; -import forge.game.cost.CostGainControl; -import forge.game.cost.CostGainLife; -import forge.game.cost.CostMill; -import forge.game.cost.CostPart; -import forge.game.cost.CostPartMana; -import forge.game.cost.CostPartWithList; -import forge.game.cost.CostPayEnergy; -import forge.game.cost.CostPayLife; -import forge.game.cost.CostPutCardToLib; -import forge.game.cost.CostPutCounter; -import forge.game.cost.CostRemoveAnyCounter; -import forge.game.cost.CostRemoveCounter; -import forge.game.cost.CostReturn; -import forge.game.cost.CostReveal; -import forge.game.cost.CostSacrifice; -import forge.game.cost.CostTapType; -import forge.game.cost.PaymentDecision; import forge.game.mana.ManaConversionMatrix; import forge.game.mana.ManaCostBeingPaid; import forge.game.player.Player; @@ -455,6 +432,54 @@ public class HumanPlay { } } } + else if (part instanceof CostExileFromStack) { + CostExileFromStack costExile = (CostExileFromStack) part; + + final List saList = new ArrayList<>(); + final List descList = new ArrayList<>(); + + for (final SpellAbilityStackInstance si : p.getGame().getStack()) { + final Card stC = si.getSourceCard(); + final SpellAbility stSA = si.getSpellAbility(true).getRootAbility(); + if (stC.isValid(part.getType().split(";"), p, source, sourceAbility) && stSA.isSpell()) { + saList.add(stSA); + if (stC.isCopiedSpell()) { + descList.add(stSA.getStackDescription() + " (Copied Spell)"); + } else { + descList.add(stSA.getStackDescription()); + } + } + } + + List payList = new ArrayList<>(); + if (part.getType().equals("All")) { + payList.addAll(saList); + } else { + final int c = getAmountFromPart(part, source, sourceAbility); + + if (saList.size() < c) { + return false; + } + + for (int i = 0; i < c; i++) { + //Have to use the stack descriptions here because some copied spells have no description otherwise + final String o = controller.getGui().oneOrNone(Localizer.getInstance().getMessage("lblExileFromStack"), descList); + + if (o != null) { + final SpellAbility toExile = saList.get(descList.indexOf(o)); + + saList.remove(toExile); + descList.remove(o); + + payList.add(toExile); + } else { + return false; + } + } + } + + costExile.payAsDecided(p, PaymentDecision.spellabilities(payList), sourceAbility); + } else if (part instanceof CostPutCardToLib) { int amount = Integer.parseInt(part.getAmount()); final ZoneType from = ((CostPutCardToLib) part).getFrom();