mirror of
https://github.com/correl/mage.git
synced 2024-12-24 03:00:14 +00:00
* Fixed some problems if a creature has multiple madness abilities.
This commit is contained in:
parent
c563d6f701
commit
c31bf97440
4 changed files with 100 additions and 10 deletions
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package mage.sets.shadowsoverinnistrad;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
|
@ -60,7 +61,18 @@ public class FalkenrathGorger extends CardImpl {
|
|||
this.subtype.add("Berserker");
|
||||
this.power = new MageInt(2);
|
||||
this.toughness = new MageInt(1);
|
||||
|
||||
/**
|
||||
* 4/8/2016 Falkenrath Gorger’s ability only applies while it’s on the
|
||||
* battlefield. If you discard it, it won’t give itself madness.
|
||||
* 4/8/2016 If Falkenrath Gorger leaves the battlefield before the
|
||||
* madness trigger has resolved for a Vampire card that gained madness
|
||||
* with its ability, the madness ability will still let you cast that
|
||||
* Vampire card for the appropriate cost even though it no longer has
|
||||
* madness. 4/8/2016 If you discard a Vampire creature card that already
|
||||
* has a madness ability, you’ll choose which madness ability exiles it.
|
||||
* You may choose either the one it normally has or the one it gains
|
||||
* from Falkenrath Gorger.
|
||||
*/
|
||||
// Each Vampire creature card you own that isn't on the battlefield has madness. Its madness cost is equal to its mana cost.
|
||||
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new FalkenrathGorgerEffect()));
|
||||
}
|
||||
|
@ -84,6 +96,8 @@ class FalkenrathGorgerEffect extends ContinuousEffectImpl {
|
|||
|
||||
}
|
||||
|
||||
HashMap<UUID, MadnessAbility> madnessAbilities = new HashMap<>(); // reuse the same ability for the same object
|
||||
|
||||
public FalkenrathGorgerEffect() {
|
||||
super(Duration.WhileOnBattlefield, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
|
||||
this.staticText = "Each Vampire creature card you own that isn't on the battlefield has madness. Its madness cost is equal to its mana cost";
|
||||
|
@ -91,6 +105,7 @@ class FalkenrathGorgerEffect extends ContinuousEffectImpl {
|
|||
|
||||
public FalkenrathGorgerEffect(final FalkenrathGorgerEffect effect) {
|
||||
super(effect);
|
||||
this.madnessAbilities.putAll(effect.madnessAbilities);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -102,25 +117,37 @@ class FalkenrathGorgerEffect extends ContinuousEffectImpl {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
HashMap<UUID, MadnessAbility> usedMadnessAbilities = new HashMap<>();
|
||||
// hand
|
||||
for (Card card : controller.getHand().getCards(filter, game)) {
|
||||
game.getState().addOtherAbility(card, new MadnessAbility(card, card.getSpellAbility().getManaCosts()));
|
||||
addMadnessToCard(game, card, usedMadnessAbilities);
|
||||
}
|
||||
// graveyard
|
||||
for (Card card : controller.getGraveyard().getCards(filter, game)) {
|
||||
game.getState().addOtherAbility(card, new MadnessAbility(card, card.getSpellAbility().getManaCosts()));
|
||||
addMadnessToCard(game, card, usedMadnessAbilities);
|
||||
}
|
||||
// Exile
|
||||
for (Card card : game.getExile().getAllCards(game)) {
|
||||
if (filter.match(card, source.getSourceId(), controller.getId(), game)) {
|
||||
if (card.getOwnerId().equals(controller.getId())) {
|
||||
game.getState().addOtherAbility(card, new MadnessAbility(card, card.getSpellAbility().getManaCosts()));
|
||||
addMadnessToCard(game, card, usedMadnessAbilities);
|
||||
}
|
||||
}
|
||||
}
|
||||
madnessAbilities.clear();
|
||||
madnessAbilities.putAll(usedMadnessAbilities);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void addMadnessToCard(Game game, Card card, HashMap<UUID, MadnessAbility> usedMadnessAbilities) {
|
||||
MadnessAbility ability = madnessAbilities.get(card.getId());
|
||||
if (ability == null) {
|
||||
ability = new MadnessAbility(card, card.getSpellAbility().getManaCosts());
|
||||
}
|
||||
game.getState().addOtherAbility(card, ability, false);
|
||||
usedMadnessAbilities.put(card.getId(), ability);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
*/
|
||||
package org.mage.test.cards.abilities.keywords;
|
||||
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
|
@ -111,7 +112,7 @@ public class MadnessTest extends CardTestPlayerBase {
|
|||
addCard(Zone.BATTLEFIELD, playerA, "Falkenrath Gorger", 1);
|
||||
|
||||
// Sacrifice a creature: Vampire Aristocrat gets +2/+2 until end of turn.
|
||||
addCard(Zone.HAND, playerA, "Vampire Aristocrat");
|
||||
addCard(Zone.HAND, playerA, "Vampire Aristocrat"); // {2}{B}
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 6);
|
||||
// Target player discards two cards. If you cast this spell during your main phase, that player discards four cards instead.
|
||||
|
@ -157,4 +158,63 @@ public class MadnessTest extends CardTestPlayerBase {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* Falkenrath Gorger + Asylum Visitor (& probably any Vampire with printed
|
||||
* Madness) + Olivia, Mobilized for War - Haste part of the triggered effect
|
||||
* may not affect entering Vampire properly, please read further for more
|
||||
* details.
|
||||
*
|
||||
* When I cast Falkenrath Gorger and then discarded Asylum Visitor with
|
||||
* Olivia, Mobilized for War 's triggered ability, two Madness pop-ups
|
||||
* appeared, I have used the first one, Asylum Visitor entered the
|
||||
* battlefield, Olivia triggered again and I used the ability to give Asylum
|
||||
* Visitor Haste and +1/+1. Then the second Madness trigger resolved for the
|
||||
* Visitor and I have cancelled it (by choosing "No" at first pop-up, but
|
||||
* from what I have tested, the choice at this point does not matter).
|
||||
* Asylum Visitor lost Haste and was both visually and functionally affected
|
||||
* by Summoning Sickness.
|
||||
*
|
||||
* I was able to avoid this issue by cancelling the first Madness pop-up and
|
||||
* then using only the second one.
|
||||
*/
|
||||
@Test
|
||||
public void testFalkenrathGorgerWithAsylumVisitor() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 1);
|
||||
|
||||
// Flying
|
||||
// Whenever another creature enters the battlefield under your control, you may discard a card. If you do, put a +1/+1 counter on that creature,
|
||||
// it gains haste until end of turn, and it becomes a Vampire in addition to its other types.
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Olivia, Mobilized for War", 1);
|
||||
|
||||
// Each Vampire creature card you own that isn't on the battlefield has madness. Its madness cost is equal to its mana cost.
|
||||
addCard(Zone.HAND, playerA, "Falkenrath Gorger", 1); // Creature Vampire 2/1 {R}
|
||||
// At the beginning of each player's upkeep, if that player has no cards in hand, you draw a card and you lose 1 life.
|
||||
// Madness {1}{B}
|
||||
addCard(Zone.HAND, playerA, "Asylum Visitor"); // Creature Vampire 3/1 {1}{B}
|
||||
addCard(Zone.HAND, playerA, "Forest");
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Falkenrath Gorger");
|
||||
setChoice(playerA, "Yes"); // Discard a card and put a +1/+1 counter on that creature, it gains haste until end of turn, and it becomes a Vampire in addition to its other types?
|
||||
setChoice(playerA, "Asylum Visitor");
|
||||
setChoice(playerA, "Yes"); // When this card is exiled this way, you may cast it by paying {1}{B} instead of putting it into your graveyard.
|
||||
setChoice(playerA, "Yes"); // Cast Asylum Visitor by madness?
|
||||
setChoice(playerA, "Yes"); // Discard a card and put a +1/+1 counter on that creature, it gains haste until end of turn, and it becomes a Vampire in addition to its other types?
|
||||
setChoice(playerA, "Forest");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, "Falkenrath Gorger", 1);
|
||||
assertPermanentCount(playerA, "Asylum Visitor", 1);
|
||||
|
||||
assertPowerToughness(playerA, "Falkenrath Gorger", 3, 2);
|
||||
assertAbility(playerA, "Falkenrath Gorger", HasteAbility.getInstance(), true);
|
||||
|
||||
assertPowerToughness(playerA, "Asylum Visitor", 4, 2);
|
||||
assertAbility(playerA, "Asylum Visitor", HasteAbility.getInstance(), true);
|
||||
|
||||
assertGraveyardCount(playerA, "Forest", 1);
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -54,6 +54,5 @@ public class GainControlAllEffect extends ContinuousEffectImpl {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Gain control of ").append(filter.getMessage());
|
||||
return sb.toString();
|
||||
//return "Gain control of " + filter;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public class MadnessAbility extends StaticAbility {
|
|||
@SuppressWarnings("unchecked")
|
||||
public MadnessAbility(Card card, ManaCosts madnessCost) {
|
||||
super(Zone.HAND, new MadnessReplacementEffect((ManaCosts<ManaCost>) madnessCost));
|
||||
addSubAbility(new MadnessTriggeredAbility((ManaCosts<ManaCost>) madnessCost));
|
||||
addSubAbility(new MadnessTriggeredAbility((ManaCosts<ManaCost>) madnessCost, getOriginalId()));
|
||||
rule = "Madness " + madnessCost.getText() + " <i>(If you discard this card, discard it into exile. When you do, cast it for its madness cost or put it into your graveyard.)</i>";
|
||||
}
|
||||
|
||||
|
@ -105,7 +105,8 @@ class MadnessReplacementEffect extends ReplacementEffectImpl {
|
|||
if (card != null) {
|
||||
if (controller.moveCardToExileWithInfo(card, source.getSourceId(), "Madness", source.getSourceId(), game, ((ZoneChangeEvent) event).getFromZone(), true)) {
|
||||
game.applyEffects(); // needed to add Madness ability to cards (e.g. by Falkenrath Gorger)
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.MADNESS_CARD_EXILED, card.getId(), card.getId(), controller.getId()));
|
||||
GameEvent gameEvent = GameEvent.getEvent(GameEvent.EventType.MADNESS_CARD_EXILED, card.getId(), source.getOriginalId(), controller.getId());
|
||||
game.fireEvent(gameEvent);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -134,14 +135,17 @@ class MadnessTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
//This array holds the Id's of all of the cards that activated madness
|
||||
private static ArrayList<UUID> activatedIds = new ArrayList<>();
|
||||
private final UUID madnessOriginalId;
|
||||
|
||||
MadnessTriggeredAbility(ManaCosts<ManaCost> madnessCost) {
|
||||
MadnessTriggeredAbility(ManaCosts<ManaCost> madnessCost, UUID madnessOriginalId) {
|
||||
super(Zone.EXILED, new MadnessCastEffect(madnessCost), true);
|
||||
this.madnessOriginalId = madnessOriginalId;
|
||||
this.setRuleVisible(false);
|
||||
}
|
||||
|
||||
MadnessTriggeredAbility(final MadnessTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.madnessOriginalId = ability.madnessOriginalId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -156,7 +160,7 @@ class MadnessTriggeredAbility extends TriggeredAbilityImpl {
|
|||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
return event.getTargetId().equals(getSourceId());
|
||||
return event.getSourceId().equals(madnessOriginalId); // Check that the event was from the connected replacement effect
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue