mirror of
https://github.com/magefree/mage.git
synced 2025-12-26 05:22:02 -08:00
Alternative cost - fixed that it doesn't allow to cast cards that was affected by cost modification effects (example: Prowl ability, see #6698);
This commit is contained in:
parent
f9a9a55f7b
commit
1e744a0aae
12 changed files with 218 additions and 114 deletions
|
|
@ -1,16 +1,16 @@
|
|||
|
||||
package mage.abilities.condition.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.keyword.ProwlAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.Game;
|
||||
import mage.watchers.common.ProwlWatcher;
|
||||
|
||||
/**
|
||||
* Checks if a the spell was cast with the alternate prowl costs
|
||||
* Is it able to activate prowl cost (damage was made)
|
||||
*
|
||||
* @author LevelX2
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum ProwlCondition implements Condition {
|
||||
|
||||
|
|
@ -18,22 +18,15 @@ public enum ProwlCondition implements Condition {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
ProwlWatcher watcher = game.getState().getWatcher(ProwlWatcher.class);
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability instanceof ProwlAbility) {
|
||||
if (((ProwlAbility) ability).isActivated(source, game)) {
|
||||
return true;
|
||||
}
|
||||
if (watcher != null && card != null) {
|
||||
for (SubType subtype : card.getSubtype(game)) {
|
||||
if (watcher.hasSubtypeMadeCombatDamage(source.getControllerId(), subtype)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{source}'s prowl cost was paid";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
package mage.abilities.condition.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.keyword.ProwlAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* Checks if a the spell was cast with the alternate prowl costs
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public enum ProwlCostWasPaidCondition implements Condition {
|
||||
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability instanceof ProwlAbility) {
|
||||
if (((ProwlAbility) ability).isActivated(source, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{source}'s prowl cost was paid";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
package mage.abilities.hint.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.ProwlCostWasPaidCondition;
|
||||
import mage.abilities.hint.ConditionHint;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum ProwlCostWasPaidHint implements Hint {
|
||||
|
||||
instance;
|
||||
private static final ConditionHint hint = new ConditionHint(ProwlCostWasPaidCondition.instance, "Prowl cost was paid");
|
||||
|
||||
@Override
|
||||
public String getText(Game game, Ability ability) {
|
||||
return hint.getText(game, ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
26
Mage/src/main/java/mage/abilities/hint/common/ProwlHint.java
Normal file
26
Mage/src/main/java/mage/abilities/hint/common/ProwlHint.java
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
package mage.abilities.hint.common;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.common.ProwlCondition;
|
||||
import mage.abilities.hint.ConditionHint;
|
||||
import mage.abilities.hint.Hint;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
* @author JayDi85
|
||||
*/
|
||||
public enum ProwlHint implements Hint {
|
||||
|
||||
instance;
|
||||
private static final ConditionHint hint = new ConditionHint(ProwlCondition.instance, "Prowl cost can be activated");
|
||||
|
||||
@Override
|
||||
public String getText(Game game, Ability ability) {
|
||||
return hint.getText(game, ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Hint copy() {
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,30 +1,26 @@
|
|||
|
||||
package mage.abilities.keyword;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.costs.AlternativeCost2;
|
||||
import mage.abilities.costs.AlternativeCost2Impl;
|
||||
import mage.abilities.costs.AlternativeSourceCosts;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.Costs;
|
||||
import mage.abilities.costs.CostsImpl;
|
||||
import mage.abilities.condition.common.ProwlCondition;
|
||||
import mage.abilities.costs.*;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.hint.common.ProwlHint;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.watchers.common.ProwlWatcher;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 702.74. Prowl #
|
||||
*
|
||||
* <p>
|
||||
* 702.74a Prowl is a static ability that functions on the stack. "Prowl [cost]"
|
||||
* means "You may pay [cost] rather than pay this spell's mana cost if a player
|
||||
* was dealt combat damage this turn by a source that, at the time it dealt that
|
||||
|
|
@ -41,13 +37,13 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
private String reminderText;
|
||||
|
||||
public ProwlAbility(Card card, String manaString) {
|
||||
super(Zone.STACK, null);
|
||||
setRuleAtTheTop(true);
|
||||
name = PROWL_KEYWORD;
|
||||
setReminderText(card);
|
||||
super(Zone.ALL, null);
|
||||
this.setRuleAtTheTop(true);
|
||||
this.name = PROWL_KEYWORD;
|
||||
this.setReminderText(card);
|
||||
this.addProwlCost(manaString);
|
||||
addWatcher(new ProwlWatcher());
|
||||
|
||||
this.addWatcher(new ProwlWatcher());
|
||||
this.addHint(ProwlHint.instance);
|
||||
}
|
||||
|
||||
public ProwlAbility(final ProwlAbility ability) {
|
||||
|
|
@ -85,26 +81,17 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
|
||||
@Override
|
||||
public boolean isAvailable(Ability source, Game game) {
|
||||
return true;
|
||||
return ProwlCondition.instance.apply(game, source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean askToActivateAlternativeCosts(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
ProwlWatcher prowlWatcher = game.getState().getWatcher(ProwlWatcher.class);
|
||||
Card card = game.getCard(ability.getSourceId());
|
||||
if (player == null || prowlWatcher == null || card == null) {
|
||||
throw new IllegalArgumentException("Params can't be null");
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
boolean canProwl = false;
|
||||
for (SubType subtype : card.getSubtype(game)) {
|
||||
if (prowlWatcher.hasSubtypeMadeCombatDamage(ability.getControllerId(), subtype)) {
|
||||
canProwl = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (canProwl) {
|
||||
if (ProwlCondition.instance.apply(game, ability)) {
|
||||
this.resetProwl();
|
||||
for (AlternativeCost2 prowlCost : prowlCosts) {
|
||||
if (prowlCost.canPay(ability, sourceId, controllerId, game)
|
||||
|
|
@ -112,7 +99,7 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
prowlCost.activate();
|
||||
ability.getManaCostsToPay().clear();
|
||||
ability.getCosts().clear();
|
||||
for (Iterator it = ((Costs) prowlCost).iterator(); it.hasNext();) {
|
||||
for (Iterator it = ((Costs) prowlCost).iterator(); it.hasNext(); ) {
|
||||
Cost cost = (Cost) it.next();
|
||||
if (cost instanceof ManaCostsImpl) {
|
||||
ability.getManaCostsToPay().add((ManaCostsImpl) cost.copy());
|
||||
|
|
@ -162,7 +149,7 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
}
|
||||
|
||||
private void setReminderText(Card card) {
|
||||
reminderText =
|
||||
reminderText =
|
||||
"(You may cast this for its prowl cost if you dealt combat damage to a player this turn with a creature that shared a creature type with {this}";
|
||||
}
|
||||
|
||||
|
|
@ -174,4 +161,4 @@ public class ProwlAbility extends StaticAbility implements AlternativeSourceCost
|
|||
}
|
||||
return alterCosts;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -3046,6 +3046,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
protected boolean canPlayCardByAlternateCost(Card sourceObject, ManaOptions availableMana, Ability ability, Game game) {
|
||||
if (sourceObject != null && !(sourceObject instanceof Permanent)) {
|
||||
Ability copyAbility; // for alternative cost and reduce tries
|
||||
for (Ability alternateSourceCostsAbility : sourceObject.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if (alternateSourceCostsAbility instanceof AlternativeSourceCosts) {
|
||||
|
|
@ -3064,7 +3065,15 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (availableMana == null) {
|
||||
return true;
|
||||
}
|
||||
for (Mana mana : manaCosts.getOptions()) {
|
||||
|
||||
// alternative cost reduce
|
||||
copyAbility = ability.copy();
|
||||
copyAbility.getManaCostsToPay().clear();
|
||||
copyAbility.getManaCostsToPay().addAll(manaCosts.copy());
|
||||
sourceObject.adjustCosts(copyAbility, game);
|
||||
game.getContinuousEffects().costModification(copyAbility, game);
|
||||
|
||||
for (Mana mana : copyAbility.getManaCostsToPay().getOptions()) {
|
||||
for (Mana avail : availableMana) {
|
||||
if (mana.enough(avail)) {
|
||||
return true;
|
||||
|
|
@ -3092,7 +3101,18 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
if (manaCosts.isEmpty()) {
|
||||
return true;
|
||||
} else {
|
||||
for (Mana mana : manaCosts.getOptions()) {
|
||||
if (availableMana == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// alternative cost reduce
|
||||
copyAbility = ability.copy();
|
||||
copyAbility.getManaCostsToPay().clear();
|
||||
copyAbility.getManaCostsToPay().addAll(manaCosts.copy());
|
||||
sourceObject.adjustCosts(copyAbility, game);
|
||||
game.getContinuousEffects().costModification(copyAbility, game);
|
||||
|
||||
for (Mana mana : copyAbility.getManaCostsToPay().getOptions()) {
|
||||
for (Mana avail : availableMana) {
|
||||
if (mana.enough(avail)) {
|
||||
return true;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue