From c6106d7f58647098e82716fe7a0180d1bc02169a Mon Sep 17 00:00:00 2001 From: swordshine Date: Sun, 3 Jul 2016 08:09:31 +0000 Subject: [PATCH] - EMN: Added Lupine Prototype by Marek 14 - EMN: Added Decimator of the Provinces (Emerge) --- .../main/java/forge/ai/ComputerUtilMana.java | 8 ++++++ .../main/java/forge/game/GameActionUtil.java | 17 +++++++++++ .../src/main/java/forge/game/card/Card.java | 5 ++++ .../main/java/forge/game/card/CardUtil.java | 2 +- .../forge/game/mana/ManaCostAdjustment.java | 23 ++++++++++++++- .../forge/game/spellability/SpellAbility.java | 19 +++++++++++++ .../src/main/java/forge/player/HumanPlay.java | 28 +++++++++++++++++++ 7 files changed, 100 insertions(+), 2 deletions(-) diff --git a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java index c307662cfa6..343502ad939 100644 --- a/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java +++ b/forge-ai/src/main/java/forge/ai/ComputerUtilMana.java @@ -1289,6 +1289,14 @@ public class ComputerUtilMana { } sa.resetSacrificedAsOffering(); } + if (sa.isEmerge() && sa.getSacrificedAsEmerge() != null) { + final Card emerge = sa.getSacrificedAsEmerge(); + emerge.setUsedToPay(false); + if (costIsPaid && !test) { + sa.getHostCard().getController().getGame().getAction().sacrifice(emerge, sa); + } + sa.resetSacrificedAsEmerge(); + } } diff --git a/forge-game/src/main/java/forge/game/GameActionUtil.java b/forge-game/src/main/java/forge/game/GameActionUtil.java index 811ffa6e9cf..a67752333d9 100644 --- a/forge-game/src/main/java/forge/game/GameActionUtil.java +++ b/forge-game/src/main/java/forge/game/GameActionUtil.java @@ -285,6 +285,23 @@ public final class GameActionUtil { alternatives.add(newSA); } } + if (sa.isSpell() && keyword.startsWith("Emerge")) { + List canEmerge = sa.getHostCard().getController().getCreaturesInPlay(); + if (source.getController().hasKeyword("You can't sacrifice creatures to cast spells or activate abilities.")) { + continue; + } + if (!canEmerge.isEmpty()) { + final SpellAbility newSA = sa.copy(); + SpellAbilityRestriction sar = new SpellAbilityRestriction(); + sar.setVariables(sa.getRestrictions()); + newSA.setRestrictions(sar); + newSA.setBasicSpell(false); + newSA.setIsEmerge(true); + newSA.setPayCosts(new Cost(keyword.substring(7), false)); + newSA.setDescription(sa.getDescription() + " (Emerge)"); + alternatives.add(newSA); + } + } if (sa.hasParam("Equip") && sa instanceof AbilityActivated && keyword.equals("EquipInstantSpeed")) { final SpellAbility newSA = ((AbilityActivated) sa).getCopy(); SpellAbilityRestriction sar = new SpellAbilityRestriction(); diff --git a/forge-game/src/main/java/forge/game/card/Card.java b/forge-game/src/main/java/forge/game/card/Card.java index 2383f3ea62d..b11e5b4a89f 100644 --- a/forge-game/src/main/java/forge/game/card/Card.java +++ b/forge-game/src/main/java/forge/game/card/Card.java @@ -1788,6 +1788,11 @@ public class Card extends GameEntity implements Comparable { } } sb.append("\r\n"); + } else if (keyword.startsWith("Emerge")) { + final Cost cost = new Cost(keyword.substring(7), false); + sb.append("Emerge ").append(cost.toSimpleString()); + sb.append(" (You may cast this spell by sacrificing a creature and paying the emerge cost reduced by that creature's converted mana cost.)"); + sb.append("\r\n"); } else if (keyword.startsWith("Splice")) { final Cost cost = new Cost(keyword.substring(19), false); sb.append("Splice onto Arcane ").append(cost.toSimpleString()).append("\r\n"); 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 db9e851ca67..1cf186b5c65 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", "Surge").build(); + "Scavenge", "Bestow", "Outlast", "Dash", "Renown", "Surge", "Emerge").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/mana/ManaCostAdjustment.java b/forge-game/src/main/java/forge/game/mana/ManaCostAdjustment.java index 3308f798037..e39d863706f 100644 --- a/forge-game/src/main/java/forge/game/mana/ManaCostAdjustment.java +++ b/forge-game/src/main/java/forge/game/mana/ManaCostAdjustment.java @@ -83,7 +83,9 @@ public class ManaCostAdjustment { if (sa.isSpell() && sa.isOffering()) { // cost reduction from offerings adjustCostByOffering(cost, sa); } - + if (sa.isSpell() && sa.isEmerge()) { // cost reduction from offerings + adjustCostByEmerge(cost, sa); + } // Set cost (only used by Trinisphere) is applied last for (final StaticAbility stAb : setAbilities) { applyAbility(stAb, "SetCost", sa, cost); @@ -197,7 +199,26 @@ public class ManaCostAdjustment { sa.setSacrificedAsOffering(toSac); toSac.setUsedToPay(true); //stop it from interfering with mana input } + + private static void adjustCostByEmerge(final ManaCostBeingPaid cost, final SpellAbility sa) { + Card toSac = null; + CardCollectionView canEmerge = CardLists.filter(sa.getActivatingPlayer().getCreaturesInPlay(), CardPredicates.canBeSacrificedBy(sa)); + + final CardCollectionView toSacList = sa.getHostCard().getController().getController().choosePermanentsToSacrifice(sa, 0, 1, canEmerge, "Creature"); + + if (!toSacList.isEmpty()) { + toSac = toSacList.getFirst(); + } + else { + return; + } + + cost.decreaseGenericMana(toSac.getCMC()); + + sa.setSacrificedAsEmerge(toSac); + toSac.setUsedToPay(true); //stop it from interfering with mana input + } /** * Applies applyRaiseCostAbility ability. * 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 0390a9267c1..60bfae53865 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -95,6 +95,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private boolean delve = false; private boolean dash = false; private boolean offering = false; + private boolean emerge = false; private boolean morphup = false; private boolean manifestUp = false; private boolean cumulativeupkeep = false; @@ -123,6 +124,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit private List chosenList = null; private CardCollection tappedForConvoke = new CardCollection(); private Card sacrificedAsOffering = null; + private Card sacrificedAsEmerge = null; private int conspireInstances = 0; private HashMap sVars = new HashMap(); @@ -778,6 +780,23 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit } } + public boolean isEmerge() { + return emerge; + } + public void setIsEmerge(final boolean bEmerge) { + emerge = bEmerge; + } + + public Card getSacrificedAsEmerge() { + return sacrificedAsEmerge; + } + public void setSacrificedAsEmerge(final Card c) { + sacrificedAsEmerge = c; + } + public void resetSacrificedAsEmerge() { + sacrificedAsEmerge = null; + } + public boolean isOffering() { return offering; } diff --git a/forge-gui/src/main/java/forge/player/HumanPlay.java b/forge-gui/src/main/java/forge/player/HumanPlay.java index 3258a76c8dc..bc9da8fa046 100644 --- a/forge-gui/src/main/java/forge/player/HumanPlay.java +++ b/forge-gui/src/main/java/forge/player/HumanPlay.java @@ -718,6 +718,14 @@ public class HumanPlay { } ability.resetSacrificedAsOffering(); } + if (ability.isEmerge() && ability.getSacrificedAsEmerge() != null) { + final Card emerge = ability.getSacrificedAsEmerge(); + emerge.setUsedToPay(false); + if (!manaInputCancelled) { + ability.getHostCard().getGame().getAction().sacrifice(emerge, ability); + } + ability.resetSacrificedAsEmerge(); + } if (ability.getTappedForConvoke() != null) { for (final Card c : ability.getTappedForConvoke()) { c.setTapped(false); @@ -774,6 +782,7 @@ public class HumanPlay { } Card offering = null; + Card emerge = null; InputPayMana inpPayment; if (ability.isOffering()) { @@ -784,6 +793,14 @@ public class HumanPlay { offering = ability.getSacrificedAsOffering(); } } + if (ability.isEmerge()) { + if (ability.getSacrificedAsEmerge() == null) { + System.out.println("Sacrifice input for Emerge cancelled"); + return false; + } else { + emerge = ability.getSacrificedAsEmerge(); + } + } if (!toPay.isPaid()) { // Input is somehow clearing out the offering card? inpPayment = new InputPayManaOfCostPayment(controller, toPay, ability, activator); @@ -810,6 +827,17 @@ public class HumanPlay { ability.resetSacrificedAsOffering(); } } + if (ability.isEmerge()) { + if (ability.getSacrificedAsEmerge() == null && emerge != null) { + ability.setSacrificedAsEmerge(emerge); + } + if (ability.getSacrificedAsEmerge() != null) { + System.out.println("Finishing up Emerge"); + emerge.setUsedToPay(false); + activator.getGame().getAction().sacrifice(emerge, ability); + ability.resetSacrificedAsEmerge(); + } + } if (ability.getTappedForConvoke() != null) { for (final Card c : ability.getTappedForConvoke()) { c.setTapped(false);