diff --git a/Mage/src/main/java/mage/abilities/SpellAbility.java b/Mage/src/main/java/mage/abilities/SpellAbility.java index f09f246b7f0..2cd291a957a 100644 --- a/Mage/src/main/java/mage/abilities/SpellAbility.java +++ b/Mage/src/main/java/mage/abilities/SpellAbility.java @@ -38,6 +38,7 @@ import mage.cards.Card; import mage.cards.SplitCard; import mage.constants.AbilityType; import mage.constants.AsThoughEffectType; +import mage.constants.SpellAbilityCastMode; import mage.constants.SpellAbilityType; import mage.constants.TimingRule; import mage.constants.Zone; @@ -51,6 +52,7 @@ import mage.players.Player; public class SpellAbility extends ActivatedAbilityImpl { protected SpellAbilityType spellAbilityType; + protected SpellAbilityCastMode spellAbilityCastMode; protected String cardName; public SpellAbility(ManaCost cost, String cardName) { @@ -62,23 +64,22 @@ public class SpellAbility extends ActivatedAbilityImpl { } public SpellAbility(ManaCost cost, String cardName, Zone zone, SpellAbilityType spellAbilityType) { + this(cost, cardName, zone, spellAbilityType, SpellAbilityCastMode.NORMAL); + } + + public SpellAbility(ManaCost cost, String cardName, Zone zone, SpellAbilityType spellAbilityType, SpellAbilityCastMode spellAbilityCastMode) { super(AbilityType.SPELL, zone); this.cardName = cardName; this.spellAbilityType = spellAbilityType; + this.spellAbilityCastMode = spellAbilityCastMode; this.addManaCost(cost); - switch (spellAbilityType) { - case SPLIT_FUSED: - this.name = "Cast fused " + cardName; - break; - default: - this.name = "Cast " + cardName; - } - + setSpellName(); } public SpellAbility(final SpellAbility ability) { super(ability); this.spellAbilityType = ability.spellAbilityType; + this.spellAbilityCastMode = ability.spellAbilityCastMode; this.cardName = ability.cardName; } @@ -209,4 +210,24 @@ public class SpellAbility extends ActivatedAbilityImpl { } return amount * xMultiplier; } + + private void setSpellName() { + switch (spellAbilityType) { + case SPLIT_FUSED: + this.name = "Cast fused " + cardName; + break; + default: + this.name = "Cast " + cardName + (this.spellAbilityCastMode != SpellAbilityCastMode.NORMAL ? " by " + spellAbilityCastMode.toString() : ""); + } + } + + public SpellAbilityCastMode getSpellAbilityCastMode() { + return spellAbilityCastMode; + } + + public void setSpellAbilityCastMode(SpellAbilityCastMode spellAbilityCastMode) { + this.spellAbilityCastMode = spellAbilityCastMode; + setSpellName(); + } + } diff --git a/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java b/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java index aa24ffb8482..b8a74f87112 100644 --- a/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/MadnessAbility.java @@ -1,8 +1,9 @@ package mage.abilities.keyword; -import java.util.ArrayList; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.SpellAbility; import mage.abilities.StaticAbility; import mage.abilities.TriggeredAbilityImpl; import mage.abilities.condition.Condition; @@ -13,10 +14,13 @@ import mage.abilities.effects.ReplacementEffectImpl; import mage.cards.Card; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SpellAbilityCastMode; +import mage.constants.SpellAbilityType; import mage.constants.Zone; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; +import mage.game.stack.Spell; import mage.players.Player; /** @@ -133,8 +137,6 @@ class MadnessReplacementEffect extends ReplacementEffectImpl { */ class MadnessTriggeredAbility extends TriggeredAbilityImpl { - //This array holds the Id's of all of the cards that activated madness - private static ArrayList activatedIds = new ArrayList<>(); private final UUID madnessOriginalId; MadnessTriggeredAbility(ManaCosts madnessCost, UUID madnessOriginalId) { @@ -176,25 +178,9 @@ class MadnessTriggeredAbility extends TriggeredAbilityImpl { } return false; } - activatedIds.add(getSourceId()); return true; } - @Override - public boolean isActivated() { - //Look through the list of activated Ids and see if the current source's Id is one of them - for (UUID currentId : activatedIds) { - if (currentId.equals(getSourceId())) { - //Remove the current source from the list, so if the card is somehow recast without - //paying the madness cost, this will return false - activatedIds.remove(currentId); - return true; - } - } - //If the current source's Id was not found, return false - return false; - } - @Override public String getRule() { return "When this card is exiled this way, " + super.getRule(); @@ -225,17 +211,15 @@ class MadnessCastEffect extends OneShotEffect { } if (owner != null && card != null && owner.chooseUse(outcome, "Cast " + card.getLogName() + " by madness?", source, game)) { - ManaCosts costRef = card.getSpellAbility().getManaCostsToPay(); + // replace with the new cost + SpellAbility castByMadness = card.getSpellAbility().copy(); + ManaCosts costRef = castByMadness.getManaCostsToPay(); + castByMadness.setSpellAbilityType(SpellAbilityType.BASE_ALTERNATE); + castByMadness.setSpellAbilityCastMode(SpellAbilityCastMode.MADNESS); costRef.clear(); costRef.add(madnessCost); - boolean result = owner.cast(card.getSpellAbility(), game, false); - // Reset the casting costs (in case the player cancels cast and plays the card later) - // TODO: Check if this is neccessary - costRef.clear(); - for (ManaCost manaCost : card.getSpellAbility().getManaCosts()) { - costRef.add(manaCost); - } + boolean result = owner.cast(castByMadness, game, false); return result; } @@ -254,14 +238,10 @@ enum MadnessCondition implements Condition { @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 MadnessTriggeredAbility) { - if (ability.isActivated()) { - return true; - } - } + MageObject madnessSpell = game.getLastKnownInformation(source.getSourceId(), Zone.STACK, source.getSourceObjectZoneChangeCounter() - 1); + if (madnessSpell instanceof Spell) { + if (((Spell) madnessSpell).getSpellAbility() != null) { + return ((Spell) madnessSpell).getSpellAbility().getSpellAbilityCastMode() == SpellAbilityCastMode.MADNESS; } } return false; diff --git a/Mage/src/main/java/mage/constants/SpellAbilityCastMode.java b/Mage/src/main/java/mage/constants/SpellAbilityCastMode.java new file mode 100644 index 00000000000..663c8c8f1bf --- /dev/null +++ b/Mage/src/main/java/mage/constants/SpellAbilityCastMode.java @@ -0,0 +1,48 @@ +/* + * 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.constants; + +/** + * + * @author LevelX2 + */ +public enum SpellAbilityCastMode { + NORMAL("Normal"), + MADNESS("Madness"); + + private final String text; + + SpellAbilityCastMode(String text) { + this.text = text; + } + + @Override + public String toString() { + return text; + } +}