This commit is contained in:
LevelX2 2013-06-26 18:30:24 +02:00
commit 1bd3f6d318
31 changed files with 1919 additions and 18 deletions

View file

@ -0,0 +1,79 @@
/*
* 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.alarareborn;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.RemoveCountersSourceCost;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author jeffwadsworth
*/
public class DeathbringerThoctar extends CardImpl<DeathbringerThoctar> {
public DeathbringerThoctar(UUID ownerId) {
super(ownerId, 36, "Deathbringer Thoctar", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{4}{B}{R}");
this.expansionSetCode = "ARB";
this.subtype.add("Zombie");
this.subtype.add("Beast");
this.color.setRed(true);
this.color.setBlack(true);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Whenever another creature dies, you may put a +1/+1 counter on Deathbringer Thoctar.
this.addAbility(new DiesCreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), true, true));
// Remove a +1/+1 counter from Deathbringer Thoctar: Deathbringer Thoctar deals 1 damage to target creature or player.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageTargetEffect(1), new RemoveCountersSourceCost(CounterType.P1P1.createInstance()));
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);
}
public DeathbringerThoctar(final DeathbringerThoctar card) {
super(card);
}
@Override
public DeathbringerThoctar copy() {
return new DeathbringerThoctar(this);
}
}

View file

@ -0,0 +1,80 @@
/*
* 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.alarareborn;
import java.util.UUID;
import mage.abilities.common.BlocksAttachedTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.SkipNextUntapTargetEffect;
import mage.abilities.effects.common.continious.BoostEquippedEffect;
import mage.abilities.effects.common.continious.GainAbilityAttachedEffect;
import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author jeffwadsworth
*/
public class ShieldOfTheRighteous extends CardImpl<ShieldOfTheRighteous> {
public ShieldOfTheRighteous(UUID ownerId) {
super(ownerId, 11, "Shield of the Righteous", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{W}{U}");
this.expansionSetCode = "ARB";
this.subtype.add("Equipment");
this.color.setBlue(true);
this.color.setWhite(true);
// Equipped creature gets +0/+2 and has vigilance.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(0, 2)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT)));
// Whenever equipped creature blocks a creature, that creature doesn't untap during its controller's next untap step.
this.addAbility(new BlocksAttachedTriggeredAbility(new SkipNextUntapTargetEffect("that creature"), "equipped", false, false, true));
// Equip {2}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(2), new TargetControlledCreaturePermanent()));
}
public ShieldOfTheRighteous(final ShieldOfTheRighteous card) {
super(card);
}
@Override
public ShieldOfTheRighteous copy() {
return new ShieldOfTheRighteous(this);
}
}

View file

@ -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 mage.sets.alarareborn;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.repository.CardRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer;
/**
*
* @author jeffwadsworth
*/
public class ThoughtHemorrhage extends CardImpl<ThoughtHemorrhage> {
public ThoughtHemorrhage(UUID ownerId) {
super(ownerId, 47, "Thought Hemorrhage", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{2}{B}{R}");
this.expansionSetCode = "ARB";
this.color.setRed(true);
this.color.setBlack(true);
// Name a nonland card. Target player reveals his or her hand. Thought Hemorrhage deals 3 damage to that player for each card with that name revealed this way. Search that player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new ThoughtHemorrhageEffect());
}
public ThoughtHemorrhage(final ThoughtHemorrhage card) {
super(card);
}
@Override
public ThoughtHemorrhage copy() {
return new ThoughtHemorrhage(this);
}
}
class ThoughtHemorrhageEffect extends OneShotEffect<ThoughtHemorrhageEffect> {
String cardName;
final String rule = "Name a nonland card. Target player reveals his or her hand. Thought Hemorrhage deals 3 damage to that player for each card with that name revealed this way. Search that player's graveyard, hand, and library for all cards with that name and exile them. Then that player shuffles his or her library";
public ThoughtHemorrhageEffect() {
super(Outcome.Detriment);
staticText = rule;
}
public ThoughtHemorrhageEffect(final ThoughtHemorrhageEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId());
if (you != null) {
Choice cardChoice = new ChoiceImpl();
cardChoice.setChoices(CardRepository.instance.getNonLandNames());
cardChoice.clearChoice();
while (!you.choose(Outcome.Detriment, cardChoice, game)) {
game.debugMessage("player canceled choosing name. retrying.");
}
cardName = cardChoice.getChoice();
game.informPlayers("Thought Hemorrhage, named card: [" + cardName + "]");
}
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) {
targetPlayer.revealCards("hand of target player", targetPlayer.getHand(), game);
for (Card card : targetPlayer.getHand().getCards(game)) {
if (card.getName().equals(cardName)) {
targetPlayer.damage(3, source.getId(), game, false, true);
}
}
for (Card card : targetPlayer.getGraveyard().getCards(game)) {
if (card.getName().equals(cardName)) {
card.moveToExile(null, "", source.getId(), game);
}
}
for (Card card : targetPlayer.getHand().getCards(game)) {
if (card.getName().equals(cardName)) {
card.moveToExile(null, "", source.getId(), game);
}
}
for (Card card : targetPlayer.getLibrary().getCards(game)) {
if (card.getName().equals(cardName)) {
card.moveToExile(null, "", source.getId(), game);
}
}
targetPlayer.shuffleLibrary(game);
return true;
}
return false;
}
@Override
public ThoughtHemorrhageEffect copy() {
return new ThoughtHemorrhageEffect(this);
}
}

View file

@ -0,0 +1,121 @@
/*
* 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.alarareborn;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author jeffwadsworth
*/
public class VectisDominator extends CardImpl<VectisDominator> {
public VectisDominator(UUID ownerId) {
super(ownerId, 84, "Vectis Dominator", Rarity.COMMON, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{1}{W}{B}");
this.expansionSetCode = "ARB";
this.subtype.add("Human");
this.subtype.add("Wizard");
this.color.setBlack(true);
this.color.setWhite(true);
this.power = new MageInt(0);
this.toughness = new MageInt(2);
// {tap}: Tap target creature unless its controller pays 2 life.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new VectisDominatorEffect(new PayLifeCost(2)), new ManaCostsImpl("{1}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public VectisDominator(final VectisDominator card) {
super(card);
}
@Override
public VectisDominator copy() {
return new VectisDominator(this);
}
}
class VectisDominatorEffect extends OneShotEffect<VectisDominatorEffect> {
protected Cost cost;
public VectisDominatorEffect(Cost cost) {
super(Outcome.Detriment);
this.staticText = "Tap target creature unless its controller pays 2 life";
this.cost = cost;
}
public VectisDominatorEffect(final VectisDominatorEffect effect) {
super(effect);
this.cost = effect.cost.copy();
}
@Override
public VectisDominatorEffect copy() {
return new VectisDominatorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
if (targetCreature != null) {
Player player = game.getPlayer(targetCreature.getControllerId());
if (player != null) {
cost.clearPaid();
final StringBuilder sb = new StringBuilder("Pay 2 life otherwise ").append(targetCreature.getName()).append(" will be tapped)");
if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) {
cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true);
}
if (!cost.isPaid()) {
return targetCreature.tap(game);
}
}
}
return false;
}
}

View 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.championsofkamigawa;
import java.util.UUID;
import mage.constants.Rarity;
/**
*
* @author LevelX2
*/
public class DampenThought extends mage.sets.modernmasters.DampenThought {
public DampenThought(UUID ownerId) {
super(ownerId);
this.cardNumber = 57;
this.expansionSetCode = "CHK";
this.rarity = Rarity.UNCOMMON;
}
public DampenThought(final DampenThought card) {
super(card);
}
@Override
public DampenThought copy() {
return new DampenThought(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.championsofkamigawa;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class GlacialRay extends mage.sets.modernmasters.GlacialRay {
public GlacialRay(UUID ownerId) {
super(ownerId);
this.cardNumber = 168;
this.expansionSetCode = "CHK";
}
public GlacialRay(final GlacialRay card) {
super(card);
}
@Override
public GlacialRay copy() {
return new GlacialRay(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.eighthedition;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class FertileGround extends mage.sets.urzassaga.FertileGround {
public FertileGround(UUID ownerId) {
super(ownerId);
this.cardNumber = 248;
this.expansionSetCode = "8ED";
}
public FertileGround(final FertileGround card) {
super(card);
}
@Override
public FertileGround copy() {
return new FertileGround(this);
}
}

View file

@ -100,7 +100,11 @@ class ErraticPortalEffect extends OneShotEffect<ErraticPortalEffect> {
Player player = game.getPlayer(targetCreature.getControllerId());
if (player != null) {
cost.clearPaid();
if (!cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), false)) {
final StringBuilder sb = new StringBuilder("Pay {1} otherwise ").append(targetCreature.getName()).append(" will be returned to its owner's hand)");
if (player.chooseUse(Outcome.Benefit, sb.toString(), game)) {
cost.pay(source, game, targetCreature.getControllerId(), targetCreature.getControllerId(), true);
}
if (!cost.isPaid()) {
return targetCreature.moveToZone(Zone.HAND, source.getSourceId(), game, true);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.futuresight;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public class JhoiraOfTheGhitu extends mage.sets.modernmasters.JhoiraOfTheGhitu {
public JhoiraOfTheGhitu(UUID ownerId) {
super(ownerId);
this.cardNumber = 157;
this.expansionSetCode = "FUT";
}
public JhoiraOfTheGhitu(final JhoiraOfTheGhitu card) {
super(card);
}
@Override
public JhoiraOfTheGhitu copy() {
return new JhoiraOfTheGhitu(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.invasion;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class FertileGround extends mage.sets.urzassaga.FertileGround {
public FertileGround(UUID ownerId) {
super(ownerId);
this.cardNumber = 188;
this.expansionSetCode = "INV";
}
public FertileGround(final FertileGround card) {
super(card);
}
@Override
public FertileGround copy() {
return new FertileGround(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.lorwyn;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class FertileGround extends mage.sets.urzassaga.FertileGround {
public FertileGround(UUID ownerId) {
super(ownerId);
this.cardNumber = 211;
this.expansionSetCode = "LRW";
}
public FertileGround(final FertileGround card) {
super(card);
}
@Override
public FertileGround copy() {
return new FertileGround(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.mirage;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class EarlyHarvest extends mage.sets.ninthedition.EarlyHarvest {
public EarlyHarvest(UUID ownerId) {
super(ownerId);
this.cardNumber = 111;
this.expansionSetCode = "MIR";
}
public EarlyHarvest(final EarlyHarvest card) {
super(card);
}
@Override
public EarlyHarvest copy() {
return new EarlyHarvest(this);
}
}

View file

@ -0,0 +1,66 @@
/*
* 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.modernmasters;
import java.util.UUID;
import mage.abilities.effects.common.PutLibraryIntoGraveTargetEffect;
import mage.abilities.keyword.SpliceOntoArcaneAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.TargetPlayer;
/**
*
* @author LevelX2
*/
public class DampenThought extends CardImpl<DampenThought> {
public DampenThought(UUID ownerId) {
super(ownerId, 39, "Dampen Thought", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{U}");
this.expansionSetCode = "MMA";
this.subtype.add("Arcane");
this.color.setBlue(true);
// Target player puts the top four cards of his or her library into his or her graveyard.
this.getSpellAbility().addEffect(new PutLibraryIntoGraveTargetEffect(4));
this.getSpellAbility().addTarget(new TargetPlayer(true));
// Splice onto Arcane {1}{U}
this.addAbility(new SpliceOntoArcaneAbility("{1}{U}"));
}
public DampenThought(final DampenThought card) {
super(card);
}
@Override
public DampenThought copy() {
return new DampenThought(this);
}
}

View file

@ -0,0 +1,66 @@
/*
* 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.modernmasters;
import java.util.UUID;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.SpliceOntoArcaneAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author LevelX2
*/
public class GlacialRay extends CardImpl<GlacialRay> {
public GlacialRay(UUID ownerId) {
super(ownerId, 115, "Glacial Ray", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{R}");
this.expansionSetCode = "MMA";
this.subtype.add("Arcane");
this.color.setRed(true);
// Glacial Ray deals 2 damage to target creature or player.
this.getSpellAbility().addEffect(new DamageTargetEffect(2));
this.getSpellAbility().addTarget(new TargetCreatureOrPlayer(true));
// Splice onto Arcane {1}{R}
this.addAbility(new SpliceOntoArcaneAbility("{1}{R}"));
}
public GlacialRay(final GlacialRay card) {
super(card);
}
@Override
public GlacialRay copy() {
return new GlacialRay(this);
}
}

View file

@ -0,0 +1,149 @@
/*
* 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.modernmasters;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.common.ExileFromHandCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continious.GainAbilityTargetEffect;
import mage.abilities.keyword.SuspendAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterNonlandCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author LevelX2
*/
public class JhoiraOfTheGhitu extends CardImpl<JhoiraOfTheGhitu> {
public JhoiraOfTheGhitu(UUID ownerId) {
super(ownerId, 177, "Jhoira of the Ghitu", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{U}{R}");
this.expansionSetCode = "MMA";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Wizard");
this.color.setRed(true);
this.color.setBlue(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// {2}, Exile a nonland card from your hand: Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new JhoiraOfTheGhituSuspendEffect(), new GenericManaCost(2));
ability.addCost(new ExileFromHandCost(new TargetCardInHand(new FilterNonlandCard("a nonland card from your hand"))));
this.addAbility(ability);
}
public JhoiraOfTheGhitu(final JhoiraOfTheGhitu card) {
super(card);
}
@Override
public JhoiraOfTheGhitu copy() {
return new JhoiraOfTheGhitu(this);
}
}
class JhoiraOfTheGhituSuspendEffect extends OneShotEffect<JhoiraOfTheGhituSuspendEffect> {
public JhoiraOfTheGhituSuspendEffect() {
super(Outcome.PutCardInPlay);
this.staticText = "Put four time counters on the exiled card. If it doesn't have suspend, it gains suspend <i>(At the beginning of your upkeep, remove a time counter from that card. When the last is removed, cast it without paying its mana cost. If it's a creature, it has haste.)</i>";
}
public JhoiraOfTheGhituSuspendEffect(final JhoiraOfTheGhituSuspendEffect effect) {
super(effect);
}
@Override
public JhoiraOfTheGhituSuspendEffect copy() {
return new JhoiraOfTheGhituSuspendEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller == null) {
return false;
}
List<Card> cards = new ArrayList<Card>();
for (Cost cost: source.getCosts()) {
if (cost instanceof ExileFromHandCost) {
cards = ((ExileFromHandCost) cost).getCards();
}
}
if (cards != null && !cards.isEmpty()) {
Card card = game.getCard(cards.get(0).getId());
boolean hasSuspend = false;
for (Ability ability :card.getAbilities()) {
if (ability instanceof SuspendAbility) {
hasSuspend = true;
break;
}
}
UUID exileId = (UUID) game.getState().getValue("SuspendExileId" + source.getControllerId().toString());
if (exileId == null) {
exileId = UUID.randomUUID();
game.getState().setValue("SuspendExileId" + source.getControllerId().toString(), exileId);
}
if (card.moveToExile(exileId, new StringBuilder("Suspended cards of ").append(controller.getName()).toString() , source.getSourceId(), game)) {
card.addCounters(CounterType.TIME.createInstance(4), game);
if (!hasSuspend) {
ContinuousEffect effect = new GainAbilityTargetEffect(new SuspendAbility(4, null, card), Duration.OneUse, null, true);
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
}
game.informPlayers(new StringBuilder(controller.getName()).append(" suspends (").append(4).append(") ").append(card.getName()).toString());
return true;
}
}
return false;
}
}

View file

@ -142,7 +142,7 @@ class ThievingSpriteEffect extends OneShotEffect<ThievingSpriteEffect> {
Card card = revealedCards.get(targetInHand.getFirstTarget(), game);
if (card != null) {
targetPlayer.discard(card, source, game);
game.informPlayers(new StringBuilder("Thieving Sprite").append(targetPlayer.getName()).append("discarded ").append(card.getName()).toString());
game.informPlayers(new StringBuilder("Thieving Sprite: ").append(targetPlayer.getName()).append(" discarded ").append(card.getName()).toString());
}
}
return true;

View file

@ -0,0 +1,98 @@
/*
* 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.ninthedition;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPlayer;
/**
*
* @author Plopman
*/
public class EarlyHarvest extends CardImpl<EarlyHarvest> {
public EarlyHarvest(UUID ownerId) {
super(ownerId, 235, "Early Harvest", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{1}{G}{G}");
this.expansionSetCode = "9ED";
this.color.setGreen(true);
// Target player untaps all basic lands he or she controls.
this.getSpellAbility().addEffect(new UntapAllLandsTargetEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
public EarlyHarvest(final EarlyHarvest card) {
super(card);
}
@Override
public EarlyHarvest copy() {
return new EarlyHarvest(this);
}
}
class UntapAllLandsTargetEffect extends OneShotEffect<UntapAllLandsTargetEffect> {
public UntapAllLandsTargetEffect() {
super(Outcome.Untap);
staticText = "Target player untaps all basic lands he or she controls";
}
public UntapAllLandsTargetEffect(final UntapAllLandsTargetEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (player != null) {
for (Permanent land: game.getBattlefield().getAllActivePermanents(new FilterLandPermanent(), player.getId(), game)) {
land.untap(game);
}
return true;
}
return false;
}
@Override
public UntapAllLandsTargetEffect copy() {
return new UntapAllLandsTargetEffect(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.planechase;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class FertileGround extends mage.sets.urzassaga.FertileGround {
public FertileGround(UUID ownerId) {
super(ownerId);
this.cardNumber = 71;
this.expansionSetCode = "HOP";
}
public FertileGround(final FertileGround card) {
super(card);
}
@Override
public FertileGround copy() {
return new FertileGround(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.seventhedition;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class EarlyHarvest extends mage.sets.ninthedition.EarlyHarvest {
public EarlyHarvest(UUID ownerId) {
super(ownerId);
this.cardNumber = 237;
this.expansionSetCode = "7ED";
}
public EarlyHarvest(final EarlyHarvest card) {
super(card);
}
@Override
public EarlyHarvest copy() {
return new EarlyHarvest(this);
}
}

View file

@ -0,0 +1,52 @@
/*
* 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.sixthedition;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class EarlyHarvest extends mage.sets.ninthedition.EarlyHarvest {
public EarlyHarvest(UUID ownerId) {
super(ownerId);
this.cardNumber = 222;
this.expansionSetCode = "6ED";
}
public EarlyHarvest(final EarlyHarvest card) {
super(card);
}
@Override
public EarlyHarvest copy() {
return new EarlyHarvest(this);
}
}

View file

@ -0,0 +1,113 @@
/*
* 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.urzassaga;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.common.AddManaOfAnyColorEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.mana.TriggeredManaAbility;
import mage.cards.CardImpl;
import mage.choices.ChoiceColor;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent;
/**
*
* @author Plopman
*/
public class FertileGround extends CardImpl<FertileGround> {
public FertileGround(UUID ownerId) {
super(ownerId, 252, "Fertile Ground", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.expansionSetCode = "USG";
this.subtype.add("Aura");
this.color.setGreen(true);
// Enchant land
TargetPermanent auraTarget = new TargetLandPermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Whenever enchanted land is tapped for mana, its controller adds one mana of any color to his or her mana pool.
this.addAbility(new FertileGroundTriggeredAbility());
}
public FertileGround(final FertileGround card) {
super(card);
}
@Override
public FertileGround copy() {
return new FertileGround(this);
}
}
class FertileGroundTriggeredAbility extends TriggeredManaAbility<FertileGroundTriggeredAbility> {
public FertileGroundTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddManaOfAnyColorEffect());
this.addChoice(new ChoiceColor());
}
public FertileGroundTriggeredAbility(FertileGroundTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent enchantment = game.getPermanent(this.getSourceId());
if(event.getType() == GameEvent.EventType.TAPPED_FOR_MANA){
if (enchantment != null && event.getSourceId().equals(enchantment.getAttachedTo())) {
return true;
}
}
return false;
}
@Override
public FertileGroundTriggeredAbility copy() {
return new FertileGroundTriggeredAbility(this);
}
@Override
public String getRule() {
return "Whenever enchanted land is tapped for mana, its controller adds one mana of any color to his or her mana pool";
}
}

View file

@ -53,6 +53,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.abilities.keyword.EntwineAbility;
import mage.constants.SpellAbilityType;
/**
@ -162,11 +163,22 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
@Override
public boolean activate(Game game, boolean noMana) {
// 20110204 - 700.2
/* 20130201 - 601.2b
* If the spell is modal the player announces the mode choice (see rule 700.2).
*/
if (!modes.choose(game, this)) {
return false;
}
//20100716 - 601.2b
/* 20130201 - 601.2b
* If the player wishes to splice any cards onto the spell (see rule 702.45), he
* or she reveals those cards in his or her hand.
*/
if (this.abilityType.equals(AbilityType.SPELL)) {
game.getContinuousEffects().applySpliceEffects(this, game);
}
Card card = game.getCard(sourceId);
if (card != null) {
card.adjustChoices(this, game);
@ -179,7 +191,7 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
}
}
// 20121001 - 601.2b
// 20130201 - 601.2b
// If the spell has alternative or additional costs that will be paid as it's being cast such
// 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).
@ -197,6 +209,7 @@ public abstract class AbilityImpl<T extends AbilityImpl<T>> implements Ability {
}
}
}
// 20121001 - 601.2b
// If the spell has a variable cost that will be paid as it's being cast (such as an {X} in
// its mana cost; see rule 107.3), the player announces the value of that variable.

View file

@ -19,6 +19,7 @@ import mage.target.targetpointer.FixedTarget;
public class BlocksAttachedTriggeredAbility extends TriggeredAbilityImpl<BlocksAttachedTriggeredAbility>{
private boolean setFixedTargetPointer;
private String attachedDescription;
private boolean setFixedTargetPointerToBlocked;
public BlocksAttachedTriggeredAbility(Effect effect, String attachedDescription, boolean optional) {
this(effect, attachedDescription, optional, false);
@ -29,6 +30,13 @@ public class BlocksAttachedTriggeredAbility extends TriggeredAbilityImpl<BlocksA
this.setFixedTargetPointer = setFixedTargetPointer;
this.attachedDescription = attachedDescription;
}
public BlocksAttachedTriggeredAbility(Effect effect, String attachedDescription, boolean optional, boolean setFixedTargetPointer, boolean setFixedTargetPointerToBlocked) {
super(Zone.BATTLEFIELD, effect, optional);
this.setFixedTargetPointer = setFixedTargetPointer;
this.attachedDescription = attachedDescription;
this.setFixedTargetPointerToBlocked = setFixedTargetPointerToBlocked;
}
public BlocksAttachedTriggeredAbility(final BlocksAttachedTriggeredAbility ability) {
super(ability);
@ -51,6 +59,11 @@ public class BlocksAttachedTriggeredAbility extends TriggeredAbilityImpl<BlocksA
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}
}
if (setFixedTargetPointerToBlocked) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
}
}
return true;
}
}

View file

@ -36,7 +36,9 @@ import mage.constants.Layer;
import mage.constants.SubLayer;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.StaticAbility;
import mage.constants.SpellAbilityType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@ -58,6 +60,7 @@ public class ContinuousEffects implements Serializable {
private ContinuousEffectsList<RestrictionEffect> restrictionEffects = new ContinuousEffectsList<RestrictionEffect>();
private ContinuousEffectsList<AsThoughEffect> asThoughEffects = new ContinuousEffectsList<AsThoughEffect>();
private ContinuousEffectsList<CostModificationEffect> costModificationEffects = new ContinuousEffectsList<CostModificationEffect>();
private ContinuousEffectsList<SpliceCardEffect> spliceCardEffects = new ContinuousEffectsList<SpliceCardEffect>();
private List<ContinuousEffectsList<?>> allEffectsLists = new ArrayList<ContinuousEffectsList<?>>();
@ -88,6 +91,7 @@ public class ContinuousEffects implements Serializable {
restrictionEffects = effect.restrictionEffects.copy();
asThoughEffects = effect.asThoughEffects.copy();
costModificationEffects = effect.costModificationEffects.copy();
spliceCardEffects = effect.spliceCardEffects.copy();
for (Map.Entry<UUID, UUID> entry : effect.sources.entrySet()) {
sources.put(entry.getKey(), entry.getValue());
}
@ -103,6 +107,7 @@ public class ContinuousEffects implements Serializable {
allEffectsLists.add(restrictionEffects);
allEffectsLists.add(asThoughEffects);
allEffectsLists.add(costModificationEffects);
allEffectsLists.add(spliceCardEffects);
}
public ContinuousEffects copy() {
@ -125,6 +130,7 @@ public class ContinuousEffects implements Serializable {
restrictionEffects.removeEndOfCombatEffects();
asThoughEffects.removeEndOfCombatEffects();
costModificationEffects.removeEndOfCombatEffects();
spliceCardEffects.removeEndOfCombatEffects();
}
public void removeEndOfTurnEffects() {
@ -135,6 +141,7 @@ public class ContinuousEffects implements Serializable {
restrictionEffects.removeEndOfTurnEffects();
asThoughEffects.removeEndOfTurnEffects();
costModificationEffects.removeEndOfTurnEffects();
spliceCardEffects.removeEndOfTurnEffects();
}
public void removeInactiveEffects(Game game) {
@ -145,6 +152,7 @@ public class ContinuousEffects implements Serializable {
restrictionEffects.removeInactiveEffects(game);
asThoughEffects.removeInactiveEffects(game);
costModificationEffects.removeInactiveEffects(game);
spliceCardEffects.removeInactiveEffects(game);
}
public List<ContinuousEffect> getLayeredEffects(Game game) {
@ -328,6 +336,29 @@ public class ContinuousEffects implements Serializable {
return costEffects;
}
/**
* Filters out splice effects that are not active.
*
* @param game
* @return
*/
private List<SpliceCardEffect> getApplicableSpliceCardEffects(Game game) {
List<SpliceCardEffect> spliceEffects = new ArrayList<SpliceCardEffect>();
for (SpliceCardEffect effect: spliceCardEffects) {
HashSet<Ability> abilities = spliceCardEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, false)) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
spliceEffects.add(effect);
break;
}
}
}
}
return spliceEffects;
}
public boolean asThough(UUID objectId, AsThoughEffectType type, Game game) {
List<AsThoughEffect> asThoughEffectsList = getApplicableAsThoughEffects(game);
@ -390,6 +421,31 @@ public class ContinuousEffects implements Serializable {
}
}
/**
* Checks all available splice effects to be applied.
*
* @param abilityToModify
* @param game
* @return
*/
public void applySpliceEffects ( Ability abilityToModify, Game game ) {
if ( ((SpellAbility) abilityToModify).getSpellAbilityType().equals(SpellAbilityType.SPLICE)) {
// on a spliced ability of a spell can't be spliced again
return;
}
List<SpliceCardEffect> spliceEffects = getApplicableSpliceCardEffects(game);
for ( SpliceCardEffect effect : spliceEffects) {
HashSet<Ability> abilities = spliceCardEffects.getAbility(effect.getId());
for (Ability ability : abilities) {
if ( effect.applies(abilityToModify, ability, game) ) {
effect.apply(game, ability, abilityToModify);
}
}
}
}
public boolean replaceEvent(GameEvent event, Game game) {
boolean caught = false;
HashMap<UUID, HashSet<UUID>> consumed = new HashMap<UUID, HashSet<UUID>>();
@ -617,6 +673,10 @@ public class ContinuousEffects implements Serializable {
CostModificationEffect newCostModificationEffect = (CostModificationEffect)effect;
costModificationEffects.addEffect(newCostModificationEffect, source);
break;
case SPLICE:
SpliceCardEffect newSpliceCardEffect = (SpliceCardEffect)effect;
spliceCardEffects.addEffect(newSpliceCardEffect, source);
break;
default:
ContinuousEffect newEffect = (ContinuousEffect)effect;
layeredEffects.addEffect(newEffect, source);

View file

@ -0,0 +1,66 @@
/*
* 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;
import mage.abilities.Ability;
import mage.game.Game;
/**
* Represents a {@link ContinuousEffect} that will modify the cost and abilities of a spell
* on the stack (splice a card). {@link mage.abilities.Ability Abilities} with this type of effect will be
* called once and only once from the {@link mage.abilities.AbilityImpl#activate(mage.game.Game,
* boolean) Ability.activate} method before alternative or additional costs are paid.
*
* @param <T>
* @author levelX2
*/
public interface SpliceCardEffect<T extends SpliceCardEffect<T>> extends ContinuousEffect<T> {
/**
* Called by the {@link ContinuousEffects#costModification(Ability abilityToModify, Game game) ContinuousEffects.costModification}
* method.
*
* @param game The game for which this effect should be applied.
* @param source The source ability of this effect.
* @param abilityToModify The {@link mage.abilities.SpellAbility} or {@link Ability} which should be modified.
* @return
*/
boolean apply ( Game game, Ability source, Ability abilityToModify );
/**
* Called by the {@link ContinuousEffects#costModification(mage.abilities.Ability, mage.game.Game) ContinuousEffects.costModification}
* method.
*
* @param abilityToModify The ability to possibly modify.
* @param source The source ability of this effect.
* @param game The game for which this effect shoul dbe applied.
* @return
*/
boolean applies(Ability abilityToModify, Ability source, Game game);
}

View file

@ -0,0 +1,67 @@
/*
* 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;
import mage.abilities.Ability;
import mage.constants.Duration;
import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.game.Game;
/**
* Simple implementation of a {@link SpliceCardEffect} offering simplified
* construction to setup the object for use by the mage framework.
* @author LevelX2
*/
public abstract class SpliceCardEffectImpl<T extends SpliceCardEffectImpl<T>> extends ContinuousEffectImpl<T> implements SpliceCardEffect<T> {
public SpliceCardEffectImpl ( Duration duration, Outcome outcome ) {
super(duration, outcome);
this.effectType = EffectType.SPLICE;
}
public SpliceCardEffectImpl(final SpliceCardEffectImpl<T> effect) {
super(effect);
this.effectType = effect.effectType;
}
/**
* Overridden and 'no-op' implementation put in place.
*
* @see #apply(mage.game.Game, mage.abilities.Ability, mage.abilities.Ability)
*
* @param game
* @param source
* @return
*/
@Override
public final boolean apply ( Game game, Ability source ) { return false; }
}

View file

@ -40,6 +40,7 @@ import mage.game.permanent.Permanent;
import mage.target.Target;
import java.util.UUID;
import mage.cards.Card;
/**
*
@ -48,23 +49,29 @@ import java.util.UUID;
public class GainAbilityTargetEffect extends ContinuousEffectImpl<GainAbilityTargetEffect> {
protected Ability ability;
// shall a card gain the ability (otherwise permanent)
private boolean onCard;
public GainAbilityTargetEffect(Ability ability, Duration duration) {
super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA,
ability.getEffects().size() > 0 ? ability.getEffects().get(0).getOutcome() : Outcome.AddAbility);
this.ability = ability;
this(ability, duration, null);
}
public GainAbilityTargetEffect(Ability ability, Duration duration, String rule) {
this(ability, duration, rule, false);
}
public GainAbilityTargetEffect(Ability ability, Duration duration, String rule, boolean onCard) {
super(duration, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA,
ability.getEffects().size() > 0 ? ability.getEffects().get(0).getOutcome() : Outcome.AddAbility);
this.ability = ability;
staticText = rule;
this.onCard = onCard;
}
public GainAbilityTargetEffect(final GainAbilityTargetEffect effect) {
super(effect);
this.ability = effect.ability.copy();
this.onCard = effect.onCard;
}
@Override
@ -81,11 +88,24 @@ public class GainAbilityTargetEffect extends ContinuousEffectImpl<GainAbilityTar
@Override
public boolean apply(Game game, Ability source) {
int affectedTargets = 0;
for (UUID permanentId : targetPointer.getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent != null) {
permanent.addAbility(ability, source.getSourceId(), game);
affectedTargets++;
if (onCard) {
for (UUID cardId : targetPointer.getTargets(game, source)) {
Card card = game.getCard(cardId);
if (card != null) {
card.addAbility(ability);
affectedTargets++;
}
}
if (duration.equals(Duration.OneUse)) {
discard();
}
} else {
for (UUID permanentId : targetPointer.getTargets(game, source)) {
Permanent permanent = game.getPermanent(permanentId);
if (permanent != null) {
permanent.addAbility(ability, source.getSourceId(), game);
affectedTargets++;
}
}
}
return affectedTargets > 0;

View file

@ -0,0 +1,210 @@
/*
* 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.keyword;
import java.util.Iterator;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.Costs;
import mage.abilities.costs.CostsImpl;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.SpliceCardEffectImpl;
import mage.cards.Card;
import mage.cards.CardsImpl;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SpellAbilityType;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
/**
* 702.45. Splice
*
* 702.45a Splice is a static ability that functions while a card is in your hand.
* "Splice onto [subtype] [cost]" means "You may reveal this card from your hand
* as you cast a [subtype] spell. If you do, copy this card's text box onto that
* spell and pay [cost] as an additional cost to cast that spell." Paying a card's
* splice cost follows the rules for paying additional costs in rules 601.2b and
* 601.2e-g.
*
* Example: Since the card with splice remains in the player's hand, it can later
* be cast normally or spliced onto another spell. It can even be discarded to pay
* a "discard a card" cost of the spell it's spliced onto.
*
* 702.45b You can't choose to use a splice ability if you can't make the required
* choices (targets, etc.) for that card's instructions. You can't splice any one
* card onto the same spell more than once. If you're splicing more than one card
* onto a spell, reveal them all at once and choose the order in which their
* instructions will be followed. The instructions on the main spell have to be
* followed first.
*
* 702.45c The spell has the characteristics of the main spell, plus the text boxes
* of each of the spliced cards. The spell doesn't gain any other characteristics
* (name, mana cost, color, supertypes, card types, subtypes, etc.) of the spliced
* cards. Text copied onto the spell that refers to a card by name refers to the spell
* on the stack, not the card from which the text was copied.
*
* Example: Glacial Ray is a red card with splice onto Arcane that reads, "Glacial
* Ray deals 2 damage to target creature or player." Suppose Glacial Ray is spliced
* onto Reach Through Mists, a blue spell. The spell is still blue, and Reach Through
* Mists deals the damage. This means that the ability can target a creature with
* protection from red and deal 2 damage to that creature.
*
* 702.45d Choose targets for the added text normally (see rule 601.2c). Note that a
* spell with one or more targets will be countered if all of its targets are illegal
* on resolution.
*
* 702.45e The spell loses any splice changes once it leaves the stack (for example,
* when it's countered, it's exiled, or it resolves).
*
* Rulings
*
* You must reveal all of the cards you intend to splice at the same time. Each individual card can only be spliced once onto a spell.
* If you have more than one card with the same name in your hand, you may splice both of them onto the spell.
* A card with a splice ability can't be spliced onto itself because the spell is on the stack (and not in your hand) when you reveal the cards you want to splice onto it.
* The target for a card that's spliced onto a spell may be the same as the target chosen for the original spell or for another spliced-on card. (A recent change to the targeting rules allows this, but most other cards are unaffected by the change.)
* If you splice a targeted card onto an untargeted spell, the entire spell will be countered if the target isn't legal when the spell resolves.
* If you splice an untargeted card onto a targeted spell, the entire spell will be countered if the target isn't legal when the spell resolves.
* A spell is countered on resolution only if *all* of its targets are illegal (or the spell is countered by an effect).
*
* @author LevelX2
*/
public class SpliceOntoArcaneAbility extends SimpleStaticAbility {
private static final String KEYWORD_TEXT = "Splice onto Arcane";
private Costs spliceCosts = new CostsImpl();
public SpliceOntoArcaneAbility(String manaString) {
super(Zone.HAND, new SpliceOntoArcaneEffect());
spliceCosts.add(new ManaCostsImpl(manaString));
}
public SpliceOntoArcaneAbility(Cost cost) {
super(Zone.HAND, new SpliceOntoArcaneEffect());
spliceCosts.add(cost);
}
public SpliceOntoArcaneAbility(final SpliceOntoArcaneAbility ability) {
super(ability);
this.spliceCosts = ability.spliceCosts.copy();
}
@Override
public SimpleStaticAbility copy() {
return new SpliceOntoArcaneAbility(this);
}
public Costs getSpliceCosts() {
return spliceCosts;
}
@Override
public String getRule() {
StringBuilder sb = new StringBuilder();
sb.append(KEYWORD_TEXT).append(" ");
sb.append(spliceCosts.getText());
sb.append(" <i>(As you cast an Arcane spell, you may reveal this card from your hand and pay its splice cost. If you do, add this card's effects to that spell.)</i>");
return sb.toString();
}
}
class SpliceOntoArcaneEffect extends SpliceCardEffectImpl<SpliceOntoArcaneEffect> {
public SpliceOntoArcaneEffect() {
super(Duration.WhileOnBattlefield, Outcome.Copy);
staticText = "Splice onto Arcane";
}
public SpliceOntoArcaneEffect(final SpliceOntoArcaneEffect effect) {
super(effect);
}
@Override
public SpliceOntoArcaneEffect copy() {
return new SpliceOntoArcaneEffect(this);
}
@Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
Player controller = game.getPlayer(source.getControllerId());
Card spliceCard = game.getCard(source.getSourceId());
if (spliceCard != null && controller != null) {
if (controller.chooseUse(outcome, new StringBuilder("Splice ").append(spliceCard.getName())
.append(" ").append(((SpliceOntoArcaneAbility) source).getSpliceCosts().getText()).append("?").toString(), game)) {
Spell spell = game.getStack().getSpell(abilityToModify.getId());
if (spell != null) {
SpellAbility splicedAbility = spliceCard.getSpellAbility().copy();
splicedAbility.setSpellAbilityType(SpellAbilityType.SPLICE);
splicedAbility.setSourceId(abilityToModify.getSourceId());
spell.addSpellAbility(splicedAbility);
for (Iterator it = ((SpliceOntoArcaneAbility) source).getSpliceCosts().iterator(); it.hasNext();) {
Cost cost = (Cost) it.next();
if (cost instanceof ManaCostsImpl) {
spell.getSpellAbility().getManaCostsToPay().add((ManaCostsImpl) cost.copy());
} else {
spell.getSpellAbility().getCosts().add(cost.copy());
}
}
// reveal the spliced card
controller.revealCards("Spliced card", new CardsImpl(spliceCard), game);
}
}
return true;
}
return false;
}
@Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
MageObject object = game.getObject(abilityToModify.getSourceId());
if (object != null && object.getSubtype().contains("Arcane")) {
return spliceSpellCanBeActivated(source, game);
}
return false;
}
private boolean spliceSpellCanBeActivated(Ability source, Game game) {
// check if spell can be activated (protection problem not solved because effect will be used from the base spell?)
Card card = game.getCard(source.getSourceId());
if (card != null) {
return card.getSpellAbility().canActivate(source.getControllerId(), game);
}
return false;
}
}

View file

@ -14,7 +14,8 @@ public enum EffectType {
ASTHOUGH("As Though Effect"),
RESTRICTION("Restriction Effect"),
REQUIREMENT("Requirement Effect"),
COSTMODIFICATION("Cost Modification Effect");
COSTMODIFICATION("Cost Modification Effect"),
SPLICE("Splice Card Effect");
private String text;

View file

@ -1065,7 +1065,9 @@ public abstract class GameImpl<T extends GameImpl<T>> implements Game, Serializa
public void addTriggeredAbility(TriggeredAbility ability) {
if (ability instanceof TriggeredManaAbility || ability instanceof DelayedTriggeredManaAbility) {
// 20110715 - 605.4
ability.resolve(this);
Ability manaAbiltiy = ability.copy();
manaAbiltiy.activate(this, false);
manaAbiltiy.resolve(this);
}
else {
TriggeredAbility newAbility = (TriggeredAbility) ability.copy();

View file

@ -118,9 +118,21 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
public boolean activate(Game game, boolean noMana) {
if (!spellAbilities.get(0).activate(game, noMana)) {
return false;
}
// if there are more abilities (fused split spell) or first ability added new abilities (splice), activate the additional abilities
boolean ignoreAbility = true;
boolean payNoMana = noMana;
for (SpellAbility spellAbility: spellAbilities) {
if (!spellAbility.activate(game, noMana)) {
return false;
// costs for spliced abilities were added to main spellAbility, so pay no man for spliced abilities
payNoMana |= spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE);
if (ignoreAbility) {
ignoreAbility = false;
} else {
if (!spellAbility.activate(game, payNoMana)) {
return false;
}
}
}
return true;
@ -142,7 +154,9 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
spellAbility.getModes().setMode(spellAbility.getModes().get(modeId));
if (spellAbility.getTargets().stillLegal(spellAbility, game)) {
legalParts = true;
updateOptionalCosts(index);
if (!spellAbility.getSpellAbilityType().equals(SpellAbilityType.SPLICE)) {
updateOptionalCosts(index);
}
result |= spellAbility.resolve(game);
}
}
@ -351,6 +365,10 @@ public class Spell<T extends Spell<T>> implements StackObject, Card {
return card.getOwnerId();
}
public void addSpellAbility(SpellAbility spellAbility) {
spellAbilities.add(spellAbility);
}
@Override
public void addAbility(Ability ability) {}