diff --git a/forge-game/src/main/java/forge/game/spellability/Spell.java b/forge-game/src/main/java/forge/game/spellability/Spell.java index 4bbe33935f2..baca8b77c1e 100644 --- a/forge-game/src/main/java/forge/game/spellability/Spell.java +++ b/forge-game/src/main/java/forge/game/spellability/Spell.java @@ -17,6 +17,8 @@ */ package forge.game.spellability; +import org.apache.commons.lang3.ObjectUtils; + import forge.card.CardStateName; import forge.card.mana.ManaCost; import forge.game.Game; @@ -100,7 +102,9 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable card.setController(activator, 0); } - if (!this.getRestrictions().canPlay(getHostCard(), this)) { + card = ObjectUtils.firstNonNull(getAlternateHost(card), card); + + if (!this.getRestrictions().canPlay(card, this)) { return false; } 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 887fd94252e..2345598569d 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbility.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbility.java @@ -47,6 +47,7 @@ import forge.game.player.Player; import forge.game.player.PlayerCollection; import forge.game.replacement.ReplacementEffect; import forge.game.staticability.StaticAbility; +import forge.game.staticability.StaticAbilityCastWithFlash; import forge.game.trigger.Trigger; import forge.game.trigger.TriggerType; import forge.game.trigger.WrappedAbility; @@ -2059,17 +2060,8 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit return true; } } - final Game game = activator.getGame(); - final CardCollection allp = new CardCollection(game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)); - allp.add(host); - for (final Card ca : allp) { - for (final StaticAbility stAb : ca.getStaticAbilities()) { - if (stAb.applyAbility("CastWithFlash", host, this, activator)) { - return true; - } - } - } - return false; + + return StaticAbilityCastWithFlash.anyWithFlash(this, host, activator); } } diff --git a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java index 6c38eccddf2..069b3fed888 100644 --- a/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java +++ b/forge-game/src/main/java/forge/game/spellability/SpellAbilityRestriction.java @@ -6,12 +6,12 @@ * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. - * + * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ @@ -24,6 +24,7 @@ import forge.game.card.*; import forge.game.cost.IndividualCostPaymentInstance; import forge.game.phase.PhaseType; import forge.game.player.Player; +import forge.game.staticability.StaticAbilityCastWithFlash; import forge.game.zone.Zone; import forge.game.zone.ZoneType; import forge.util.Expressions; @@ -35,7 +36,7 @@ import java.util.Map; *

* SpellAbilityRestriction class. *

- * + * * @author Forge * @version $Id$ */ @@ -61,7 +62,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { *

* setRestrictions. *

- * + * * @param params * a {@link java.util.HashMap} object. * @since 1.0.15 @@ -321,7 +322,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { String validPlayer = this.getActivator(); return activator.isValid(validPlayer, c.getController(), c, sa); } - + public final boolean checkOtherRestrictions(final Card c, final SpellAbility sa, final Player activator) { final Game game = activator.getGame(); @@ -484,7 +485,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { *

* canPlay. *

- * + * * @param c * a {@link forge.game.card.Card} object. * @param sa @@ -503,6 +504,12 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { System.out.println(c.getName() + " Did not have activator set in SpellAbilityRestriction.canPlay()"); } + if (!StaticAbilityCastWithFlash.anyWithFlashNeedsTargeting(sa, c, activator)) { + if (!sa.canCastTiming(c, activator)) { + return false; + } + } + if (!sa.hasSVar("IsCastFromPlayEffect")) { if (!checkTimingRestrictions(c, sa)) { return false; @@ -516,7 +523,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables { if (!checkZoneRestrictions(c, sa)) { return false; } - + if (!checkOtherRestrictions(c, sa, activator)) { return false; } diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java index 8f2d8987037..8d2f5392fec 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbility.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbility.java @@ -403,24 +403,6 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone return false; } - public final boolean applyAbility(final String mode, final Card card, final SpellAbility spellAbility, final Player player) { - - // don't apply the ability if it hasn't got the right mode - if (!getParam("Mode").equals(mode)) { - return false; - } - - if (this.isSuppressed() || !this.checkConditions()) { - return false; - } - - if (mode.equals("CastWithFlash")) { - return StaticAbilityCastWithFlash.applyWithFlashAbility(this, spellAbility, card, player); - } - - return false; - } - public final boolean applyAbility(String mode, Card card, CounterType type) { // don't apply the ability if it hasn't got the right mode diff --git a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCastWithFlash.java b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCastWithFlash.java index aa52bb57c9d..08e4a883ecc 100644 --- a/forge-game/src/main/java/forge/game/staticability/StaticAbilityCastWithFlash.java +++ b/forge-game/src/main/java/forge/game/staticability/StaticAbilityCastWithFlash.java @@ -1,15 +1,57 @@ package forge.game.staticability; -import java.util.List; +import com.google.common.collect.Iterables; -import forge.game.GameObject; +import forge.game.Game; +import forge.game.GameObjectPredicates; import forge.game.card.Card; +import forge.game.card.CardCollection; import forge.game.player.Player; import forge.game.spellability.SpellAbility; import forge.game.zone.ZoneType; public class StaticAbilityCastWithFlash { - public static boolean applyWithFlashAbility(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) { + + static String MODE = "CastWithFlash"; + + public static boolean anyWithFlashNeedsTargeting(final SpellAbility sa, final Card card, final Player activator) { + final Game game = activator.getGame(); + final CardCollection allp = new CardCollection(game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)); + allp.add(card); + for (final Card ca : allp) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) { + continue; + } + if (applyWithFlashNeedsTargeting(stAb, sa, card, activator)) { + return true; + } + } + } + return false; + } + + public static boolean anyWithFlash(final SpellAbility sa, final Card card, final Player activator) { + final Game game = activator.getGame(); + final CardCollection allp = new CardCollection(game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)); + allp.add(card); + for (final Card ca : allp) { + for (final StaticAbility stAb : ca.getStaticAbilities()) { + if (!stAb.getParam("Mode").equals(MODE) || stAb.isSuppressed() || !stAb.checkConditions()) { + continue; + } + if (applyWithFlashAbility(stAb, sa, card, activator)) { + return true; + } + } + } + return false; + } + + + + + public static boolean commonParts(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) { final Card hostCard = stAb.getHostCard(); if (stAb.hasParam("ValidCard") @@ -21,32 +63,36 @@ public class StaticAbilityCastWithFlash { && !sa.isValid(stAb.getParam("ValidSA").split(","), hostCard.getController(), hostCard, null)) { return false; } - + if (stAb.hasParam("Caster") && (activator != null) && !activator.isValid(stAb.getParam("Caster"), hostCard.getController(), hostCard, null)) { return false; } + return true; + } + + public static boolean applyWithFlashNeedsTargeting(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) { + if (!commonParts(stAb, sa, card, activator)) { + return false; + } + + return stAb.hasParam("Targeting"); + } + + public static boolean applyWithFlashAbility(final StaticAbility stAb, final SpellAbility sa, final Card card, final Player activator) { + final Card hostCard = stAb.getHostCard(); + + if (!commonParts(stAb, sa, card, activator)) { + return false; + } if (stAb.hasParam("Targeting")) { if (!sa.usesTargeting()) { return false; } - boolean found = false; - String[] valids = stAb.getParam("Targeting").split(","); - for (GameObject ga : sa.getTargets()) { - if (ga.isValid(valids, hostCard.getController(), hostCard, null)) { - found = true; - break; - } - } - if (!found) { - return false; - } - } - if (stAb.hasParam("Origin")) { - List src = ZoneType.listValueOf(stAb.getParam("Origin")); - if (!src.contains(hostCard.getGame().getZoneOf(card).getZoneType())) { + String[] valids = stAb.getParam("Targeting").split(","); + if (!Iterables.any(sa.getTargets(), GameObjectPredicates.restriction(valids, hostCard.getController(), hostCard, null))) { return false; } }