mirror of
https://github.com/correl/mage.git
synced 2025-04-02 03:18:09 -09:00
Fixed some put into graveyard effects that were implemented wrongly as triggered effects to replacment effects (LegacyWeapon, Progenitus, Darksteel Colossus, Blightsteel Colossus).
This commit is contained in:
parent
cc676b2258
commit
b094df2a52
11 changed files with 424 additions and 186 deletions
Mage.Sets/src/mage/sets
apocalypse
conflux
darksteel
innistrad
mirrodinbesieged
returntoravnica
Mage.Tests/src/test/java/org/mage/test/cards/replacement
Mage/src/mage
abilities
common
effects/common
players
|
@ -29,21 +29,14 @@ package mage.sets.apocalypse;
|
|||
|
||||
import java.util.UUID;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereTriggeredAbility;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereAbility;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ExileTargetEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.abilities.effects.common.RevealAndShuffleIntoLibrarySourceEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetPermanent;
|
||||
|
||||
/**
|
||||
|
@ -64,7 +57,7 @@ public class LegacyWeapon extends CardImpl {
|
|||
ability.addTarget(new TargetPermanent());
|
||||
this.addAbility(ability);
|
||||
// If Legacy Weapon would be put into a graveyard from anywhere, reveal Legacy Weapon and shuffle it into its owner's library instead.
|
||||
this.addAbility(new PutIntoGraveFromAnywhereTriggeredAbility(new LegacyWeaponEffect()));
|
||||
this.addAbility(new PutIntoGraveFromAnywhereAbility(new RevealAndShuffleIntoLibrarySourceEffect()));
|
||||
}
|
||||
|
||||
public LegacyWeapon(final LegacyWeapon card) {
|
||||
|
@ -76,37 +69,3 @@ public class LegacyWeapon extends CardImpl {
|
|||
return new LegacyWeapon(this);
|
||||
}
|
||||
}
|
||||
|
||||
class LegacyWeaponEffect extends OneShotEffect {
|
||||
|
||||
public LegacyWeaponEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "reveal {this} and shuffle it into its owner's library instead";
|
||||
}
|
||||
|
||||
public LegacyWeaponEffect(final LegacyWeaponEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LegacyWeaponEffect copy() {
|
||||
return new LegacyWeaponEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
Player player = game.getPlayer(card.getOwnerId());
|
||||
if (player != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.add(card);
|
||||
player.revealCards("Legacy Weapon", cards, game);
|
||||
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,21 +30,14 @@ package mage.sets.conflux;
|
|||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereAbility;
|
||||
import mage.abilities.effects.common.RevealAndShuffleIntoLibrarySourceEffect;
|
||||
import mage.abilities.keyword.ProtectionAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -72,10 +65,11 @@ public class Progenitus extends CardImpl {
|
|||
// spells or abilities, and all damage that would be dealt to Progenitus is prevented.
|
||||
// 2/1/2009: Progenitus can still be affected by effects that don't target it or deal damage
|
||||
// to it (such as Day of Judgment).
|
||||
|
||||
// Protection from everything
|
||||
this.addAbility(new ProgenitusProtectionAbility());
|
||||
// If Progenitus would be put into a graveyard from anywhere, reveal Progenitus and shuffle it into its owner's library instead.
|
||||
this.addAbility(new PutIntoGraveFromAnywhereTriggeredAbility(new ProgenitusEffect()));
|
||||
this.addAbility(new PutIntoGraveFromAnywhereAbility(new RevealAndShuffleIntoLibrarySourceEffect()));
|
||||
}
|
||||
|
||||
public Progenitus(final Progenitus card) {
|
||||
|
@ -113,37 +107,3 @@ class ProgenitusProtectionAbility extends ProtectionAbility {
|
|||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
class ProgenitusEffect extends OneShotEffect {
|
||||
|
||||
public ProgenitusEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "reveal {this} and shuffle it into its owner's library instead";
|
||||
}
|
||||
|
||||
public ProgenitusEffect(final ProgenitusEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ProgenitusEffect copy() {
|
||||
return new ProgenitusEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card card = game.getCard(source.getSourceId());
|
||||
if (card != null) {
|
||||
Player player = game.getPlayer(card.getOwnerId());
|
||||
if (player != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.add(card);
|
||||
player.revealCards("Progenitus", cards, game);
|
||||
card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,19 +33,11 @@ import java.util.UUID;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Rarity;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereAbility;
|
||||
import mage.abilities.effects.common.RevealAndShuffleIntoLibrarySourceEffect;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
|
@ -58,9 +50,15 @@ public class DarksteelColossus extends CardImpl {
|
|||
this.subtype.add("Golem");
|
||||
this.power = new MageInt(11);
|
||||
this.toughness = new MageInt(11);
|
||||
|
||||
// Trample
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
|
||||
// Darksteel Colossus is indestructible.
|
||||
this.addAbility(IndestructibleAbility.getInstance());
|
||||
this.addAbility(new PutIntoGraveFromAnywhereTriggeredAbility(new DarksteelColossusEffect(), false));
|
||||
|
||||
// If Darksteel Colossus would be put into a graveyard from anywhere, reveal Darksteel Colossus and shuffle it into its owner's library instead.
|
||||
this.addAbility(new PutIntoGraveFromAnywhereAbility(new RevealAndShuffleIntoLibrarySourceEffect()));
|
||||
}
|
||||
|
||||
public DarksteelColossus(final DarksteelColossus card) {
|
||||
|
@ -73,37 +71,3 @@ public class DarksteelColossus extends CardImpl {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
class DarksteelColossusEffect extends OneShotEffect {
|
||||
DarksteelColossusEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "reveal {this} and shuffle it into its owner's library instead";
|
||||
}
|
||||
|
||||
DarksteelColossusEffect(final DarksteelColossusEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card c = game.getCard(source.getSourceId());
|
||||
if (c != null) {
|
||||
Player player = game.getPlayer(c.getOwnerId());
|
||||
if (player != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.add(c);
|
||||
player.revealCards("Blightsteel Colossus", cards, game);
|
||||
c.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DarksteelColossusEffect copy() {
|
||||
return new DarksteelColossusEffect(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -68,10 +68,12 @@ public class LilianaOfTheVeil extends CardImpl {
|
|||
|
||||
// +1: Each player discards a card.
|
||||
this.addAbility(new LoyaltyAbility(new DiscardEachPlayerEffect(), 1));
|
||||
|
||||
// -2: Target player sacrifices a creature.
|
||||
LoyaltyAbility ability = new LoyaltyAbility(new SacrificeEffect(new FilterCreaturePermanent(), 1, "Target player"), -2);
|
||||
ability.addTarget(new TargetPlayer());
|
||||
this.addAbility(ability);
|
||||
|
||||
// -6: Separate all permanents target player controls into two piles. That player sacrifices all permanents in the pile of his or her choice.
|
||||
ability = new LoyaltyAbility(new LilianaOfTheVeilEffect(), -6);
|
||||
ability.addTarget(new TargetPlayer());
|
||||
|
|
|
@ -33,20 +33,12 @@ import java.util.UUID;
|
|||
import mage.constants.CardType;
|
||||
import mage.constants.Rarity;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.common.PutIntoGraveFromAnywhereAbility;
|
||||
import mage.abilities.effects.common.RevealAndShuffleIntoLibrarySourceEffect;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.abilities.keyword.InfectAbility;
|
||||
import mage.abilities.keyword.TrampleAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
* @author Loki
|
||||
|
@ -59,10 +51,16 @@ public class BlightsteelColossus extends CardImpl {
|
|||
this.subtype.add("Golem");
|
||||
this.power = new MageInt(11);
|
||||
this.toughness = new MageInt(11);
|
||||
|
||||
// Trample, infect
|
||||
this.addAbility(TrampleAbility.getInstance());
|
||||
this.addAbility(InfectAbility.getInstance());
|
||||
|
||||
// Blightsteel Colossus is indestructible.
|
||||
this.addAbility(IndestructibleAbility.getInstance());
|
||||
this.addAbility(new PutIntoGraveFromAnywhereTriggeredAbility(new BlightsteelColossusEffect(), false));
|
||||
|
||||
// If Blightsteel Colossus would be put into a graveyard from anywhere, reveal Blightsteel Colossus and shuffle it into its owner's library instead.
|
||||
this.addAbility(new PutIntoGraveFromAnywhereAbility(new RevealAndShuffleIntoLibrarySourceEffect()));
|
||||
}
|
||||
|
||||
public BlightsteelColossus(final BlightsteelColossus card) {
|
||||
|
@ -75,37 +73,3 @@ public class BlightsteelColossus extends CardImpl {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
class BlightsteelColossusEffect extends OneShotEffect {
|
||||
BlightsteelColossusEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "reveal {this} and shuffle it into its owner's library";
|
||||
}
|
||||
|
||||
BlightsteelColossusEffect(final BlightsteelColossusEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card c = game.getCard(source.getSourceId());
|
||||
if (c != null) {
|
||||
Player player = game.getPlayer(c.getOwnerId());
|
||||
if (player != null) {
|
||||
Cards cards = new CardsImpl();
|
||||
cards.add(c);
|
||||
player.revealCards("Blightsteel Colossus", cards, game);
|
||||
c.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true);
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BlightsteelColossusEffect copy() {
|
||||
return new BlightsteelColossusEffect(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -104,7 +104,7 @@ class DryadMilitantReplacementEffect extends ReplacementEffectImpl {
|
|||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD) {
|
||||
Card card = (Card) game.getCard(event.getTargetId());
|
||||
Card card = game.getCard(event.getTargetId());
|
||||
if (card != null && (card.getCardType().contains(CardType.SORCERY) || card.getCardType().contains(CardType.INSTANT))) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -165,10 +165,7 @@ class RestInPeaceReplacementEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,133 @@
|
|||
/*
|
||||
* 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 org.mage.test.cards.replacement;
|
||||
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* Checks if change zone replacement effects work as intended
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class ZoneChangeReplacementTest extends CardTestPlayerBase {
|
||||
|
||||
// If Darksteel Colossus would be put into a graveyard from anywhere,
|
||||
// reveal Darksteel Colossus and shuffle it into its owner's library instead.
|
||||
@Test
|
||||
public void testFromLibraryZoneChange() {
|
||||
addCard(Zone.LIBRARY, playerA, "Darksteel Colossus");
|
||||
// Tome Scour - Sorcery - {U}
|
||||
// Target player puts the top five cards of his or her library into his or her graveyard.
|
||||
addCard(Zone.HAND, playerA, "Tome Scour");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
skipInitShuffling();
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Tome Scour", playerA);
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Darksteel Colossus", 0);
|
||||
assertGraveyardCount(playerA, 5); // 4 + Tome Scour
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testFromHandZoneChange() {
|
||||
addCard(Zone.HAND, playerA, "Progenitus");
|
||||
// Distress - Sorcery - {B}{B}
|
||||
// Target player reveals his or her hand. You choose a nonland card from it. That player discards that card.
|
||||
addCard(Zone.HAND, playerA, "Distress");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Distress", playerA);
|
||||
setChoice(playerA, "Progenitus");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Progenitus", 0);
|
||||
assertGraveyardCount(playerA, 1); // Distress
|
||||
|
||||
assertHandCount(playerA, "Progenitus", 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void checkBridgeDoesWork() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Silvercoat Lion");
|
||||
// Diabolic Edict - Instant - {1}{B}
|
||||
// Target player sacrifices a creature.
|
||||
addCard(Zone.HAND, playerA, "Diabolic Edict");
|
||||
// Whenever a nontoken creature is put into your graveyard from the battlefield, if Bridge from
|
||||
// Below is in your graveyard, put a 2/2 black Zombie creature token onto the battlefield.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bridge from Below");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Diabolic Edict", playerA);
|
||||
setChoice(playerA, "Silvercoat Lion");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Silvercoat Lion", 1);
|
||||
assertGraveyardCount(playerA, 3); // Diabolic Edict + Bridge from Below + Silvercoat Lion
|
||||
assertPermanentCount(playerA, "Zombie", 1); // Silvercoat Lion goes to graveyard so a Zombie tokes is created
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoesntTriggerDiesTriggeredAbilities() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Progenitus");
|
||||
// Diabolic Edict - Instant - {1}{B}
|
||||
// Target player sacrifices a creature.
|
||||
addCard(Zone.HAND, playerA, "Diabolic Edict");
|
||||
// Whenever a nontoken creature is put into your graveyard from the battlefield, if Bridge from
|
||||
// Below is in your graveyard, put a 2/2 black Zombie creature token onto the battlefield.
|
||||
addCard(Zone.GRAVEYARD, playerA, "Bridge from Below");
|
||||
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 2);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Diabolic Edict", playerA);
|
||||
setChoice(playerA, "Progenitus");
|
||||
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertGraveyardCount(playerA, "Progenitus", 0);
|
||||
assertGraveyardCount(playerA, 2); // Diabolic Edict + Bridge from Below
|
||||
assertPermanentCount(playerA, "Zombie", 0); // Progenitus never touches graveyard - so no Zombie tokes is created
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
/*
|
||||
* 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.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.effects.ContinuousEffect;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.Effects;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.constants.Duration;
|
||||
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;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class PutIntoGraveFromAnywhereAbility extends SimpleStaticAbility {
|
||||
|
||||
public PutIntoGraveFromAnywhereAbility(Effect baseEffect) {
|
||||
this(baseEffect, null, "", true, false);
|
||||
}
|
||||
|
||||
public PutIntoGraveFromAnywhereAbility(Effect baseEffect, Condition condition, String text, boolean selfScope, boolean optional) {
|
||||
super(Zone.ALL, new PutIntoGraveFromAnywhereEffect(baseEffect, condition, text, selfScope, optional));
|
||||
}
|
||||
|
||||
public PutIntoGraveFromAnywhereAbility(final PutIntoGraveFromAnywhereAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SimpleStaticAbility copy() {
|
||||
return new PutIntoGraveFromAnywhereAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "If {this} would be put into a graveyard from anywhere, " + super.getRule();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class PutIntoGraveFromAnywhereEffect extends ReplacementEffectImpl {
|
||||
|
||||
protected Effects baseEffects = new Effects();
|
||||
protected String text;
|
||||
protected Condition condition;
|
||||
protected boolean optional;
|
||||
|
||||
public static final String SOURCE_CAST_SPELL_ABILITY = "sourceCastSpellAbility";
|
||||
|
||||
public PutIntoGraveFromAnywhereEffect(Effect baseEffect) {
|
||||
this(baseEffect, "");
|
||||
}
|
||||
|
||||
public PutIntoGraveFromAnywhereEffect(Effect baseEffect, String text) {
|
||||
this(baseEffect, null, text, true, false);
|
||||
}
|
||||
|
||||
public PutIntoGraveFromAnywhereEffect(Effect baseEffect, String text, boolean optional) {
|
||||
this(baseEffect, null, text, true, optional);
|
||||
}
|
||||
|
||||
public PutIntoGraveFromAnywhereEffect(Effect baseEffect, Condition condition, String text) {
|
||||
this(baseEffect, condition, text, true, false);
|
||||
}
|
||||
|
||||
public PutIntoGraveFromAnywhereEffect(Effect baseEffect, Condition condition, String text, boolean selfScope, boolean optional) {
|
||||
super(Duration.EndOfGame, baseEffect.getOutcome(), selfScope);
|
||||
this.baseEffects.add(baseEffect);
|
||||
this.text = text;
|
||||
this.condition = condition;
|
||||
this.optional = optional;
|
||||
}
|
||||
|
||||
public PutIntoGraveFromAnywhereEffect(PutIntoGraveFromAnywhereEffect effect) {
|
||||
super(effect);
|
||||
this.baseEffects = effect.baseEffects.copy();
|
||||
this.text = effect.text;
|
||||
this.condition = effect.condition;
|
||||
this.optional = effect.optional;
|
||||
}
|
||||
|
||||
public void addEffect(Effect effect) {
|
||||
baseEffects.add(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (GameEvent.EventType.ZONE_CHANGE.equals(event.getType())
|
||||
&& ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD
|
||||
&& event.getTargetId().equals(source.getSourceId())) {
|
||||
if (condition == null || condition.apply(game, source)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
if (optional) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject object = game.getObject(source.getSourceId());
|
||||
if (controller == null || object == null) {
|
||||
return false;
|
||||
}
|
||||
if (!controller.chooseUse(outcome, new StringBuilder("Use effect of ").append(object.getLogName()).append("?").toString(), game)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Spell spell = game.getStack().getSpell(event.getSourceId());
|
||||
for (Effect effect: baseEffects) {
|
||||
if (effect instanceof ContinuousEffect) {
|
||||
game.addEffect((ContinuousEffect) effect, source);
|
||||
}
|
||||
else {
|
||||
if (spell != null) {
|
||||
effect.setValue(SOURCE_CAST_SPELL_ABILITY, spell.getSpellAbility());
|
||||
}
|
||||
effect.apply(game, source);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getText(Mode mode) {
|
||||
return (text == null || text.isEmpty()) ? baseEffects.getText(mode) : text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PutIntoGraveFromAnywhereEffect copy() {
|
||||
return new PutIntoGraveFromAnywhereEffect(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* 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.effects.common;
|
||||
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
|
||||
public class RevealAndShuffleIntoLibrarySourceEffect extends OneShotEffect {
|
||||
|
||||
public RevealAndShuffleIntoLibrarySourceEffect() {
|
||||
super(Outcome.Neutral);
|
||||
staticText = "reveal {this} and shuffle it into its owner's library instead";
|
||||
}
|
||||
|
||||
public RevealAndShuffleIntoLibrarySourceEffect(final RevealAndShuffleIntoLibrarySourceEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Card sourceCard = game.getCard(source.getSourceId());
|
||||
MageObject sourceObject = game.getObject(source.getSourceId());
|
||||
if (sourceCard != null) {
|
||||
Player player = game.getPlayer(sourceCard.getOwnerId());
|
||||
if (player != null) {
|
||||
Zone fromZone = game.getState().getZone(sourceCard.getId());
|
||||
Cards cards = new CardsImpl();
|
||||
cards.add(sourceCard);
|
||||
player.revealCards(sourceObject.getLogName(), cards, game);
|
||||
player.moveCardToLibraryWithInfo(sourceCard, source.getSourceId(), game, fromZone, true, true);
|
||||
player.shuffleLibrary(game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RevealAndShuffleIntoLibrarySourceEffect copy() {
|
||||
return new RevealAndShuffleIntoLibrarySourceEffect(this);
|
||||
}
|
||||
|
||||
}
|
|
@ -631,13 +631,14 @@ public abstract class PlayerImpl implements Player, Serializable {
|
|||
the moment before the cost was paid (see rule 717, "Handling Illegal Actions").
|
||||
*/
|
||||
if (card != null) {
|
||||
// write info to game log first so game log infos from triggered or replacement effects follow in the game log
|
||||
game.informPlayers(new StringBuilder(name).append(" discards ").append(card.getName()).toString());
|
||||
/* If a card is discarded while Rest in Peace is on the battlefield, abilities that function
|
||||
* when a card is discarded (such as madness) still work, even though that card never reaches
|
||||
* a graveyard. In addition, spells or abilities that check the characteristics of a discarded
|
||||
* card (such as Chandra Ablaze's first ability) can find that card in exile. */
|
||||
* card (such as Chandra Ablaze's first ability) can find that card in exile. */
|
||||
card.moveToZone(Zone.GRAVEYARD, source==null?null:source.getSourceId(), game, false);
|
||||
// So discard is also successful if card is moved to another zone by replacement effect!
|
||||
card.moveToZone(Zone.GRAVEYARD, source==null?null:source.getSourceId(), game, false);
|
||||
game.informPlayers(new StringBuilder(name).append(" discards ").append(card.getName()).toString());
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.DISCARDED_CARD, card.getId(), source==null?null:source.getSourceId(), playerId));
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue