Merge branch 'master' of ssh://git.magefree.com/var/lib/git/mage

This commit is contained in:
intimidatingant 2012-03-14 20:53:15 -07:00
commit a20d1fbf8e
51 changed files with 4061 additions and 198 deletions

View file

@ -0,0 +1,150 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.condition.common.FatefulHourCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.PreventAllDamageEffect;
import mage.cards.CardImpl;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterAttackingCreature;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author BetaSteward
*/
public class ClingingMists extends CardImpl<ClingingMists> {
private static final FilterPermanent filter = new FilterPermanent();
public ClingingMists(UUID ownerId) {
super(ownerId, 109, "Clinging Mists", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{2}{G}");
this.expansionSetCode = "DKA";
this.color.setGreen(true);
// Prevent all combat damage that would be dealt this turn.
this.getSpellAbility().addEffect(new PreventAllDamageEffect(filter, Constants.Duration.EndOfTurn, true));
// Fateful hour If you have 5 or less life, tap all attacking creatures. Those creatures don't untap during their controller's next untap step.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(new ClingingMistsEffect(),
FatefulHourCondition.getInstance(), "If you have 5 or less life, tap all attacking creatures. Those creatures don't untap during their controller's next untap step."));
}
public ClingingMists(final ClingingMists card) {
super(card);
}
@Override
public ClingingMists copy() {
return new ClingingMists(this);
}
}
class ClingingMistsEffect extends OneShotEffect<ClingingMistsEffect> {
private static final FilterAttackingCreature filter = new FilterAttackingCreature("attacking creatures");
public ClingingMistsEffect() {
super(Constants.Outcome.Tap);
staticText = "tap all attacking creatures. Those creatures don't untap during their controller's next untap step";
}
public ClingingMistsEffect(final ClingingMistsEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent creature: game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
creature.tap(game);
game.addEffect(new ClingingMistsEffect2(creature.getId()), source);
}
return true;
}
@Override
public ClingingMistsEffect copy() {
return new ClingingMistsEffect(this);
}
}
class ClingingMistsEffect2 extends ReplacementEffectImpl<ClingingMistsEffect2> {
protected UUID creatureId;
public ClingingMistsEffect2(UUID creatureId) {
super(Constants.Duration.OneUse, Constants.Outcome.Detriment);
this.creatureId = creatureId;
}
public ClingingMistsEffect2(final ClingingMistsEffect2 effect) {
super(effect);
creatureId = effect.creatureId;
}
@Override
public ClingingMistsEffect2 copy() {
return new ClingingMistsEffect2(this);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
used = true;
return true;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (game.getTurn().getStepType() == Constants.PhaseStep.UNTAP &&
event.getType() == GameEvent.EventType.UNTAP &&
event.getTargetId().equals(creatureId)) {
return true;
}
return false;
}
}

View file

@ -0,0 +1,74 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.MustBlockSourceEffect;
import mage.abilities.effects.common.continious.GainAbilityTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.CardImpl;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author BetaSteward
*/
public class DeadlyAllure extends CardImpl<DeadlyAllure> {
public DeadlyAllure(UUID ownerId) {
super(ownerId, 58, "Deadly Allure", Rarity.UNCOMMON, new CardType[]{CardType.SORCERY}, "{B}");
this.expansionSetCode = "DKA";
this.color.setBlack(true);
// Target creature gains deathtouch until end of turn and must be blocked this turn if able.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new MustBlockSourceEffect()), Constants.Duration.EndOfTurn));
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DeathtouchAbility.getInstance(), Constants.Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Flashback {G}
this.addAbility(new FlashbackAbility(new ManaCostsImpl("{G}"), Constants.TimingRule.SORCERY));
}
public DeadlyAllure(final DeadlyAllure card) {
super(card);
}
@Override
public DeadlyAllure copy() {
return new DeadlyAllure(this);
}
}

View file

@ -0,0 +1,114 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.filter.Filter;
import mage.filter.common.FilterNonTokenPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.WolfToken;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent;
/**
*
* @author BetaSteward
*/
public class FeedThePack extends CardImpl<FeedThePack> {
public FeedThePack(UUID ownerId) {
super(ownerId, 114, "Feed the Pack", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{5}{G}");
this.expansionSetCode = "DKA";
this.color.setGreen(true);
// At the beginning of your end step, you may sacrifice a nontoken creature. If you do, put X 2/2 green Wolf creature tokens onto the battlefield, where X is the sacrificed creature's toughness.
this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new FeedThePackEffect(), true));
}
public FeedThePack(final FeedThePack card) {
super(card);
}
@Override
public FeedThePack copy() {
return new FeedThePack(this);
}
}
class FeedThePackEffect extends OneShotEffect<FeedThePackEffect> {
private static final FilterNonTokenPermanent filter = new FilterNonTokenPermanent("nontoken creature");
static {
filter.getCardType().add(CardType.CREATURE);
filter.setScopeCardType(Filter.ComparisonScope.Any);
filter.setTargetController(Constants.TargetController.YOU);
}
public FeedThePackEffect() {
super(Constants.Outcome.Sacrifice);
this.staticText = "sacrifice a nontoken creature. If you do, put X 2/2 green Wolf creature tokens onto the battlefield, where X is the sacrificed creature's toughness";
}
public FeedThePackEffect(final FeedThePackEffect effect) {
super(effect);
}
@Override
public FeedThePackEffect copy() {
return new FeedThePackEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Target target = new TargetPermanent(filter);
Player player = game.getPlayer(source.getControllerId());
if (player.choose(Outcome.PutCreatureInPlay, target, source.getSourceId(), game)) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null && permanent.sacrifice(source.getSourceId(), game)) {
int toughness = permanent.getToughness().getValue();
WolfToken token = new WolfToken();
token.putOntoBattlefield(toughness, game, source.getSourceId(), source.getControllerId());
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,157 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.UndyingAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreatureOrPlayer;
/**
*
* @author BetaSteward
*/
public class FlayerOfTheHatebound extends CardImpl<FlayerOfTheHatebound> {
public FlayerOfTheHatebound(UUID ownerId) {
super(ownerId, 89, "Flayer of the Hatebound", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{5}{R}");
this.expansionSetCode = "DKA";
this.subtype.add("Devil");
this.color.setRed(true);
this.power = new MageInt(4);
this.toughness = new MageInt(2);
this.addAbility(new UndyingAbility());
// Whenever Flayer of the Hatebound or another creature enters the battlefield from your graveyard, that creature deals damage equal to its power to target creature or player.
Ability ability = new FlayerTriggeredAbility();
ability.addTarget(new TargetCreatureOrPlayer());
this.addAbility(ability);
}
public FlayerOfTheHatebound(final FlayerOfTheHatebound card) {
super(card);
}
@Override
public FlayerOfTheHatebound copy() {
return new FlayerOfTheHatebound(this);
}
}
class FlayerTriggeredAbility extends TriggeredAbilityImpl<FlayerTriggeredAbility> {
public FlayerTriggeredAbility() {
super(Constants.Zone.BATTLEFIELD, new FlayerEffect(), false);
}
public FlayerTriggeredAbility(FlayerTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (((ZoneChangeEvent) event).getToZone() == Constants.Zone.BATTLEFIELD
&& ((ZoneChangeEvent) event).getFromZone() == Constants.Zone.GRAVEYARD
&& permanent.getOwnerId().equals(controllerId)
&& permanent.getCardType().contains(CardType.CREATURE)) {
Effect effect = this.getEffects().get(0);
effect.setValue("damageSource", event.getTargetId());
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever Flayer of the Hatebound or another creature enters the battlefield from your graveyard, that creature deals damage equal to its power to target creature or player.";
}
@Override
public FlayerTriggeredAbility copy() {
return new FlayerTriggeredAbility(this);
}
}
class FlayerEffect extends OneShotEffect<FlayerEffect> {
public FlayerEffect() {
super(Constants.Outcome.Damage);
staticText = "that creature deals damage equal to its power to target creature or player";
}
public FlayerEffect(final FlayerEffect effect) {
super(effect);
}
@Override
public FlayerEffect copy() {
return new FlayerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
UUID creatureId = (UUID) getValue("damageSource");
Permanent creature = game.getPermanent(creatureId);
if (creature == null) {
creature = (Permanent) game.getLastKnownInformation(creatureId, Constants.Zone.BATTLEFIELD);
}
if (creature != null) {
int amount = creature.getPower().getValue();
UUID target = source.getTargets().getFirstTarget();
Permanent targetCreature = game.getPermanent(target);
if (targetCreature != null) {
targetCreature.damage(amount, creature.getId(), game, true, false);
return true;
}
Player player = game.getPlayer(target);
if (player != null) {
player.damage(amount, creature.getId(), game, false, true);
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,124 @@
/*
* 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.darkascension;
import java.util.List;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.condition.common.MorbidCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DiscardTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer;
/**
*
* @author North
*/
public class GruesomeDiscovery extends CardImpl<GruesomeDiscovery> {
public GruesomeDiscovery(UUID ownerId) {
super(ownerId, 66, "Gruesome Discovery", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{B}{B}");
this.expansionSetCode = "DKA";
this.color.setBlack(true);
// Target player discards two cards.
// Morbid - If a creature died this turn, instead that player reveals his or her hand, you choose two cards from it, then that player discards those cards.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new GruesomeDiscoveryEffect(),
new DiscardTargetEffect(2),
MorbidCondition.getInstance(),
"Target player discards two cards. Morbid - If a creature died this turn, instead that player reveals his or her hand, you choose two cards from it, then that player discards those cards"));
this.getSpellAbility().addTarget(new TargetPlayer());
}
public GruesomeDiscovery(final GruesomeDiscovery card) {
super(card);
}
@Override
public GruesomeDiscovery copy() {
return new GruesomeDiscovery(this);
}
}
class GruesomeDiscoveryEffect extends OneShotEffect<GruesomeDiscoveryEffect> {
public GruesomeDiscoveryEffect() {
super(Outcome.Discard);
this.staticText = "target player reveals his or her hand, you choose two cards from it, then that player discards those cards";
}
public GruesomeDiscoveryEffect(final GruesomeDiscoveryEffect effect) {
super(effect);
}
@Override
public GruesomeDiscoveryEffect copy() {
return new GruesomeDiscoveryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (player != null && targetPlayer != null) {
targetPlayer.revealCards("Gruesome Discovery", targetPlayer.getHand(), game);
if (targetPlayer.getHand().size() <= 2) {
targetPlayer.discard(2, source, game);
}
TargetCard target = new TargetCard(2, Zone.PICK, new FilterCard());
target.setRequired(true);
if (player.choose(Outcome.Benefit, targetPlayer.getHand(), target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card card = targetPlayer.getHand().get(targetId, game);
if (card != null) {
return targetPlayer.discard(card, source, game);
}
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,105 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author North
*/
public class Hellrider extends CardImpl<Hellrider> {
public Hellrider(UUID ownerId) {
super(ownerId, 93, "Hellrider", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.expansionSetCode = "DKA";
this.subtype.add("Devil");
this.color.setRed(true);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.addAbility(HasteAbility.getInstance());
// Whenever a creature you control attacks, Hellrider deals 1 damage to defending player.
this.addAbility(new HellriderTriggeredAbility());
}
public Hellrider(final Hellrider card) {
super(card);
}
@Override
public Hellrider copy() {
return new Hellrider(this);
}
}
class HellriderTriggeredAbility extends TriggeredAbilityImpl<HellriderTriggeredAbility> {
public HellriderTriggeredAbility() {
super(Zone.BATTLEFIELD, new DamageTargetEffect(1));
}
public HellriderTriggeredAbility(final HellriderTriggeredAbility ability) {
super(ability);
}
@Override
public HellriderTriggeredAbility copy() {
return new HellriderTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED) {
Permanent source = game.getPermanent(event.getSourceId());
if (source != null && source.getControllerId().equals(controllerId)) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(event.getTargetId()));
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever a creature you control attacks, {this} deals 1 damage to defending player.";
}
}

View file

@ -0,0 +1,76 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
/**
*
* @author BetaSteward
*/
public class HinterlandHermit extends CardImpl<HinterlandHermit> {
public HinterlandHermit(UUID ownerId) {
super(ownerId, 94, "Hinterland Hermit", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.expansionSetCode = "DKA";
this.subtype.add("Human");
this.subtype.add("Werewolf");
this.canTransform = true;
this.secondSideCard = new HinterlandScourge(ownerId);
this.color.setRed(true);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// At the beginning of each upkeep, if no spells were cast last turn, transform Hinterland Hermit.
this.addAbility(new TransformAbility());
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), Constants.TargetController.ANY, false);
this.addAbility(new ConditionalTriggeredAbility(ability, NoSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.NO_SPELLS_TRANSFORM_RULE));
}
public HinterlandHermit(final HinterlandHermit card) {
super(card);
}
@Override
public HinterlandHermit copy() {
return new HinterlandHermit(this);
}
}

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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.MustBlockSourceEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
/**
*
* @author BetaSteward
*/
public class HinterlandScourge extends CardImpl<HinterlandScourge> {
public HinterlandScourge(UUID ownerId) {
super(ownerId, 94, "Hinterland Scourge", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "DKA";
this.subtype.add("Werewolf");
// this card is the second face of double-faced card
this.nightCard = true;
this.canTransform = true;
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Hinterland Scourge must be blocked if able.
this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new MustBlockSourceEffect()));
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Hinterland Scourge.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), Constants.TargetController.ANY, false);
this.addAbility(new ConditionalTriggeredAbility(ability, TwoOrMoreSpellsWereCastLastTurnCondition.getInstance(), TransformAbility.TWO_OR_MORE_SPELLS_TRANSFORM_RULE));
}
public HinterlandScourge(final HinterlandScourge card) {
super(card);
}
@Override
public HinterlandScourge copy() {
return new HinterlandScourge(this);
}
}

View file

@ -0,0 +1,233 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.counters.CounterType;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
/**
*
* @author North
*/
public class JarOfEyeballs extends CardImpl<JarOfEyeballs> {
public JarOfEyeballs(UUID ownerId) {
super(ownerId, 152, "Jar of Eyeballs", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}");
this.expansionSetCode = "DKA";
// Whenever a creature you control dies, put two eyeball counters on Jar of Eyeballs.
this.addAbility(new JarOfEyeballsTriggeredAbility());
// {3}, {tap}, Remove all eyeball counters from Jar of Eyeballs:
// Look at the top X cards of your library, where X is the number of eyeball counters removed this way.
// Put one of them into your hand and the rest on the bottom of your library in any order.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new JarOfEyeballsEffect(), new GenericManaCost(3));
ability.addCost(new TapSourceCost());
ability.addCost(new JarOfEyeballsCost());
this.addAbility(ability);
}
public JarOfEyeballs(final JarOfEyeballs card) {
super(card);
}
@Override
public JarOfEyeballs copy() {
return new JarOfEyeballs(this);
}
}
class JarOfEyeballsTriggeredAbility extends TriggeredAbilityImpl<JarOfEyeballsTriggeredAbility> {
public JarOfEyeballsTriggeredAbility() {
super(Zone.BATTLEFIELD, new AddCountersSourceEffect(CounterType.EYEBALL.createInstance(2)));
}
public JarOfEyeballsTriggeredAbility(final JarOfEyeballsTriggeredAbility ability) {
super(ability);
}
@Override
public JarOfEyeballsTriggeredAbility copy() {
return new JarOfEyeballsTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) {
Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (permanent.getControllerId().equals(this.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever a creature you control dies, " + super.getRule();
}
}
class JarOfEyeballsCost extends CostImpl<JarOfEyeballsCost> {
private int removedCounters;
public JarOfEyeballsCost() {
super();
this.removedCounters = 0;
this.text = "Remove all eyeball counters from {this}";
}
public JarOfEyeballsCost(JarOfEyeballsCost cost) {
super(cost);
this.removedCounters = cost.removedCounters;
}
@Override
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
return true;
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
Permanent permanent = game.getPermanent(ability.getSourceId());
if (permanent != null) {
this.removedCounters = permanent.getCounters().getCount(CounterType.EYEBALL);
if (this.removedCounters > 0) {
permanent.removeCounters(CounterType.EYEBALL.createInstance(this.removedCounters), game);
}
}
this.paid = true;
return true;
}
@Override
public JarOfEyeballsCost copy() {
return new JarOfEyeballsCost(this);
}
public int getRemovedCounters() {
return this.removedCounters;
}
}
class JarOfEyeballsEffect extends OneShotEffect<JarOfEyeballsEffect> {
public JarOfEyeballsEffect() {
super(Outcome.DrawCard);
this.staticText = "Look at the top X cards of your library, where X is the number of eyeball counters removed this way. Put one of them into your hand and the rest on the bottom of your library in any order";
}
public JarOfEyeballsEffect(final JarOfEyeballsEffect effect) {
super(effect);
}
@Override
public JarOfEyeballsEffect copy() {
return new JarOfEyeballsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
int countersRemoved = 0;
for (Cost cost : source.getCosts()) {
if (cost instanceof JarOfEyeballsCost) {
countersRemoved = ((JarOfEyeballsCost) cost).getRemovedCounters();
}
}
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = new CardsImpl(Zone.PICK);
int count = Math.min(player.getLibrary().size(), countersRemoved);
for (int i = 0; i < count; i++) {
Card card = player.getLibrary().removeFromTop(game);
if (card != null) {
cards.add(card);
game.setZone(card.getId(), Zone.PICK);
}
}
player.lookAtCards("Jar of Eyeballs", cards, game);
TargetCard target = new TargetCard(Zone.PICK, new FilterCard("card to put into your hand"));
if (player.choose(Outcome.DrawCard, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.HAND, source.getId(), game, false);
}
}
target = new TargetCard(Zone.PICK, new FilterCard("card to put on the bottom of your library"));
target.setRequired(true);
while (cards.size() > 1) {
player.choose(Outcome.Neutral, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
card.moveToZone(Zone.LIBRARY, source.getId(), game, false);
}
target.clearChosen();
}
if (cards.size() == 1) {
Card card = cards.get(cards.iterator().next(), game);
card.moveToZone(Zone.LIBRARY, source.getId(), game, false);
}
return true;
}
}

View file

@ -0,0 +1,148 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.DiesTriggeredAbility;
import mage.abilities.common.delayed.AtEndOfTurnDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ReturnFromExileEffect;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author BetaSteward
*/
public class LoyalCathar extends CardImpl<LoyalCathar> {
public LoyalCathar(UUID ownerId) {
super(ownerId, 13, "Loyal Cathar", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{W}{W}");
this.expansionSetCode = "DKA";
this.subtype.add("Human");
this.subtype.add("Soldier");
this.canTransform = true;
this.secondSideCard = new UnhallowedCathar(ownerId);
this.color.setWhite(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.addAbility(VigilanceAbility.getInstance());
// When Loyal Cathar dies, return it to the battlefield transformed under your control at the beginning of the next end step.
this.addAbility(new TransformAbility());
this.addAbility(new DiesTriggeredAbility(new LoyalCatharEffect()));
}
public LoyalCathar(final LoyalCathar card) {
super(card);
}
@Override
public LoyalCathar copy() {
return new LoyalCathar(this);
}
}
class LoyalCatharEffect extends OneShotEffect<LoyalCatharEffect> {
private static final String effectText = "return it to the battlefield transformed under your control at the beginning of the next end step";
LoyalCatharEffect ( ) {
super(Constants.Outcome.Benefit);
staticText = effectText;
}
LoyalCatharEffect(LoyalCatharEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
//create delayed triggered ability
AtEndOfTurnDelayedTriggeredAbility delayedAbility = new AtEndOfTurnDelayedTriggeredAbility(new ReturnLoyalCatharEffect(source.getSourceId()));
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
@Override
public LoyalCatharEffect copy() {
return new LoyalCatharEffect(this);
}
}
class ReturnLoyalCatharEffect extends OneShotEffect<ReturnLoyalCatharEffect> {
private UUID cardId;
public ReturnLoyalCatharEffect(UUID cardId) {
super(Constants.Outcome.PutCardInPlay);
this.cardId = cardId;
this.staticText = "return it to the battlefield transformed under your control";
}
public ReturnLoyalCatharEffect(final ReturnLoyalCatharEffect effect) {
super(effect);
this.cardId = effect.cardId;
}
@Override
public ReturnLoyalCatharEffect copy() {
return new ReturnLoyalCatharEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(cardId);
if (card != null) {
card.putOntoBattlefield(game, Constants.Zone.GRAVEYARD, source.getSourceId(), source.getControllerId());
Permanent perm = game.getPermanent(cardId);
if (perm != null && perm.canTransform()) {
perm.transform(game);
return true;
}
}
return false;
}
}

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.darkascension;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.delayed.AtEndOfTurnDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.sets.tokens.EmptyToken;
import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
*
* @author BetaSteward
*/
public class Seance extends CardImpl<Seance> {
public Seance(UUID ownerId) {
super(ownerId, 20, "Seance", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
this.expansionSetCode = "DKA";
this.color.setWhite(true);
// At the beginning of each upkeep, you may exile target creature card from your graveyard. If you do, put a token onto the battlefield that's a copy of that card except it's a Spirit in addition to its other types. Exile it at the beginning of the next end step.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new SeanceEffect(), Constants.TargetController.ANY, true);
ability.addTarget(new TargetCardInYourGraveyard(new FilterCreatureCard()));
this.addAbility(ability);
}
public Seance(final Seance card) {
super(card);
}
@Override
public Seance copy() {
return new Seance(this);
}
}
class SeanceEffect extends OneShotEffect<SeanceEffect> {
public SeanceEffect() {
super(Constants.Outcome.PutCreatureInPlay);
this.staticText = "put a token onto the battlefield that's a copy of that card except it's a Spirit in addition to its other types. Exile it at the beginning of the next end step";
}
public SeanceEffect(final SeanceEffect effect) {
super(effect);
}
@Override
public SeanceEffect copy() {
return new SeanceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Card card = game.getCard(source.getFirstTarget());
if (card != null) {
card.moveToExile(null, "", source.getSourceId(), game);
EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from(card);
if (!token.getSubtype().contains("Spirit"))
token.getSubtype().add("Spirit");
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
ExileTargetEffect exileEffect = new ExileTargetEffect();
exileEffect.setTargetPointer(new FixedTarget(token.getLastAddedToken()));
DelayedTriggeredAbility delayedAbility = new AtEndOfTurnDelayedTriggeredAbility(exileEffect);
delayedAbility.setSourceId(source.getSourceId());
delayedAbility.setControllerId(source.getControllerId());
game.addDelayedTriggeredAbility(delayedAbility);
return true;
}
return false;
}
}

View file

@ -0,0 +1,151 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.DamagedCreatureEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author North
*/
public class SpitefulShadows extends CardImpl<SpitefulShadows> {
public SpitefulShadows(UUID ownerId) {
super(ownerId, 75, "Spiteful Shadows", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}");
this.expansionSetCode = "DKA";
this.subtype.add("Aura");
this.color.setBlack(true);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// Whenever enchanted creature is dealt damage, it deals that much damage to its controller.
this.addAbility(new SpitefulShadowsTriggeredAbility());
}
public SpitefulShadows(final SpitefulShadows card) {
super(card);
}
@Override
public SpitefulShadows copy() {
return new SpitefulShadows(this);
}
}
class SpitefulShadowsTriggeredAbility extends TriggeredAbilityImpl<SpitefulShadowsTriggeredAbility> {
public SpitefulShadowsTriggeredAbility() {
super(Zone.BATTLEFIELD, new SpitefulShadowsEffect());
}
public SpitefulShadowsTriggeredAbility(final SpitefulShadowsTriggeredAbility ability) {
super(ability);
}
@Override
public SpitefulShadowsTriggeredAbility copy() {
return new SpitefulShadowsTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.DAMAGED_CREATURE) {
Permanent enchantment = game.getPermanent(sourceId);
if (enchantment != null && enchantment.getAttachedTo() != null) {
if (event.getTargetId().equals(enchantment.getAttachedTo())) {
this.getEffects().get(0).setValue("damageAmount", event.getAmount());
this.getEffects().get(0).setValue("targetId", event.getTargetId());
return true;
}
}
}
return false;
}
@Override
public String getRule() {
return "Whenever enchanted creature is dealt damage, it deals that much damage to its controller.";
}
}
class SpitefulShadowsEffect extends OneShotEffect<SpitefulShadowsEffect> {
public SpitefulShadowsEffect() {
super(Outcome.Damage);
this.staticText = "it deals that much damage to its controller";
}
public SpitefulShadowsEffect(final SpitefulShadowsEffect effect) {
super(effect);
}
@Override
public SpitefulShadowsEffect copy() {
return new SpitefulShadowsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Integer damageAmount = (Integer) this.getValue("damageAmount");
UUID targetId = (UUID) this.getValue("targetId");
if (damageAmount != null && targetId != null) {
Permanent permanent = game.getPermanent(targetId);
if (permanent == null)
permanent = (Permanent) game.getLastKnownInformation(targetId, Zone.BATTLEFIELD);
if (permanent != null) {
Player player = game.getPlayer(permanent.getControllerId());
if (player != null) {
player.damage(damageAmount, targetId, game, false, true);
return true;
}
}
}
return false;
}
}

View file

@ -0,0 +1,68 @@
/*
* 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.darkascension;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.common.CantBlockAbility;
import mage.cards.CardImpl;
/**
*
* @author BetaSteward
*/
public class UnhallowedCathar extends CardImpl<UnhallowedCathar> {
public UnhallowedCathar(UUID ownerId) {
super(ownerId, 13, "Unhallowed Cathar", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "DKA";
this.subtype.add("Zombie");
this.subtype.add("Soldier");
// this card is the second face of double-faced card
this.nightCard = true;
this.canTransform = true;
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Unhallowed Cathar can't block.
this.addAbility(CantBlockAbility.getInstance());
}
public UnhallowedCathar(final UnhallowedCathar card) {
super(card);
}
@Override
public UnhallowedCathar copy() {
return new UnhallowedCathar(this);
}
}

View file

@ -0,0 +1,101 @@
/*
* 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.dissension;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
/**
*
* @author North
*/
public class ProperBurial extends CardImpl<ProperBurial> {
public ProperBurial(UUID ownerId) {
super(ownerId, 16, "Proper Burial", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}");
this.expansionSetCode = "DIS";
this.color.setWhite(true);
// Whenever a creature you control dies, you gain life equal to that creature's toughness.
this.addAbility(new ProperBurialTriggeredAbility());
}
public ProperBurial(final ProperBurial card) {
super(card);
}
@Override
public ProperBurial copy() {
return new ProperBurial(this);
}
}
class ProperBurialTriggeredAbility extends TriggeredAbilityImpl<ProperBurialTriggeredAbility> {
public ProperBurialTriggeredAbility() {
super(Zone.BATTLEFIELD, null);
}
public ProperBurialTriggeredAbility(final ProperBurialTriggeredAbility ability) {
super(ability);
}
@Override
public ProperBurialTriggeredAbility copy() {
return new ProperBurialTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) {
Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (permanent.getControllerId().equals(this.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) {
this.addEffect(new GainLifeEffect(permanent.getToughness().getValue()));
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever a creature you control dies, you gain life equal to that creature's toughness.";
}
}

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 North
*/
public class GravePact extends mage.sets.ninthedition.GravePact {
public GravePact(UUID ownerId) {
super(ownerId);
this.cardNumber = 137;
this.expansionSetCode = "8ED";
}
public GravePact(final GravePact card) {
super(card);
}
@Override
public GravePact copy() {
return new GravePact(this);
}
}

View file

@ -43,11 +43,11 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.Filter;
import mage.filter.common.FilterNonTokenPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
import mage.target.common.TargetCreaturePermanent;
import mage.target.TargetPermanent;
/**
*
@ -55,6 +55,13 @@ import mage.target.common.TargetCreaturePermanent;
*/
public class PhyrexianIngester extends CardImpl<PhyrexianIngester> {
private static final FilterNonTokenPermanent filter = new FilterNonTokenPermanent("nontoken creature");
static {
filter.getCardType().add(CardType.CREATURE);
filter.setScopeCardType(Filter.ComparisonScope.Any);
}
public PhyrexianIngester(UUID ownerId) {
super(ownerId, 41, "Phyrexian Ingester", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{6}{U}");
this.expansionSetCode = "NPH";
@ -66,22 +73,7 @@ public class PhyrexianIngester extends CardImpl<PhyrexianIngester> {
// Imprint - When Phyrexian Ingester enters the battlefield, you may exile target nontoken creature.
Ability ability = new EntersBattlefieldTriggeredAbility(new PhyrexianIngesterImprintEffect(), true);
FilterCreaturePermanent filter = new FilterCreaturePermanent("nontoken creature") {
@Override
public boolean match(Permanent permanent) {
if (!super.match(permanent)) {
return notFilter;
}
if (permanent instanceof PermanentToken) {
return notFilter;
}
return !notFilter;
}
};
ability.addTarget(new TargetCreaturePermanent(filter));
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
// Phyrexian Ingester gets +X/+Y, where X is the exiled creature card's power and Y is its toughness.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new PhyrexianIngesterBoostEffect()));

View file

@ -0,0 +1,139 @@
/*
* 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.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author North
*/
public class GravePact extends CardImpl<GravePact> {
public GravePact(UUID ownerId) {
super(ownerId, 135, "Grave Pact", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{1}{B}{B}{B}");
this.expansionSetCode = "9ED";
this.color.setBlack(true);
// Whenever a creature you control dies, each other player sacrifices a creature.
this.addAbility(new GravePactTriggeredAbility());
}
public GravePact(final GravePact card) {
super(card);
}
@Override
public GravePact copy() {
return new GravePact(this);
}
}
class GravePactTriggeredAbility extends TriggeredAbilityImpl<GravePactTriggeredAbility> {
public GravePactTriggeredAbility() {
super(Zone.BATTLEFIELD, new GravePactEffect());
}
public GravePactTriggeredAbility(final GravePactTriggeredAbility ability) {
super(ability);
}
@Override
public GravePactTriggeredAbility copy() {
return new GravePactTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE
&& ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD
&& ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD) {
Permanent permanent = (Permanent) game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD);
if (permanent.getControllerId().equals(this.getControllerId()) && permanent.getCardType().contains(CardType.CREATURE)) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever a creature you control dies, " + super.getRule();
}
}
class GravePactEffect extends OneShotEffect<GravePactEffect> {
public GravePactEffect() {
super(Outcome.Sacrifice);
this.staticText = "each other player sacrifices a creature";
}
public GravePactEffect(final GravePactEffect effect) {
super(effect);
}
@Override
public GravePactEffect copy() {
return new GravePactEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID playerId : game.getPlayerList()) {
if (!playerId.equals(source.getControllerId())) {
Player player = game.getPlayer(playerId);
Target target = new TargetControlledCreaturePermanent();
if (player != null && player.choose(Outcome.Sacrifice, target, source.getSourceId(), game)) {
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent != null) {
permanent.sacrifice(source.getSourceId(), game);
}
}
}
}
return false;
}
}

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 North
*/
public class GravePact extends mage.sets.ninthedition.GravePact {
public GravePact(UUID ownerId) {
super(ownerId);
this.cardNumber = 28;
this.expansionSetCode = "HOP";
}
public GravePact(final GravePact card) {
super(card);
}
@Override
public GravePact copy() {
return new GravePact(this);
}
}

View file

@ -28,9 +28,8 @@
package mage.sets.planechase;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
@ -47,6 +46,8 @@ public class SyphonSoul extends CardImpl<SyphonSoul> {
super(ownerId, 43, "Syphon Soul", Rarity.COMMON, new CardType[]{CardType.SORCERY}, "{2}{B}");
this.expansionSetCode = "HOP";
this.color.setBlack(true);
// Syphon Soul deals 2 damage to each other player. You gain life equal to the damage dealt this way.
this.getSpellAbility().addEffect(new SyphonSoulEffect());
}
@ -62,7 +63,7 @@ public class SyphonSoul extends CardImpl<SyphonSoul> {
class SyphonSoulEffect extends OneShotEffect<SyphonSoulEffect> {
public SyphonSoulEffect() {
super(Constants.Outcome.Damage);
super(Outcome.Damage);
staticText = "{this} deals 2 damage to each other player. You gain life equal to the damage dealt this way";
}
@ -72,12 +73,15 @@ class SyphonSoulEffect extends OneShotEffect<SyphonSoulEffect> {
@Override
public boolean apply(Game game, Ability source) {
int loseLife = 0;
for (UUID opponentId : game.getOpponents(source.getControllerId())) {
loseLife += game.getPlayer(opponentId).loseLife(2, game);
int damageDealt = 0;
for (UUID playerId : game.getPlayerList()) {
if (!playerId.equals(source.getControllerId())) {
damageDealt += game.getPlayer(playerId).damage(2, source.getSourceId(), game, false, true);
}
}
if (damageDealt > 0) {
game.getPlayer(source.getControllerId()).gainLife(damageDealt, game);
}
if (loseLife > 0)
game.getPlayer(source.getControllerId()).gainLife(loseLife, game);
return true;
}

View file

@ -0,0 +1,154 @@
/*
* 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.tempest;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author North
*/
public class EssenceBottle extends CardImpl<EssenceBottle> {
public EssenceBottle(UUID ownerId) {
super(ownerId, 276, "Essence Bottle", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}");
this.expansionSetCode = "TMP";
// {3}, {tap}: Put an elixir counter on Essence Bottle.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new AddCountersSourceEffect(CounterType.ELIXIR.createInstance()),
new GenericManaCost(3));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// {tap}, Remove all elixir counters from Essence Bottle: You gain 2 life for each elixir counter removed this way.
ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new EssenceBottleEffect(), new TapSourceCost());
ability.addCost(new EssenceBottleCost());
this.addAbility(ability);
}
public EssenceBottle(final EssenceBottle card) {
super(card);
}
@Override
public EssenceBottle copy() {
return new EssenceBottle(this);
}
}
class EssenceBottleCost extends CostImpl<EssenceBottleCost> {
private int removedCounters;
public EssenceBottleCost() {
super();
this.removedCounters = 0;
this.text = "Remove all elixir counters from {this}";
}
public EssenceBottleCost(EssenceBottleCost cost) {
super(cost);
this.removedCounters = cost.removedCounters;
}
@Override
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
return true;
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
Permanent permanent = game.getPermanent(ability.getSourceId());
if (permanent != null) {
this.removedCounters = permanent.getCounters().getCount(CounterType.ELIXIR);
if (this.removedCounters > 0) {
permanent.removeCounters(CounterType.ELIXIR.createInstance(this.removedCounters), game);
}
}
this.paid = true;
return true;
}
@Override
public EssenceBottleCost copy() {
return new EssenceBottleCost(this);
}
public int getRemovedCounters() {
return this.removedCounters;
}
}
class EssenceBottleEffect extends OneShotEffect<EssenceBottleEffect> {
public EssenceBottleEffect() {
super(Outcome.GainLife);
this.staticText = "You gain 2 life for each elixir counter removed this way";
}
public EssenceBottleEffect(final EssenceBottleEffect effect) {
super(effect);
}
@Override
public EssenceBottleEffect copy() {
return new EssenceBottleEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
int countersRemoved = 0;
for (Cost cost : source.getCosts()) {
if (cost instanceof EssenceBottleCost) {
countersRemoved = ((EssenceBottleCost) cost).getRemovedCounters();
}
}
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
player.gainLife(countersRemoved * 2, game);
return true;
}
return false;
}
}

View file

@ -0,0 +1,188 @@
/*
* 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.tempest;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.cards.CardImpl;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author North
*/
public class TortureChamber extends CardImpl<TortureChamber> {
public TortureChamber(UUID ownerId) {
super(ownerId, 303, "Torture Chamber", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}");
this.expansionSetCode = "TMP";
// At the beginning of your upkeep, put a pain counter on Torture Chamber.
this.addAbility(new OnEventTriggeredAbility(EventType.UPKEEP_STEP_PRE, "beginning of your upkeep", new AddCountersSourceEffect(CounterType.PAIN.createInstance())));
// At the beginning of your end step, Torture Chamber deals damage to you equal to the number of pain counters on it.
this.addAbility(new BeginningOfYourEndStepTriggeredAbility(new TortureChamberEffect1(), false));
// {1}, {tap}, Remove all pain counters from Torture Chamber: Torture Chamber deals damage to target creature equal to the number of pain counters removed this way.
SimpleActivatedAbility ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TortureChamberEffect2(), new GenericManaCost(1));
ability.addCost(new TapSourceCost());
ability.addCost(new TortureChamberCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public TortureChamber(final TortureChamber card) {
super(card);
}
@Override
public TortureChamber copy() {
return new TortureChamber(this);
}
}
class TortureChamberCost extends CostImpl<TortureChamberCost> {
private int removedCounters;
public TortureChamberCost() {
super();
this.removedCounters = 0;
this.text = "Remove all pain counters from {this}";
}
public TortureChamberCost(TortureChamberCost cost) {
super(cost);
this.removedCounters = cost.removedCounters;
}
@Override
public boolean canPay(UUID sourceId, UUID controllerId, Game game) {
return true;
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana) {
Permanent permanent = game.getPermanent(ability.getSourceId());
if (permanent != null) {
this.removedCounters = permanent.getCounters().getCount(CounterType.PAIN);
if (this.removedCounters > 0) {
permanent.removeCounters(CounterType.PAIN.createInstance(this.removedCounters), game);
}
}
this.paid = true;
return true;
}
@Override
public TortureChamberCost copy() {
return new TortureChamberCost(this);
}
public int getRemovedCounters() {
return this.removedCounters;
}
}
class TortureChamberEffect1 extends OneShotEffect<TortureChamberEffect1> {
public TortureChamberEffect1() {
super(Outcome.Damage);
this.staticText = "{this} deals damage to you equal to the number of pain counters on it";
}
public TortureChamberEffect1(final TortureChamberEffect1 effect) {
super(effect);
}
@Override
public TortureChamberEffect1 copy() {
return new TortureChamberEffect1(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
int painCounters = permanent.getCounters().getCount(CounterType.PAIN);
player.damage(painCounters, source.getSourceId(), game, false, true);
return true;
}
return false;
}
}
class TortureChamberEffect2 extends OneShotEffect<TortureChamberEffect2> {
public TortureChamberEffect2() {
super(Outcome.Damage);
this.staticText = "{this} deals damage to target creature equal to the number of pain counters removed this way";
}
public TortureChamberEffect2(final TortureChamberEffect2 effect) {
super(effect);
}
@Override
public TortureChamberEffect2 copy() {
return new TortureChamberEffect2(this);
}
@Override
public boolean apply(Game game, Ability source) {
int countersRemoved = 0;
for (Cost cost : source.getCosts()) {
if (cost instanceof TortureChamberCost) {
countersRemoved = ((TortureChamberCost) cost).getRemovedCounters();
}
}
Permanent permanent = game.getPermanent(source.getFirstTarget());
if (permanent != null) {
permanent.damage(countersRemoved, source.getSourceId(), game, true, false);
return true;
}
return false;
}
}

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.tenth;
import java.util.UUID;
/**
*
* @author Backfir3
*/
public class AngelicChorus extends mage.sets.urzassaga.AngelicChorus {
public AngelicChorus(UUID ownerId) {
super(ownerId);
this.cardNumber = 4;
this.expansionSetCode = "10E";
}
public AngelicChorus(final AngelicChorus card) {
super(card);
}
@Override
public AngelicChorus copy() {
return new AngelicChorus(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.tenth;
import java.util.UUID;
/**
*
* @author North
*/
public class GravePact extends mage.sets.ninthedition.GravePact {
public GravePact(UUID ownerId) {
super(ownerId);
this.cardNumber = 144;
this.expansionSetCode = "10E";
}
public GravePact(final GravePact card) {
super(card);
}
@Override
public GravePact copy() {
return new GravePact(this);
}
}

View file

@ -0,0 +1,76 @@
/*
* 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.Constants.CardType;
import mage.Constants.Duration;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continious.GainAbilityAllEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.filter.Filter.ComparisonScope;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreaturePermanent;
/**
*
* @author Backfir3
*/
public class AbsoluteGrace extends CardImpl<AbsoluteGrace> {
private static final FilterCard filter = new FilterCard("Black");
static {
filter.setUseColor(true);
filter.getColor().setBlack(true);
filter.setScopeColor(ComparisonScope.Any);
}
public AbsoluteGrace(UUID ownerId) {
super(ownerId, 1, "Absolute Grace", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
this.expansionSetCode = "USG";
this.color.setWhite(true);
Ability ability = new ProtectionAbility(filter);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false)));
}
public AbsoluteGrace(final AbsoluteGrace card) {
super(card);
}
@Override
public AbsoluteGrace copy() {
return new AbsoluteGrace(this);
}
}

View file

@ -0,0 +1,76 @@
/*
* 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.Constants.CardType;
import mage.Constants.Duration;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continious.GainAbilityAllEffect;
import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl;
import mage.filter.Filter.ComparisonScope;
import mage.filter.FilterCard;
import mage.filter.common.FilterCreaturePermanent;
/**
*
* @author Backfir3
*/
public class AbsoluteLaw extends CardImpl<AbsoluteLaw> {
private static final FilterCard filter = new FilterCard("Red");
static {
filter.setUseColor(true);
filter.getColor().setRed(true);
filter.setScopeColor(ComparisonScope.Any);
}
public AbsoluteLaw(UUID ownerId) {
super(ownerId, 2, "Absolute Law", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
this.expansionSetCode = "USG";
this.color.setWhite(true);
Ability ability = new ProtectionAbility(filter);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAllEffect(ability, Duration.WhileOnBattlefield, new FilterCreaturePermanent(), false)));
}
public AbsoluteLaw(final AbsoluteLaw card) {
super(card);
}
@Override
public AbsoluteLaw copy() {
return new AbsoluteLaw(this);
}
}

View file

@ -0,0 +1,142 @@
/*
* 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.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author Backfir3
*/
public class AngelicChorus extends CardImpl<AngelicChorus> {
public AngelicChorus(UUID ownerId) {
super(ownerId, 3, "Angelic Chorus", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{W}{W}");
this.expansionSetCode = "USG";
this.color.setWhite(true);
Ability ability = new AngelicChorusTriggeredAbility();
this.addAbility(ability);
}
public AngelicChorus(final AngelicChorus card) {
super(card);
}
@Override
public AngelicChorus copy() {
return new AngelicChorus(this);
}
}
class AngelicChorusTriggeredAbility extends TriggeredAbilityImpl<AngelicChorusTriggeredAbility> {
public AngelicChorusTriggeredAbility() {
super(Zone.BATTLEFIELD, new AngelicChorusEffect(), false);
}
public AngelicChorusTriggeredAbility(AngelicChorusTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == EventType.ZONE_CHANGE) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD
&& permanent.getCardType().contains(CardType.CREATURE)
&& permanent.getControllerId().equals(this.controllerId)) {
Effect effect = this.getEffects().get(0);
effect.setValue("lifeSource", event.getTargetId());
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever a creature enters the battlefield under your control, you gain life equal to its toughness.";
}
@Override
public AngelicChorusTriggeredAbility copy() {
return new AngelicChorusTriggeredAbility(this);
}
}
class AngelicChorusEffect extends OneShotEffect<AngelicChorusEffect> {
public AngelicChorusEffect() {
super(Outcome.GainLife);
staticText = "you gain life equal to its toughness";
}
public AngelicChorusEffect(final AngelicChorusEffect effect) {
super(effect);
}
@Override
public AngelicChorusEffect copy() {
return new AngelicChorusEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
UUID creatureId = (UUID) getValue("lifeSource");
Permanent creature = game.getPermanent(creatureId);
if (creature == null) {
creature = (Permanent) game.getLastKnownInformation(creatureId, Zone.BATTLEFIELD);
}
if (creature != null) {
int amount = creature.getToughness().getValue();
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
player.gainLife(amount, game);
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,85 @@
/*
* 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.Constants.CardType;
import mage.Constants.Duration;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.continious.BoostTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Backfir3
*/
public class AngelicPage extends CardImpl<AngelicPage> {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("attacking or blocking creature");
static {
filter.setAttacking(true);
filter.setUseAttacking(true);
filter.setBlocking(true);
filter.setUseBlocking(true);
}
public AngelicPage(UUID ownerId) {
super(ownerId, 4, "Angelic Page", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.expansionSetCode = "USG";
this.subtype.add("Angel");
this.subtype.add("Spirit");
this.color.setWhite(true);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
this.addAbility(FlyingAbility.getInstance());
//{T}: Target attacking or blocking creature gets +1/+1 until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostTargetEffect(1, 1, Duration.EndOfTurn), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
this.addAbility(ability);
}
public AngelicPage(final AngelicPage card) {
super(card);
}
@Override
public AngelicPage copy() {
return new AngelicPage(this);
}
}

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.sets.urzassaga;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.Mana;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.effects.common.BasicManaEffect;
import mage.cards.CardImpl;
/**
*
* @author Backfir3
*/
public class BloodVassal extends CardImpl<BloodVassal> {
public BloodVassal(UUID ownerId) {
super(ownerId, 118, "Blood Vassal", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.expansionSetCode = "USG";
this.subtype.add("Thrull");
this.color.setBlack(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BasicManaEffect(new Mana(0, 0, 0, 0, 2, 0, 0)), new SacrificeSourceCost()));
}
public BloodVassal(final BloodVassal card) {
super(card);
}
@Override
public BloodVassal copy() {
return new BloodVassal(this);
}
}

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.urzassaga;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.players.Player;
/**
*
* @author Backfir3
*/
public class CacklingFiend extends CardImpl<CacklingFiend> {
public CacklingFiend(UUID ownerId) {
super(ownerId, 121, "Cackling Fiend", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{2}{B}{B}");
this.expansionSetCode = "USG";
this.subtype.add("Zombie");
this.color.setBlack(true);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
this.addAbility(FlyingAbility.getInstance());
this.addAbility(new EntersBattlefieldTriggeredAbility(new CacklingFiendEffect(), false));
}
public CacklingFiend(final CacklingFiend card) {
super(card);
}
@Override
public CacklingFiend copy() {
return new CacklingFiend(this);
}
}
class CacklingFiendEffect extends OneShotEffect<CacklingFiendEffect> {
public CacklingFiendEffect() {
super(Outcome.Discard);
staticText = "each opponent discards a card";
}
public CacklingFiendEffect(final CacklingFiendEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
for (UUID playerId: game.getOpponents(source.getControllerId())) {
Player player = game.getPlayer(playerId);
player.discard(1, source, game);
}
return true;
}
@Override
public CacklingFiendEffect copy() {
return new CacklingFiendEffect(this);
}
}

View file

@ -0,0 +1,72 @@
/*
* 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.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.MageInt;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.RegenerateSourceEffect;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
/**
*
* @author Backfir3
*/
public class ChildOfGaea extends CardImpl<ChildOfGaea> {
public ChildOfGaea(UUID ownerId) {
super(ownerId, 242, "Child of Gaea", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{G}{G}{G}");
this.expansionSetCode = "USG";
this.subtype.add("Elemental");
this.color.setGreen(true);
this.power = new MageInt(7);
this.toughness = new MageInt(7);
this.addAbility(TrampleAbility.getInstance());
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{G}{G}")), Constants.TargetController.YOU, false));
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{G}")));
}
public ChildOfGaea(final ChildOfGaea card) {
super(card);
}
@Override
public ChildOfGaea copy() {
return new ChildOfGaea(this);
}
}

View file

@ -0,0 +1,72 @@
/*
* 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.Constants.CardType;
import mage.Constants.Rarity;
import mage.Mana;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.mana.DynamicManaAbility;
import mage.cards.CardImpl;
import mage.filter.Filter;
import mage.filter.common.FilterControlledPermanent;
/**
*
* @author Backfir3
*/
public class GaeasCradle extends CardImpl<GaeasCradle> {
private static final FilterControlledPermanent filter = new FilterControlledPermanent("creature you control");;
static {
filter.getCardType().add(CardType.CREATURE);
filter.setScopeSubtype(Filter.ComparisonScope.Any);
}
public GaeasCradle(UUID ownerId) {
super(ownerId, 321, "Gaea's Cradle", Rarity.RARE, new CardType[]{CardType.LAND}, "");
this.expansionSetCode = "USG";
this.supertype.add("Legendary");
DynamicManaAbility ability = new DynamicManaAbility(Mana.GreenMana, new PermanentsOnBattlefieldCount(filter));
this.addAbility(ability);
}
public GaeasCradle(final GaeasCradle card) {
super(card);
}
@Override
public GaeasCradle copy() {
return new GaeasCradle(this);
}
}

View file

@ -0,0 +1,134 @@
/*
* 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.Constants.CardType;
import mage.Constants.Duration;
import mage.Constants.Layer;
import mage.Constants.Outcome;
import mage.Constants.Rarity;
import mage.Constants.SubLayer;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ShroudAbility;
import mage.cards.CardImpl;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author Backfir3
*/
public class ZephidsEmbrace extends CardImpl<ZephidsEmbrace> {
public ZephidsEmbrace(UUID ownerId) {
super(ownerId, 114, "Zephid's Embrace", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}");
this.expansionSetCode = "USG";
this.color.setBlue(true);
this.subtype.add("Aura");
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ZephidsEmbraceEffect()));
}
public ZephidsEmbrace(final ZephidsEmbrace card) {
super(card);
}
@Override
public ZephidsEmbrace copy() {
return new ZephidsEmbrace(this);
}
}
class ZephidsEmbraceEffect extends ContinuousEffectImpl<ZephidsEmbraceEffect> {
public ZephidsEmbraceEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "Enchanted creature gets +2/+2 and has flying and shroud";
}
public ZephidsEmbraceEffect(final ZephidsEmbraceEffect effect) {
super(effect);
}
@Override
public ZephidsEmbraceEffect copy() {
return new ZephidsEmbraceEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent enchantment = game.getPermanent(source.getSourceId());
if (enchantment != null && enchantment.getAttachedTo() != null) {
Permanent creature = game.getPermanent(enchantment.getAttachedTo());
if (creature != null) {
switch (layer) {
case PTChangingEffects_7:
if (sublayer == SubLayer.ModifyPT_7c) {
creature.addPower(2);
creature.addToughness(2);
}
break;
case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) {
creature.addAbility(FlyingAbility.getInstance(), game);
creature.addAbility(ShroudAbility.getInstance(), game);
}
break;
}
return true;
}
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.PTChangingEffects_7;
}
}

View file

@ -0,0 +1,72 @@
package org.mage.test.cards;
import mage.Constants;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* also tests regenerate and
* tests that permanents with protection can be sacrificed
*
* @author BetaSteward
*/
public class TestClingingMists extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "White Knight");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Constants.Zone.HAND, playerA, "Clinging Mists");
castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Clinging Mists");
attack(1, playerA, "White Knight");
setStopAt(1, Constants.PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
}
@Test
public void testCardExile1() {
setLife(playerA, 5);
addCard(Constants.Zone.BATTLEFIELD, playerA, "Abbey Griffin");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Constants.Zone.HAND, playerA, "Clinging Mists");
attack(1, playerA, "Abbey Griffin");
castSpell(1, Constants.PhaseStep.DECLARE_BLOCKERS, playerA, "Clinging Mists");
setStopAt(3, Constants.PhaseStep.END_TURN);
execute();
assertLife(playerA, 5);
assertLife(playerB, 20);
assertTapped("Abbey Griffin", true);
}
@Test
public void testCardExile2() {
setLife(playerA, 5);
addCard(Constants.Zone.BATTLEFIELD, playerA, "Forest", 3);
addCard(Constants.Zone.HAND, playerA, "Clinging Mists");
addCard(Constants.Zone.BATTLEFIELD, playerB, "Mountain");
addCard(Constants.Zone.BATTLEFIELD, playerB, "Abbey Griffin");
addCard(Constants.Zone.HAND, playerB, "Lightning Bolt");
attack(2, playerB, "Abbey Griffin");
castSpell(2, Constants.PhaseStep.DECLARE_BLOCKERS, playerA, "Clinging Mists");
castSpell(2, Constants.PhaseStep.POSTCOMBAT_MAIN, playerB, "Lightning Bolt", playerA);
setStopAt(6, Constants.PhaseStep.DRAW);
execute();
assertLife(playerA, 2);
assertLife(playerB, 20);
assertTapped("Abbey Griffin", false);
assertGraveyardCount(playerB, "Lightning Bolt", 1);
}
}

View file

@ -0,0 +1,28 @@
package org.mage.test.cards;
import mage.Constants;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class TestFeedThePack extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Feed the Pack");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Craw Wurm");
setStopAt(2, Constants.PhaseStep.DRAW);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Wolf", 4);
assertPermanentCount(playerB, "Craw Wurm", 0);
}
}

View file

@ -0,0 +1,67 @@
package org.mage.test.cards;
import mage.Constants;
import mage.filter.Filter;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* also tests undying
*
* @author BetaSteward
*/
public class TestFlayerOfTheHatebound extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Flayer of the Hatebound");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 1);
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt", 1);
castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Flayer of the Hatebound");
setStopAt(2, Constants.PhaseStep.DRAW);
execute();
assertLife(playerA, 20);
assertLife(playerB, 15);
assertPermanentCount(playerA, "Flayer of the Hatebound", 1);
assertPowerToughness(playerA, "Flayer of the Hatebound", 5, 3, Filter.ComparisonScope.Any);
}
@Test
public void testCard1() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Flayer of the Hatebound");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Constants.Zone.GRAVEYARD, playerA, "Reassembling Skeleton", 1);
activateAbility(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "{1}{B}:");
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 19);
assertPermanentCount(playerA, "Flayer of the Hatebound", 1);
assertPermanentCount(playerA, "Reassembling Skeleton", 1);
assertPowerToughness(playerA, "Flayer of the Hatebound", 4, 2, Filter.ComparisonScope.Any);
}
@Test
public void testCard2() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Flayer of the Hatebound");
addCard(Constants.Zone.BATTLEFIELD, playerB, "Swamp", 2);
addCard(Constants.Zone.GRAVEYARD, playerB, "Reassembling Skeleton", 1);
activateAbility(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerB, "{1}{B}:");
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Flayer of the Hatebound", 1);
assertPermanentCount(playerB, "Reassembling Skeleton", 1);
assertPowerToughness(playerA, "Flayer of the Hatebound", 4, 2, Filter.ComparisonScope.Any);
}
}

View file

@ -0,0 +1,57 @@
package org.mage.test.cards;
import mage.Constants;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class TestHinterlandScourge extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Hinterland Hermit");
// addCard(Constants.Zone.BATTLEFIELD, playerB, "Ornithopter");
setStopAt(2, Constants.PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Hinterland Hermit", 0);
assertPermanentCount(playerA, "Hinterland Scourge", 1);
}
@Test
public void testCard1() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Hinterland Hermit");
addCard(Constants.Zone.BATTLEFIELD, playerB, "Ornithopter");
attack(3, playerA, "Hinterland Scourge");
setStopAt(3, Constants.PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Hinterland Hermit", 0);
assertPermanentCount(playerA, "Hinterland Scourge", 1);
assertPermanentCount(playerB, "Ornithopter", 0);
}
@Test
public void testCard2() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Hinterland Hermit");
attack(3, playerA, "Hinterland Scourge");
setStopAt(3, Constants.PhaseStep.END_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 17);
assertPermanentCount(playerA, "Hinterland Hermit", 0);
assertPermanentCount(playerA, "Hinterland Scourge", 1);
}
}

View file

@ -0,0 +1,41 @@
package org.mage.test.cards;
import mage.Constants;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class TestSeance extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Seance");
addCard(Constants.Zone.GRAVEYARD, playerA, "Craw Wurm");
setStopAt(1, Constants.PhaseStep.DRAW);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertExileCount("Craw Wurm", 1);
assertPermanentCount(playerA, "Craw Wurm", 1);
}
@Test
public void testCard1() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Seance");
addCard(Constants.Zone.GRAVEYARD, playerA, "Craw Wurm");
setStopAt(2, Constants.PhaseStep.DRAW);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertExileCount("Craw Wurm", 1);
assertPermanentCount(playerA, "Craw Wurm", 0);
}
}

View file

@ -0,0 +1,30 @@
package org.mage.test.cards;
import mage.Constants;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class TestUnhallowedCathar extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Loyal Cathar");
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", "Loyal Cathar");
setStopAt(2, Constants.PhaseStep.DRAW);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "Loyal Cathar", 0);
assertPermanentCount(playerA, "Unhallowed Cathar", 1);
}
}

View file

@ -0,0 +1,56 @@
package org.mage.test.cards.damage;
import mage.Constants;
import mage.counters.CounterType;
import org.junit.Ignore;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* also tests regenerate and
* tests that permanents with protection can be sacrificed
*
* @author BetaSteward
*/
public class TestSpitefulShadows extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Glistener Elf");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Constants.Zone.HAND, playerA, "Spiteful Shadows");
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Spiteful Shadows", "Glistener Elf");
castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Glistener Elf");
setStopAt(1, Constants.PhaseStep.END_TURN);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertCounterCount(playerA, CounterType.POISON, 3);
}
@Test
public void testCard1() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Craw Wurm");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Swamp", 2);
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 2);
addCard(Constants.Zone.HAND, playerA, "Spiteful Shadows");
addCard(Constants.Zone.HAND, playerA, "Lightning Bolt");
castSpell(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "Spiteful Shadows", "Craw Wurm");
castSpell(1, Constants.PhaseStep.POSTCOMBAT_MAIN, playerA, "Lightning Bolt", "Craw Wurm");
setStopAt(1, Constants.PhaseStep.END_TURN);
execute();
assertLife(playerA, 17);
assertLife(playerB, 20);
assertCounterCount(playerA, CounterType.POISON, 0);
}
}

View file

@ -391,6 +391,17 @@ public abstract class CardTestPlayerAPIImpl extends MageTestPlayerBase implement
Assert.assertEquals("(Battlefield) Counter counts are not equal (" + cardName + ":" + type + ")", count, found.getCounters().getCount(type));
}
/**
* Assert counter count on a player
*
* @param player The player whos counters should be counted.
* @param type Type of the counter that should be counted.
* @param count Expected count.
*/
public void assertCounterCount(Player player, CounterType type, int count) throws AssertionError {
Assert.assertEquals("(Battlefield) Counter counts are not equal (" + player.getName() + ":" + type + ")", count, player.getCounters().getCount(type));
}
/**
* Assert whether a permanent is a specified type or not

View file

@ -26,13 +26,13 @@ public class BoostContinuousEffectTest extends CardTestBase {
@Test
public void testHonorOfThePoor2() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Honor of the Pure");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Honor of the Pure", 2);
addCard(Constants.Zone.BATTLEFIELD, playerA, "White Knight");
addCard(Constants.Zone.BATTLEFIELD, playerA, "Black Knight");
setStopAt(1, PhaseStep.CLEANUP);
execute();
assertPowerToughness(playerA, "White Knight", 3, 3, Filter.ComparisonScope.Any);
assertPowerToughness(playerA, "White Knight", 4, 4, Filter.ComparisonScope.Any);
assertPowerToughness(playerA, "Black Knight", 2, 2, Filter.ComparisonScope.Any);
}

View file

@ -0,0 +1,53 @@
package org.mage.test.serverside.cards.effects;
import org.mage.test.cards.*;
import junit.framework.Assert;
import mage.Constants;
import mage.filter.Filter;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author BetaSteward
*/
public class TestActivatedContinuousEffect extends CardTestPlayerBase {
@Test
public void testCard() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 3);
addCard(Constants.Zone.BATTLEFIELD, playerA, "Captive Flame");
addCard(Constants.Zone.BATTLEFIELD, playerA, "White Knight");
activateAbility(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "{R}:", "White Knight");
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "White Knight", 1);
assertPowerToughness(playerA, "White Knight", 3, 2, Filter.ComparisonScope.Any);
}
@Test
public void testCard2() {
addCard(Constants.Zone.BATTLEFIELD, playerA, "Mountain", 3);
addCard(Constants.Zone.BATTLEFIELD, playerA, "Captive Flame");
addCard(Constants.Zone.BATTLEFIELD, playerA, "White Knight");
activateAbility(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "{R}:", "White Knight");
activateAbility(1, Constants.PhaseStep.PRECOMBAT_MAIN, playerA, "{R}:", "White Knight");
setStopAt(1, Constants.PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertPermanentCount(playerA, "White Knight", 1);
assertPowerToughness(playerA, "White Knight", 4, 2, Filter.ComparisonScope.Any);
}
}

View file

@ -29,24 +29,14 @@
package mage.abilities.effects;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.UUID;
import java.util.*;
import mage.Constants.AsThoughEffectType;
import mage.Constants.Duration;
import mage.Constants.EffectType;
import mage.Constants.Layer;
import mage.Constants.SubLayer;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.StaticAbility;
import mage.cards.Card;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@ -60,16 +50,13 @@ import mage.players.Player;
public class ContinuousEffects implements Serializable {
//transient Continuous effects
private final ArrayList<ContinuousEffect> layeredEffects = new ArrayList<ContinuousEffect>();
private final ArrayList<ReplacementEffect> replacementEffects = new ArrayList<ReplacementEffect>();
private final ArrayList<PreventionEffect> preventionEffects = new ArrayList<PreventionEffect>();
private final ArrayList<RequirementEffect> requirementEffects = new ArrayList<RequirementEffect>();
private final ArrayList<RestrictionEffect> restrictionEffects = new ArrayList<RestrictionEffect>();
private final ArrayList<AsThoughEffect> asThoughEffects = new ArrayList<AsThoughEffect>();
private final ArrayList<CostModificationEffect> costModificationEffects = new ArrayList<CostModificationEffect>();
//map Abilities to Continuous effects
private final Map<UUID, Ability> abilityMap = new HashMap<UUID, Ability>();
private ContinuousEffectsList<ContinuousEffect> layeredEffects = new ContinuousEffectsList<ContinuousEffect>();
private ContinuousEffectsList<ReplacementEffect> replacementEffects = new ContinuousEffectsList<ReplacementEffect>();
private ContinuousEffectsList<PreventionEffect> preventionEffects = new ContinuousEffectsList<PreventionEffect>();
private ContinuousEffectsList<RequirementEffect> requirementEffects = new ContinuousEffectsList<RequirementEffect>();
private ContinuousEffectsList<RestrictionEffect> restrictionEffects = new ContinuousEffectsList<RestrictionEffect>();
private ContinuousEffectsList<AsThoughEffect> asThoughEffects = new ContinuousEffectsList<AsThoughEffect>();
private ContinuousEffectsList<CostModificationEffect> costModificationEffects = new ContinuousEffectsList<CostModificationEffect>();
private final ApplyCountersEffect applyCounters;
private final PlaneswalkerRedirectionEffect planeswalkerRedirectionEffect;
@ -82,37 +69,13 @@ public class ContinuousEffects implements Serializable {
public ContinuousEffects(final ContinuousEffects effect) {
this.applyCounters = effect.applyCounters.copy();
this.planeswalkerRedirectionEffect = effect.planeswalkerRedirectionEffect.copy();
layeredEffects.ensureCapacity(effect.layeredEffects.size());
for (ContinuousEffect entry: effect.layeredEffects) {
layeredEffects.add((ContinuousEffect) entry.copy());
}
replacementEffects.ensureCapacity(effect.replacementEffects.size());
for (ReplacementEffect entry: effect.replacementEffects) {
replacementEffects.add((ReplacementEffect)entry.copy());
}
preventionEffects.ensureCapacity(effect.preventionEffects.size());
for (PreventionEffect entry: effect.preventionEffects) {
preventionEffects.add((PreventionEffect)entry.copy());
}
requirementEffects.ensureCapacity(effect.requirementEffects.size());
for (RequirementEffect entry: effect.requirementEffects) {
requirementEffects.add((RequirementEffect)entry.copy());
}
restrictionEffects.ensureCapacity(effect.restrictionEffects.size());
for (RestrictionEffect entry: effect.restrictionEffects) {
restrictionEffects.add((RestrictionEffect)entry.copy());
}
asThoughEffects.ensureCapacity(effect.asThoughEffects.size());
for (AsThoughEffect entry: effect.asThoughEffects) {
asThoughEffects.add((AsThoughEffect)entry.copy());
}
costModificationEffects.ensureCapacity(effect.costModificationEffects.size());
for ( CostModificationEffect entry : effect.costModificationEffects ) {
costModificationEffects.add(entry);
}
for (Entry<UUID, Ability> entry: effect.abilityMap.entrySet()) {
abilityMap.put(entry.getKey(), entry.getValue().copy());
}
layeredEffects = effect.layeredEffects.copy();
replacementEffects = effect.replacementEffects.copy();
preventionEffects = effect.preventionEffects.copy();
requirementEffects = effect.requirementEffects.copy();
restrictionEffects = effect.restrictionEffects.copy();
asThoughEffects = effect.asThoughEffects.copy();
costModificationEffects = effect.costModificationEffects.copy();
}
public ContinuousEffects copy() {
@ -128,92 +91,41 @@ public class ContinuousEffects implements Serializable {
}
public Ability getAbility(UUID effectId) {
return abilityMap.get(effectId);
Ability ability = layeredEffects.getAbility(effectId);
if (ability == null)
ability = replacementEffects.getAbility(effectId);
if (ability == null)
ability = preventionEffects.getAbility(effectId);
if (ability == null)
ability = requirementEffects.getAbility(effectId);
if (ability == null)
ability = restrictionEffects.getAbility(effectId);
if (ability == null)
ability = asThoughEffects.getAbility(effectId);
if (ability == null)
ability = costModificationEffects.getAbility(effectId);
return ability;
}
public void removeEndOfTurnEffects() {
for (Iterator<ContinuousEffect> i = layeredEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<ReplacementEffect> i = replacementEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<PreventionEffect> i = preventionEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<RequirementEffect> i = requirementEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<RestrictionEffect> i = restrictionEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<AsThoughEffect> i = asThoughEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
for (Iterator<CostModificationEffect> i = costModificationEffects.iterator(); i.hasNext();) {
ContinuousEffect entry = i.next();
if (entry.getDuration() == Duration.EndOfTurn)
i.remove();
}
layeredEffects.removeEndOfTurnEffects();
replacementEffects.removeEndOfTurnEffects();
preventionEffects.removeEndOfTurnEffects();
requirementEffects.removeEndOfTurnEffects();
restrictionEffects.removeEndOfTurnEffects();
asThoughEffects.removeEndOfTurnEffects();
costModificationEffects.removeEndOfTurnEffects();
}
public void removeInactiveEffects(Game game) {
for (Iterator<ContinuousEffect> i = layeredEffects.iterator(); i.hasNext();) {
if (isInactive(i.next(), game))
i.remove();
}
for (Iterator<ReplacementEffect> i = replacementEffects.iterator(); i.hasNext();) {
if (isInactive(i.next(), game))
i.remove();
}
for (Iterator<PreventionEffect> i = preventionEffects.iterator(); i.hasNext();) {
if (isInactive(i.next(), game))
i.remove();
}
for (Iterator<RequirementEffect> i = requirementEffects.iterator(); i.hasNext();) {
if (isInactive(i.next(), game))
i.remove();
}
for (Iterator<RestrictionEffect> i = restrictionEffects.iterator(); i.hasNext();) {
if (isInactive(i.next(), game))
i.remove();
}
for (Iterator<AsThoughEffect> i = asThoughEffects.iterator(); i.hasNext();) {
if (isInactive(i.next(), game))
i.remove();
}
for (Iterator<CostModificationEffect> i = costModificationEffects.iterator(); i.hasNext();) {
if (isInactive(i.next(), game))
i.remove();
}
}
layeredEffects.removeInactiveEffects(game);
replacementEffects.removeInactiveEffects(game);
preventionEffects.removeInactiveEffects(game);
requirementEffects.removeInactiveEffects(game);
restrictionEffects.removeInactiveEffects(game);
asThoughEffects.removeInactiveEffects(game);
costModificationEffects.removeInactiveEffects(game);
private boolean isInactive(ContinuousEffect effect, Game game) {
Ability ability = abilityMap.get(effect.getId());
if (ability == null)
return true;
switch(effect.getDuration()) {
case WhileOnBattlefield:
if (game.getObject(ability.getSourceId()) == null)
return (true);
case OneUse:
return effect.isUsed();
case Custom:
return effect.isInactive(abilityMap.get(effect.getId()), game);
}
return false;
}
private List<ContinuousEffect> getLayeredEffects(Game game) {
@ -223,7 +135,7 @@ public class ContinuousEffects implements Serializable {
case WhileOnBattlefield:
case WhileOnStack:
case WhileInGraveyard:
Ability ability = abilityMap.get(effect.getId());
Ability ability = layeredEffects.getAbility(effect.getId());
if (ability.isInUseableZone(game))
layerEffects.add(effect);
break;
@ -247,7 +159,7 @@ public class ContinuousEffects implements Serializable {
public List<RequirementEffect> getApplicableRequirementEffects(Permanent permanent, Game game) {
List<RequirementEffect> effects = new ArrayList<RequirementEffect>();
for (RequirementEffect effect: requirementEffects) {
Ability ability = abilityMap.get(effect.getId());
Ability ability = requirementEffects.getAbility(effect.getId());
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game)) {
if (effect.applies(permanent, ability, game))
effects.add(effect);
@ -259,7 +171,7 @@ public class ContinuousEffects implements Serializable {
public List<RestrictionEffect> getApplicableRestrictionEffects(Permanent permanent, Game game) {
List<RestrictionEffect> effects = new ArrayList<RestrictionEffect>();
for (RestrictionEffect effect: restrictionEffects) {
Ability ability = abilityMap.get(effect.getId());
Ability ability = restrictionEffects.getAbility(effect.getId());
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game)) {
if (effect.applies(permanent, ability, game))
effects.add(effect);
@ -280,7 +192,7 @@ public class ContinuousEffects implements Serializable {
replaceEffects.add(planeswalkerRedirectionEffect);
//get all applicable transient Replacement effects
for (ReplacementEffect effect: replacementEffects) {
Ability ability = abilityMap.get(effect.getId());
Ability ability = replacementEffects.getAbility(effect.getId());
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game)) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(event, ability, game)) {
@ -290,7 +202,7 @@ public class ContinuousEffects implements Serializable {
}
}
for (PreventionEffect effect: preventionEffects) {
Ability ability = abilityMap.get(effect.getId());
Ability ability = preventionEffects.getAbility(effect.getId());
if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game)) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(event, ability, game)) {
@ -307,7 +219,7 @@ public class ContinuousEffects implements Serializable {
AsThoughEffect effect = entry;
if (effect.getAsThoughEffectType() == type) {
if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) {
if (effect.applies(objectId, abilityMap.get(entry.getId()), game)) {
if (effect.applies(objectId, asThoughEffects.getAbility(entry.getId()), game)) {
return true;
}
}
@ -317,7 +229,7 @@ public class ContinuousEffects implements Serializable {
}
/**
* Inspects all {@link Permanent permanent's} {@link Ability abilities} on the battlefied
* Inspects all {@link Permanent permanent's} {@link Ability abilities} on the battlefield
* for {@link CostModificationEffect cost modification effects} and applies them if necessary.
*
* @param abilityToModify
@ -326,8 +238,8 @@ public class ContinuousEffects implements Serializable {
*/
public void costModification ( Ability abilityToModify, Game game ) {
for ( CostModificationEffect effect : costModificationEffects ) {
if ( effect.applies(abilityToModify, abilityMap.get(effect.getId()), game) ) {
effect.apply(game, abilityMap.get(effect.getId()), abilityToModify);
if ( effect.applies(abilityToModify, costModificationEffects.getAbility(effect.getId()), game) ) {
effect.apply(game, costModificationEffects.getAbility(effect.getId()), abilityToModify);
}
}
}
@ -354,7 +266,7 @@ public class ContinuousEffects implements Serializable {
index = player.chooseEffect(rEffects, game);
}
ReplacementEffect rEffect = rEffects.get(index);
caught = rEffect.replaceEvent(event, abilityMap.get(rEffect.getId()), game);
caught = rEffect.replaceEvent(event, this.getAbility(rEffect.getId()), game);
if (caught)
break;
consumed.add(rEffect.getId());
@ -368,47 +280,47 @@ public class ContinuousEffects implements Serializable {
List<ContinuousEffect> layerEffects = getLayeredEffects(game);
List<ContinuousEffect> layer = filterLayeredEffects(layerEffects, Layer.CopyEffects_1);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.CopyEffects_1, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.CopyEffects_1, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
layer = filterLayeredEffects(layerEffects, Layer.ControlChangingEffects_2);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.ControlChangingEffects_2, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
layer = filterLayeredEffects(layerEffects, Layer.TextChangingEffects_3);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.TextChangingEffects_3, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
layer = filterLayeredEffects(layerEffects, Layer.TypeChangingEffects_4);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.TypeChangingEffects_4, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
layer = filterLayeredEffects(layerEffects, Layer.ColorChangingEffects_5);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.ColorChangingEffects_5, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
layer = filterLayeredEffects(layerEffects, Layer.AbilityAddingRemovingEffects_6);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
layerEffects = getLayeredEffects(game);
layer = filterLayeredEffects(layerEffects, Layer.PTChangingEffects_7);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, abilityMap.get(effect.getId()), game);
effect.apply(Layer.PTChangingEffects_7, SubLayer.SetPT_7b, layeredEffects.getAbility(effect.getId()), game);
}
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, abilityMap.get(effect.getId()), game);
effect.apply(Layer.PTChangingEffects_7, SubLayer.ModifyPT_7c, layeredEffects.getAbility(effect.getId()), game);
}
applyCounters.apply(Layer.PTChangingEffects_7, SubLayer.Counters_7d, null, game);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, abilityMap.get(effect.getId()), game);
effect.apply(Layer.PTChangingEffects_7, SubLayer.SwitchPT_e, layeredEffects.getAbility(effect.getId()), game);
}
layer = filterLayeredEffects(layerEffects, Layer.PlayerEffects);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.PlayerEffects, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.PlayerEffects, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
layer = filterLayeredEffects(layerEffects, Layer.RulesEffects);
for (ContinuousEffect effect: layer) {
effect.apply(Layer.RulesEffects, SubLayer.NA, abilityMap.get(effect.getId()), game);
effect.apply(Layer.RulesEffects, SubLayer.NA, layeredEffects.getAbility(effect.getId()), game);
}
}
@ -416,38 +328,31 @@ public class ContinuousEffects implements Serializable {
switch (effect.getEffectType()) {
case REPLACEMENT:
ReplacementEffect newReplacementEffect = (ReplacementEffect)effect;
replacementEffects.add(newReplacementEffect);
abilityMap.put(newReplacementEffect.getId(), source);
replacementEffects.addEffect(newReplacementEffect, source);
break;
case PREVENTION:
PreventionEffect newPreventionEffect = (PreventionEffect)effect;
preventionEffects.add(newPreventionEffect);
abilityMap.put(newPreventionEffect.getId(), source);
preventionEffects.addEffect(newPreventionEffect, source);
break;
case RESTRICTION:
RestrictionEffect newRestrictionEffect = (RestrictionEffect)effect;
restrictionEffects.add(newRestrictionEffect);
abilityMap.put(newRestrictionEffect.getId(), source);
restrictionEffects.addEffect(newRestrictionEffect, source);
break;
case REQUIREMENT:
RequirementEffect newRequirementEffect = (RequirementEffect)effect;
requirementEffects.add(newRequirementEffect);
abilityMap.put(newRequirementEffect.getId(), source);
requirementEffects.addEffect(newRequirementEffect, source);
break;
case ASTHOUGH:
AsThoughEffect newAsThoughEffect = (AsThoughEffect)effect;
asThoughEffects.add(newAsThoughEffect);
abilityMap.put(newAsThoughEffect.getId(), source);
asThoughEffects.addEffect(newAsThoughEffect, source);
break;
case COSTMODIFICATION:
CostModificationEffect newCostModificationEffect = (CostModificationEffect)effect;
costModificationEffects.add(newCostModificationEffect);
abilityMap.put(newCostModificationEffect.getId(), source);
costModificationEffects.addEffect(newCostModificationEffect, source);
break;
default:
ContinuousEffect newEffect = (ContinuousEffect)effect;
layeredEffects.add(newEffect);
abilityMap.put(newEffect.getId(), source);
layeredEffects.addEffect(newEffect, source);
break;
}
}
@ -460,7 +365,6 @@ public class ContinuousEffects implements Serializable {
restrictionEffects.clear();
asThoughEffects.clear();
costModificationEffects.clear();
abilityMap.clear();
}
}

View file

@ -0,0 +1,111 @@
/*
* Copyright 2012 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 java.util.*;
import mage.Constants;
import mage.abilities.Ability;
import mage.game.Game;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class ContinuousEffectsList<T extends ContinuousEffect> extends ArrayList<T> {
private final Map<UUID, Ability> abilityMap = new HashMap<UUID, Ability>();
public ContinuousEffectsList() { }
public ContinuousEffectsList(final ContinuousEffectsList<T> effects) {
this.ensureCapacity(effects.size());
for (ContinuousEffect cost: effects) {
this.add((T)cost.copy());
}
for (Map.Entry<UUID, Ability> entry: effects.abilityMap.entrySet()) {
abilityMap.put(entry.getKey(), entry.getValue().copy());
}
}
public ContinuousEffectsList copy() {
return new ContinuousEffectsList(this);
}
public void removeEndOfTurnEffects() {
for (Iterator<T> i = this.iterator(); i.hasNext();) {
T entry = i.next();
if (entry.getDuration() == Constants.Duration.EndOfTurn) {
i.remove();
abilityMap.remove(entry.getId());
}
}
}
public void removeInactiveEffects(Game game) {
for (Iterator<T> i = this.iterator(); i.hasNext();) {
T entry = i.next();
if (isInactive(entry, game)) {
i.remove();
abilityMap.remove(entry.getId());
}
}
}
private boolean isInactive(T effect, Game game) {
Ability ability = abilityMap.get(effect.getId());
if (ability == null)
return true;
switch(effect.getDuration()) {
case WhileOnBattlefield:
if (game.getObject(ability.getSourceId()) == null)
return (true);
case OneUse:
return effect.isUsed();
case Custom:
return effect.isInactive(abilityMap.get(effect.getId()), game);
}
return false;
}
public void addEffect(T effect, Ability source) {
if (abilityMap.containsKey(effect.getId()))
return;
this.add(effect);
this.abilityMap.put(effect.getId(), source);
}
public Ability getAbility(UUID effectId) {
return abilityMap.get(effectId);
}
@Override
public void clear() {
super.clear();
abilityMap.clear();
}
}

View file

@ -65,7 +65,7 @@ public class GetEmblemEffect extends OneShotEffect<GetEmblemEffect> {
newEmblem.setControllerId(source.getControllerId());
game.getState().getCommand().add(newEmblem);
for (Ability ability: newEmblem.getAbilities()) {
game.getState().addAbility(ability);
ability.resolve(game);
}
return true;
}

View file

@ -60,7 +60,10 @@ public enum CounterType {
KI(new KiCounter().name),
SLIME(new SlimeCounter().name),
SPORE(new SporeCounter().name),
STUDY(new StudyCounter().name);
STUDY(new StudyCounter().name),
EYEBALL(new EyeballCounter().name),
ELIXIR(new ElixirCounter().name),
PAIN(new PainCounter().name);
private String name;
@ -144,6 +147,12 @@ public enum CounterType {
return new SporeCounter(amount);
case STUDY:
return new StudyCounter(amount);
case EYEBALL:
return new EyeballCounter(amount);
case ELIXIR:
return new ElixirCounter(amount);
case PAIN:
return new PainCounter(amount);
}
return null;
}

View file

@ -0,0 +1,47 @@
/*
* 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.counters.common;
import mage.counters.Counter;
/**
*
* @author North
*/
public class ElixirCounter extends Counter<ElixirCounter> {
public ElixirCounter() {
super("Elixir");
this.count = 1;
}
public ElixirCounter(int amount) {
super("Elixir");
this.count = amount;
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.counters.common;
import mage.counters.Counter;
/**
*
* @author North
*/
public class EyeballCounter extends Counter<EyeballCounter> {
public EyeballCounter() {
super("Eyeball");
this.count = 1;
}
public EyeballCounter(int amount) {
super("Eyeball");
this.count = amount;
}
}

View file

@ -0,0 +1,47 @@
/*
* 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.counters.common;
import mage.counters.Counter;
/**
*
* @author North
*/
public class PainCounter extends Counter<PainCounter> {
public PainCounter() {
super("Pain");
this.count = 1;
}
public PainCounter(int amount) {
super("Pain");
this.count = amount;
}
}

View file

@ -0,0 +1,71 @@
/*
* Copyright 2012 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.filter.common;
import mage.filter.FilterPermanent;
import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public class FilterNonTokenPermanent extends FilterPermanent<FilterNonTokenPermanent> {
public FilterNonTokenPermanent() {
this("nontoken permanent");
}
public FilterNonTokenPermanent(String name) {
super(name);
}
public FilterNonTokenPermanent(final FilterNonTokenPermanent filter) {
super(filter);
}
@Override
public boolean match(Permanent permanent) {
if (!super.match(permanent)) {
return notFilter;
}
if (permanent instanceof PermanentToken) {
return notFilter;
}
return !notFilter;
}
@Override
public FilterNonTokenPermanent copy() {
return new FilterNonTokenPermanent(this);
}
}

View file

@ -864,6 +864,12 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
int actualDamage = event.getAmount();
if (actualDamage > 0) {
Permanent source = game.getPermanent(sourceId);
if(source == null){
MageObject lastKnownInformation = game.getLastKnownInformation(sourceId, Zone.BATTLEFIELD);
if(lastKnownInformation instanceof Permanent){
source = (Permanent) lastKnownInformation;
}
}
if (source != null && (source.getAbilities().containsKey(InfectAbility.getInstance().getId()))) {
addCounters(CounterType.POISON.createInstance(actualDamage), game);
} else {
@ -1389,6 +1395,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
// do nothing
}
@Override
public void setAllowBadMoves(boolean allowBadMoves) {
// do nothing
}