Merge pull request #2 from magefree/master

update from master
This commit is contained in:
Li REN 2013-06-13 17:31:40 -07:00
commit c8f31960de
14 changed files with 938 additions and 22 deletions

View file

@ -0,0 +1,75 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.commander;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CounterUnlessPaysEffect;
import mage.abilities.keyword.StormAbility;
import mage.cards.CardImpl;
import mage.filter.FilterSpell;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.target.TargetSpell;
/**
*
* @author Plopman
*/
public class Flusterstorm extends CardImpl<Flusterstorm> {
private static final FilterSpell filter = new FilterSpell("instant or sorcery spell");
static {
filter.add(Predicates.or(new CardTypePredicate(Constants.CardType.INSTANT), new CardTypePredicate(Constants.CardType.SORCERY)));
}
public Flusterstorm(UUID ownerId) {
super(ownerId, 46, "Flusterstorm", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{U}");
this.expansionSetCode = "CMD";
this.color.setBlue(true);
// Counter target instant or sorcery spell unless its controller pays {1}.
this.getSpellAbility().addEffect(new CounterUnlessPaysEffect(new ManaCostsImpl("{1}")));
this.getSpellAbility().addTarget(new TargetSpell(filter));
// Storm
this.addAbility(new StormAbility());
}
public Flusterstorm(final Flusterstorm card) {
super(card);
}
@Override
public Flusterstorm copy() {
return new Flusterstorm(this);
}
}

View file

@ -94,11 +94,11 @@ class CantBeBlockedExceptByCreaturesWithFlyingOrReachEffect extends RestrictionE
@Override
public boolean canBeBlocked(Permanent attacker, Permanent blocker, Ability source, Game game) {
if (!blocker.getAbilities().containsKey(FlyingAbility.getInstance().getId())
|| !blocker.getAbilities().containsKey(ReachAbility.getInstance().getId())) {
return false;
if (blocker.getAbilities().containsKey(FlyingAbility.getInstance().getId())
|| blocker.getAbilities().containsKey(ReachAbility.getInstance().getId())) {
return true;
}
return true;
return false;
}
@Override

View file

@ -93,7 +93,7 @@ class MistbindCliqueAbility extends ZoneChangeTriggeredAbility<MistbindCliqueAbi
public MistbindCliqueAbility() {
super(Zone.BATTLEFIELD, Zone.EXILED, new MistbindCliqueTapEffect(), "When a Faerie is championed with {this}, ", false);
this.addTarget(new TargetPlayer());
this.addTarget(new TargetPlayer(true));
}
public MistbindCliqueAbility(MistbindCliqueAbility ability) {

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.modernmasters;
import java.util.UUID;
/**
*
* @author Plopman
*/
public class FaerieMacabre extends mage.sets.shadowmoor.FaerieMacabre {
public FaerieMacabre(UUID ownerId) {
super(ownerId);
this.cardNumber = 86;
this.expansionSetCode = "MMA";
}
public FaerieMacabre(final FaerieMacabre card) {
super(card);
}
@Override
public FaerieMacabre copy() {
return new FaerieMacabre(this);
}
}

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.morningtide;
import java.awt.List;
import java.util.ArrayList;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.AttacksCreatureYourControlTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.AttackingPredicate;
import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author Plopman
*/
public class SharedAnimosity extends CardImpl<SharedAnimosity> {
public SharedAnimosity(UUID ownerId) {
super(ownerId, 104, "Shared Animosity", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
this.expansionSetCode = "MOR";
this.color.setRed(true);
// Whenever a creature you control attacks, it gets +1/+0 until end of turn for each other attacking creature that shares a creature type with it.
this.addAbility(new AttacksCreatureYourControlTriggeredAbility(new SharedAnimosityEffect(), false, true));
}
public SharedAnimosity(final SharedAnimosity card) {
super(card);
}
@Override
public SharedAnimosity copy() {
return new SharedAnimosity(this);
}
}
class SharedAnimosityEffect extends ContinuousEffectImpl<SharedAnimosityEffect> {
private int power;
public SharedAnimosityEffect() {
super(Constants.Duration.EndOfTurn, Constants.Layer.PTChangingEffects_7, Constants.SubLayer.ModifyPT_7c, Constants.Outcome.BoostCreature);
}
public SharedAnimosityEffect(final SharedAnimosityEffect effect) {
super(effect);
this.power = effect.power;
}
@Override
public SharedAnimosityEffect copy() {
return new SharedAnimosityEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
Permanent permanent = game.getPermanent(this.targetPointer.getFirst(game, source));
if (permanent != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(Predicates.not(new PermanentIdPredicate(this.targetPointer.getFirst(game, source))));
filter.add(new AttackingPredicate());
boolean isChangeling = false;
for(Ability ability : permanent.getAbilities()){
if(ability instanceof ChangelingAbility){
isChangeling = true;
}
}
if(!isChangeling){
ArrayList<Predicate<MageObject>> predicateList = new ArrayList<Predicate<MageObject>>();
for(String subtype : permanent.getSubtype()){
predicateList.add(new SubtypePredicate(subtype));
}
filter.add(Predicates.or(predicateList));
}
power = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getId(), game).size();
}
targetPointer.init(game, source);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent target = (Permanent) game.getPermanent(this.targetPointer.getFirst(game, source));
if (target != null) {
target.addPower(power);
return true;
}
return false;
}
@Override
public String getText(Mode mode) {
return "it gets +1/+0 until end of turn for each other attacking creature that shares a creature type with it";
}
}

View file

@ -31,6 +31,10 @@ package mage.sets.returntoravnica;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.Constants.Zone;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.CantCounterSourceEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.cards.CardImpl;
@ -58,7 +62,11 @@ public class AbruptDecay extends CardImpl<AbruptDecay> {
this.color.setBlack(true);
// Abrupt Decay can't be countered by spells or abilities.
this.getSpellAbility().addEffect(new CantCounterSourceEffect());
Effect effect = new CantCounterSourceEffect();
effect.setText("{this} can't be countered by spells or abilities");
Ability ability = new SimpleStaticAbility(Zone.STACK,effect);
ability.setRuleAtTheTop(true);
this.addAbility(ability);
// Destroy target nonland permanent with converted mana cost 3 or less.
this.getSpellAbility().addEffect(new DestroyTargetEffect());

View file

@ -0,0 +1,111 @@
/*
* 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.shadowmoor;
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.Mode;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardSourceCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.target.common.TargetCardInGraveyard;
/**
*
* @author Plopman
*/
public class FaerieMacabre extends CardImpl<FaerieMacabre> {
public FaerieMacabre(UUID ownerId) {
super(ownerId, 66, "Faerie Macabre", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.expansionSetCode = "SHM";
this.subtype.add("Faerie");
this.subtype.add("Rogue");
this.color.setBlack(true);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Discard Faerie Macabre: Exile up to two target cards from graveyards.
Ability ability = new SimpleActivatedAbility(Constants.Zone.HAND, new ExileTargetEffect(), new DiscardSourceCost());
ability.addTarget(new TargetCardInGraveyard(0, 2, new FilterCard("cards from graveyards")));
this.addAbility(ability);
}
public FaerieMacabre(final FaerieMacabre card) {
super(card);
}
@Override
public FaerieMacabre copy() {
return new FaerieMacabre(this);
}
}
class ExileTargetEffect extends OneShotEffect<ExileTargetEffect> {
public ExileTargetEffect() {
super(Constants.Outcome.Exile);
}
public ExileTargetEffect(final ExileTargetEffect effect) {
super(effect);
}
@Override
public ExileTargetEffect copy() {
return new ExileTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
for(UUID uuid : source.getTargets().get(0).getTargets()){
Card card = game.getCard(uuid);
if (card != null) {
card.moveToExile(null, "Faerie Macabre", source.getSourceId(), game);
}
}
return true;
}
@Override
public String getText(Mode mode) {
return "Exile up to two target cards from graveyards";
}
}

View file

@ -0,0 +1,131 @@
/*
* 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.shardsofalara;
import java.util.UUID;
import mage.Constants;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.other.OwnerIdPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
/**
*
* @author Plopman
*/
public class LichsMirror extends CardImpl<LichsMirror> {
public LichsMirror(UUID ownerId) {
super(ownerId, 210, "Lich's Mirror", Rarity.MYTHIC, new CardType[]{CardType.ARTIFACT}, "{5}");
this.expansionSetCode = "ALA";
// If you would lose the game, instead shuffle your hand, your graveyard, and all permanents you own into your library, then draw seven cards and your life total becomes 20.
this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new LichsMirrorEffect()));
}
public LichsMirror(final LichsMirror card) {
super(card);
}
@Override
public LichsMirror copy() {
return new LichsMirror(this);
}
}
class LichsMirrorEffect extends ReplacementEffectImpl<LichsMirrorEffect> {
public LichsMirrorEffect() {
super(Constants.Duration.WhileOnBattlefield, Constants.Outcome.Benefit);
staticText = "If you would lose the game, instead shuffle your hand, your graveyard, and all permanents you own into your library, then draw seven cards and your life total becomes 20";
}
public LichsMirrorEffect(final LichsMirrorEffect effect) {
super(effect);
}
@Override
public LichsMirrorEffect copy() {
return new LichsMirrorEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(event.getPlayerId());
if (player != null) {
FilterControlledPermanent filter = new FilterControlledPermanent();
filter.add(new OwnerIdPredicate(player.getId()));
for (UUID uuid : player.getHand().copy()) {
Card card = game.getCard(uuid);
if (card != null) {
card.moveToZone(Constants.Zone.LIBRARY, source.getId(), game, true);
}
}
for (UUID uuid : player.getGraveyard().copy()) {
Card card = game.getCard(uuid);
if (card != null) {
card.moveToZone(Constants.Zone.LIBRARY, source.getId(), game, true);
}
}
for(Permanent permanent : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)){
permanent.moveToZone(Constants.Zone.LIBRARY, source.getId(), game, true);
}
player.shuffleLibrary(game);
player.drawCards(7, game);
player.setLife(20, game);
}
return true;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.LOSES && event.getPlayerId().equals(source.getControllerId())) {
return true;
}
return false;
}
}

View file

@ -0,0 +1,166 @@
/*
* 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.shardsofalara;
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.ActivatedAbilityImpl;
import mage.abilities.SpellAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.ReachAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.combat.CombatGroup;
import mage.players.Player;
/**
*
* @author Plopman
*/
public class QasaliAmbusher extends CardImpl<QasaliAmbusher> {
public QasaliAmbusher(UUID ownerId) {
super(ownerId, 184, "Qasali Ambusher", Rarity.UNCOMMON, new CardType[]{CardType.CREATURE}, "{1}{G}{W}");
this.expansionSetCode = "ALA";
this.subtype.add("Cat");
this.subtype.add("Warrior");
this.color.setGreen(true);
this.color.setWhite(true);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Reach
this.addAbility(ReachAbility.getInstance());
// If a creature is attacking you and you control a Forest and a Plains, you may casbt Qasali Ambusher without paying its mana cost and as though it had flash.
this.addAbility(new QasaliAmbusherAbility());
}
public QasaliAmbusher(final QasaliAmbusher card) {
super(card);
}
@Override
public QasaliAmbusher copy() {
return new QasaliAmbusher(this);
}
}
class QasaliAmbusherAbility extends ActivatedAbilityImpl<QasaliAmbusherAbility> {
private static final FilterControlledLandPermanent filterPlains = new FilterControlledLandPermanent();
private static final FilterControlledLandPermanent filterForest = new FilterControlledLandPermanent();
static {
filterPlains.add(new SubtypePredicate("Plains"));
filterForest.add(new SubtypePredicate("Forest"));
}
public QasaliAmbusherAbility() {
super(Constants.Zone.HAND, new QasaliAmbusherEffect(), new ManaCostsImpl());
this.timing = Constants.TimingRule.INSTANT;
this.usesStack = false;
}
public QasaliAmbusherAbility(final QasaliAmbusherAbility ability) {
super(ability);
}
@Override
public QasaliAmbusherAbility copy() {
return new QasaliAmbusherAbility(this);
}
@Override
public boolean canActivate(UUID playerId, Game game) {
if(super.canActivate(playerId, game)){
if(game.getBattlefield().getActivePermanents(filterPlains, this.getControllerId(), this.getSourceId(), game).size() > 0
&& game.getBattlefield().getActivePermanents(filterForest, this.getControllerId(), this.getSourceId(), game).size() > 0){
for(CombatGroup group : game.getCombat().getGroups()){
if(group.getDefenderId().equals(getControllerId())){
return true;
}
}
}
}
return false;
}
@Override
public String getRule(boolean all) {
return this.getRule();
}
@Override
public String getRule() {
return "If a creature is attacking you and you control a Forest and a Plains, you may casbt Qasali Ambusher without paying its mana cost and as though it had flash";
}
}
class QasaliAmbusherEffect extends OneShotEffect<QasaliAmbusherEffect> {
public QasaliAmbusherEffect() {
super(Constants.Outcome.Benefit);
staticText = "";
}
public QasaliAmbusherEffect(final QasaliAmbusherEffect effect) {
super(effect);
}
@Override
public QasaliAmbusherEffect copy() {
return new QasaliAmbusherEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Card card = (Card) game.getObject(source.getSourceId());
if (card != null) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
SpellAbility spellAbility = card.getSpellAbility();
spellAbility.clear();
return controller.cast(spellAbility, game, true);
}
}
return false;
}
}

View file

@ -0,0 +1,140 @@
/*
* 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.shardsofalara;
import java.util.List;
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.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterLandPermanent;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author Plopman
*/
public class RealmRazer extends CardImpl<RealmRazer> {
public RealmRazer(UUID ownerId) {
super(ownerId, 187, "Realm Razer", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{R}{G}{W}");
this.expansionSetCode = "ALA";
this.subtype.add("Beast");
this.color.setRed(true);
this.color.setGreen(true);
this.color.setWhite(true);
this.power = new MageInt(4);
this.toughness = new MageInt(2);
// When Realm Razer enters the battlefield, exile all lands.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ExileAllEffect()));
// When Realm Razer leaves the battlefield, return the exiled cards to the battlefield tapped under their owners' control.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new RealmRazerEffect(), false));
}
public RealmRazer(final RealmRazer card) {
super(card);
}
@Override
public RealmRazer copy() {
return new RealmRazer(this);
}
}
class ExileAllEffect extends OneShotEffect<ExileAllEffect> {
public ExileAllEffect() {
super(Constants.Outcome.Exile);
staticText = "exile all lands";
}
public ExileAllEffect(final ExileAllEffect effect) {
super(effect);
}
@Override
public ExileAllEffect copy() {
return new ExileAllEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
List<Permanent> permanents = game.getBattlefield().getActivePermanents(new FilterLandPermanent(), source.getControllerId(), source.getId(), game);
for (Permanent permanent: permanents) {
permanent.moveToExile(source.getSourceId(), "Realm Razer", source.getSourceId(), game);
}
return true;
}
}
class RealmRazerEffect extends OneShotEffect<RealmRazerEffect> {
public RealmRazerEffect() {
super(Constants.Outcome.ReturnToHand);
this.staticText = "return the exiled cards to the battlefield tapped under their owners' control";
}
public RealmRazerEffect(final RealmRazerEffect effect) {
super(effect);
}
@Override
public RealmRazerEffect copy() {
return new RealmRazerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
ExileZone exZone = game.getExile().getExileZone(source.getSourceId());
if (exZone != null) {
for (Card card : exZone.getCards(game)) {
if (card != null) {
if(card.putOntoBattlefield(game, Constants.Zone.EXILED, source.getSourceId(), card.getOwnerId())){
game.getPermanent(card.getId()).setTapped(true);
}
}
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,64 @@
/*
* 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.timespiral;
import java.util.UUID;
import mage.Constants.CardType;
import mage.Constants.Rarity;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawCardTargetEffect;
import mage.abilities.keyword.SuspendAbility;
import mage.cards.CardImpl;
import mage.target.TargetPlayer;
/**
*
* @author Plopman
*/
public class AncestralVision extends CardImpl<AncestralVision> {
public AncestralVision(UUID ownerId) {
super(ownerId, 48, "Ancestral Vision", Rarity.RARE, new CardType[]{CardType.SORCERY}, "");
this.expansionSetCode = "TSP";
// Suspend 4-{U}
this.addAbility(new SuspendAbility(4, new ManaCostsImpl("U"), this));
// Target player draws three cards.
this.getSpellAbility().addTarget(new TargetPlayer());
this.getSpellAbility().addEffect(new DrawCardTargetEffect(3));
}
public AncestralVision(final AncestralVision card) {
super(card);
}
@Override
public AncestralVision copy() {
return new AncestralVision(this);
}
}

View file

@ -41,7 +41,6 @@ import mage.cards.repository.CardRepository;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -58,11 +57,10 @@ public class EngineeredPlague extends CardImpl<EngineeredPlague> {
this.color.setBlack(true);
FilterCreaturePermanent filter = new FilterCreaturePermanent("All creatures of the chosen type");
// As Engineered Plague enters the battlefield, choose a creature type.
this.addAbility(new AsEntersBattlefieldAbility(new EngineeredPlagueEntersBattlefieldEffect(filter), "choose a creature type"));
this.addAbility(new AsEntersBattlefieldAbility(new EngineeredPlagueEntersBattlefieldEffect(), "choose a creature type"));
// All creatures of the chosen type get -1/-1.
this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new BoostAllEffect(-1, -1, Constants.Duration.WhileOnBattlefield, filter, false)));
this.addAbility(new SimpleStaticAbility(Constants.Zone.BATTLEFIELD, new BoostAllEffect(-1, -1, Constants.Duration.WhileOnBattlefield, new FilterEngineeredPlague(), false)));
}
public EngineeredPlague(final EngineeredPlague card) {
@ -76,16 +74,13 @@ public class EngineeredPlague extends CardImpl<EngineeredPlague> {
class EngineeredPlagueEntersBattlefieldEffect extends OneShotEffect<EngineeredPlagueEntersBattlefieldEffect> {
private FilterCreaturePermanent filter;
public EngineeredPlagueEntersBattlefieldEffect(FilterCreaturePermanent filter) {
public EngineeredPlagueEntersBattlefieldEffect() {
super(Constants.Outcome.Benefit);
this.filter = filter;
staticText = "As {this} enters the battlefield, choose a creature type";
}
public EngineeredPlagueEntersBattlefieldEffect(final EngineeredPlagueEntersBattlefieldEffect effect) {
super(effect);
this.filter = effect.filter;
}
@Override
@ -100,7 +95,7 @@ public class EngineeredPlague extends CardImpl<EngineeredPlague> {
game.debugMessage("player canceled choosing type. retrying.");
}
game.informPlayers(permanent.getName() + ": " + player.getName() + " has chosen " + typeChoice.getChoice());
filter.add(new SubtypePredicate(typeChoice.getChoice()));
game.getState().setValue(permanent.getId() + "_type", typeChoice.getChoice().toString());
permanent.addInfo("chosen type", "<i>Chosen type: " + typeChoice.getChoice() + "</i>");
}
return false;
@ -113,7 +108,36 @@ public class EngineeredPlague extends CardImpl<EngineeredPlague> {
}
class FilterEngineeredPlague extends FilterCreaturePermanent {
public FilterEngineeredPlague() {
super("All creatures of the chosen type");
}
public FilterEngineeredPlague(final FilterEngineeredPlague filter) {
super(filter);
}
@Override
public FilterEngineeredPlague copy() {
return new FilterEngineeredPlague(this);
}
@Override
public boolean match(Permanent permanent, UUID sourceId, UUID playerId, Game game) {
if(super.match(permanent, sourceId, playerId, game)){
String subtype = (String) game.getState().getValue(sourceId + "_type");
if(subtype != null && !subtype.equals("") && permanent.hasSubtype(subtype)){
return true;
}
}
return false;
}
}
}

View file

@ -71,8 +71,9 @@ public class CantCounterSourceEffect extends ReplacementEffectImpl<CantCounterSo
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == EventType.COUNTER) {
UUID spellId = game.getCard(source.getSourceId()).getSpellAbility().getId();
if (event.getTargetId().equals(spellId))
if (event.getTargetId().equals(spellId)) {
return true;
}
}
return false;
}

View file

@ -55,8 +55,9 @@ public class SpellStack extends ArrayDeque<StackObject> {
top = this.peek();
top.resolve(game);
} finally {
if (top != null)
if (top != null) {
this.remove(top);
}
}
}
@ -89,11 +90,13 @@ public class SpellStack extends ArrayDeque<StackObject> {
public StackObject getStackObject(UUID id) {
for (StackObject stackObject: this) {
UUID objectId = stackObject.getId();
if (objectId.equals(id))
if (objectId.equals(id)) {
return stackObject;
}
UUID sourceId = stackObject.getSourceId();
if (sourceId.equals(id))
if (sourceId.equals(id)) {
return stackObject;
}
}
return null;
}
@ -101,10 +104,12 @@ public class SpellStack extends ArrayDeque<StackObject> {
public Spell getSpell(UUID id) {
for (StackObject stackObject: this) {
if (stackObject.getId().equals(id)) {
if (stackObject instanceof Spell)
if (stackObject instanceof Spell) {
return (Spell)stackObject;
else
}
else {
return null;
}
}
}
return null;