mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
Added possibility to use Morph with a land. Minor changes to some cards.
This commit is contained in:
parent
40febbe086
commit
4b66cd8367
15 changed files with 323 additions and 111 deletions
|
@ -56,7 +56,7 @@ public class ForceOfWill extends CardImpl {
|
|||
this.color.setBlue(true);
|
||||
|
||||
// You may pay 1 life and exile a blue card from your hand rather than pay Force of Will's mana cost.
|
||||
FilterOwnedCard filter = new FilterOwnedCard("blue card from your hand");
|
||||
FilterOwnedCard filter = new FilterOwnedCard("a blue card from your hand");
|
||||
filter.add(new ColorPredicate(ObjectColor.BLUE));
|
||||
filter.add(Predicates.not(new CardIdPredicate(this.getId()))); // the exile cost can never be paid with the card itself
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ package mage.sets.fifthdawn;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.SourceIsSpellCondition;
|
||||
import mage.abilities.costs.AlternativeCostSourceAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
|
@ -71,7 +72,7 @@ public class FistOfSuns extends CardImpl {
|
|||
|
||||
class FistOfSunsRuleEffect extends ContinuousEffectImpl {
|
||||
|
||||
static AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(new ManaCostsImpl("{W}{U}{B}{R}{G}"));
|
||||
static AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(new ManaCostsImpl("{W}{U}{B}{R}{G}"), SourceIsSpellCondition.getInstance());
|
||||
|
||||
public FistOfSunsRuleEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Detriment);
|
||||
|
|
|
@ -30,6 +30,7 @@ package mage.sets.magic2013;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.SourceIsSpellCondition;
|
||||
import mage.abilities.costs.AlternativeCostSourceAbility;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -73,7 +74,7 @@ public class Omniscience extends CardImpl {
|
|||
class OmniscienceCastingEffect extends ContinuousEffectImpl {
|
||||
|
||||
static AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(
|
||||
null, null, null, new FilterNonlandCard(), true);
|
||||
null, SourceIsSpellCondition.getInstance(), null, new FilterNonlandCard(), true);
|
||||
|
||||
public OmniscienceCastingEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Detriment);
|
||||
|
|
|
@ -30,6 +30,7 @@ package mage.sets.stronghold;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.SourceIsSpellCondition;
|
||||
import mage.abilities.costs.AlternativeCostSourceAbility;
|
||||
import mage.abilities.costs.common.DiscardCardCost;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
|
@ -82,7 +83,7 @@ class DreamHallsEffect extends ContinuousEffectImpl {
|
|||
filter.add(new SharesColorWithSourcePredicate());
|
||||
}
|
||||
|
||||
static AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(new DiscardCardCost(filter));
|
||||
static AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(new DiscardCardCost(filter), SourceIsSpellCondition.getInstance());
|
||||
|
||||
public DreamHallsEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Detriment);
|
||||
|
|
|
@ -30,6 +30,7 @@ package mage.sets.tempest;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.condition.common.SourceIsSpellCondition;
|
||||
import mage.abilities.costs.AlternativeCostSourceAbility;
|
||||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.Effect;
|
||||
|
@ -103,7 +104,7 @@ class AlurenRuleEffect extends ContinuousEffectImpl {
|
|||
filter.add(new ConvertedManaCostPredicate(ComparisonType.LessThan, 4));
|
||||
}
|
||||
|
||||
static AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(null, null, null, filter, true);
|
||||
static AlternativeCostSourceAbility alternativeCastingCostAbility = new AlternativeCostSourceAbility(null, SourceIsSpellCondition.getInstance(), null, filter, true);
|
||||
|
||||
public AlurenRuleEffect() {
|
||||
super(Duration.WhileOnBattlefield, Outcome.Detriment);
|
||||
|
|
|
@ -49,6 +49,8 @@ public class LlanowarElves extends CardImpl {
|
|||
this.color.setGreen(true);
|
||||
this.power = new MageInt(1);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
// {T}: Add {G} to your mana pool.
|
||||
this.addAbility(new GreenManaAbility());
|
||||
}
|
||||
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.common.ZoneChangeTriggeredAbility;
|
||||
import mage.abilities.costs.AlternativeCost;
|
||||
import mage.abilities.costs.AlternativeSourceCosts;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.abilities.mana.ManaAbility;
|
||||
|
|
|
@ -47,6 +47,7 @@ import mage.constants.EffectType;
|
|||
import mage.constants.Zone;
|
||||
import mage.game.Controllable;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.Target;
|
||||
import mage.target.Targets;
|
||||
|
||||
|
@ -473,4 +474,7 @@ public interface Ability extends Controllable, Serializable {
|
|||
* @param active execute no cost modification
|
||||
*/
|
||||
void setCostModificationActive(boolean active);
|
||||
|
||||
boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game);
|
||||
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -238,36 +239,10 @@ public abstract class AbilityImpl implements Ability {
|
|||
// as buyback, kicker, or convoke costs (see rules 117.8 and 117.9), the player announces his
|
||||
// or her intentions to pay any or all of those costs (see rule 601.2e).
|
||||
// A player can't apply two alternative methods of casting or two alternative costs to a single spell.
|
||||
if (sourceObject != null && !(this instanceof FlashbackAbility)) {
|
||||
boolean alternativeCostisUsed = false;
|
||||
for (Ability ability : sourceObject.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if (!noMana && ability instanceof AlternativeSourceCosts) {
|
||||
AlternativeSourceCosts alternativeSpellCosts = (AlternativeSourceCosts) ability;
|
||||
if (alternativeSpellCosts.isAvailable(this, game)) {
|
||||
if (alternativeSpellCosts.askToActivateAlternativeCosts(this, game)) {
|
||||
// only one alternative costs may be activated
|
||||
alternativeCostisUsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ability instanceof OptionalAdditionalSourceCosts) {
|
||||
((OptionalAdditionalSourceCosts)ability).addOptionalAdditionalCosts(this, game);
|
||||
}
|
||||
}
|
||||
// controller specific alternate spell costs
|
||||
if (!noMana && !alternativeCostisUsed) {
|
||||
if (this.getAbilityType().equals(AbilityType.SPELL)) {
|
||||
for (AlternativeSourceCosts alternativeSourceCosts: controller.getAlternativeSourceCosts()) {
|
||||
if (alternativeSourceCosts.isAvailable(this, game)) {
|
||||
if (alternativeSourceCosts.askToActivateAlternativeCosts(this, game)) {
|
||||
// only one alternative costs may be activated
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!activateAlternateOrAdditionalCosts(sourceObject, noMana, controller, game)){
|
||||
if (getAbilityType().equals(AbilityType.SPELL)
|
||||
&& ((SpellAbility) this).getSpellAbilityType().equals(SpellAbilityType.LAND_ALTERNATE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,7 +342,7 @@ public abstract class AbilityImpl implements Ability {
|
|||
game.informPlayers(new StringBuilder(controller.getName()).append(" announces a value of ").append(xValue).append(" for ").append(variableManaCost.getText()).toString());
|
||||
}
|
||||
activated = true;
|
||||
// fire if tapped for mana (may only fires now because else costs of ability itself can be payed with mana of abilities that trigger for that event
|
||||
// fire if tapped for mana (may only fire now because else costs of ability itself can be payed with mana of abilities that trigger for that event
|
||||
if (this.getAbilityType().equals(AbilityType.MANA)) {
|
||||
for (Cost cost: costs) {
|
||||
if (cost instanceof TapSourceCost) {
|
||||
|
@ -384,6 +359,44 @@ public abstract class AbilityImpl implements Ability {
|
|||
return activated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game) {
|
||||
boolean alternativeCostisUsed = false;
|
||||
if (sourceObject != null && !(sourceObject instanceof Permanent) && !(this instanceof FlashbackAbility)) {
|
||||
for (Ability ability : sourceObject.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if (!noMana && ability instanceof AlternativeSourceCosts) {
|
||||
AlternativeSourceCosts alternativeSpellCosts = (AlternativeSourceCosts) ability;
|
||||
if (alternativeSpellCosts.isAvailable(this, game)) {
|
||||
if (alternativeSpellCosts.askToActivateAlternativeCosts(this, game)) {
|
||||
// only one alternative costs may be activated
|
||||
alternativeCostisUsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ability instanceof OptionalAdditionalSourceCosts) {
|
||||
((OptionalAdditionalSourceCosts)ability).addOptionalAdditionalCosts(this, game);
|
||||
}
|
||||
}
|
||||
// controller specific alternate spell costs
|
||||
if (!noMana && !alternativeCostisUsed) {
|
||||
if (this.getAbilityType().equals(AbilityType.SPELL)) {
|
||||
for (AlternativeSourceCosts alternativeSourceCosts: controller.getAlternativeSourceCosts()) {
|
||||
if (alternativeSourceCosts.isAvailable(this, game)) {
|
||||
if (alternativeSourceCosts.askToActivateAlternativeCosts(this, game)) {
|
||||
// only one alternative costs may be activated
|
||||
alternativeCostisUsed = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return alternativeCostisUsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the setting of non mana X costs
|
||||
* @param controller *
|
||||
|
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
|
||||
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* The views and conclusions contained in the software and documentation are those of the
|
||||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
package mage.abilities.condition.common;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.constants.CardType;
|
||||
import mage.game.Game;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class SourceIsSpellCondition implements Condition {
|
||||
|
||||
private static final SourceIsSpellCondition fInstance = new SourceIsSpellCondition();
|
||||
|
||||
public static Condition getInstance() {
|
||||
return fInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
MageObject object = game.getObject(source.getSourceId());
|
||||
return object != null && !object.getCardType().contains(CardType.LAND);
|
||||
}
|
||||
}
|
|
@ -50,7 +50,7 @@ public class ExileFromHandCost extends CostImpl {
|
|||
|
||||
public ExileFromHandCost(TargetCardInHand target) {
|
||||
this.addTarget(target);
|
||||
this.text = "Exile " + target.getTargetName();
|
||||
this.text = "exile " + target.getTargetName();
|
||||
}
|
||||
|
||||
public ExileFromHandCost(ExileFromHandCost cost) {
|
||||
|
|
|
@ -33,7 +33,6 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import mage.ObjectColor;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.SpellAbility;
|
||||
import mage.abilities.StaticAbility;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.common.TurnFaceUpAbility;
|
||||
|
@ -48,6 +47,7 @@ import mage.abilities.costs.mana.ManaCosts;
|
|||
import mage.abilities.effects.ContinuousEffectImpl;
|
||||
import mage.abilities.effects.common.continious.SourceEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.AbilityType;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Layer;
|
||||
|
@ -181,7 +181,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
|
||||
@Override
|
||||
public boolean askToActivateAlternativeCosts(Ability ability, Game game) {
|
||||
if (ability instanceof SpellAbility) {
|
||||
if (ability.getAbilityType().equals(AbilityType.SPELL)) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
Spell spell = game.getStack().getSpell(ability.getId());
|
||||
if (player != null && spell != null) {
|
||||
|
@ -214,6 +214,28 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
|
|||
}
|
||||
}
|
||||
}
|
||||
if (ability.getAbilityType().equals(AbilityType.PLAY_LAND)) {
|
||||
Player player = game.getPlayer(controllerId);
|
||||
if (player != null) {
|
||||
this.resetMorph();
|
||||
if (alternateCosts.canPay(ability, sourceId, controllerId, game)) {
|
||||
if (player.chooseUse(Outcome.Benefit, new StringBuilder("Cast this card as a 2/2 face-down creature for ").append(getCosts().getText()).append(" ?").toString(), game)) {
|
||||
activateMorph(game);
|
||||
// change mana costs
|
||||
ability.getManaCostsToPay().clear();
|
||||
ability.getCosts().clear();
|
||||
for (Iterator it = this.alternateCosts.iterator(); it.hasNext();) {
|
||||
Cost cost = (Cost) it.next();
|
||||
if (cost instanceof ManaCost) {
|
||||
ability.getManaCostsToPay().add((ManaCost)cost.copy());
|
||||
} else {
|
||||
ability.getCosts().add(cost.copy());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return isActivated(ability, game);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ package mage.constants;
|
|||
public enum SpellAbilityType {
|
||||
BASE("Basic SpellAbility"),
|
||||
BASE_ALTERNATE("Basic SpellAbility Alternate"), // used for Overload, Flashback to know they must be handled as Alternate casting costs
|
||||
LAND_ALTERNATE("Basic SpellAbility Alternate Land"), // used for Lands with Morph to cast as Face Down creature
|
||||
SPLIT("Split SpellAbility"),
|
||||
SPLIT_FUSED("Split SpellAbility"),
|
||||
SPLIT_LEFT("LeftSplit SpellAbility"),
|
||||
|
|
|
@ -56,6 +56,7 @@ import java.util.List;
|
|||
import java.util.UUID;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.AbilityWord;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -450,6 +451,11 @@ public class StackAbility implements StackObject, Ability {
|
|||
throw new UnsupportedOperationException("Not supported.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean activateAlternateOrAdditionalCosts(MageObject sourceObject, boolean noMana, Player controller, Game game) {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getGameLogMessage(Game game) {
|
||||
throw new UnsupportedOperationException("Not supported."); //To change body of generated methods, choose Tools | Templates.
|
||||
|
|
|
@ -61,6 +61,7 @@ import mage.abilities.costs.AlternativeCost;
|
|||
import mage.abilities.costs.AlternativeCostSourceAbility;
|
||||
import mage.abilities.costs.AlternativeSourceCosts;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.OptionalAdditionalSourceCosts;
|
||||
import mage.abilities.costs.mana.ManaCost;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.RestrictionEffect;
|
||||
|
@ -88,6 +89,14 @@ import mage.constants.ManaType;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.PlayerAction;
|
||||
import static mage.constants.PlayerAction.PASS_PRIORITY_CANCEL_ALL_ACTIONS;
|
||||
import static mage.constants.PlayerAction.PASS_PRIORITY_UNTIL_MY_NEXT_TURN;
|
||||
import static mage.constants.PlayerAction.PASS_PRIORITY_UNTIL_NEXT_MAIN_PHASE;
|
||||
import static mage.constants.PlayerAction.PASS_PRIORITY_UNTIL_NEXT_TURN;
|
||||
import static mage.constants.PlayerAction.PASS_PRIORITY_UNTIL_STACK_RESOLVED;
|
||||
import static mage.constants.PlayerAction.PASS_PRIORITY_UNTIL_TURN_END_STEP;
|
||||
import static mage.constants.PlayerAction.PERMISSION_REQUESTS_ALLOWED_OFF;
|
||||
import static mage.constants.PlayerAction.PERMISSION_REQUESTS_ALLOWED_ON;
|
||||
import mage.constants.RangeOfInfluence;
|
||||
import mage.constants.SpellAbilityType;
|
||||
import mage.constants.TimingRule;
|
||||
|
@ -940,6 +949,32 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
@Override
|
||||
public boolean playLand(Card card, Game game) {
|
||||
// Check for alternate casting possibilities: e.g. land with Morph
|
||||
ActivatedAbility playLandAbility = null;
|
||||
boolean found = false;
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if ((ability instanceof AlternativeSourceCosts) ||(ability instanceof OptionalAdditionalSourceCosts)) {
|
||||
found = true;
|
||||
}
|
||||
if (ability instanceof PlayLandAbility) {
|
||||
playLandAbility = (ActivatedAbility) ability;
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
SpellAbility spellAbility = new SpellAbility(null, "", game.getState().getZone(card.getId()), SpellAbilityType.LAND_ALTERNATE);
|
||||
spellAbility.setControllerId(this.getId());
|
||||
spellAbility.setSourceId(card.getId());
|
||||
if (cast(spellAbility, game, false)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (playLandAbility == null) {
|
||||
return false;
|
||||
}
|
||||
if (!playLandAbility.canActivate(this.playerId, game)) {
|
||||
return false;
|
||||
}
|
||||
//20091005 - 305.1
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, card.getId(), card.getId(), playerId))) {
|
||||
// int bookmark = game.bookmarkState();
|
||||
|
@ -1026,35 +1061,35 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
@Override
|
||||
public boolean activateAbility(ActivatedAbility ability, Game game) {
|
||||
boolean result;
|
||||
if (!ability.canActivate(this.playerId, game)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ability instanceof PassAbility) {
|
||||
pass(game);
|
||||
return true;
|
||||
}
|
||||
else if (ability instanceof PlayLandAbility) {
|
||||
if (ability instanceof PlayLandAbility) {
|
||||
Card card = hand.get(ability.getSourceId(), game);
|
||||
if (card == null) {
|
||||
card = game.getCard(ability.getSourceId());
|
||||
}
|
||||
result = playLand(card, game);
|
||||
}
|
||||
else if (ability instanceof SpecialAction) {
|
||||
result = specialAction((SpecialAction)ability.copy(), game);
|
||||
}
|
||||
else if (ability instanceof ManaAbility) {
|
||||
result = playManaAbility((ManaAbility)ability.copy(), game);
|
||||
}
|
||||
else if (ability instanceof FlashbackAbility){
|
||||
result = playAbility(ability.copy(), game);
|
||||
}
|
||||
else if (ability instanceof SpellAbility) {
|
||||
result = cast((SpellAbility)ability, game, false);
|
||||
}
|
||||
else {
|
||||
result = playAbility(ability.copy(), game);
|
||||
} else {
|
||||
if (!ability.canActivate(this.playerId, game)) {
|
||||
return false;
|
||||
}
|
||||
if (ability instanceof SpecialAction) {
|
||||
result = specialAction((SpecialAction)ability.copy(), game);
|
||||
}
|
||||
else if (ability instanceof ManaAbility) {
|
||||
result = playManaAbility((ManaAbility)ability.copy(), game);
|
||||
}
|
||||
else if (ability instanceof FlashbackAbility){
|
||||
result = playAbility(ability.copy(), game);
|
||||
}
|
||||
else if (ability instanceof SpellAbility) {
|
||||
result = cast((SpellAbility)ability, game, false);
|
||||
}
|
||||
else {
|
||||
result = playAbility(ability.copy(), game);
|
||||
}
|
||||
}
|
||||
|
||||
//if player has taken an action then reset all player passed flags
|
||||
|
@ -1120,9 +1155,21 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
protected LinkedHashMap<UUID, ActivatedAbility> getUseableActivatedAbilities(MageObject object, Zone zone, Game game) {
|
||||
LinkedHashMap<UUID, ActivatedAbility> useable = new LinkedHashMap<>();
|
||||
if (!(object instanceof Permanent) || ((Permanent)object).canUseActivatedAbilities(game)) {
|
||||
for (ActivatedAbility ability: object.getAbilities().getActivatedAbilities(zone)) {
|
||||
if (ability.canActivate(playerId, game)) {
|
||||
useable.put(ability.getId(), ability);
|
||||
for (Ability ability: object.getAbilities()) {
|
||||
if (ability.getZone().match(zone)) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
if (((ActivatedAbility)ability).canActivate(playerId, game)) {
|
||||
useable.put(ability.getId(), (ActivatedAbility)ability);
|
||||
}
|
||||
} else if (ability instanceof AlternativeSourceCosts){
|
||||
if (object.getCardType().contains(CardType.LAND)) {
|
||||
for (Ability ability2: object.getAbilities().copy()) {
|
||||
if (ability2 instanceof PlayLandAbility) {
|
||||
useable.put(ability2.getId(), (ActivatedAbility)ability2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (zone != Zone.HAND) {
|
||||
|
@ -2094,9 +2141,8 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
MageObject object = game.getObject(ability.getSourceId());
|
||||
for (Ability objectAbility :object.getAbilities()) {
|
||||
// old alternate costs
|
||||
for (Ability objectAbility :sourceObject.getAbilities()) {
|
||||
if (objectAbility instanceof AlternativeCostSourceAbility) {
|
||||
if (objectAbility.getCosts().canPay(ability, ability.getSourceId(), playerId, game)) {
|
||||
return true;
|
||||
|
@ -2109,38 +2155,79 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(sourceObject instanceof Permanent)) {
|
||||
for (Ability alternateSourceCostsAbility : sourceObject.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if (alternateSourceCostsAbility instanceof AlternativeSourceCosts) {
|
||||
if (((AlternativeSourceCosts)alternateSourceCostsAbility).isAvailable(ability, game)) {
|
||||
if (alternateSourceCostsAbility.getCosts().canPay(ability, playerId, playerId, game)) {
|
||||
ManaCostsImpl manaCosts = new ManaCostsImpl();
|
||||
for(Cost cost:alternateSourceCostsAbility.getCosts()) {
|
||||
if (cost instanceof ManaCost) {
|
||||
manaCosts.add(cost);
|
||||
}
|
||||
}
|
||||
// new alternate costs
|
||||
if(canPlayCardByAlternateCost(card, available, ability, game)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (manaCosts.size() == 0) {
|
||||
return true;
|
||||
protected boolean canPlayCardByAlternateCost(Card sourceObject, ManaOptions available, Ability ability, Game game) {
|
||||
if (!(sourceObject instanceof Permanent)) {
|
||||
for (Ability alternateSourceCostsAbility : sourceObject.getAbilities()) {
|
||||
// if cast for noMana no Alternative costs are allowed
|
||||
if (alternateSourceCostsAbility instanceof AlternativeSourceCosts) {
|
||||
if (((AlternativeSourceCosts)alternateSourceCostsAbility).isAvailable(ability, game)) {
|
||||
if (alternateSourceCostsAbility.getCosts().canPay(ability, playerId, playerId, game)) {
|
||||
ManaCostsImpl manaCosts = new ManaCostsImpl();
|
||||
for(Cost cost:alternateSourceCostsAbility.getCosts()) {
|
||||
if (cost instanceof ManaCost) {
|
||||
manaCosts.add(cost);
|
||||
}
|
||||
else {
|
||||
for (Mana mana: manaCosts.getOptions()) {
|
||||
for (Mana avail: available) {
|
||||
if (mana.enough(avail)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (manaCosts.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
for (Mana mana: manaCosts.getOptions()) {
|
||||
for (Mana avail: available) {
|
||||
if (mana.enough(avail)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
protected boolean canLandPlayAlternateSourceCostsAbility(Card sourceObject, ManaOptions available, Ability ability, Game game) {
|
||||
if (!(sourceObject instanceof Permanent)) {
|
||||
Ability sourceAbility = null;
|
||||
for(Ability landAbility : sourceObject.getAbilities()) {
|
||||
if (landAbility.getAbilityType().equals(AbilityType.PLAY_LAND)) {
|
||||
sourceAbility = landAbility;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sourceAbility != null && ((AlternativeSourceCosts)ability).isAvailable(sourceAbility, game)) {
|
||||
if (ability.getCosts().canPay(ability, sourceObject.getId(), this.getId(), game)) {
|
||||
ManaCostsImpl manaCosts = new ManaCostsImpl();
|
||||
for(Cost cost:ability.getCosts()) {
|
||||
if (cost instanceof ManaCost) {
|
||||
manaCosts.add(cost);
|
||||
}
|
||||
}
|
||||
|
||||
if (manaCosts.size() == 0) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
for (Mana mana: manaCosts.getOptions()) {
|
||||
for (Mana avail: available) {
|
||||
if (mana.enough(avail)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -2156,15 +2243,19 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
|
||||
if (hidden) {
|
||||
for (Card card : hand.getUniqueCards(game)) {
|
||||
for (Ability ability : card.getAbilities().getPlayableAbilities(Zone.HAND)) { // gets this activated ability from hand? (Morph?)
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
if (ability instanceof PlayLandAbility) {
|
||||
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
|
||||
break;
|
||||
for (Ability ability : card.getAbilities()) { // gets this activated ability from hand? (Morph?)
|
||||
if (ability.getZone().match(Zone.HAND)) {
|
||||
if (ability instanceof ActivatedAbility) {
|
||||
if (!(ability instanceof PlayLandAbility) ||
|
||||
!game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
|
||||
if (canPlay((ActivatedAbility) ability, availableMana, card, game)) {
|
||||
playable.add(ability);
|
||||
}
|
||||
}
|
||||
} else if (card.getCardType().contains(CardType.LAND) && ability instanceof AlternativeSourceCosts) {
|
||||
if (canLandPlayAlternateSourceCostsAbility(card, availableMana, ability, game)) { // e.g. Land with Morph
|
||||
playable.add(ability);
|
||||
}
|
||||
}
|
||||
if (canPlay((ActivatedAbility) ability, availableMana, card, game)) {
|
||||
playable.add(ability);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2265,23 +2356,36 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
available.addMana(manaPool.getMana());
|
||||
|
||||
for (Card card : hand.getCards(game)) {
|
||||
for (ActivatedAbility ability : card.getAbilities().getPlayableAbilities(Zone.HAND)) {
|
||||
if (ability instanceof PlayLandAbility) {
|
||||
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
|
||||
break;
|
||||
Abilities:
|
||||
for (Ability ability : card.getAbilities()) {
|
||||
if (ability.getZone().match(Zone.HAND)) {
|
||||
switch (ability.getAbilityType()) {
|
||||
case PLAY_LAND:
|
||||
if (game.getContinuousEffects().preventedByRuleModification(GameEvent.getEvent(GameEvent.EventType.PLAY_LAND, ability.getSourceId(), ability.getSourceId(), playerId), ability, game, true)) {
|
||||
break;
|
||||
}
|
||||
if (canPlay((ActivatedAbility) ability, available, card, game)) {
|
||||
playable.add(card.getId());
|
||||
break Abilities;
|
||||
}
|
||||
break;
|
||||
case ACTIVATED:
|
||||
case SPELL:
|
||||
if (canPlay((ActivatedAbility) ability, available, card, game)) {
|
||||
playable.add(card.getId());
|
||||
break Abilities;
|
||||
}
|
||||
break;
|
||||
case STATIC:
|
||||
if (card.getCardType().contains(CardType.LAND) && ability instanceof AlternativeSourceCosts) {
|
||||
if (canLandPlayAlternateSourceCostsAbility(card, available, ability, game)) { // e.g. Land with Morph
|
||||
playable.add(card.getId());
|
||||
break Abilities;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (canPlay(ability, available, card, game)) {
|
||||
playable.add(card.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
// for (ActivatedAbility ability : card.getAbilities().getActivatedAbilities(Zone.HAND)) {
|
||||
// if (!playable.contains(ability.getSourceId()) && canPlay(ability, available, card, game)) {
|
||||
// playable.add(card.getId());
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue