mirror of
https://github.com/correl/mage.git
synced 2024-12-25 11:11:16 +00:00
Added Mana Drain and Spell Crumple. Fixed replacement effect of Hinder.
This commit is contained in:
parent
97276cbd2a
commit
48e8be4fc2
14 changed files with 599 additions and 48 deletions
|
@ -35,14 +35,20 @@ import mage.constants.Zone;
|
|||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -91,27 +97,98 @@ class HinderEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
UUID objectId = source.getFirstTarget();
|
||||
UUID sourceId = source.getSourceId();
|
||||
|
||||
// counter code from Spellstack
|
||||
StackObject stackObject = game.getStack().getStackObject(objectId);
|
||||
if (stackObject != null && !game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) {
|
||||
if (stackObject instanceof Spell) {
|
||||
game.rememberLKI(objectId, Zone.STACK, (Spell) stackObject);
|
||||
}
|
||||
game.getStack().remove(stackObject);
|
||||
MageObject targetObject = game.getObject(stackObject.getSourceId());
|
||||
Zone targetZone = Zone.LIBRARY;
|
||||
if (targetObject instanceof Card) {
|
||||
Card card = (Card) targetObject;
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
boolean top = player.chooseUse(Outcome.Neutral, "Put " + card.getName() + " on top of the library? Otherwise it will be put on the bottom.", game);
|
||||
card.moveToZone(targetZone, sourceId, game, top);
|
||||
game.informPlayers(player.getName() + " has put " + card.getName() + " on " + (top ? "top" : "the bottom") + " of the library.");
|
||||
MageObject sourceObject = game.getObject(sourceId);
|
||||
if (stackObject != null && sourceObject != null) {
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) {
|
||||
if ( stackObject instanceof Spell ) {
|
||||
game.rememberLKI(objectId, Zone.STACK, (Spell)stackObject);
|
||||
}
|
||||
// Hinder specific code
|
||||
ReplacementEffectImpl effect = new HinderReplacementEffect();
|
||||
effect.setTargetPointer(new FixedTarget(stackObject.getId()));
|
||||
game.addEffect(effect, source);
|
||||
// Hinder specific code end
|
||||
game.informPlayers(new StringBuilder(stackObject.getName()).append(" is countered by ").append(sourceObject.getLogName()).toString());
|
||||
game.getStack().remove(stackObject);
|
||||
stackObject.counter(sourceId, game); // tries to move to graveyard
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
|
||||
} else {
|
||||
game.informPlayers("Server: Couldn't move card to zone = " + targetZone + " as it has other than Card type.");
|
||||
game.informPlayers(new StringBuilder(stackObject.getName()).append(" could not be countered by ").append(sourceObject.getLogName()).toString());
|
||||
}
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// counter code from Spellstack end
|
||||
}
|
||||
}
|
||||
|
||||
class HinderReplacementEffect extends ReplacementEffectImpl {
|
||||
|
||||
private PhaseStep phaseStep;
|
||||
|
||||
public HinderReplacementEffect() {
|
||||
super(Duration.OneUse, Outcome.Benefit);
|
||||
staticText = "If that spell is countered this way, put that card on the top or bottom of its owner's library instead of into that player's graveyard";
|
||||
phaseStep = null;
|
||||
}
|
||||
|
||||
public HinderReplacementEffect(final HinderReplacementEffect effect) {
|
||||
super(effect);
|
||||
phaseStep = effect.phaseStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HinderReplacementEffect copy() {
|
||||
return new HinderReplacementEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (!game.getPhase().getStep().getType().equals(phaseStep)) {
|
||||
return true;
|
||||
}
|
||||
return super.isInactive(source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
phaseStep = game.getPhase().getStep().getType();
|
||||
super.init(source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
MageObject targetObject = game.getObject(event.getTargetId());
|
||||
if (targetObject instanceof Card) {
|
||||
Card card = (Card) targetObject;
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
if (player != null) {
|
||||
boolean top = player.chooseUse(Outcome.Neutral, "Put " + card.getName() + " on top of the library? Otherwise it will be put on the bottom.", game);
|
||||
if (card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, top, event.getAppliedEffects())) {
|
||||
game.informPlayers(player.getName() + " has put " + card.getName() + " on " + (top ? "top" : "the bottom") + " of the library.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone().equals(Zone.GRAVEYARD)) {
|
||||
MageObject mageObject = game.getLastKnownInformation(getTargetPointer().getFirst(game, source), Zone.STACK);
|
||||
if (mageObject instanceof Spell) {
|
||||
return ((Spell)mageObject).getSourceId().equals(event.getTargetId());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public class MagusOfTheVineyard extends CardImpl {
|
|||
|
||||
// At the beginning of each player's precombat main phase, add {G}{G} to that player's mana pool.
|
||||
this.addAbility(new BeginningOfPreCombatMainTriggeredAbility(
|
||||
Zone.BATTLEFIELD, new AddManaToManaPoolEffect(GreenMana(2)), TargetController.ANY, false, true));
|
||||
Zone.BATTLEFIELD, new AddManaToManaPoolEffect(GreenMana(2), "that player's"), TargetController.ANY, false, true));
|
||||
}
|
||||
|
||||
public MagusOfTheVineyard(final MagusOfTheVineyard card) {
|
||||
|
|
195
Mage.Sets/src/mage/sets/commander/SpellCrumple.java
Normal file
195
Mage.Sets/src/mage/sets/commander/SpellCrumple.java
Normal file
|
@ -0,0 +1,195 @@
|
|||
/*
|
||||
* 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.sets.commander;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.ReturnToLibrarySpellEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.game.stack.StackObject;
|
||||
import mage.players.Player;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class SpellCrumple extends CardImpl {
|
||||
|
||||
public SpellCrumple(UUID ownerId) {
|
||||
super(ownerId, 63, "Spell Crumple", Rarity.UNCOMMON, new CardType[]{CardType.INSTANT}, "{1}{U}{U}");
|
||||
this.expansionSetCode = "CMD";
|
||||
|
||||
this.color.setBlue(true);
|
||||
|
||||
// Counter target spell. If that spell is countered this way, put it on the bottom of its owner's library instead of into that player's graveyard. Put Spell Crumple on the bottom of its owner's library.
|
||||
this.getSpellAbility().addTarget(new TargetSpell());
|
||||
this.getSpellAbility().addEffect(new SpellCrumpleCounterEffect());
|
||||
this.getSpellAbility().addEffect(new ReturnToLibrarySpellEffect(false));
|
||||
}
|
||||
|
||||
public SpellCrumple(final SpellCrumple card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellCrumple copy() {
|
||||
return new SpellCrumple(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SpellCrumpleCounterEffect extends OneShotEffect {
|
||||
|
||||
public SpellCrumpleCounterEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Counter target spell. If that spell is countered this way, put it on the bottom of its owner's library instead of into that player's graveyard";
|
||||
}
|
||||
|
||||
public SpellCrumpleCounterEffect(final SpellCrumpleCounterEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellCrumpleCounterEffect copy() {
|
||||
return new SpellCrumpleCounterEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
UUID objectId = source.getFirstTarget();
|
||||
UUID sourceId = source.getSourceId();
|
||||
// counter code from SpellStack
|
||||
StackObject stackObject = game.getStack().getStackObject(objectId);
|
||||
MageObject sourceObject = game.getObject(sourceId);
|
||||
if (stackObject != null && sourceObject != null) {
|
||||
if (!game.replaceEvent(GameEvent.getEvent(GameEvent.EventType.COUNTER, objectId, sourceId, stackObject.getControllerId()))) {
|
||||
if ( stackObject instanceof Spell ) {
|
||||
game.rememberLKI(objectId, Zone.STACK, (Spell)stackObject);
|
||||
}
|
||||
// Spell Crumple specific code
|
||||
ReplacementEffectImpl effect = new SpellCrumpleReplacementEffect();
|
||||
effect.setTargetPointer(new FixedTarget(stackObject.getId()));
|
||||
game.addEffect(effect, source);
|
||||
// Spell Crumple specific code end
|
||||
game.informPlayers(new StringBuilder(stackObject.getName()).append(" is countered by ").append(sourceObject.getLogName()).toString());
|
||||
game.getStack().remove(stackObject);
|
||||
stackObject.counter(sourceId, game); // tries to move to graveyard
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
|
||||
} else {
|
||||
game.informPlayers(new StringBuilder(stackObject.getName()).append(" could not be countered by ").append(sourceObject.getLogName()).toString());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
// counter code from SpellStack end
|
||||
}
|
||||
}
|
||||
|
||||
class SpellCrumpleReplacementEffect extends ReplacementEffectImpl {
|
||||
|
||||
private PhaseStep phaseStep;
|
||||
|
||||
public SpellCrumpleReplacementEffect() {
|
||||
super(Duration.OneUse, Outcome.Benefit);
|
||||
staticText = "If that spell is countered this way, put it on the bottom of its owner's library instead of into that player's graveyard";
|
||||
phaseStep = null;
|
||||
}
|
||||
|
||||
public SpellCrumpleReplacementEffect(final SpellCrumpleReplacementEffect effect) {
|
||||
super(effect);
|
||||
phaseStep = effect.phaseStep;
|
||||
}
|
||||
|
||||
@Override
|
||||
public SpellCrumpleReplacementEffect copy() {
|
||||
return new SpellCrumpleReplacementEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isInactive(Ability source, Game game) {
|
||||
if (!game.getPhase().getStep().getType().equals(phaseStep)) {
|
||||
return true;
|
||||
}
|
||||
return super.isInactive(source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
phaseStep = game.getPhase().getStep().getType();
|
||||
super.init(source, game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
MageObject targetObject = game.getObject(event.getTargetId());
|
||||
if (targetObject instanceof Card) {
|
||||
Card card = (Card) targetObject;
|
||||
if (card.moveToZone(Zone.LIBRARY, source.getSourceId(), game, false, event.getAppliedEffects())) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
game.informPlayers(controller.getName() + " has put " + card.getName() + " on the bottom of the library.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone().equals(Zone.GRAVEYARD)) {
|
||||
MageObject mageObject = game.getLastKnownInformation(getTargetPointer().getFirst(game, source), Zone.STACK);
|
||||
if (mageObject instanceof Spell) {
|
||||
return ((Spell)mageObject).getSourceId().equals(event.getTargetId());
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
|
@ -35,7 +35,8 @@ import mage.constants.Rarity;
|
|||
import mage.constants.TargetController;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.delayed.AtTheBeginOfPreCombatMainDelayedTriggeredAbility;
|
||||
import mage.abilities.common.delayed.AtTheBeginOMainPhaseDelayedTriggeredAbility;
|
||||
import mage.abilities.common.delayed.AtTheBeginOMainPhaseDelayedTriggeredAbility.PhaseSelection;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.ManaEffect;
|
||||
import mage.cards.CardImpl;
|
||||
|
@ -91,18 +92,19 @@ class PlasmCaptureCounterEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
boolean result = false;
|
||||
Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source));
|
||||
if (spell != null) {
|
||||
result = game.getStack().counter(getTargetPointer().getFirst(game, source), source.getSourceId(), game);
|
||||
game.getStack().counter(getTargetPointer().getFirst(game, source), source.getSourceId(), game);
|
||||
// mana gets added also if counter is not successful
|
||||
int mana = spell.getConvertedManaCost();
|
||||
AtTheBeginOfPreCombatMainDelayedTriggeredAbility delayedAbility =
|
||||
new AtTheBeginOfPreCombatMainDelayedTriggeredAbility(new PlasmCaptureManaEffect(mana), TargetController.YOU);
|
||||
AtTheBeginOMainPhaseDelayedTriggeredAbility delayedAbility =
|
||||
new AtTheBeginOMainPhaseDelayedTriggeredAbility(new PlasmCaptureManaEffect(mana), TargetController.YOU, PhaseSelection.NEXT_PRECOMBAT_MAIN);
|
||||
delayedAbility.setSourceId(source.getSourceId());
|
||||
delayedAbility.setControllerId(source.getControllerId());
|
||||
game.addDelayedTriggeredAbility(delayedAbility);
|
||||
return true;
|
||||
}
|
||||
return result;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,11 +154,8 @@ class PlasmCaptureManaEffect extends ManaEffect {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
if (mana != null) {
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
return true;
|
||||
}
|
||||
player.getManaPool().addMana(mana, game, source);
|
||||
return true;
|
||||
|
||||
}
|
||||
return false;
|
||||
|
|
54
Mage.Sets/src/mage/sets/legends/ManaDrain.java
Normal file
54
Mage.Sets/src/mage/sets/legends/ManaDrain.java
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* 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.sets.legends;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.constants.Rarity;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ManaDrain extends mage.sets.vintagemasters.ManaDrain {
|
||||
|
||||
public ManaDrain(UUID ownerId) {
|
||||
super(ownerId);
|
||||
this.cardNumber = 65;
|
||||
this.expansionSetCode = "LEG";
|
||||
this.rarity = Rarity.UNCOMMON;
|
||||
}
|
||||
|
||||
public ManaDrain(final ManaDrain card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaDrain copy() {
|
||||
return new ManaDrain(this);
|
||||
}
|
||||
}
|
|
@ -51,7 +51,7 @@ public class EladamrisVineyard extends CardImpl {
|
|||
|
||||
// At the beginning of each player's precombat main phase, add {G}{G} to that player's mana pool.
|
||||
this.addAbility(new BeginningOfPreCombatMainTriggeredAbility(
|
||||
Zone.BATTLEFIELD, new AddManaToManaPoolEffect(GreenMana(2)), TargetController.ANY, false, true));
|
||||
Zone.BATTLEFIELD, new AddManaToManaPoolEffect(GreenMana(2), "that player's"), TargetController.ANY, false, true));
|
||||
}
|
||||
|
||||
public EladamrisVineyard(final EladamrisVineyard card) {
|
||||
|
|
109
Mage.Sets/src/mage/sets/vintagemasters/ManaDrain.java
Normal file
109
Mage.Sets/src/mage/sets/vintagemasters/ManaDrain.java
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
* 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.sets.vintagemasters;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.Mana;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.delayed.AtTheBeginOMainPhaseDelayedTriggeredAbility;
|
||||
import mage.abilities.common.delayed.AtTheBeginOMainPhaseDelayedTriggeredAbility.PhaseSelection;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.AddManaToManaPoolEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.Rarity;
|
||||
import mage.constants.TargetController;
|
||||
import mage.game.Game;
|
||||
import mage.game.stack.Spell;
|
||||
import mage.target.TargetSpell;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ManaDrain extends CardImpl {
|
||||
|
||||
public ManaDrain(UUID ownerId) {
|
||||
super(ownerId, 78, "Mana Drain", Rarity.MYTHIC, new CardType[]{CardType.INSTANT}, "{U}{U}");
|
||||
this.expansionSetCode = "VMA";
|
||||
|
||||
this.color.setBlue(true);
|
||||
|
||||
// Counter target spell. At the beginning of your next main phase, add {X} to your mana pool, where X is that spell's converted mana cost.
|
||||
this.getSpellAbility().addTarget(new TargetSpell());
|
||||
this.getSpellAbility().addEffect(new ManaDrainCounterEffect());
|
||||
}
|
||||
|
||||
public ManaDrain(final ManaDrain card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaDrain copy() {
|
||||
return new ManaDrain(this);
|
||||
}
|
||||
}
|
||||
|
||||
class ManaDrainCounterEffect extends OneShotEffect {
|
||||
|
||||
public ManaDrainCounterEffect() {
|
||||
super(Outcome.Benefit);
|
||||
this.staticText = "Counter target spell. At the beginning of your next main phase, add {X} to your mana pool, where X is that spell's converted mana cost";
|
||||
}
|
||||
|
||||
public ManaDrainCounterEffect(final ManaDrainCounterEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ManaDrainCounterEffect copy() {
|
||||
return new ManaDrainCounterEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source));
|
||||
if (spell != null) {
|
||||
game.getStack().counter(getTargetPointer().getFirst(game, source), source.getSourceId(), game);
|
||||
// mana gets added also if counter is not successful
|
||||
int cmc = spell.getConvertedManaCost();
|
||||
Effect effect = new AddManaToManaPoolEffect(new Mana(0,0,0,0,0,cmc,0), "your");
|
||||
effect.setTargetPointer(new FixedTarget(source.getControllerId()));
|
||||
AtTheBeginOMainPhaseDelayedTriggeredAbility delayedAbility =
|
||||
new AtTheBeginOMainPhaseDelayedTriggeredAbility(effect, TargetController.YOU, PhaseSelection.NEXT_MAIN);
|
||||
delayedAbility.setSourceId(source.getSourceId());
|
||||
delayedAbility.setControllerId(source.getControllerId());
|
||||
game.addDelayedTriggeredAbility(delayedAbility);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -37,7 +37,6 @@ import mage.MageInt;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleStaticAbility;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
|
|
|
@ -99,6 +99,10 @@ public class MageObjectReference implements Comparable<MageObjectReference> {
|
|||
return hash;
|
||||
}
|
||||
|
||||
public boolean refersTo(UUID id, Game game) {
|
||||
return refersTo(game.getObject(id));
|
||||
}
|
||||
|
||||
public boolean refersTo(Permanent permanent) {
|
||||
return permanent.getZoneChangeCounter()== zoneChangeCounter && permanent.getId().equals(sourceId);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
* authors and should not be interpreted as representing official policies, either expressed
|
||||
* or implied, of BetaSteward_at_googlemail.com.
|
||||
*/
|
||||
|
||||
package mage.abilities.common.delayed;
|
||||
|
||||
import mage.constants.TargetController;
|
||||
|
@ -33,35 +32,57 @@ import mage.abilities.DelayedTriggeredAbility;
|
|||
import mage.abilities.effects.Effect;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.GameEvent.EventType;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class AtTheBeginOMainPhaseDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||
|
||||
public class AtTheBeginOfPreCombatMainDelayedTriggeredAbility extends DelayedTriggeredAbility {
|
||||
public enum PhaseSelection {
|
||||
|
||||
private TargetController targetController;
|
||||
NEXT_PRECOMBAT_MAIN("next precombat"),
|
||||
NEXT_POSTCOMAT_MAIN("next postcombat"),
|
||||
NEXT_MAIN("next");
|
||||
|
||||
public AtTheBeginOfPreCombatMainDelayedTriggeredAbility(Effect effect, TargetController targetController) {
|
||||
super(effect);
|
||||
this.targetController = targetController;
|
||||
private final String text;
|
||||
|
||||
PhaseSelection(String text) {
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
public AtTheBeginOfPreCombatMainDelayedTriggeredAbility(AtTheBeginOfPreCombatMainDelayedTriggeredAbility ability) {
|
||||
private final TargetController targetController;
|
||||
private final PhaseSelection phaseSelection;
|
||||
|
||||
public AtTheBeginOMainPhaseDelayedTriggeredAbility(Effect effect, TargetController targetController, PhaseSelection phaseSelection) {
|
||||
super(effect);
|
||||
this.targetController = targetController;
|
||||
this.phaseSelection = phaseSelection;
|
||||
|
||||
}
|
||||
|
||||
public AtTheBeginOMainPhaseDelayedTriggeredAbility(final AtTheBeginOMainPhaseDelayedTriggeredAbility ability) {
|
||||
super(ability);
|
||||
this.targetController = ability.targetController;
|
||||
this.phaseSelection = ability.phaseSelection;
|
||||
}
|
||||
|
||||
@Override
|
||||
public AtTheBeginOfPreCombatMainDelayedTriggeredAbility copy() {
|
||||
return new AtTheBeginOfPreCombatMainDelayedTriggeredAbility(this);
|
||||
public AtTheBeginOMainPhaseDelayedTriggeredAbility copy() {
|
||||
return new AtTheBeginOMainPhaseDelayedTriggeredAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
if (event.getType() == GameEvent.EventType.PRECOMBAT_MAIN_PHASE_PRE) {
|
||||
if (checkPhase(event.getType())) {
|
||||
switch (targetController) {
|
||||
case ANY:
|
||||
return true;
|
||||
|
@ -87,21 +108,34 @@ public class AtTheBeginOfPreCombatMainDelayedTriggeredAbility extends DelayedTri
|
|||
return false;
|
||||
}
|
||||
|
||||
private boolean checkPhase(EventType eventType) {
|
||||
switch (phaseSelection) {
|
||||
case NEXT_MAIN:
|
||||
return EventType.PRECOMBAT_MAIN_PHASE_PRE.equals(eventType) || EventType.PRECOMBAT_MAIN_PHASE_POST.equals(eventType);
|
||||
case NEXT_POSTCOMAT_MAIN:
|
||||
return EventType.PRECOMBAT_MAIN_PHASE_POST.equals(eventType);
|
||||
case NEXT_PRECOMBAT_MAIN:
|
||||
return EventType.PRECOMBAT_MAIN_PHASE_PRE.equals(eventType);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
switch (targetController) {
|
||||
case YOU:
|
||||
sb.append("At the beginning of your next precombat main phase, ");
|
||||
sb.append("At the beginning of your ").append(phaseSelection.toString()).append(" main phase, ");
|
||||
break;
|
||||
case OPPONENT:
|
||||
sb.append("At the beginning of an opponent's next precombat main phase, ");
|
||||
sb.append("At the beginning of an opponent's ").append(phaseSelection.toString()).append(" main phase, ");
|
||||
break;
|
||||
case ANY:
|
||||
sb.append("At the beginning of the next precombat main phase, ");
|
||||
sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" main phase, ");
|
||||
break;
|
||||
case CONTROLLER_ATTACHED_TO:
|
||||
sb.append("At the beginning of the next precombat main phase of enchanted creature's controller, ");
|
||||
sb.append("At the beginning of the ").append(phaseSelection.toString()).append(" main phase of enchanted creature's controller, ");
|
||||
break;
|
||||
}
|
||||
sb.append(getEffects().getText(modes.getMode()));
|
|
@ -22,10 +22,10 @@ public class AddManaToManaPoolEffect extends OneShotEffect {
|
|||
|
||||
protected Mana mana;
|
||||
|
||||
public AddManaToManaPoolEffect(Mana mana) {
|
||||
public AddManaToManaPoolEffect(Mana mana, String textManaPoolOwner) {
|
||||
super(Outcome.PutManaInPool);
|
||||
this.mana = mana;
|
||||
this.staticText = "add " + mana.toString() + " to that player's mana pool";
|
||||
this.staticText = "add " + mana.toString() + " to " + textManaPoolOwner + " mana pool";
|
||||
}
|
||||
|
||||
public AddManaToManaPoolEffect(final AddManaToManaPoolEffect effect) {
|
||||
|
|
|
@ -9,6 +9,7 @@ import mage.game.Game;
|
|||
|
||||
import java.io.ObjectStreamException;
|
||||
import java.util.UUID;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -41,7 +42,10 @@ public class ReturnToHandSpellEffect extends PostResolveEffect implements MageSi
|
|||
|
||||
@Override
|
||||
public void postResolve(Card card, Ability source, UUID controllerId, Game game) {
|
||||
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null) {
|
||||
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.STACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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 java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.PostResolveEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public class ReturnToLibrarySpellEffect extends PostResolveEffect {
|
||||
|
||||
private final boolean toTop;
|
||||
|
||||
public ReturnToLibrarySpellEffect(boolean top) {
|
||||
staticText = "Put {this} on "+ (top ? "top":"the bottom") + " of its owner's library";
|
||||
this.toTop = top;
|
||||
}
|
||||
|
||||
public ReturnToLibrarySpellEffect(final ReturnToLibrarySpellEffect effect) {
|
||||
super(effect);
|
||||
this.toTop = effect.toTop;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ReturnToLibrarySpellEffect copy() {
|
||||
return new ReturnToLibrarySpellEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void postResolve(Card card, Ability source, UUID controllerId, Game game) {
|
||||
Player controller = game.getPlayer(controllerId);
|
||||
if (controller != null) {
|
||||
controller.moveCardToLibraryWithInfo(card, source.getSourceId(), game, Zone.STACK, toTop, true);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -73,6 +73,9 @@ public class SpellStack extends ArrayDeque<StackObject> {
|
|||
}
|
||||
|
||||
public boolean counter(UUID objectId, UUID sourceId, Game game) {
|
||||
// the counter logic is copied by some spells to handle replacement effects of the countered spell
|
||||
// so if logic is changed here check those spells for needed changes too
|
||||
// Concerned cards to check: Hinder, Spell Crumple
|
||||
StackObject stackObject = getStackObject(objectId);
|
||||
MageObject sourceObject = game.getObject(sourceId);
|
||||
if (stackObject != null && sourceObject != null) {
|
||||
|
@ -81,7 +84,7 @@ public class SpellStack extends ArrayDeque<StackObject> {
|
|||
game.rememberLKI(objectId, Zone.STACK, (Spell)stackObject);
|
||||
}
|
||||
this.remove(stackObject);
|
||||
stackObject.counter(sourceId, game);
|
||||
stackObject.counter(sourceId, game); // tries to move to graveyard
|
||||
game.informPlayers(new StringBuilder(stackObject.getName()).append(" is countered by ").append(sourceObject.getLogName()).toString());
|
||||
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.COUNTERED, objectId, sourceId, stackObject.getControllerId()));
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue