WithFlash: refactor into Static

This commit is contained in:
Hans Mackowiak
2020-11-30 10:50:15 +00:00
committed by Michael Kamensky
parent 779da47dcf
commit 49e7f20a41
46 changed files with 185 additions and 145 deletions

View File

@@ -697,6 +697,8 @@ public class AiController {
public AiPlayDecision canPlaySa(SpellAbility sa) {
final Card card = sa.getHostCard();
final boolean isRightTiming = sa.canCastTiming(player);
if (!checkAiSpecificRestrictions(sa)) {
return AiPlayDecision.CantPlayAi;
}
@@ -764,6 +766,9 @@ public class AiController {
return AiPlayDecision.CurseEffects;
}
if (sa instanceof SpellPermanent) {
if (!isRightTiming) {
return AiPlayDecision.AnotherTime;
}
return canPlayFromEffectAI((SpellPermanent)sa, false, true);
}
if (sa.usesTargeting() && !sa.isTargetNumberValid()) {
@@ -776,8 +781,14 @@ public class AiController {
&& !player.cantLoseForZeroOrLessLife() && player.canLoseLife()) {
return AiPlayDecision.CurseEffects;
}
if (!isRightTiming) {
return AiPlayDecision.AnotherTime;
}
return canPlaySpellBasic(card, sa);
}
if (!isRightTiming) {
return AiPlayDecision.AnotherTime;
}
return AiPlayDecision.WillPlay;
}

View File

@@ -1011,7 +1011,7 @@ public class ComputerUtilCombat {
return power;
}
for (SpellAbility ability : blocker.getAllSpellAbilities()) {
if (!(ability instanceof AbilityActivated)) {
if (!ability.isActivatedAbility()) {
continue;
}
if (ability.hasParam("ActivationPhases") || ability.hasParam("SorcerySpeed") || ability.hasParam("ActivationZone")) {
@@ -1145,7 +1145,7 @@ public class ComputerUtilCombat {
return toughness;
}
for (SpellAbility ability : blocker.getAllSpellAbilities()) {
if (!(ability instanceof AbilityActivated)) {
if (!ability.isActivatedAbility()) {
continue;
}
@@ -1368,7 +1368,7 @@ public class ComputerUtilCombat {
return power;
}
for (SpellAbility ability : attacker.getAllSpellAbilities()) {
if (!(ability instanceof AbilityActivated)) {
if (!ability.isActivatedAbility()) {
continue;
}
if (ability.hasParam("ActivationPhases") || ability.hasParam("SorcerySpeed") || ability.hasParam("ActivationZone")) {
@@ -1591,7 +1591,7 @@ public class ComputerUtilCombat {
return toughness;
}
for (SpellAbility ability : attacker.getAllSpellAbilities()) {
if (!(ability instanceof AbilityActivated)) {
if (!ability.isActivatedAbility()) {
continue;
}
@@ -2445,7 +2445,7 @@ public class ComputerUtilCombat {
final Player controller = combatant.getController();
for (Card c : controller.getCardsIn(ZoneType.Battlefield)) {
for (SpellAbility ability : c.getAllSpellAbilities()) {
if (!(ability instanceof AbilityActivated)) {
if (!ability.isActivatedAbility()) {
continue;
}
if (ability.getApi() != ApiType.Pump) {

View File

@@ -88,7 +88,8 @@ public class AttachAi extends SpellAbilityAi {
if (ai.getController().isAI()) {
advancedFlash = ((PlayerControllerAi)ai.getController()).getAi().getBooleanProperty(AiProps.FLASH_ENABLE_ADVANCED_LOGIC);
}
if (source.withFlash(ai) && source.isAura() && advancedFlash && !doAdvancedFlashAuraLogic(ai, sa, sa.getTargetCard())) {
if (!ai.canCastSorcery() && sa.canCastTiming(ai)
&& source.isAura() && advancedFlash && !doAdvancedFlashAuraLogic(ai, sa, sa.getTargetCard())) {
return false;
}

View File

@@ -63,7 +63,7 @@ public class CopySpellAbilityAi extends SpellAbilityAi {
}
}
if (top.isWrapper() || !(top instanceof SpellAbility || top instanceof AbilityActivated)) {
if (top.isWrapper() || !(top instanceof SpellAbility || top.isActivatedAbility())) {
// Shouldn't even try with triggered or wrapped abilities at this time, will crash
return false;
} else if (top.getApi() == ApiType.CopySpellAbility) {
@@ -91,7 +91,7 @@ public class CopySpellAbilityAi extends SpellAbilityAi {
AiPlayDecision decision = AiPlayDecision.CantPlaySa;
if (top instanceof Spell) {
decision = ((PlayerControllerAi) aiPlayer.getController()).getAi().canPlayFromEffectAI((Spell) topCopy, true, true);
} else if (top instanceof AbilityActivated && top.getActivatingPlayer().equals(aiPlayer)
} else if (top.isActivatedAbility() && top.getActivatingPlayer().equals(aiPlayer)
&& logic.contains("CopyActivatedAbilities")) {
decision = AiPlayDecision.WillPlay; // FIXME: we activated it once, why not again? Or bad idea?
}

View File

@@ -86,7 +86,7 @@ public class PermanentCreatureAi extends PermanentAi {
if (ai.getController().isAI()) {
advancedFlash = ((PlayerControllerAi)ai.getController()).getAi().getBooleanProperty(AiProps.FLASH_ENABLE_ADVANCED_LOGIC);
}
if (card.withFlash(ai)) {
if (!ai.canCastSorcery() && sa.canCastTiming(ai)) {
if (advancedFlash) {
return doAdvancedFlashLogic(card, ai, sa);
} else {

View File

@@ -146,7 +146,7 @@ public class SpellAbilityPicker {
return false;
}
if (sa.isSpell()) {
return !sa.getHostCard().isInstant() && !sa.getHostCard().withFlash(player);
return !sa.canCastTiming(player);
}
if (sa.isPwAbility()) {
return !sa.getHostCard().hasKeyword("CARDNAME's loyalty abilities can be activated at instant speed.");

View File

@@ -221,7 +221,6 @@ public final class GameActionUtil {
// below are for some special cases of activated abilities
if (sa.isCycling() && activator.hasKeyword("CyclingForZero")) {
for (final KeywordInterface inst : source.getKeywords()) {
// need to find the correct Keyword from which this Ability is from
if (!inst.getAbilities().contains(sa)) {
@@ -249,15 +248,6 @@ public final class GameActionUtil {
}
}
if (sa.hasParam("Equip") && activator.hasKeyword("EquipInstantSpeed")) {
final SpellAbility newSA = sa.copy(activator);
SpellAbilityRestriction sar = newSA.getRestrictions();
sar.setSorcerySpeed(false);
sar.setInstantSpeed(true);
newSA.setDescription(sa.getDescription() + " (you may activate any time you could cast an instant )");
alternatives.add(newSA);
}
return alternatives;
}

View File

@@ -180,7 +180,6 @@ public class StaticEffect {
boolean setPT = false;
String[] addHiddenKeywords = null;
boolean removeMayPlay = false;
boolean removeWithFlash = false;
if (hasParam("ChangeColorWordsTo")) {
changeColorWordsTo = getParam("ChangeColorWordsTo");
@@ -197,9 +196,6 @@ public class StaticEffect {
if (hasParam("MayPlay")) {
removeMayPlay = true;
}
if (hasParam("WithFlash")) {
removeWithFlash = true;
}
if (hasParam("IgnoreEffectCost")) {
getSource().removeChangedCardTraits(getTimestamp());
@@ -284,9 +280,6 @@ public class StaticEffect {
if (removeMayPlay) {
affectedCard.removeMayPlay(ability);
}
if (removeWithFlash) {
affectedCard.removeWithFlash(getTimestamp());
}
if (hasParam("GainTextOf")) {
affectedCard.removeTextChangeState(getTimestamp());

View File

@@ -111,8 +111,6 @@ public class Card extends GameEntity implements Comparable<Card> {
private final Map<StaticAbility, CardPlayOption> mayPlay = Maps.newHashMap();
private final Multimap<Long, Player> withFlash = HashMultimap.create();
// changes by AF animate and continuous static effects - timestamp is the key of maps
private final Map<Long, CardChangedType> changedCardTypes = Maps.newTreeMap();
private final NavigableMap<Long, String> changedCardNames = Maps.newTreeMap();
@@ -6433,21 +6431,6 @@ public class Card extends GameEntity implements Comparable<Card> {
return n;
}
public boolean withFlash(Player p) {
if (hasKeyword(Keyword.FLASH)) {
return true;
}
return withFlash.containsValue(p);
}
public void addWithFlash(Long timestamp, Iterable<Player> players) {
withFlash.putAll(timestamp, players);
}
public void removeWithFlash(Long timestamp) {
withFlash.removeAll(timestamp);
}
public boolean canBeDiscardedBy(SpellAbility sa) {
if (!isInZone(ZoneType.Hand)) {
return false;

View File

@@ -12,7 +12,6 @@ import forge.game.keyword.Keyword;
import forge.game.keyword.KeywordInterface;
import forge.game.mana.ManaCostBeingPaid;
import forge.game.player.Player;
import forge.game.spellability.AbilityActivated;
import forge.game.spellability.SpellAbility;
import forge.game.spellability.SpellAbilityPredicates;
import forge.game.spellability.TargetChoices;
@@ -468,11 +467,11 @@ public class CostAdjustment {
}
}
} else if (type.equals("Ability")) {
if (!(sa instanceof AbilityActivated) || sa.isReplacementAbility()) {
if (!sa.isActivatedAbility() || sa.isReplacementAbility()) {
return false;
}
} else if (type.equals("NonManaAbility")) {
if (!(sa instanceof AbilityActivated) || sa.isManaAbility() || sa.isReplacementAbility()) {
if (!sa.isActivatedAbility() || sa.isManaAbility() || sa.isReplacementAbility()) {
return false;
}
} else if (type.equals("Buyback")) {
@@ -488,7 +487,7 @@ public class CostAdjustment {
return false;
}
} else if (type.equals("Equip")) {
if (!(sa instanceof AbilityActivated) || !sa.hasParam("Equip")) {
if (!sa.isActivatedAbility() || !sa.hasParam("Equip")) {
return false;
}
} else if (type.equals("Flashback")) {

View File

@@ -34,9 +34,7 @@ import forge.util.collect.FCollectionView;
* @author Forge
* @version $Id$
*/
public abstract class AbilityActivated extends SpellAbility implements java.io.Serializable, Cloneable {
/** Constant <code>serialVersionUID=1L</code>. */
private static final long serialVersionUID = 1L;
public abstract class AbilityActivated extends SpellAbility implements Cloneable {
/**
* <p>
@@ -71,6 +69,8 @@ public abstract class AbilityActivated extends SpellAbility implements java.io.S
}
}
public boolean isActivatedAbility() { return true; }
/** {@inheritDoc} */
@Override
public boolean canPlay() {

View File

@@ -17,8 +17,6 @@
*/
package forge.game.spellability;
import com.google.common.collect.Sets;
import forge.card.CardStateName;
import forge.card.mana.ManaCost;
import forge.game.Game;
@@ -95,41 +93,11 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
return false;
}
boolean lkicheck = false;
// do performanceMode only for cases where the activator is different than controller
if (!Spell.performanceMode && activator != null && !card.getController().equals(activator)) {
// always make a lki copy in this case?
card = CardUtil.getLKICopy(card);
card.setController(activator, 0);
lkicheck = true;
}
Card lkiHost = getAlternateHost(card);
if (lkiHost != null) {
card = lkiHost;
lkicheck = true;
}
if (lkicheck) {
game.getTracker().freeze(); //prevent views flickering during while updating for state-based effects
game.getAction().checkStaticAbilities(false, Sets.newHashSet(card), new CardCollection(card));
}
boolean isInstant = card.isInstant();
boolean flash = card.withFlash(activator);
// reset static abilities
if (lkicheck) {
game.getAction().checkStaticAbilities(false);
// clear delayed changes, this check should not have updated the view
game.getTracker().clearDelayed();
game.getTracker().unfreeze();
}
if (!(isInstant || activator.canCastSorcery() || flash || getRestrictions().isInstantSpeed()
|| hasSVar("IsCastFromPlayEffect"))) {
return false;
}
if (!this.getRestrictions().canPlay(getHostCard(), this)) {

View File

@@ -352,6 +352,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
public boolean isSpell() { return false; }
public boolean isAbility() { return true; }
public boolean isActivatedAbility() { return false; }
public boolean isMorphUp() {
return this.hasParam("MorphUp");
@@ -1734,7 +1735,7 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
}
}
else if (incR[0].equals("Activated")) {
if (!(root instanceof AbilityActivated)) {
if (!root.isActivatedAbility()) {
return false;
}
}
@@ -2035,4 +2036,46 @@ public abstract class SpellAbility extends CardTraitBase implements ISpellAbilit
public void setXManaCostPaid(final Integer n) {
xManaCostPaid = n;
}
public boolean canCastTiming(Player activator) {
return canCastTiming(getHostCard(), activator);
}
public boolean canCastTiming(Card host, Player activator) {
// no spell or no activated ability, no check there
if (!isSpell() && !isActivatedAbility()) {
return true;
}
final Game game = activator.getGame();
if (activator.canCastSorcery() || getRestrictions().isInstantSpeed()) {
return true;
}
if (isSpell()) {
if (hasSVar("IsCastFromPlayEffect") || host.isInstant() || host.hasKeyword(Keyword.FLASH)) {
return true;
}
}
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;
}
}
}
// spells per default are sorcerySpeed
if (isSpell()) {
return false;
} else if (isActivatedAbility()) {
// Activated Abillties are instant speed per default
return !getRestrictions().isSorcerySpeed();
}
return true;
}
}

View File

@@ -503,10 +503,6 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
System.out.println(c.getName() + " Did not have activator set in SpellAbilityRestriction.canPlay()");
}
if (this.isSorcerySpeed() && !activator.canCastSorcery()) {
return false;
}
if (!sa.hasSVar("IsCastFromPlayEffect")) {
if (!checkTimingRestrictions(c, sa)) {
return false;

View File

@@ -346,7 +346,6 @@ public class StaticAbility extends CardTraitBase implements IIdentifiable, Clone
if (mode.equals("CantBeCast")) {
return StaticAbilityCantBeCast.applyCantBeCastAbility(this, card, player);
}
if (mode.equals("CantPlayLand")) {
return StaticAbilityCantBeCast.applyCantPlayLandAbility(this, card, player);
}
@@ -404,6 +403,24 @@ 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

View File

@@ -0,0 +1,56 @@
package forge.game.staticability;
import java.util.List;
import forge.game.GameObject;
import forge.game.card.Card;
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) {
final Card hostCard = stAb.getHostCard();
if (stAb.hasParam("ValidCard")
&& !card.isValid(stAb.getParam("ValidCard").split(","), hostCard.getController(), hostCard, null)) {
return false;
}
if (stAb.hasParam("ValidSA")
&& !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;
}
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<ZoneType> src = ZoneType.listValueOf(stAb.getParam("Origin"));
if (!src.contains(hostCard.getGame().getZoneOf(card).getZoneType())) {
return false;
}
}
return true;
}
}

View File

@@ -39,7 +39,6 @@ import forge.game.keyword.Keyword;
import forge.game.player.Player;
import forge.game.replacement.ReplacementEffect;
import forge.game.replacement.ReplacementHandler;
import forge.game.spellability.AbilityActivated;
import forge.game.spellability.AbilityStatic;
import forge.game.spellability.SpellAbility;
import forge.game.trigger.Trigger;
@@ -142,7 +141,6 @@ public final class StaticAbilityContinuous {
Set<Keyword> cantHaveKeyword = null;
List<Player> mayLookAt = null;
List<Player> withFlash = null;
boolean controllerMayPlay = false, mayPlayWithoutManaCost = false, mayPlayWithFlash = false;
String mayPlayAltManaCost = null;
@@ -506,9 +504,6 @@ public final class StaticAbilityContinuous {
mayPlayGrantZonePermissions = false;
}
}
if (params.containsKey("WithFlash")) {
withFlash = AbilityUtils.getDefinedPlayers(hostCard, params.get("WithFlash"), null);
}
if (params.containsKey("IgnoreEffectCost")) {
String cost = params.get("IgnoreEffectCost");
@@ -756,7 +751,7 @@ public final class StaticAbilityContinuous {
for (Card c : cardsIGainedAbilitiesFrom) {
for (SpellAbility sa : c.getSpellAbilities()) {
if (sa instanceof AbilityActivated) {
if (sa.isActivatedAbility()) {
if (loyaltyAB && !sa.isPwAbility()) {
continue;
}
@@ -865,9 +860,6 @@ public final class StaticAbilityContinuous {
if (mayLookAt != null) {
affectedCard.addMayLookAt(se.getTimestamp(), mayLookAt);
}
if (withFlash != null) {
affectedCard.addWithFlash(se.getTimestamp(), withFlash);
}
if (controllerMayPlay && (mayPlayLimit == null || stAb.getMayPlayTurn() < mayPlayLimit)) {
String mayPlayAltCost = mayPlayAltManaCost;

View File

@@ -1,9 +1,8 @@
Name:Akoum
ManaCost:no cost
Types:Plane Zendikar
S:Mode$ Continuous | EffectZone$ Command | Affected$ Enchantment | WithFlash$ Player | AffectedZone$ Exile,Graveyard,Hand,Library | Description$ Players may cast enchantment spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Enchantment | ValidSA$ Spell | EffectZone$ Command | Caster$ Player | Description$ Players may cast enchantment spells as though they had flash.
T:Mode$ PlanarDice | Result$ Chaos | TriggerZones$ Command | Execute$ RolledChaos | TriggerDescription$ Whenever you roll {CHAOS}, destroy target creature that isn't enchanted.
SVar:RolledChaos:DB$ Destroy | ValidTgts$ Creature.unenchanted | TgtPrompt$ Select target creature that isn't enchanted
SVar:Picture:http://www.wizards.com/global/images/magic/general/akoum.jpg
SVar:AIRollPlanarDieParams:Mode$ Always | OppHasCreatureInPlay$ True | RollInMain1$ True
Oracle:Players may cast enchantment spells as though they had flash.\nWhenever you roll {CHAOS}, destroy target creature that isn't enchanted.

View File

@@ -3,9 +3,8 @@ ManaCost:no cost
Types:Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Effect | Cost$ G U T | Name$ Refuge Effect | StaticAbilities$ QuickSpell | SpellDescription$ You may cast spells this turn as though they had flash.
SVar:QuickSpell:Mode$ Continuous | EffectZone$ Command | Affected$ Card | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast spells this turn as though they had flash.
SVar:QuickSpell:Mode$ CastWithFlash | ValidCard$ Card | ValidSA$ Spell | EffectZone$ Command | Caster$ You | Description$ You may cast spells this turn as though they had flash.
SVar:PlayMain1:TRUE
AI:RemoveDeck:Random
AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/alchemists_refuge.jpg
Oracle:{T}: Add {C}.\n{G}{U}, {T}: You may cast spells this turn as though they had flash.

View File

@@ -3,7 +3,7 @@ ManaCost:2 R
Types:Enchantment Aura
K:Enchant creature
A:SP$ Attach | Cost$ 2 R | ValidTgts$ Creature | AILogic$ Pump
S:Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | AffectedZone$ Hand,Graveyard,Exile,Command,Library | WithFlash$ You | Condition$ Ferocious | Description$ Ferocious — If you control a creature with power 4 or greater, you may cast Dragon Grip as though it had flash.
S:Mode$ CastWithFlash | ValidCard$ Card.Self | ValidSA$ Spell | EffectZone$ All | Caster$ You | Condition$ Ferocious | Description$ Ferocious — If you control a creature with power 4 or greater, you may cast Dragon Grip as though it had flash.
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ First Strike | AddPower$ 2 | Description$ Enchanted creature gets +2/+0 and has first strike.
SVar:Picture:http://www.wizards.com/global/images/magic/general/dragon_grip.jpg
Oracle:Ferocious — If you control a creature with power 4 or greater, you may cast Dragon Grip as though it had flash. (You may cast it any time you could cast an instant.)\nEnchant creature\nEnchanted creature gets +2/+0 and has first strike.

View File

@@ -3,7 +3,7 @@ ManaCost:no cost
Types:Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Effect | Cost$ 1 T Sac<1/CARDNAME> | Name$ Emergence Zone Effect | StaticAbilities$ QuickSpell | SpellDescription$ You may cast spells this turn as though they had flash.
SVar:QuickSpell:Mode$ Continuous | EffectZone$ Command | Affected$ Card | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast spells this turn as though they had flash.
SVar:QuickSpell:Mode$ CastWithFlash | ValidCard$ Card | ValidSA$ Spell | EffectZone$ Command | Caster$ You | Description$ You may cast spells this turn as though they had flash.
SVar:PlayMain1:TRUE
AI:RemoveDeck:Random
AI:RemoveDeck:All

View File

@@ -2,7 +2,6 @@ Name:Hungering Yeti
ManaCost:4 R
Types:Creature Yeti
PT:4/4
S:Mode$ Continuous | Affected$ Card.Self | EffectZone$ All | WithFlash$ You | AffectedZone$ Hand,Graveyard,Exile,Command,Library | IsPresent$ Permanent.Green+YouCtrl,Permanent.Blue+YouCtrl | Description$ As long as you control a green or blue permanent, you may cast CARDNAME as though it had flash.
S:Mode$ CastWithFlash | ValidCard$ Card.Self | ValidSA$ Spell | EffectZone$ All | Caster$ You | IsPresent$ Permanent.Green+YouCtrl,Permanent.Blue+YouCtrl | Description$ As long as you control a green or blue permanent, you may cast CARDNAME as though it had flash.
DeckHints:Color$Green|Blue
SVar:Picture:http://www.wizards.com/global/images/magic/general/hungering_yeti.jpg
Oracle:As long as you control a green or blue permanent, you may cast Hungering Yeti as though it had flash. (You may cast it any time you could cast an instant.)

View File

@@ -4,6 +4,5 @@ Types:Creature Dragon
PT:4/4
K:Flying
K:Haste
S:Mode$ Continuous | Affected$ Sorcery | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library | Description$ You may cast sorcery spells as though they had flash.
SVar:Picture:http://www.wizards.com/global/images/magic/general/hypersonic_dragon.jpg
S:Mode$ CastWithFlash | ValidCard$ Sorcery | ValidSA$ Spell | Caster$ You | Description$ You may cast sorcery spells as though they had flash.
Oracle:Flying, haste\nYou may cast sorcery spells as though they had flash. (You may cast them any time you could cast an instant.)

View File

@@ -2,6 +2,5 @@ Name:Leonin Shikari
ManaCost:1 W
Types:Creature Cat Soldier
PT:2/2
S:Mode$ Continuous | Affected$ You | AddKeyword$ EquipInstantSpeed | Description$ You may activate equip abilities any time you could cast an instant.
SVar:Picture:http://www.wizards.com/global/images/magic/general/leonin_shikari.jpg
S:Mode$ CastWithFlash | ValidSA$ Activated.Equip | Caster$ You | Description$ You may activate equip abilities any time you could cast an instant.
Oracle:You may activate equip abilities any time you could cast an instant.

View File

@@ -3,7 +3,6 @@ ManaCost:2 U U
Types:Enchantment
K:MayEffectFromOpeningHand:FromHand
SVar:FromHand:DB$ ChangeZone | Defined$ Self | Origin$ Hand | Destination$ Battlefield | SpellDescription$ If CARDNAME is in your opening hand, you may begin the game with it on the battlefield.
S:Mode$ Continuous | Affected$ Card | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Card | ValidSA$ Spell | Caster$ You | Description$ You may cast spells as though they had flash.
SVar:NonStackingEffect:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/leyline_of_anticipation.jpg
Oracle:If Leyline of Anticipation is in your opening hand, you may begin the game with it on the battlefield.\nYou may cast spells as though they had flash. (You may cast them any time you could cast an instant.)

View File

@@ -3,7 +3,6 @@ ManaCost:3 G U
Types:Creature Human Wizard
PT:2/3
S:Mode$ Continuous | Affected$ Creature.YouCtrl,Land.YouCtrl | AddHiddenKeyword$ CARDNAME untaps during each other player's untap step. | Description$ Untap all creatures and lands you control during each other player's untap step.
S:Mode$ Continuous | Affected$ Creature | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast creature spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Creature | ValidSA$ Spell | Caster$ You | Description$ You may cast creature spells as though they had flash.
SVar:UntapsEachOtherPlayerTurn:Creature,Land
SVar:Picture:http://www.wizards.com/global/images/magic/general/prophet_of_kruphix.jpg
Oracle:Untap all creatures and lands you control during each other player's untap step.\nYou may cast creature spells as though they had flash.

View File

@@ -3,7 +3,6 @@ ManaCost:1 G
Types:Creature Sliver
PT:1/1
K:Flash
S:Mode$ Continuous | Affected$ Sliver | WithFlash$ Player | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ Any player may cast Sliver spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Sliver | ValidSA$ Spell | Caster$ Player | Description$ Any player may cast Sliver spells as though they had flash.
SVar:PlayMain1:TRUE
SVar:Picture:http://www.wizards.com/global/images/magic/general/quick_sliver.jpg
Oracle:Flash\nAny player may cast Sliver spells as though they had flash.

View File

@@ -3,9 +3,8 @@ ManaCost:U
Types:Instant
A:SP$Effect | Cost$ U | Name$ Quicken effect | StaticAbilities$ QuickenStA | Triggers$ SpellCastTrig | SVars$ Quickened | SubAbility$ DBDraw | SpellDescription$ The next sorcery card you cast this turn can be cast as though it had flash.
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card.
SVar:QuickenStA:Mode$ Continuous | EffectZone$ Command | Affected$ Sorcery | AffectedZone$ Hand,Graveyard,Exile,Library | WithFlash$ You
SVar:QuickenStA:Mode$ CastWithFlash | ValidCard$ Sorcery | ValidSA$ Spell | EffectZone$ Command | Caster$ You
SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Sorcery | ValidActivatingPlayer$ You | Execute$ Quickened | Static$ True | TriggerDescription$ The next sorcery card you cast this turn can be cast as though it had flash.
SVar:Quickened:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/quicken.jpg
Oracle:The next sorcery card you cast this turn can be cast as though it had flash. (It can be cast any time you could cast an instant.)\nDraw a card.

View File

@@ -4,7 +4,7 @@ Types:Legendary Creature Human Wizard
PT:3/3
K:Flash
K:Flying
S:Mode$ Continuous | Affected$ Card.Historic+nonToken | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast historic spells as though they had flash. (Artifacts, legendaries, and Sagas are historic.)
S:Mode$ CastWithFlash | ValidCard$ Card.Historic | ValidSA$ Spell | Caster$ You | Description$ You may cast historic spells as though they had flash. (Artifacts, legendaries, and Sagas are historic.)
SVar:NonStackingEffect:True
Oracle:Flash\nFlying\nYou may cast historic spells as though they had flash. (Artifacts, legendaries, and Sagas are historic.)

View File

@@ -6,6 +6,6 @@ K:Flash
K:Flying
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ When CARDNAME enters the battlefield, target Spirit gains hexproof until end of turn.
SVar:TrigPump:DB$ Pump | ValidTgts$ Spirit | TgtPrompt$ Select target Spirit | KW$ Hexproof
S:Mode$ Continuous | EffectZone$ Battlefield | Affected$ Spirit | WithFlash$ You | AffectedZone$ Command,Exile,Graveyard,Hand,Library | Description$ You may Spirit spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Spirit | ValidSA$ Spell | Caster$ You | Description$ You may Spirit spells as though they had flash.
DeckHints:Type$Spirit
Oracle:Flash\nFlying\nWhen Rattlechains enters the battlefield, target Spirit gains hexproof until end of turn.\nYou may cast Spirit spells as though they had flash.

View File

@@ -2,6 +2,5 @@ Name:Rootwater Shaman
ManaCost:2 U
Types:Creature Merfolk Shaman
PT:2/2
S:Mode$ Continuous | Affected$ Card.Aura+withEnchant creature | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Stack | Description$ You may cast Aura spells with enchant creature as though they had flash.
SVar:Picture:http://www.wizards.com/global/images/magic/general/rootwater_shaman.jpg
S:Mode$ CastWithFlash | ValidCard$ Card.Aura+withEnchant creature | ValidSA$ Spell | Caster$ You | Description$ You may cast Aura spells with enchant creature as though they had flash.
Oracle:You may cast Aura spells with enchant creature as though they had flash.

View File

@@ -3,7 +3,7 @@ ManaCost:G
Types:Instant
K:CARDNAME can't be countered.
A:SP$ Effect | Cost$ G | Name$ Savage Summoning effect | StaticAbilities$ STFlash | Triggers$ SpellCastTrig | SVars$ SavageSummon,ExileSelf,ETBCounters,ETBAddExtraCounter,MoveToBattlefield,STCantBeCountered | SpellDescription$ The next creature card you cast this turn can be cast as though it had flash. That spell can't be countered. That creature enters the battlefield with an additional +1/+1 counter on it.
SVar:STFlash:Mode$ Continuous | EffectZone$ Command | Affected$ Card.Creature | AffectedZone$ Hand,Graveyard,Exile,Command,Library | WithFlash$ You
SVar:STFlash:Mode$ CastWithFlash | ValidCard$ Card.Creature | ValidSA$ Spell | EffectZone$ Command | Caster$ You
SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ SavageSummon | Static$ True | TriggerDescription$ The next creature card you cast this turn can be cast as though it had flash. That spell can't be countered. That creature enters the battlefield with an additional +1/+1 counter on it.
SVar:SavageSummon:DB$ Effect | StaticAbilities$ STCantBeCountered | ReplacementEffects$ ETBCounters | SVars$ ExileSelf,ETBAddExtraCounter,MoveToBattlefield | RememberObjects$ TriggeredCard | SubAbility$ ExileSelf
SVar:STCantBeCountered:Mode$ Continuous | EffectZone$ Command | Affected$ Card.IsRemembered | AddHiddenKeyword$ CARDNAME can't be countered. | AffectedZone$ Stack | Description$ That spell can't be countered.

View File

@@ -3,9 +3,8 @@ ManaCost:W
Types:Instant
A:SP$ Effect | Cost$ W | Name$ Scout's Warning effect | StaticAbilities$ ScoutFlash | Triggers$ SpellCastTrig | SVars$ WarningGiven | SubAbility$ DBDraw | SpellDescription$ The next creature card you play this turn can be played as though it had flash.
SVar:DBDraw:DB$ Draw | NumCards$ 1 | SpellDescription$ Draw a card.
SVar:ScoutFlash:Mode$ Continuous | EffectZone$ Command | Affected$ Creature | AffectedZone$ Hand,Graveyard,Exile,Library,Command | WithFlash$ You
SVar:ScoutFlash:Mode$ CastWithFlash | ValidCard$ Creature | ValidSA$ Spell | EffectZone$ Command | Caster$ You
SVar:SpellCastTrig:Mode$ SpellCast | ValidCard$ Creature | ValidActivatingPlayer$ You | Execute$ WarningGiven | Static$ True | TriggerDescription$ The next creature card you play this turn can be played as though it had flash.
SVar:WarningGiven:DB$ ChangeZone | Defined$ Self | Origin$ Command | Destination$ Exile
AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/scouts_warning.jpg
Oracle:The next creature card you play this turn can be played as though it had flash.\nDraw a card.

View File

@@ -3,6 +3,5 @@ ManaCost:3
Types:Artifact Creature Myr
PT:2/2
K:Flash
S:Mode$ Continuous | Affected$ Artifact | AffectedZone$ Exile,Graveyard,Hand,Library,Command | WithFlash$ You | Description$ You may cast artifact spells as though they had flash.
SVar:Picture:http://www.wizards.com/global/images/magic/general/shimmer_myr.jpg
S:Mode$ CastWithFlash | ValidCard$ Artifact | ValidSA$ Spell | Caster$ You | Description$ You may cast artifact spells as though they had flash.
Oracle:Flash\nYou may cast artifact spells as though they had flash.

View File

@@ -1,10 +1,9 @@
Name:Sigarda's Aid
ManaCost:W
Types:Enchantment
S:Mode$ Continuous | Affected$ Card.Aura,Card.Equipment | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command,Stack | Description$ You may cast Aura and Equipment spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Card.Aura,Card.Equipment | ValidSA$ Spell | Caster$ You | Description$ You may cast Aura and Equipment spells as though they had flash.
T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Equipment+YouCtrl | TriggerZones$ Battlefield | Execute$ TrigAttach | OptionalDecider$ You | TriggerDescription$ Whenever an Equipment enters the battlefield under your control, you may attach it to target creature you control.
SVar:TrigAttach:DB$ Attach | ValidTgts$ Creature.YouCtrl | TgtPrompt$ Target creature you control | Object$ TriggeredCard
SVar:NonStackingEffect:True
DeckHints:Type$Aura|Equipment
SVar:Picture:http://www.wizards.com/global/images/magic/general/sigardas_aid.jpg
Oracle:You may cast Aura and Equipment spells as though they had flash.\nWhenever an Equipment enters the battlefield under your control, you may attach it to target creature you control.

View File

@@ -2,6 +2,5 @@ Name:Swift Reckoning
ManaCost:1 W
Types:Sorcery
A:SP$ Destroy | Cost$ 1 W | ValidTgts$ Creature.tapped | TgtPrompt$ Select target tapped creature | SpellDescription$ Destroy target tapped creature.
S:Mode$ Continuous | EffectZone$ All | Affected$ Card.Self | AffectedZone$ Hand,Graveyard,Exile,Command,Library | WithFlash$ You | IsPresent$ Instant.YouOwn,Sorcery.YouOwn | PresentZone$ Graveyard | PresentCompare$ GE2 | Description$ Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may cast CARDNAME as though it had flash.
SVar:Picture:http://www.wizards.com/global/images/magic/general/swift_reckoning.jpg
S:Mode$ CastWithFlash | ValidCard$ Card.Self | ValidSA$ Spell | EffectZone$ All | Caster$ You | IsPresent$ Instant.YouOwn,Sorcery.YouOwn | PresentZone$ Graveyard | PresentCompare$ GE2 | Description$ Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may cast CARDNAME as though it had flash.
Oracle:Spell mastery — If there are two or more instant and/or sorcery cards in your graveyard, you may cast Swift Reckoning as though it had flash. (You may cast it any time you could cast an instant.)\nDestroy target tapped creature.

View File

@@ -2,6 +2,5 @@ Name:Tawnos
ManaCost:no cost
Types:Vanguard
HandLifeModifier:+3/-4
S:Mode$ Continuous | EffectZone$ Command | Affected$ Artifact,Creature,Enchantment | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library | Description$ You may cast artifact, creature, and enchantment spells as though they had flash.
SVar:Picture:https://downloads.cardforge.org/images/cards/VAN/Tawnos.full.jpg
S:Mode$ CastWithFlash | ValidCard$ Artifact,Creature,Enchantment | ValidSA$ Spell | EffectZone$ Command | Caster$ You | Description$ You may cast artifact, creature, and enchantment spells as though they had flash.
Oracle:Hand +3, life -4\nYou may cast artifact, creature, and enchantment spells as though they had flash.

View File

@@ -4,7 +4,7 @@ Types:Legendary Planeswalker Teferi
Loyalty:4
S:Mode$ CantBeCast | ValidCard$ Card | Caster$ Opponent | OnlySorcerySpeed$ True | Description$ Each opponent can cast spells only any time they could cast a sorcery.
A:AB$ Effect | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | StaticAbilities$ STPlay | Duration$ UntilYourNextTurn | AILogic$ Main2 | SpellDescription$ Until your next turn, you may cast sorcery spells as though they had flash.
SVar:STPlay:Mode$ Continuous | EffectZone$ Command | Affected$ Sorcery | AffectedZone$ Exile,Graveyard,Hand,Library,Command | WithFlash$ You | Description$ Until your next turn, you may cast sorcery spells as though they had flash.
SVar:STPlay:Mode$ CastWithFlash | ValidCard$ Sorcery | ValidSA$ Spell | EffectZone$ Command | Caster$ You | Description$ Until your next turn, you may cast sorcery spells as though they had flash.
SVar:PlayMain1:TRUE
A:AB$ ChangeZone | Cost$ SubCounter<3/LOYALTY> | Planeswalker$ True | Origin$ Battlefield | Destination$ Hand | TargetMin$ 0 | TargetMax$ 1 | ValidTgts$ Artifact,Creature,Enchantment | TgtPrompt$ Select target artifact, creature, or enchantment | SpellDescription$ Return up to one target artifact, creature, or enchantment to its owner's hand. Draw a card. | SubAbility$ DBDraw
SVar:DBDraw:DB$Draw | NumCards$ 1

View File

@@ -2,6 +2,6 @@ Name:Tidal Barracuda
ManaCost:3 U
Types:Creature Fish
PT:3/4
S:Mode$ Continuous | Affected$ Card | WithFlash$ Player | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ Any player may cast spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Card | ValidSA$ Spell | Caster$ Player | Description$ Any player may cast spells as though they had flash.
S:Mode$ CantBeCast | ValidCard$ Card | Condition$ PlayerTurn | Caster$ Opponent | Description$ Your opponents can't cast spells during your turn.
Oracle:Any player may cast spells as though they had flash.\nYour opponents can't cast spells during your turn.

View File

@@ -0,0 +1,9 @@
Name:Timely Ward
ManaCost:2 W
Types:Enchantment Aura
K:Enchant creature
A:SP$ Attach | Cost$ 2 W | ValidTgts$ Creature | AILogic$ Pump
S:Mode$ CastWithFlash | ValidCard$ Card.Self | ValidSA$ Spell | EffectZone$ All | Caster$ You | Targeting$ Card.Commander | Description$ You may cast this spell as though it had flash if it targets a commander.
S:Mode$ Continuous | Affected$ Creature.EnchantedBy | AddKeyword$ Indestructible | Description$ Enchanted creature has indestructible.
AI:RemoveDeck:All
Oracle:You may cast this spell as though it had flash if it targets a commander.\nEnchant creature\nEnchanted creature has indestructible.

View File

@@ -1,7 +1,6 @@
Name:Vedalken Orrery
ManaCost:4
Types:Artifact
S:Mode$ Continuous | Affected$ Card | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Card | ValidSA$ Spell | Caster$ You | Description$ You may cast spells as though they had flash.
SVar:NonStackingEffect:True
SVar:Picture:http://www.wizards.com/global/images/magic/general/vedalken_orrery.jpg
Oracle:You may cast spells as though they had flash.

View File

@@ -1,8 +1,7 @@
Name:Vernal Equinox
ManaCost:3 G
Types:Enchantment
S:Mode$ Continuous | Affected$ Creature.nonToken,Enchantment.nonToken | AffectedZone$ Exile,Graveyard,Hand,Library,Command,Stack | WithFlash$ Player | Description$ Any player may cast creature and enchantment spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Creature,Enchantment | ValidSA$ Spell | Caster$ Player | Description$ Any player may cast creature and enchantment spells as though they had flash.
SVar:NonStackingEffect:True
AI:RemoveDeck:Random
SVar:Picture:http://www.wizards.com/global/images/magic/general/vernal_equinox.jpg
Oracle:Any player may cast creature and enchantment spells as though they had flash.

View File

@@ -2,7 +2,7 @@ Name:Vivien, Champion of the Wilds
ManaCost:2 G
Types:Legendary Planeswalker Vivien
Loyalty:4
S:Mode$ Continuous | Affected$ Creature | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast creature spells as though they had flash.
S:Mode$ CastWithFlash | ValidCard$ Creature | ValidSA$ Spell | Caster$ You | Description$ You may cast creature spells as though they had flash.
A:AB$ Pump | Cost$ AddCounter<1/LOYALTY> | Planeswalker$ True | ValidTgts$ Creature | TargetMin$ 0 | TargetMax$ 1 | TgtPrompt$ Select target creature | KW$ Vigilance & Reach | UntilYourNextTurn$ True | SpellDescription$ Until your next turn, up to one target creature gains vigilance and reach.
A:AB$ Dig | Cost$ SubCounter<2/LOYALTY> | Planeswalker$ True | Defined$ You | DigNum$ 3 | DestinationZone$ Exile | ExileFaceDown$ True | RememberChanged$ True | SubAbility$ DBEffect | AILogic$ DigForCreature | SpellDescription$ Look at the top three cards of your library. Exile one face down and put the rest on the bottom of your library in any order. For as long as it remains exiled, you may look at that card and you may cast it if it's a creature card.
SVar:DBEffect:DB$ Effect | RememberObjects$ Remembered | StaticAbilities$ STPlay1,STPlay2 | Duration$ Permanent | ForgetOnMoved$ Exile | SubAbility$ DBCleanup

View File

@@ -3,7 +3,6 @@ ManaCost:no cost
Types:Land
A:AB$ Mana | Cost$ T | Produced$ C | SpellDescription$ Add {C}.
A:AB$ Effect | Cost$ 2 T | Name$ Winding Canyons Effect | StaticAbilities$ GiveFlash | SpellDescription$ Until end of turn, you may cast creature spells as though they had flash.
SVar:GiveFlash:Mode$ Continuous | EffectZone$ Command | Affected$ Creature.nonToken | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ Until end of turn, you may cast creature spells as though they had flash.
SVar:GiveFlash:Mode$ CastWithFlash | ValidCard$ Creature | ValidSA$ Spell | EffectZone$ Command | Caster$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ Until end of turn, you may cast creature spells as though they had flash.
AI:RemoveDeck:All
SVar:Picture:http://www.wizards.com/global/images/magic/general/winding_canyons.jpg
Oracle:{T}: Add {C}.\n{2}, {T}: You may cast creature spells this turn as though they had flash.

View File

@@ -3,6 +3,5 @@ ManaCost:2 G G
Types:Legendary Creature Elf Shaman
PT:4/4
K:Flash
S:Mode$ Continuous | Affected$ Creature.Green+nonToken | WithFlash$ You | AffectedZone$ Exile,Graveyard,Hand,Library,Command | Description$ You may cast green creature spells as though they had flash.
SVar:Picture:http://www.wizards.com/global/images/magic/general/yeva_natures_herald.jpg
S:Mode$ CastWithFlash | ValidCard$ Creature.Green | ValidSA$ Spell | Caster$ You | Description$ You may cast green creature spells as though they had flash.
Oracle:Flash (You may cast this spell any time you could cast an instant.)\nYou may cast green creature spells as though they had flash.

View File

@@ -128,7 +128,7 @@ public class HumanPlaySpellAbility {
human.incNumManaConversion();
}
if (ability.isAbility() && ability instanceof AbilityActivated) {
if (ability.isAbility() && ability.isActivatedAbility()) {
final Map<String, String> params = Maps.newHashMap();
params.put("ManaColorConversion", "Additive");
@@ -151,6 +151,7 @@ public class HumanPlaySpellAbility {
final boolean prerequisitesMet = announceValuesLikeX()
&& announceType()
&& (!mayChooseTargets || ability.setupTargets()) // if you can choose targets, then do choose them.
&& ability.canCastTiming(human)
&& (isFree || payment.payCost(new HumanCostDecision(controller, human, ability, ability.getHostCard())));
if (!prerequisitesMet) {