Merge origin/master

This commit is contained in:
fireshoes 2016-02-23 11:32:29 -06:00
commit a662acbc58
121 changed files with 5148 additions and 811 deletions

View file

@ -200,7 +200,7 @@ class IllusionistsGambitRestrictionEffect extends RestrictionEffect {
}
@Override
public boolean canAttack(UUID defenderId, Ability source, Game game) {
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
if (defenderId.equals(source.getControllerId())) {
return false;
}

View file

@ -33,6 +33,7 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.keyword.FlashAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
@ -122,6 +123,10 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) {
if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
Card card = game.getCard(event.getTargetId());
Object entersTransformed = game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId());
if (entersTransformed instanceof Boolean && (Boolean) entersTransformed && card.getSecondCardFace() != null) {
card = card.getSecondCardFace();
}
if (card.getCardType().contains(CardType.CREATURE)) { // TODO: Bestow Card cast as Enchantment probably not handled correctly
CreatureWasCastWatcher watcher = (CreatureWasCastWatcher) game.getState().getWatchers().get("CreatureWasCast");
if (watcher != null && !watcher.wasCreatureCastThisTurn(event.getTargetId())) {

View file

@ -32,15 +32,12 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.CreateTokenTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.game.Game;
import mage.game.permanent.token.SpiritWhiteToken;
import mage.game.permanent.token.ElfToken;
import mage.game.permanent.token.Token;
import mage.players.Player;
@ -58,7 +55,6 @@ public class SylvanOffering extends CardImpl {
super(ownerId, 48, "Sylvan Offering", Rarity.RARE, new CardType[]{CardType.SORCERY}, "{X}{G}");
this.expansionSetCode = "C14";
// Choose an opponent. You and that player each put an X/X green Treefolk creature token onto the battlefield.
this.getSpellAbility().addEffect(new SylvanOfferingEffect1());
// Choose an opponent. You and that player each put X 1/1 green Elf Warrior creature tokens onto the battlefield.
@ -101,9 +97,10 @@ class SylvanOfferingEffect1 extends OneShotEffect {
if (opponent != null) {
int xValue = source.getManaCostsToPay().getX();
Effect effect = new CreateTokenTargetEffect(new SylvanOfferingTreefolkToken(xValue));
effect.setTargetPointer(new FixedTarget(controller.getId()));
effect.apply(game, source);
effect.setTargetPointer(new FixedTarget(opponent.getId()));
effect.apply(game, source);
new CreateTokenTargetEffect(new SylvanOfferingTreefolkToken(xValue)).apply(game, source);
return true;
}
}
@ -127,12 +124,12 @@ class SylvanOfferingTreefolkToken extends Token {
class SylvanOfferingEffect2 extends OneShotEffect {
SylvanOfferingEffect2() {
SylvanOfferingEffect2() {
super(Outcome.Sacrifice);
this.staticText = "<br>Choose an opponent. You and that player each put X 1/1 green Elf Warrior creature tokens onto the battlefield";
}
SylvanOfferingEffect2(final SylvanOfferingEffect2 effect) {
SylvanOfferingEffect2(final SylvanOfferingEffect2 effect) {
super(effect);
}
@ -151,9 +148,10 @@ class SylvanOfferingEffect2 extends OneShotEffect {
if (opponent != null) {
int xValue = source.getManaCostsToPay().getX();
Effect effect = new CreateTokenTargetEffect(new ElfToken(), xValue);
effect.setTargetPointer(new FixedTarget(controller.getId()));
effect.apply(game, source);
effect.setTargetPointer(new FixedTarget(opponent.getId()));
effect.apply(game, source);
new CreateTokenEffect(new ElfToken(), xValue).apply(game, source);
return true;
}
}

View file

@ -0,0 +1,99 @@
/*
* 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.exodus;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.Filter;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import mage.game.Game;
import mage.target.Target;
import mage.target.TargetPermanent;
/**
*
* @author spjspj
*/
public class Plaguebearer extends CardImpl {
private final UUID originalId;
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("nonblack creature");
static {
filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
}
public Plaguebearer(UUID ownerId) {
super(ownerId, 71, "Plaguebearer", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.expansionSetCode = "EXO";
this.subtype.add("Zombie");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {X}{X}{B}: Destroy target nonblack creature with converted mana cost X.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{X}{X}{B}"));
ability.addTarget(new TargetPermanent(filter));
originalId = ability.getOriginalId();
this.addAbility(ability);
}
@Override
public void adjustTargets(Ability ability, Game game) {
if (ability.getOriginalId().equals(originalId)) {
int xValue = ability.getManaCostsToPay().getX();
ability.getTargets().clear();
FilterCreaturePermanent filter = new FilterCreaturePermanent(new StringBuilder("nonblack creature with converted mana cost ").append(xValue).toString());
filter.add(new ConvertedManaCostPredicate(Filter.ComparisonType.Equal, xValue));
filter.add(Predicates.not(new ColorPredicate(ObjectColor.BLACK)));
Target target = new TargetPermanent(filter);
ability.addTarget(target);
}
}
public Plaguebearer(final Plaguebearer card) {
super(card);
this.originalId = card.originalId;
}
@Override
public Plaguebearer copy() {
return new Plaguebearer(this);
}
}

View file

@ -92,7 +92,7 @@ class SilentArbiterAttackRestrictionEffect extends RestrictionEffect {
}
@Override
public boolean canAttack(UUID defenderId, Ability source, Game game) {
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
return game.getCombat().getAttackers().isEmpty();
}
}

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.fourthedition;
import java.util.UUID;
/**
*
* @author spjspj
*/
public class EnergyTap extends mage.sets.legends.EnergyTap {
public EnergyTap(UUID ownerId) {
super(ownerId);
this.cardNumber = 69;
this.expansionSetCode = "4ED";
}
public EnergyTap(final EnergyTap card) {
super(card);
}
@Override
public EnergyTap copy() {
return new EnergyTap(this);
}
}

View file

@ -0,0 +1,102 @@
/*
* 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;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.counters.CounterType;
import mage.game.Game;
import mage.watchers.common.CastSpellLastTurnWatcher;
/**
*
* @author Quercitron
*/
public class StormEntity extends CardImpl {
public StormEntity(UUID ownerId) {
super(ownerId, 122, "Storm Entity", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.expansionSetCode = "FUT";
this.subtype.add("Elemental");
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// Haste
this.addAbility(HasteAbility.getInstance());
// Storm Entity enters the battlefield with a +1/+1 counter on it for each other spell cast this turn.
this.addAbility(new EntersBattlefieldAbility(
new AddCountersSourceEffect(
CounterType.P1P1.createInstance(),
new OtherSpellsCastThisTurnCount(),
true),
"with a +1/+1 counter on it for each other spell cast this turn"));
}
public StormEntity(final StormEntity card) {
super(card);
}
@Override
public StormEntity copy() {
return new StormEntity(this);
}
}
class OtherSpellsCastThisTurnCount implements DynamicValue {
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get("CastSpellLastTurnWatcher");
return watcher.getAmountOfSpellsAllPlayersCastOnCurrentTurn() - 1;
}
@Override
public DynamicValue copy() {
return new OtherSpellsCastThisTurnCount();
}
@Override
public String toString() {
return "X";
}
@Override
public String getMessage() {
return "other spell cast this turn";
}
}

View file

@ -97,7 +97,7 @@ class EssenceOfTheWildEffect extends ReplacementEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Permanent sourceObject = ((EntersTheBattlefieldEvent) event).getTarget();
Permanent sourceObject = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (sourceObject != null) {
game.addEffect(new CopyEffect(Duration.Custom, sourceObject, event.getTargetId()), source);
}

View file

@ -0,0 +1,146 @@
/*
* 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.Set;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.RestrictionEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.watchers.common.AttackedThisTurnWatcher;
import mage.watchers.common.BlockedThisTurnWatcher;
/**
*
* @author Quercitron
*/
public class DuelingGrounds extends CardImpl {
public DuelingGrounds(UUID ownerId) {
super(ownerId, 245, "Dueling Grounds", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}{W}");
this.expansionSetCode = "INV";
// No more than one creature can attack each turn.
this.addAbility(
new SimpleStaticAbility(Zone.BATTLEFIELD, new NoMoreThanOneCreatureCanAttackEachTurnEffect()),
new AttackedThisTurnWatcher());
// No more than one creature can block each turn.
this.addAbility(
new SimpleStaticAbility(Zone.BATTLEFIELD, new NoMoreThanOneCreatureCanBlockEachTurnEffect()),
new BlockedThisTurnWatcher());
}
public DuelingGrounds(final DuelingGrounds card) {
super(card);
}
@Override
public DuelingGrounds copy() {
return new DuelingGrounds(this);
}
}
class NoMoreThanOneCreatureCanAttackEachTurnEffect extends RestrictionEffect {
public NoMoreThanOneCreatureCanAttackEachTurnEffect() {
super(Duration.WhileOnBattlefield);
}
public NoMoreThanOneCreatureCanAttackEachTurnEffect(final NoMoreThanOneCreatureCanAttackEachTurnEffect effect) {
super(effect);
this.staticText = "No more than one creature can attack each turn";
}
@Override
public ContinuousEffect copy() {
return new NoMoreThanOneCreatureCanAttackEachTurnEffect(this);
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
return true;
}
@Override
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
if (!game.getCombat().getAttackers().isEmpty()) {
return false;
}
AttackedThisTurnWatcher watcher = (AttackedThisTurnWatcher) game.getState().getWatchers().get("AttackedThisTurn");
Set<UUID> attackedThisTurnCreatures = watcher.getAttackedThisTurnCreatures();
return attackedThisTurnCreatures.isEmpty()
|| (attackedThisTurnCreatures.size() == 1 && attackedThisTurnCreatures.contains(attacker.getId()));
}
}
class NoMoreThanOneCreatureCanBlockEachTurnEffect extends RestrictionEffect {
public NoMoreThanOneCreatureCanBlockEachTurnEffect() {
super(Duration.WhileOnBattlefield);
this.staticText = "No more than one creature can block each turn";
}
public NoMoreThanOneCreatureCanBlockEachTurnEffect(final NoMoreThanOneCreatureCanBlockEachTurnEffect effect) {
super(effect);
}
@Override
public ContinuousEffect copy() {
return new NoMoreThanOneCreatureCanBlockEachTurnEffect(this);
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
return true;
}
@Override
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
if (!game.getCombat().getBlockers().isEmpty()) {
return false;
}
BlockedThisTurnWatcher watcher = (BlockedThisTurnWatcher) game.getState().getWatchers().get("BlockedThisTurn");
Set<MageObjectReference> blockedThisTurnCreatures = watcher.getBlockedThisTurnCreatures();
MageObjectReference blockerReference = new MageObjectReference(blocker.getId(), blocker.getZoneChangeCounter(game), game);
return blockedThisTurnCreatures.isEmpty()
|| (blockedThisTurnCreatures.size() == 1 && blockedThisTurnCreatures.contains(blockerReference));
}
}

View file

@ -0,0 +1,110 @@
/*
* 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.Mana;
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.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author spjspj
*/
public class EnergyTap extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creature you crontrol");
static {
filter.add(Predicates.not(new TappedPredicate()));
}
public EnergyTap(UUID ownerId) {
super(ownerId, 54, "Energy Tap", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{U}");
this.expansionSetCode = "LEG";
// Tap target untapped creature you control. If you do, add X mana of {C} to your mana pool, where X is that creature's converted mana cost.
this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent(filter));
this.getSpellAbility().addEffect(new EnergyTapEffect());
}
public EnergyTap(final EnergyTap card) {
super(card);
}
@Override
public EnergyTap copy() {
return new EnergyTap(this);
}
}
class EnergyTapEffect extends OneShotEffect {
EnergyTapEffect() {
super(Outcome.PutManaInPool);
this.staticText = "Tap target untapped creature you control. If you do, add X mana of {C} to your mana pool, where X is that creature's converted mana cost";
}
EnergyTapEffect(final EnergyTapEffect effect) {
super(effect);
}
@Override
public EnergyTapEffect copy() {
return new EnergyTapEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
boolean applied = false;
Permanent targetCreature = game.getPermanent(targetPointer.getFirst(game, source));
if (targetCreature != null) {
applied = targetCreature.tap(game);
if (applied) {
player.getManaPool().addMana(new Mana(0, 0, 0, 0, 0, 0, 0, targetCreature.getManaCost().convertedManaCost()), game, source);
}
}
return applied;
}
}

View file

@ -90,7 +90,7 @@ class GoblinGoonCantAttackEffect extends RestrictionEffect {
}
@Override
public boolean canAttack(UUID defenderId, Ability source, Game game) {
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
UUID defendingPlayerId;
Player defender = game.getPlayer(defenderId);
if (defender == null) {

View file

@ -63,12 +63,12 @@ public class MageRingNetwork extends CardImpl {
new ManaCostsImpl("{1}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {T}, Remove X storage counters from Mage-Ring Network: Add {x} to your mana pool.
// {T}, Remove any number of storage counters from Mage-Ring Network: Add {C} to your mana pool for each storage counter removed this way.
ability = new DynamicManaAbility(
Mana.ColorlessMana(1),
new RemovedCountersForCostValue(),
new TapSourceCost(),
"Add {X} to your mana pool",
"Add {C} to your mana pool for each storage counter removed this way",
true, new CountersCount(CounterType.STORAGE));
ability.addCost(new RemoveVariableCountersSourceCost(CounterType.STORAGE.createInstance(),
"Remove X storage counters from {this}"));

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.masterseditioniii;
import java.util.UUID;
import mage.constants.Rarity;
/**
*
* @author spjspj
*/
public class GaeasTouch extends mage.sets.thedark.GaeasTouch {
public GaeasTouch(UUID ownerId) {
super(ownerId);
this.cardNumber = 120;
this.expansionSetCode = "ME3";
this.rarity = Rarity.UNCOMMON;
}
public GaeasTouch(final GaeasTouch card) {
super(card);
}
@Override
public GaeasTouch copy() {
return new GaeasTouch(this);
}
}

View file

@ -91,7 +91,7 @@ class ChainedThroatseekerCantAttackEffect extends RestrictionEffect {
}
@Override
public boolean canAttack(UUID defenderId, Ability source, Game game) {
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
Player targetPlayer = game.getPlayer(defenderId);
if (targetPlayer != null) {
if (targetPlayer.getCounters().containsKey(CounterType.POISON)) {

View file

@ -38,6 +38,7 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
@ -46,6 +47,12 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class JoragaAuxiliary extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("other target creatures");
static {
filter.add(new AnotherPredicate());
}
public JoragaAuxiliary(UUID ownerId) {
super(ownerId, 154, "Joraga Auxiliary", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{G}{W}");
this.expansionSetCode = "OGW";
@ -55,9 +62,9 @@ public class JoragaAuxiliary extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// {4}{G}{W}: Support 2.
// {4}{G}{W}: Support 2. (Put a +1/+1 counter on each of up to two other target creatures.)
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SupportEffect(this, 2, true), new ManaCostsImpl("{4}{G}{W}"));
ability.addTarget(new TargetCreaturePermanent(0, 2, new FilterCreaturePermanent("target creatures"), false));
ability.addTarget(new TargetCreaturePermanent(0, 2, filter, false));
this.addAbility(ability);
}

View file

@ -0,0 +1,118 @@
/*
* 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.onslaught;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.keyword.MorphAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterEnchantmentPermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.target.TargetPermanent;
/**
*
* @author djbrez
*/
public class DawningPurist extends CardImpl {
public DawningPurist(UUID ownerId) {
super(ownerId, 22, "Dawning Purist", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.expansionSetCode = "ONS";
this.subtype.add("Human");
this.subtype.add("Cleric");
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Whenever Dawning Purist deals combat damage to a player, you may destroy target enchantment that player controls.
this.addAbility(new DawningPuristTriggeredAbility());
// Morph {1}{W}
this.addAbility(new MorphAbility(this, new ManaCostsImpl("{1}{W}")));
}
public DawningPurist(final DawningPurist card) {
super(card);
}
@Override
public DawningPurist copy() {
return new DawningPurist(this);
}
}
class DawningPuristTriggeredAbility extends TriggeredAbilityImpl {
DawningPuristTriggeredAbility() {
super(Zone.BATTLEFIELD, new DestroyTargetEffect(), true);
}
DawningPuristTriggeredAbility(final DawningPuristTriggeredAbility ability) {
super(ability);
}
@java.lang.Override
public DawningPuristTriggeredAbility copy() {
return new DawningPuristTriggeredAbility(this);
}
@java.lang.Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
}
@java.lang.Override
public boolean checkTrigger(GameEvent event, Game game) {
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event;
if (damageEvent.isCombatDamage() && event.getSourceId().equals(this.getSourceId())) {
FilterEnchantmentPermanent filter = new FilterEnchantmentPermanent("enchantment that player controls");
filter.add(new ControllerIdPredicate(event.getPlayerId()));
filter.setMessage("enchantment controlled by " + game.getPlayer(event.getTargetId()).getLogName());
this.getTargets().clear();
this.addTarget(new TargetPermanent(filter));
return true;
}
return false;
}
@java.lang.Override
public String getRule() {
return "Whenever {this} deals combat damage to a player, you may destroy target enchantment that player controls.";
}
}

View file

@ -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.sets.onslaught;
import java.util.UUID;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author djbrez
*/
public class WirewoodPride extends CardImpl {
private static final FilterCreaturePermanent elfCount = new FilterCreaturePermanent("Elves");
static {
elfCount.add(new SubtypePredicate("Elf"));
}
public WirewoodPride(UUID ownerId) {
super(ownerId, 303, "Wirewood Pride", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{G}");
this.expansionSetCode = "ONS";
// Target creature gets +X/+X until end of turn, where X is the number of Elves on the battlefield.
PermanentsOnBattlefieldCount amount = new PermanentsOnBattlefieldCount(elfCount);
Effect effect = new BoostTargetEffect(amount, amount, Duration.EndOfTurn, true);
effect.setText("Target creature gets +X/+X until end of turn, where X is the number of Elves on the battlefield");
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
}
public WirewoodPride(final WirewoodPride card) {
super(card);
}
@Override
public WirewoodPride copy() {
return new WirewoodPride(this);
}
}

View file

@ -57,7 +57,7 @@ import mage.game.permanent.Permanent;
*/
public class LeoninArbiter extends CardImpl {
private static final String keyString = "_ignoreEffectForTurn";
private static final String KEY_STRING = "_ignoreEffectForTurn";
public LeoninArbiter(UUID ownerId) {
super(ownerId, 14, "Leonin Arbiter", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{1}{W}");
@ -69,10 +69,10 @@ public class LeoninArbiter extends CardImpl {
this.toughness = new MageInt(2);
// Players can't search libraries.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeoninArbiterCantSearchEffect(keyString)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeoninArbiterCantSearchEffect(KEY_STRING)));
// Any player may pay {2} for that player to ignore this effect until end of turn.
this.addAbility(new LeoninArbiterSpecialAction(keyString));
this.addAbility(new LeoninArbiterSpecialAction(KEY_STRING));
}
public LeoninArbiter(final LeoninArbiter card) {
@ -132,7 +132,7 @@ class LeoninArbiterIgnoreEffect extends OneShotEffect {
// Using a Map.Entry since there is no pair class
long zoneChangeCount = permanent.getZoneChangeCounter(game);
long turnNum = game.getTurnNum();
Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL;
Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL;
Map.Entry<Long, Set<UUID>> turnIgnoringPlayersPair = (Map.Entry<Long, Set<UUID>>) game.getState().getValue(key);
if (turnIgnoringPlayersPair == null || !activationState.equals(turnIgnoringPlayersPair.getKey())) {
@ -169,13 +169,13 @@ class LeoninArbiterCantSearchEffect extends ContinuousRuleModifyingEffectImpl {
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
boolean applies = true;
boolean applies = true;
String key = permanent.getId() + keyString;
Map.Entry<Long, Set<UUID>> turnIgnoringPlayersPair = (Map.Entry<Long, Set<UUID>>) game.getState().getValue(key);
if (turnIgnoringPlayersPair != null) {
long zoneChangeCount = permanent.getZoneChangeCounter(game);
long turnNum = game.getTurnNum();
Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL;
Long activationState = zoneChangeCount << 32 | turnNum & 0xFFFFFFFFL;
if (activationState.equals(turnIgnoringPlayersPair.getKey())) {
applies = !turnIgnoringPlayersPair.getValue().contains(event.getPlayerId());
}

View file

@ -71,20 +71,20 @@ public class PemminsAura extends CardImpl {
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// {U}: Untap enchanted creature.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new UntapEnchantedEffect(), new ManaCostsImpl("{U}")));
// {U}: Enchanted creature gains flying until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(FlyingAbility.getInstance(),
AttachmentType.AURA, Duration.EndOfTurn), new ManaCostsImpl("{U}")));
AttachmentType.AURA, Duration.EndOfTurn), new ManaCostsImpl("{U}")));
// {U}: Enchanted creature gains shroud until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(ShroudAbility.getInstance(),
AttachmentType.AURA, Duration.EndOfTurn), new ManaCostsImpl("{U}")));
AttachmentType.AURA, Duration.EndOfTurn), new ManaCostsImpl("{U}")));
// {1}: Enchanted creature gets +1/-1 or -1/+1 until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PemminsAuraBoostEnchantedEffect(), new ManaCostsImpl("U")));
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new PemminsAuraBoostEnchantedEffect(), new ManaCostsImpl("{1}")));
}
public PemminsAura(final PemminsAura card) {
@ -121,7 +121,7 @@ class PemminsAuraBoostEnchantedEffect extends OneShotEffect {
Player controller = game.getPlayer(source.getControllerId());
Permanent enchantment = game.getPermanent(source.getSourceId());
Permanent creature = game.getPermanent(enchantment.getAttachedTo());
if (controller != null && creature != null) {
if (controller != null && creature != null) {
Choice choice = new ChoiceImpl(true);
choice.setMessage("Select how to boost");
choice.getChoices().add(CHOICE_1);
@ -141,4 +141,4 @@ class PemminsAuraBoostEnchantedEffect extends OneShotEffect {
}
return false;
}
}
}

View file

@ -0,0 +1,125 @@
/*
* 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.thedark;
import mage.cards.CardImpl;
import mage.constants.Rarity;
import mage.Mana;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.mana.SimpleManaAbility;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.LimitedTimesPerTurnActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.mageobject.SupertypePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
/**
*
* @author spjspj
*/
public class GaeasTouch extends CardImpl {
public GaeasTouch(UUID ownerId) {
super(ownerId, 40, "Gaea's Touch", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{G}{G}");
this.expansionSetCode = "DRK";
// You may put a basic Forest card from your hand onto the battlefield. Activate this ability only any time you could cast a sorcery and only once each turn.
LimitedTimesPerTurnActivatedAbility ability = new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, new PutBasicForestOnBattlefieldEffect(), new GenericManaCost(0), 1);
ability.setTiming(TimingRule.SORCERY);
addAbility(ability);
// Sacrifice Gaea's Touch: Add {G}{G} to your mana pool.
addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, Mana.GreenMana(2), new SacrificeSourceCost()));
}
public GaeasTouch(final GaeasTouch card) {
super(card);
}
@Override
public GaeasTouch copy() {
return new GaeasTouch(this);
}
}
class PutBasicForestOnBattlefieldEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("basic Forest card");
static {
filter.add(Predicates.and(new CardTypePredicate(CardType.LAND), new SupertypePredicate("Basic")));
filter.add(new SubtypePredicate("Forest"));
}
private static final String choiceText = "Put a basic Forest card from your hand onto the battlefield?";
public PutBasicForestOnBattlefieldEffect() {
super(Outcome.PutLandInPlay);
this.staticText = "put a basic Forest card from your hand onto the battlefield";
}
public PutBasicForestOnBattlefieldEffect(final PutBasicForestOnBattlefieldEffect effect) {
super(effect);
}
@Override
public PutBasicForestOnBattlefieldEffect copy() {
return new PutBasicForestOnBattlefieldEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null || !player.chooseUse(Outcome.PutLandInPlay, choiceText, source, game)) {
return false;
}
TargetCardInHand target = new TargetCardInHand(filter);
if (player.choose(Outcome.PutLandInPlay, target, source.getSourceId(), game)) {
Card card = game.getCard(target.getFirstTarget());
if (card != null) {
card.putOntoBattlefield(game, Zone.HAND, source.getSourceId(), source.getControllerId());
return true;
}
}
return false;
}
}

View file

@ -92,7 +92,7 @@ class TeferisMoatRestrictionEffect extends RestrictionEffect {
}
@Override
public boolean canAttack(UUID defenderId, Ability source, Game game) {
public boolean canAttack(Permanent attacker, UUID defenderId, Ability source, Game game) {
return !defenderId.equals(source.getControllerId());
}
@ -100,4 +100,4 @@ class TeferisMoatRestrictionEffect extends RestrictionEffect {
public TeferisMoatRestrictionEffect copy() {
return new TeferisMoatRestrictionEffect(this);
}
}
}

View file

@ -0,0 +1,116 @@
/*
* 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.urzasdestiny;
import java.util.UUID;
import mage.Mana;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AddManaToManaPoolTargetControllerEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.mana.DelayedTriggeredManaAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.ColoredManaSymbol;
import mage.constants.Duration;
import mage.constants.Rarity;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author spjspj
*/
public class BubblingMuck extends CardImpl {
public BubblingMuck(UUID ownerId) {
super(ownerId, 54, "Bubbling Muck", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{B}");
this.expansionSetCode = "UDS";
// Until end of turn, whenever a player taps a Swamp for mana, that player adds {B} to his or her mana pool.
this.getSpellAbility().addEffect(new CreateDelayedTriggeredAbilityEffect(new BubblingMuckTriggeredAbility()));
}
public BubblingMuck(final BubblingMuck card) {
super(card);
}
@Override
public BubblingMuck copy() {
return new BubblingMuck(this);
}
}
class BubblingMuckTriggeredAbility extends DelayedTriggeredManaAbility {
private static final FilterLandPermanent filter = new FilterLandPermanent("Swamp");
static {
filter.add(new SubtypePredicate("Swamp"));
}
public BubblingMuckTriggeredAbility() {
super(new AddManaToManaPoolTargetControllerEffect(new Mana(ColoredManaSymbol.B), "his or her"), Duration.EndOfTurn, false);
this.usesStack = false;
}
public BubblingMuckTriggeredAbility(BubblingMuckTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.TAPPED_FOR_MANA;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent land = game.getPermanent(event.getTargetId());
if (land != null && filter.match(land, game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(land.getControllerId()));
}
return true;
}
return false;
}
@Override
public BubblingMuckTriggeredAbility copy() {
return new BubblingMuckTriggeredAbility(this);
}
@Override
public String getRule() {
return "Until end of turn, whenever a player taps a Swamp for mana, that player adds {B} to his or her mana pool";
}
}

View file

@ -70,8 +70,10 @@ public class GildedDrake extends CardImpl {
// Flying
this.addAbility(FlyingAbility.getInstance());
// When Gilded Drake enters the battlefield, exchange control of Gilded Drake and up to one target creature an opponent controls. If you don't make an exchange, sacrifice Gilded Drake. This ability can't be countered except by spells and abilities.
// When Gilded Drake enters the battlefield, exchange control of Gilded Drake and up to one target creature an opponent controls. If you don't make an exchange, sacrifice Gilded Drake.
// This ability can't be countered except by spells and abilities.
Ability ability = new EntersBattlefieldTriggeredAbility(new GildedDrakeEffect());
ability.setCanFizzle(false);
ability.addTarget(new TargetCreaturePermanent(0, 1, filter, false));
this.addAbility(ability);
}

View file

@ -117,13 +117,13 @@ class MarchesaTheBlackRoseTriggeredAbility extends TriggeredAbilityImpl {
public boolean checkTrigger(GameEvent event, Game game) {
if (((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) {
Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
Permanent permanent = ((ZoneChangeEvent) event).getTarget();
if (permanent != null
&& permanent.getControllerId().equals(this.getControllerId())
&& permanent.getCardType().contains(CardType.CREATURE)
&& permanent.getCounters().getCount(CounterType.P1P1) > 0) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(permanent.getId()));
effect.setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game) + 1));
}
return true;
}