StaticAbilityCastWithFlash: refactor that it can be checked before targets

This commit is contained in:
Hans Mackowiak
2020-12-05 11:34:00 +01:00
parent db77e2861c
commit f0f6f70b28
5 changed files with 87 additions and 56 deletions

View File

@@ -17,6 +17,8 @@
*/ */
package forge.game.spellability; package forge.game.spellability;
import org.apache.commons.lang3.ObjectUtils;
import forge.card.CardStateName; import forge.card.CardStateName;
import forge.card.mana.ManaCost; import forge.card.mana.ManaCost;
import forge.game.Game; import forge.game.Game;
@@ -100,7 +102,9 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
card.setController(activator, 0); card.setController(activator, 0);
} }
if (!this.getRestrictions().canPlay(getHostCard(), this)) { card = ObjectUtils.firstNonNull(getAlternateHost(card), card);
if (!this.getRestrictions().canPlay(card, this)) {
return false; return false;
} }

View File

@@ -47,6 +47,7 @@ import forge.game.player.Player;
import forge.game.player.PlayerCollection; import forge.game.player.PlayerCollection;
import forge.game.replacement.ReplacementEffect; import forge.game.replacement.ReplacementEffect;
import forge.game.staticability.StaticAbility; import forge.game.staticability.StaticAbility;
import forge.game.staticability.StaticAbilityCastWithFlash;
import forge.game.trigger.Trigger; import forge.game.trigger.Trigger;
import forge.game.trigger.TriggerType; import forge.game.trigger.TriggerType;
import forge.game.trigger.WrappedAbility; import forge.game.trigger.WrappedAbility;
@@ -2059,17 +2060,8 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
return true; return true;
} }
} }
final Game game = activator.getGame();
final CardCollection allp = new CardCollection(game.getCardsIn(ZoneType.STATIC_ABILITIES_SOURCE_ZONES)); return StaticAbilityCastWithFlash.anyWithFlash(this, host, activator);
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;
} }
} }

View File

@@ -6,12 +6,12 @@
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or * the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
@@ -24,6 +24,7 @@ import forge.game.card.*;
import forge.game.cost.IndividualCostPaymentInstance; import forge.game.cost.IndividualCostPaymentInstance;
import forge.game.phase.PhaseType; import forge.game.phase.PhaseType;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.staticability.StaticAbilityCastWithFlash;
import forge.game.zone.Zone; import forge.game.zone.Zone;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
import forge.util.Expressions; import forge.util.Expressions;
@@ -35,7 +36,7 @@ import java.util.Map;
* <p> * <p>
* SpellAbilityRestriction class. * SpellAbilityRestriction class.
* </p> * </p>
* *
* @author Forge * @author Forge
* @version $Id$ * @version $Id$
*/ */
@@ -61,7 +62,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
* <p> * <p>
* setRestrictions. * setRestrictions.
* </p> * </p>
* *
* @param params * @param params
* a {@link java.util.HashMap} object. * a {@link java.util.HashMap} object.
* @since 1.0.15 * @since 1.0.15
@@ -321,7 +322,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
String validPlayer = this.getActivator(); String validPlayer = this.getActivator();
return activator.isValid(validPlayer, c.getController(), c, sa); return activator.isValid(validPlayer, c.getController(), c, sa);
} }
public final boolean checkOtherRestrictions(final Card c, final SpellAbility sa, final Player activator) { public final boolean checkOtherRestrictions(final Card c, final SpellAbility sa, final Player activator) {
final Game game = activator.getGame(); final Game game = activator.getGame();
@@ -484,7 +485,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
* <p> * <p>
* canPlay. * canPlay.
* </p> * </p>
* *
* @param c * @param c
* a {@link forge.game.card.Card} object. * a {@link forge.game.card.Card} object.
* @param sa * @param sa
@@ -503,6 +504,12 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
System.out.println(c.getName() + " Did not have activator set in SpellAbilityRestriction.canPlay()"); 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 (!sa.hasSVar("IsCastFromPlayEffect")) {
if (!checkTimingRestrictions(c, sa)) { if (!checkTimingRestrictions(c, sa)) {
return false; return false;
@@ -516,7 +523,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
if (!checkZoneRestrictions(c, sa)) { if (!checkZoneRestrictions(c, sa)) {
return false; return false;
} }
if (!checkOtherRestrictions(c, sa, activator)) { if (!checkOtherRestrictions(c, sa, activator)) {
return false; return false;
} }

View File

@@ -403,24 +403,6 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
return false; 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) { public final boolean applyAbility(String mode, Card card, CounterType type) {
// don't apply the ability if it hasn't got the right mode // don't apply the ability if it hasn't got the right mode

View File

@@ -1,15 +1,57 @@
package forge.game.staticability; 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.Card;
import forge.game.card.CardCollection;
import forge.game.player.Player; import forge.game.player.Player;
import forge.game.spellability.SpellAbility; import forge.game.spellability.SpellAbility;
import forge.game.zone.ZoneType; import forge.game.zone.ZoneType;
public class StaticAbilityCastWithFlash { 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(); final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard") if (stAb.hasParam("ValidCard")
@@ -21,32 +63,36 @@ public class StaticAbilityCastWithFlash {
&& !sa.isValid(stAb.getParam("ValidSA").split(","), hostCard.getController(), hostCard, null)) { && !sa.isValid(stAb.getParam("ValidSA").split(","), hostCard.getController(), hostCard, null)) {
return false; return false;
} }
if (stAb.hasParam("Caster") && (activator != null) if (stAb.hasParam("Caster") && (activator != null)
&& !activator.isValid(stAb.getParam("Caster"), hostCard.getController(), hostCard, null)) { && !activator.isValid(stAb.getParam("Caster"), hostCard.getController(), hostCard, null)) {
return false; 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 (stAb.hasParam("Targeting")) {
if (!sa.usesTargeting()) { if (!sa.usesTargeting()) {
return false; 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")) { String[] valids = stAb.getParam("Targeting").split(",");
List<ZoneType> src = ZoneType.listValueOf(stAb.getParam("Origin")); if (!Iterables.any(sa.getTargets(), GameObjectPredicates.restriction(valids, hostCard.getController(), hostCard, null))) {
if (!src.contains(hostCard.getGame().getZoneOf(card).getZoneType())) {
return false; return false;
} }
} }