mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-18 03:38:01 +00:00
- Spells with "May be played without paying its mana cost" are no longer automatically playable by also paying their mana cost.
This commit is contained in:
@@ -42,6 +42,7 @@ import forge.card.spellability.Ability;
|
|||||||
import forge.card.spellability.AbilityStatic;
|
import forge.card.spellability.AbilityStatic;
|
||||||
import forge.card.spellability.SpellAbility;
|
import forge.card.spellability.SpellAbility;
|
||||||
import forge.card.spellability.SpellAbilityRequirements;
|
import forge.card.spellability.SpellAbilityRequirements;
|
||||||
|
import forge.card.spellability.SpellAbilityRestriction;
|
||||||
import forge.card.spellability.Target;
|
import forge.card.spellability.Target;
|
||||||
import forge.card.spellability.TargetSelection;
|
import forge.card.spellability.TargetSelection;
|
||||||
import forge.card.staticability.StaticAbility;
|
import forge.card.staticability.StaticAbility;
|
||||||
@@ -1868,10 +1869,9 @@ public class GameAction {
|
|||||||
final SpellAbility[] abilities = this.canPlaySpellAbility(c.getSpellAbility());
|
final SpellAbility[] abilities = this.canPlaySpellAbility(c.getSpellAbility());
|
||||||
final ArrayList<String> choices = new ArrayList<String>();
|
final ArrayList<String> choices = new ArrayList<String>();
|
||||||
final Player human = AllZone.getHumanPlayer();
|
final Player human = AllZone.getHumanPlayer();
|
||||||
|
final PlayerZone zone = AllZone.getZoneOf(c);
|
||||||
|
|
||||||
if (c.isLand() && human.canPlayLand()) {
|
if (c.isLand() && human.canPlayLand()) {
|
||||||
final PlayerZone zone = AllZone.getZoneOf(c);
|
|
||||||
|
|
||||||
if (zone.is(Zone.Hand) || ((!zone.is(Zone.Battlefield)) && c.hasStartOfKeyword("May be played"))) {
|
if (zone.is(Zone.Hand) || ((!zone.is(Zone.Battlefield)) && c.hasStartOfKeyword("May be played"))) {
|
||||||
choices.add("Play land");
|
choices.add("Play land");
|
||||||
}
|
}
|
||||||
@@ -1917,7 +1917,8 @@ public class GameAction {
|
|||||||
choices.add(newSA.toString());
|
choices.add(newSA.toString());
|
||||||
map.put(newSA.toString(), newSA);
|
map.put(newSA.toString(), newSA);
|
||||||
}
|
}
|
||||||
if (!flashb || c.hasKeyword("May be played") || c.hasKeyword("May be played by your Opponent")) {
|
SpellAbilityRestriction restrictions = sa.getRestrictions();
|
||||||
|
if (restrictions != null && restrictions.checkZoneRestrictions(zone, c, sa)) {
|
||||||
choices.add(sa.toString());
|
choices.add(sa.toString());
|
||||||
map.put(sa.toString(), sa);
|
map.put(sa.toString(), sa);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2471,7 +2471,7 @@ public class CardFactoryUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sa.isSpell()
|
if (sa.isSpell()
|
||||||
&& (c.hasStartOfKeyword("May be played")
|
&& (c.hasKeyword("May be played")
|
||||||
|| c.hasKeyword("May be played without paying its mana cost")
|
|| c.hasKeyword("May be played without paying its mana cost")
|
||||||
|| (c.hasStartOfKeyword("Flashback") && zone
|
|| (c.hasStartOfKeyword("Flashback") && zone
|
||||||
.is(Zone.Graveyard))) && restrictZone.equals(Zone.Hand)) {
|
.is(Zone.Graveyard))) && restrictZone.equals(Zone.Hand)) {
|
||||||
@@ -2487,7 +2487,7 @@ public class CardFactoryUtil {
|
|||||||
@Override
|
@Override
|
||||||
public boolean addCard(final Card c) {
|
public boolean addCard(final Card c) {
|
||||||
|
|
||||||
if (c.hasKeyword("May be played by your Opponent")) {
|
if (c.hasKeyword("May be played by your opponent")) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -94,6 +94,20 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
|||||||
final Card card = this.getSourceCard();
|
final Card card = this.getSourceCard();
|
||||||
|
|
||||||
final Player activator = this.getActivatingPlayer();
|
final Player activator = this.getActivatingPlayer();
|
||||||
|
|
||||||
|
if (!(card.isInstant() || card.hasKeyword("Flash") || PhaseHandler.canCastSorcery(activator))) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.getRestrictions().canPlay(card, this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.getPayCosts() != null) {
|
||||||
|
if (!CostPayment.canPayAdditionalCosts(this.getPayCosts(), this)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// CantBeCast static abilities
|
// CantBeCast static abilities
|
||||||
final CardList allp = AllZoneUtil.getCardsIn(Zone.Battlefield);
|
final CardList allp = AllZoneUtil.getCardsIn(Zone.Battlefield);
|
||||||
@@ -107,17 +121,7 @@ public abstract class Spell extends SpellAbility implements java.io.Serializable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getPayCosts() != null) {
|
return true;
|
||||||
if (!CostPayment.canPayAdditionalCosts(this.getPayCosts(), this)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.getRestrictions().canPlay(card, this)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (card.isInstant() || card.hasKeyword("Flash") || PhaseHandler.canCastSorcery(activator));
|
|
||||||
} // canPlay()
|
} // canPlay()
|
||||||
|
|
||||||
/** {@inheritDoc} */
|
/** {@inheritDoc} */
|
||||||
|
|||||||
@@ -180,6 +180,33 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
|||||||
this.setSvarOperand(params.get("SVarCompare").substring(2));
|
this.setSvarOperand(params.get("SVarCompare").substring(2));
|
||||||
}
|
}
|
||||||
} // end setRestrictions()
|
} // end setRestrictions()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* checkZoneRestrictions.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param cardZone
|
||||||
|
* a PlayerZone object.
|
||||||
|
* @param c
|
||||||
|
* a {@link forge.Card} object.
|
||||||
|
* @param sa
|
||||||
|
* a {@link forge.card.spellability.SpellAbility} object.
|
||||||
|
* @return a boolean.
|
||||||
|
*/
|
||||||
|
public final boolean checkZoneRestrictions(final PlayerZone cardZone, final Card c, final SpellAbility sa) {
|
||||||
|
if (!cardZone.is(this.getZone())) {
|
||||||
|
// If Card is not in the default activating zone, do some additional checks
|
||||||
|
// Not a Spell, or on Battlefield, return false
|
||||||
|
if (!sa.isSpell() || cardZone.is(Zone.Battlefield) || !this.getZone().equals(Zone.Hand)) {
|
||||||
|
return false;
|
||||||
|
} else if (!c.hasKeyword("May be played") && !c.hasKeyword("May be played by your opponent")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
@@ -198,10 +225,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final PlayerZone cardZone = AllZone.getZoneOf(c);
|
final PlayerZone cardZone = AllZone.getZoneOf(c);
|
||||||
if (!cardZone.is(this.getZone())) {
|
if (!checkZoneRestrictions(cardZone, c, sa)) {
|
||||||
// If Card is not in the default activating zone, do some additional
|
|
||||||
// checks
|
|
||||||
// Not a Spell, or on Battlefield, return false
|
|
||||||
if (!sa.isSpell() || cardZone.is(Zone.Battlefield) || !this.getZone().equals(Zone.Hand)) {
|
if (!sa.isSpell() || cardZone.is(Zone.Battlefield) || !this.getZone().equals(Zone.Hand)) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!c.hasStartOfKeyword("May be played")
|
} else if (!c.hasStartOfKeyword("May be played")
|
||||||
@@ -229,7 +253,7 @@ public class SpellAbilityRestriction extends SpellAbilityVariables {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!this.isAnyPlayer() && !activator.equals(c.getController())
|
if (!this.isAnyPlayer() && !activator.equals(c.getController())
|
||||||
&& !c.hasKeyword("May be played by your Opponent")) {
|
&& !c.hasKeyword("May be played by your opponent")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user