Merge remote-tracking branch 'remotes/upstream/master'

This commit is contained in:
ciaccona007 2017-07-27 15:59:51 -04:00
commit 6e2679ed48
59 changed files with 1409 additions and 503 deletions

View file

@ -47,17 +47,18 @@ public class AdornedPouncer extends CardImpl {
this.power = new MageInt(1);
this.toughness = new MageInt(1);
//double strike
// Double strike
addAbility(DoubleStrikeAbility.getInstance());
//eternalize 3WW
// Eternalize 3WW
addAbility(new EternalizeAbility(new ManaCostsImpl("{3}{W}{W}"), this));
}
public AdornedPouncer(AdornedPouncer adornedPouncer) {
super(adornedPouncer);
public AdornedPouncer(final AdornedPouncer card) {
super(card);
}
@Override
public AdornedPouncer copy() {
return new AdornedPouncer(this);
}

View file

@ -89,7 +89,8 @@ class LoseControlTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkEventType(GameEvent event, Game game) {
return (event.getType() == GameEvent.EventType.LOST_CONTROL);
return event.getType() == GameEvent.EventType.LOST_CONTROL
|| event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override

View file

@ -27,7 +27,6 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -40,16 +39,14 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.LifelinkAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.constants.*;
import mage.counters.CounterType;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author fireshoes
@ -59,8 +56,7 @@ public class CartoucheOfAmbition extends CardImpl {
public CartoucheOfAmbition(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}");
this.subtype.add("Aura");
this.subtype.add("Cartouche");
this.subtype.add(SubType.AURA, SubType.CARTOUCHE);
// Enchant creature you control
TargetPermanent auraTarget = new TargetControlledCreaturePermanent();

View file

@ -27,7 +27,6 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -40,14 +39,12 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.constants.*;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
*
* @author fireshoes
@ -57,8 +54,7 @@ public class CartoucheOfKnowledge extends CardImpl {
public CartoucheOfKnowledge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
this.subtype.add("Aura");
this.subtype.add("Cartouche");
this.subtype.add(SubType.AURA, SubType.CARTOUCHE);
// Enchant creature you control
TargetPermanent auraTarget = new TargetControlledCreaturePermanent();

View file

@ -27,7 +27,6 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -40,15 +39,13 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.constants.*;
import mage.game.permanent.token.WarriorVigilantToken;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import java.util.UUID;
/**
*
* @author fireshoes
@ -58,8 +55,7 @@ public class CartoucheOfSolidarity extends CardImpl {
public CartoucheOfSolidarity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
this.subtype.add("Aura");
this.subtype.add("Cartouche");
this.subtype.add(SubType.AURA, SubType.CARTOUCHE);
// Enchant creature you control
TargetPermanent auraTarget = new TargetControlledCreaturePermanent();

View file

@ -27,7 +27,6 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -48,6 +47,8 @@ import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetOpponentsCreaturePermanent;
import java.util.UUID;
/**
*
* @author stravant
@ -57,8 +58,7 @@ public class CartoucheOfStrength extends CardImpl {
public CartoucheOfStrength(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
this.subtype.add("Aura");
this.subtype.add("Cartouche");
this.subtype.add(SubType.AURA, SubType.CARTOUCHE);
// Enchant creature you control
TargetPermanent auraTarget = new TargetControlledCreaturePermanent();

View file

@ -27,7 +27,6 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -40,15 +39,13 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.constants.*;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author fireshoes
@ -58,8 +55,7 @@ public class CartoucheOfZeal extends CardImpl {
public CartoucheOfZeal(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{R}");
this.subtype.add("Aura");
this.subtype.add("Cartouche");
this.subtype.add(SubType.AURA, SubType.CARTOUCHE);
// Enchant creature you control
TargetPermanent auraTarget = new TargetControlledCreaturePermanent();

View file

@ -27,12 +27,14 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CrewAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -43,7 +45,7 @@ public class ConsulateDreadnought extends CardImpl {
public ConsulateDreadnought(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(7);
this.toughness = new MageInt(11);

View file

@ -27,13 +27,15 @@
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CrewAbility;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -43,7 +45,7 @@ public class CultivatorsCaravan extends CardImpl {
public CultivatorsCaravan(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(5);
this.toughness = new MageInt(5);

View file

@ -27,7 +27,6 @@
*/
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EndOfCombatTriggeredAbility;
@ -39,12 +38,15 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.watchers.common.AttackedOrBlockedThisCombatWatcher;
import java.util.UUID;
/**
*
* @author spjspj
@ -54,7 +56,7 @@ public class DaredevilDragster extends CardImpl {
public DaredevilDragster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(4);
this.toughness = new MageInt(4);

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.d;
import java.util.UUID;
@ -47,7 +46,6 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author L_J
@ -55,7 +53,7 @@ import mage.target.targetpointer.FixedTarget;
public class DaruSpiritualist extends CardImpl {
public DaruSpiritualist(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{W}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W}");
this.subtype.add("Human");
this.subtype.add("Cleric");
@ -104,12 +102,9 @@ class DaruSpiritualistTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
UUID targetId = event.getTargetId();
Permanent creature = game.getPermanent(event.getTargetId());
if (creature != null && filter.match(creature, getSourceId(), getControllerId(), game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
}
this.getEffects().setTargetPointer(new FixedTarget(creature, game));
return true;
}
return false;

View file

@ -27,7 +27,6 @@
*/
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleEvasionAbility;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
@ -37,9 +36,12 @@ import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate;
import java.util.UUID;
/**
*
* @author emerald000
@ -53,7 +55,7 @@ public class DemolitionStomper extends CardImpl {
public DemolitionStomper(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{6}");
this.subtype.add("Vehicle");
this.subtype.add( SubType.VEHICLE);
this.power = new MageInt(10);
this.toughness = new MageInt(7);

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.cards.d;
import java.util.UUID;
import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.common.DealsDamageToAPlayerAttachedTriggeredAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.SacrificeEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.common.FilterLandPermanent;
/**
*
* @author TheElk801
*/
public class DestructiveUrge extends CardImpl {
public DestructiveUrge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}{R}");
this.subtype.add("Aura");
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Whenever enchanted creature deals combat damage to a player, that player sacrifices a land.
ability = new DealsDamageToAPlayerAttachedTriggeredAbility(new SacrificeEffect(new FilterLandPermanent(), 1, "that player"), "enchanted", false, true);
this.addAbility(ability);
}
public DestructiveUrge(final DestructiveUrge card) {
super(card);
}
@Override
public DestructiveUrge copy() {
return new DestructiveUrge(this);
}
}

View file

@ -27,7 +27,6 @@
*/
package mage.cards.f;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -40,6 +39,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -49,7 +51,7 @@ public class FleetwheelCruiser extends CardImpl {
public FleetwheelCruiser(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(5);
this.toughness = new MageInt(3);

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.cards.f;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.PayCostToAttackBlockEffectImpl;
import mage.abilities.effects.PayCostToAttackBlockEffectImpl.RestrictType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledPermanent;
/**
*
* @author jeffwadsworth
*/
public class FloodedWoodlands extends CardImpl {
public FloodedWoodlands(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{B}");
// Green creatures can't attack unless their controller sacrifices a land for each green creature he or she controls that's attacking.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new FloodedWoodlandsCostToAttackBlockEffect()));
}
public FloodedWoodlands(final FloodedWoodlands card) {
super(card);
}
@Override
public FloodedWoodlands copy() {
return new FloodedWoodlands(this);
}
}
class FloodedWoodlandsCostToAttackBlockEffect extends PayCostToAttackBlockEffectImpl {
FloodedWoodlandsCostToAttackBlockEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK,
new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))));
staticText = "Green creatures can't attack unless their controller sacrifices a land <i>(This cost is paid as attackers are declared.)</i>";
}
FloodedWoodlandsCostToAttackBlockEffect(FloodedWoodlandsCostToAttackBlockEffect effect) {
super(effect);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanent(event.getSourceId());
return (permanent != null
&& permanent.isCreature()
&& permanent.getColor(game).isGreen());
}
@Override
public FloodedWoodlandsCostToAttackBlockEffect copy() {
return new FloodedWoodlandsCostToAttackBlockEffect(this);
}
}

View file

@ -27,7 +27,6 @@
*/
package mage.cards.h;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -49,6 +48,8 @@ import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
/**
* @author JRHerlehy
*/
@ -58,7 +59,7 @@ public class HeartOfKiran extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(4);
this.toughness = new MageInt(4);

View file

@ -28,7 +28,6 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.GainLifeEffect;
@ -41,6 +40,8 @@ import mage.constants.TargetController;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import java.util.UUID;
/**
* @author Loki
*/
@ -55,7 +56,7 @@ public class HondenOfCleansingFire extends CardImpl {
public HondenOfCleansingFire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{W}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add("Shrine");
this.subtype.add(SubType.SHRINE);
// At the beginning of your upkeep, you gain 2 life for each Shrine you control.

View file

@ -28,7 +28,6 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
@ -43,6 +42,8 @@ import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetCreatureOrPlayer;
import java.util.UUID;
/**
*
* @author Loki
@ -58,7 +59,7 @@ public class HondenOfInfiniteRage extends CardImpl {
public HondenOfInfiniteRage (UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{2}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add("Shrine");
this.subtype.add(SubType.SHRINE);
// At the beginning of your upkeep, Honden of Infinite Rage deals damage to target creature or player equal to the number of Shrines you control.

View file

@ -28,7 +28,6 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.CreateTokenEffect;
@ -42,6 +41,8 @@ import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.permanent.token.SpiritToken;
import java.util.UUID;
/**
* @author Loki
*/
@ -56,7 +57,7 @@ public class HondenOfLifesWeb extends CardImpl {
public HondenOfLifesWeb(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{G}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add("Shrine");
this.subtype.add(SubType.SHRINE);
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new CreateTokenEffect(new SpiritToken(), new PermanentsOnBattlefieldCount(filter)), TargetController.YOU, false));
}

View file

@ -28,7 +28,6 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
@ -43,6 +42,8 @@ import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetOpponent;
import java.util.UUID;
/**
* @author Loki
*/
@ -57,7 +58,7 @@ public class HondenOfNightsReach extends CardImpl {
public HondenOfNightsReach(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{B}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add("Shrine");
this.subtype.add(SubType.SHRINE);
// At the beginning of your upkeep, target opponent discards a card for each Shrine you control.

View file

@ -28,7 +28,6 @@
package mage.cards.h;
import java.util.UUID;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
@ -41,6 +40,8 @@ import mage.constants.TargetController;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import java.util.UUID;
/**
* @author Loki
*/
@ -55,7 +56,7 @@ public class HondenOfSeeingWinds extends CardImpl {
public HondenOfSeeingWinds(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{4}{U}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add("Shrine");
this.subtype.add(SubType.SHRINE);
// At the beginning of your upkeep, draw a card for each Shrine you control.

View file

@ -27,12 +27,14 @@
*/
package mage.cards.i;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CrewAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -43,7 +45,7 @@ public class IrontreadCrusher extends CardImpl {
public IrontreadCrusher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(6);
this.toughness = new MageInt(6);

View file

@ -0,0 +1,165 @@
/*
* 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.cards.k;
import java.util.Optional;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.PhasingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
* @author jeffwadsworth
*/
public class KatabaticWinds extends CardImpl {
public KatabaticWinds(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}");
// Phasing
this.addAbility(PhasingAbility.getInstance());
// Creatures with flying can't attack or block, and their activated abilities with {tap} in their costs can't be activated.
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new KatabaticWindsRestrictionEffect());
ability.addEffect(new KatabaticWindsRuleModifyingEffect());
this.addAbility(ability);
}
public KatabaticWinds(final KatabaticWinds card) {
super(card);
}
@Override
public KatabaticWinds copy() {
return new KatabaticWinds(this);
}
}
class KatabaticWindsRestrictionEffect extends RestrictionEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
static {
filter.add(new AbilityPredicate(FlyingAbility.class));
}
public KatabaticWindsRestrictionEffect() {
super(Duration.WhileOnBattlefield);
staticText = "Creatures with flying can't attack or block";
}
public KatabaticWindsRestrictionEffect(final KatabaticWindsRestrictionEffect effect) {
super(effect);
}
@Override
public KatabaticWindsRestrictionEffect copy() {
return new KatabaticWindsRestrictionEffect(this);
}
@Override
public boolean canAttack(Game game) {
return false;
}
@Override
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
return false;
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
return filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}
}
class KatabaticWindsRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl {
public KatabaticWindsRuleModifyingEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = ", and their activated abilities with {tap} in their costs can't be activated";
}
public KatabaticWindsRuleModifyingEffect(final KatabaticWindsRuleModifyingEffect effect) {
super(effect);
}
@Override
public KatabaticWindsRuleModifyingEffect copy() {
return new KatabaticWindsRuleModifyingEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
MageObject object = game.getObject(event.getSourceId());
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
if (ability.isPresent()
&& object != null
&& object.isCreature()
&& object.getAbilities().contains(FlyingAbility.getInstance())
&& game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId())) {
if (ability.get().getCosts().stream().anyMatch((cost) -> (cost instanceof TapSourceCost))) {
return true;
}
}
return false;
}
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
return "Creatures with flying can't use their activated abilities that use {tap} in their costs.";
}
}

View file

@ -0,0 +1,87 @@
/*
* 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.cards.k;
import java.util.UUID;
import mage.target.common.TargetCreaturePermanent;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.CardsInControllerGraveCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.combat.CantAttackAttachedEffect;
import mage.abilities.effects.common.combat.CantAttackBlockAttachedEffect;
import mage.constants.Outcome;
import mage.target.TargetPermanent;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AbilityWord;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Zone;
/**
*
* @author TheElk801
*/
public class KirtarsDesire extends CardImpl {
public KirtarsDesire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
this.subtype.add("Aura");
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature can't attack.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackAttachedEffect(AttachmentType.AURA)));
// Threshold - Enchanted creature can't block as long as seven or more cards are in your graveyard.
ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
new CantAttackBlockAttachedEffect(AttachmentType.AURA), new CardsInControllerGraveCondition(7),
"Enchanted creature can't block as long as seven or more cards are in your graveyard"));
ability.setAbilityWord(AbilityWord.THRESHOLD);
this.addAbility(ability);
}
public KirtarsDesire(final KirtarsDesire card) {
super(card);
}
@Override
public KirtarsDesire copy() {
return new KirtarsDesire(this);
}
}

View file

@ -27,7 +27,6 @@
*/
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
@ -36,12 +35,15 @@ import mage.abilities.keyword.CrewAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
/**
*
* @author Styxo
@ -61,7 +63,7 @@ public class MobileGarrison extends CardImpl {
public MobileGarrison(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(3);
this.toughness = new MageInt(4);

View file

@ -104,7 +104,7 @@ class MystifyingMazeEffect extends OneShotEffect {
if (permanent != null && sourceObject != null) {
if (permanent.moveToExile(source.getSourceId(), sourceObject.getIdName(), source.getSourceId(), game)) {
//create delayed triggered ability
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect();
Effect effect = new ReturnToBattlefieldUnderOwnerControlTargetEffect(true);
effect.setText("At the beginning of the next end step, return it to the battlefield tapped under its owner's control");
effect.setTargetPointer(new FixedTarget(source.getFirstTarget(), game));
game.addDelayedTriggeredAbility(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(effect), source);

View file

@ -27,7 +27,6 @@
*/
package mage.cards.o;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CrewAbility;
import mage.abilities.keyword.HasteAbility;
@ -35,6 +34,9 @@ import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -44,7 +46,7 @@ public class OvalchaseDragster extends CardImpl {
public OvalchaseDragster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(6);
this.toughness = new MageInt(1);

View file

@ -27,7 +27,6 @@
*/
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -46,6 +45,8 @@ import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.filter.predicate.permanent.AnotherPredicate;
import mage.target.common.TargetControlledPermanent;
import java.util.UUID;
/**
* @author JRHerlehy
*/
@ -61,7 +62,7 @@ public class PeacewalkerColossus extends CardImpl {
public PeacewalkerColossus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(6);
this.toughness = new MageInt(6);

View file

@ -0,0 +1,95 @@
/*
* 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.cards.p;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PutOnLibraryTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author TheElk801
*/
public class PipersMelody extends CardImpl {
public PipersMelody(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{G}");
// Shuffle any number of target creature cards from your graveyard into your library.
this.getSpellAbility().addEffect(new PipersMelodyShuffleEffect());
this.getSpellAbility().addTarget(new TargetCardInYourGraveyard(0, Integer.MAX_VALUE, new FilterCreatureCard("creature cards from your graveyard")));
}
public PipersMelody(final PipersMelody card) {
super(card);
}
@Override
public PipersMelody copy() {
return new PipersMelody(this);
}
}
class PipersMelodyShuffleEffect extends OneShotEffect {
PipersMelodyShuffleEffect() {
super(Outcome.Neutral);
this.staticText = "Shuffle any number of target cards from your graveyard into your library";
}
PipersMelodyShuffleEffect(final PipersMelodyShuffleEffect effect) {
super(effect);
}
@Override
public PipersMelodyShuffleEffect copy() {
return new PipersMelodyShuffleEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
controller.moveCards(new CardsImpl(this.getTargetPointer().getTargets(game, source)), Zone.LIBRARY, source, game);
controller.shuffleLibrary(source, game);
return true;
}
return false;
}
}

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.cards.r;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.SacrificeTargetCost;
import mage.abilities.effects.PayCostToAttackBlockEffectImpl;
import mage.abilities.effects.PayCostToAttackBlockEffectImpl.RestrictType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledPermanent;
/**
*
* @author jeffwadsworth
*/
public class Reclamation extends CardImpl {
public Reclamation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{G}{W}");
// Black creatures can't attack unless their controller sacrifices a land for each black creature he or she controls that's attacking.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ReclamationCostToAttackBlockEffect()));
}
public Reclamation(final Reclamation card) {
super(card);
}
@Override
public Reclamation copy() {
return new Reclamation(this);
}
}
class ReclamationCostToAttackBlockEffect extends PayCostToAttackBlockEffectImpl {
ReclamationCostToAttackBlockEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment, RestrictType.ATTACK,
new SacrificeTargetCost(new TargetControlledPermanent(new FilterControlledLandPermanent("a land"))));
staticText = "Black creatures can't attack unless their controller sacrifices a land <i>(This cost is paid as attackers are declared.)</i>";
}
ReclamationCostToAttackBlockEffect(ReclamationCostToAttackBlockEffect effect) {
super(effect);
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanent(event.getSourceId());
return (permanent != null
&& permanent.isCreature()
&& permanent.getColor(game).isBlack());
}
@Override
public ReclamationCostToAttackBlockEffect copy() {
return new ReclamationCostToAttackBlockEffect(this);
}
}

View file

@ -27,7 +27,6 @@
*/
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.AttacksTriggeredAbility;
@ -40,6 +39,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -49,7 +51,7 @@ public class RenegadeFreighter extends CardImpl {
public RenegadeFreighter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{3}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(4);
this.toughness = new MageInt(3);

View file

@ -27,13 +27,15 @@
*/
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.keyword.CrewAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -43,7 +45,7 @@ public class SkySkiff extends CardImpl {
public SkySkiff(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);

View file

@ -27,7 +27,6 @@
*/
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldOrAttacksSourceTriggeredAbility;
@ -37,12 +36,15 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.filter.common.FilterCreatureOrPlaneswalkerPermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.common.TargetCreatureOrPlaneswalker;
import java.util.UUID;
/**
* @author emerald000
*/
@ -57,7 +59,7 @@ public class SkysovereignConsulFlagship extends CardImpl {
public SkysovereignConsulFlagship(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(6);
this.toughness = new MageInt(5);

View file

@ -27,7 +27,6 @@
*/
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
import mage.abilities.effects.Effect;
@ -37,6 +36,9 @@ import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -46,7 +48,7 @@ public class SmugglersCopter extends CardImpl {
public SmugglersCopter(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(3);
this.toughness = new MageInt(3);

View file

@ -27,8 +27,10 @@
*/
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.combat.CantAttackBlockAllEffect;
import mage.abilities.effects.RestrictionEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -36,12 +38,12 @@ import mage.constants.Duration;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.EnchantedPredicate;
import java.util.UUID;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author ciaccona007
* @author jeffwadsworth
*/
public class SongOfSerenity extends CardImpl {
@ -49,9 +51,8 @@ public class SongOfSerenity extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
// Creatures that are enchanted can't attack or block.
FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures that are enchanted");
filter.add(new EnchantedPredicate());
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockAllEffect(Duration.WhileOnBattlefield, filter)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SongOfSerenityRestrictionEffect()));
}
public SongOfSerenity(final SongOfSerenity card) {
@ -63,3 +64,41 @@ public class SongOfSerenity extends CardImpl {
return new SongOfSerenity(this);
}
}
class SongOfSerenityRestrictionEffect extends RestrictionEffect {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
static {
filter.add(new EnchantedPredicate());
}
public SongOfSerenityRestrictionEffect() {
super(Duration.WhileOnBattlefield);
staticText = "Creatures that are enchanted can't attack or block";
}
public SongOfSerenityRestrictionEffect(final SongOfSerenityRestrictionEffect effect) {
super(effect);
}
@Override
public SongOfSerenityRestrictionEffect copy() {
return new SongOfSerenityRestrictionEffect(this);
}
@Override
public boolean canAttack(Game game) {
return false;
}
@Override
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
return false;
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
return filter.match(permanent, source.getSourceId(), source.getControllerId(), game);
}
}

View file

@ -27,7 +27,6 @@
*/
package mage.cards.u;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
@ -36,8 +35,11 @@ import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author JRHerlehy
*/
@ -46,7 +48,7 @@ public class UntetheredExpress extends CardImpl {
public UntetheredExpress(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
this.subtype.add("Vehicle");
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(4);
this.toughness = new MageInt(4);

View file

@ -27,7 +27,6 @@
*/
package mage.cards.u;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
@ -37,9 +36,12 @@ import mage.abilities.mana.ColorlessManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.game.permanent.token.AssemblyWorkerToken;
import java.util.UUID;
/**
*
* @author Loki
@ -48,7 +50,7 @@ public class UrzasFactory extends CardImpl {
public UrzasFactory(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.subtype.add("Urza's");
this.subtype.add(SubType.URZAS);
// {tap}: Add {C} to your mana pool.
this.addAbility(new ColorlessManaAbility());

View file

@ -27,7 +27,6 @@
*/
package mage.cards.u;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.UrzaTerrainValue;
@ -35,6 +34,9 @@ import mage.abilities.mana.DynamicManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -43,8 +45,7 @@ import mage.constants.CardType;
public class UrzasMine extends CardImpl {
public UrzasMine(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
this.subtype.add("Urza's");
this.subtype.add("Mine");
this.subtype.add(SubType.URZAS, SubType.MINE);
// {T}: Add {C} to your mana pool. If you control an Urza's Power-Plant and an Urza's Tower, add {C}{C} to your mana pool instead.
Ability urzaManaAbility = new DynamicManaAbility(Mana.ColorlessMana(1), new UrzaTerrainValue(2),

View file

@ -27,7 +27,6 @@
*/
package mage.cards.u;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.UrzaTerrainValue;
@ -35,6 +34,9 @@ import mage.abilities.mana.DynamicManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -43,8 +45,7 @@ import mage.constants.CardType;
public class UrzasPowerPlant extends CardImpl {
public UrzasPowerPlant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
this.subtype.add("Urza's");
this.subtype.add("Power-Plant");
this.subtype.add(SubType.URZAS, SubType.POWER_PLANT);
// {T}: Add {C} to your mana pool. If you control an Urza's Mine and an Urza's Tower, add {C}{C} to your mana pool instead.
Ability urzaManaAbility = new DynamicManaAbility(Mana.ColorlessMana(1), new UrzaTerrainValue(2),

View file

@ -27,7 +27,6 @@
*/
package mage.cards.u;
import java.util.UUID;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.UrzaTerrainValue;
@ -35,6 +34,9 @@ import mage.abilities.mana.DynamicManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
*
@ -43,8 +45,7 @@ import mage.constants.CardType;
public class UrzasTower extends CardImpl {
public UrzasTower(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.LAND},"");
this.subtype.add("Urza's");
this.subtype.add("Tower");
this.subtype.add(SubType.URZAS, SubType.TOWER);
// {T}: Add {C} to your mana pool. If you control an Urza's Mine and an Urza's Power-Plant, add {C}{C}{C} to your mana pool instead.
Ability urzaManaAbility = new DynamicManaAbility(Mana.ColorlessMana(1), new UrzaTerrainValue(3),

View file

@ -110,6 +110,7 @@ public class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Fire Covenant", 367, Rarity.UNCOMMON, mage.cards.f.FireCovenant.class));
cards.add(new SetCardInfo("Flame Spirit", 184, Rarity.UNCOMMON, mage.cards.f.FlameSpirit.class));
cards.add(new SetCardInfo("Flare", 185, Rarity.COMMON, mage.cards.f.Flare.class));
cards.add(new SetCardInfo("Flooded Woodlands", 368, Rarity.RARE, mage.cards.f.FloodedWoodlands.class));
cards.add(new SetCardInfo("Flow of Maggots", 13, Rarity.RARE, mage.cards.f.FlowOfMaggots.class));
cards.add(new SetCardInfo("Folk of the Pines", 123, Rarity.COMMON, mage.cards.f.FolkOfThePines.class));
cards.add(new SetCardInfo("Forbidden Lore", 124, Rarity.RARE, mage.cards.f.ForbiddenLore.class));
@ -229,6 +230,7 @@ public class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Rally", 272, Rarity.COMMON, mage.cards.r.Rally.class));
cards.add(new SetCardInfo("Ray of Command", 92, Rarity.COMMON, mage.cards.r.RayOfCommand.class));
cards.add(new SetCardInfo("Ray of Erasure", 93, Rarity.COMMON, mage.cards.r.RayOfErasure.class));
cards.add(new SetCardInfo("Reclamation", 378, Rarity.RARE, mage.cards.r.Reclamation.class));
cards.add(new SetCardInfo("Red Scarab", 273, Rarity.UNCOMMON, mage.cards.r.RedScarab.class));
cards.add(new SetCardInfo("Regeneration", 147, Rarity.COMMON, mage.cards.r.Regeneration.class));
cards.add(new SetCardInfo("Rime Dryad", 148, Rarity.COMMON, mage.cards.r.RimeDryad.class));

View file

@ -194,6 +194,7 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Kamahl, Pit Fighter", 198, Rarity.RARE, mage.cards.k.KamahlPitFighter.class));
cards.add(new SetCardInfo("Kamahl's Desire", 199, Rarity.COMMON, mage.cards.k.KamahlsDesire.class));
cards.add(new SetCardInfo("Karmic Justice", 26, Rarity.RARE, mage.cards.k.KarmicJustice.class));
cards.add(new SetCardInfo("Kirtar's Desire", 27, Rarity.COMMON, mage.cards.k.KirtarsDesire.class));
cards.add(new SetCardInfo("Kirtar's Wrath", 28, Rarity.RARE, mage.cards.k.KirtarsWrath.class));
cards.add(new SetCardInfo("Krosan Archer", 246, Rarity.COMMON, mage.cards.k.KrosanArcher.class));
cards.add(new SetCardInfo("Krosan Avenger", 247, Rarity.COMMON, mage.cards.k.KrosanAvenger.class));
@ -260,6 +261,7 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Pianna, Nomad Captain", 39, Rarity.RARE, mage.cards.p.PiannaNomadCaptain.class));
cards.add(new SetCardInfo("Pilgrim of Justice", 40, Rarity.COMMON, mage.cards.p.PilgrimOfJustice.class));
cards.add(new SetCardInfo("Pilgrim of Virtue", 41, Rarity.COMMON, mage.cards.p.PilgrimOfVirtue.class));
cards.add(new SetCardInfo("Piper's Melody", 261, Rarity.UNCOMMON, mage.cards.p.PipersMelody.class));
cards.add(new SetCardInfo("Plains", 331, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Plains", 332, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true)));
cards.add(new SetCardInfo("Plains", 333, Rarity.LAND, mage.cards.basiclands.Plains.class, new CardGraphicInfo(null, true)));

View file

@ -120,6 +120,7 @@ public class UrzasSaga extends ExpansionSet {
cards.add(new SetCardInfo("Dark Hatchling", 126, Rarity.RARE, mage.cards.d.DarkHatchling.class));
cards.add(new SetCardInfo("Dark Ritual", 127, Rarity.COMMON, mage.cards.d.DarkRitual.class));
cards.add(new SetCardInfo("Despondency", 129, Rarity.COMMON, mage.cards.d.Despondency.class));
cards.add(new SetCardInfo("Destructive Urge", 180, Rarity.UNCOMMON, mage.cards.d.DestructiveUrge.class));
cards.add(new SetCardInfo("Diabolic Servitude", 130, Rarity.UNCOMMON, mage.cards.d.DiabolicServitude.class));
cards.add(new SetCardInfo("Disciple of Grace", 10, Rarity.COMMON, mage.cards.d.DiscipleOfGrace.class));
cards.add(new SetCardInfo("Disciple of Law", 11, Rarity.COMMON, mage.cards.d.DiscipleOfLaw.class));

View file

@ -107,6 +107,7 @@ public class Visions extends ExpansionSet {
cards.add(new SetCardInfo("Jungle Basin", 164, Rarity.UNCOMMON, mage.cards.j.JungleBasin.class));
cards.add(new SetCardInfo("Kaervek's Spite", 13, Rarity.RARE, mage.cards.k.KaerveksSpite.class));
cards.add(new SetCardInfo("Karoo", 165, Rarity.UNCOMMON, mage.cards.k.Karoo.class));
cards.add(new SetCardInfo("Katabatic Winds", 59, Rarity.RARE, mage.cards.k.KatabaticWinds.class));
cards.add(new SetCardInfo("Keeper of Kookus", 85, Rarity.COMMON, mage.cards.k.KeeperOfKookus.class));
cards.add(new SetCardInfo("King Cheetah", 60, Rarity.COMMON, mage.cards.k.KingCheetah.class));
cards.add(new SetCardInfo("Knight of Valor", 111, Rarity.COMMON, mage.cards.k.KnightOfValor.class));

View file

@ -7,14 +7,14 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class AfflictTest extends CardTestPlayerBase {
private String khenra = "Khenra Eternal";
private String elves = "Llanowar Elves";
private final String khenra = "Khenra Eternal";
private final String elves = "Llanowar Elves";
@Test
public void testBecomesBlocked(){
public void testBecomesBlocked() {
addCard(Zone.BATTLEFIELD, playerA, khenra);
addCard(Zone.BATTLEFIELD, playerB, elves );
addCard(Zone.BATTLEFIELD, playerB, elves);
attack(1, playerA, khenra);
block(1, playerB, elves, khenra);
@ -27,10 +27,10 @@ public class AfflictTest extends CardTestPlayerBase {
}
@Test
public void testNotBlocked(){
public void testNotBlocked() {
addCard(Zone.BATTLEFIELD, playerA, khenra);
addCard(Zone.BATTLEFIELD, playerB, elves );
addCard(Zone.BATTLEFIELD, playerB, elves);
attack(1, playerA, khenra);
@ -40,4 +40,36 @@ public class AfflictTest extends CardTestPlayerBase {
assertLife(playerB, 18);
}
// My afflict didn't come through after using Endless Sands on my own creature. The afflict ability was on the stack already.
@Test
public void testRemoveAfflictCreatureAfterAfflictIsOnTheStack() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 2);
// Afflict 2 (Whenever this creature becomes blocked, defending player loses 2 life.)
// {1}{R}: Frontline Devastator gets +1/+0 until end of turn.
addCard(Zone.BATTLEFIELD, playerA, "Frontline Devastator");
// {T}: Add {C} to your mana pool.
// {2}, {T}: Exile target creature you control.
// {4}, {T}, Sacrifice Endless Sands: Return each creature card exiled with Endless Sands to the battlefield under its owners control.
addCard(Zone.BATTLEFIELD, playerA, "Endless Sands");
// Deathtouch
// When Ruin Rat dies, exile target card from an opponent's graveyard.
addCard(Zone.BATTLEFIELD, playerB, "Ruin Rat"); // Creature 1/1
attack(1, playerA, "Frontline Devastator");
block(1, playerB, "Ruin Rat", "Frontline Devastator");
activateAbility(1, PhaseStep.DECLARE_BLOCKERS, playerA, "{2},", "Frontline Devastator");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertExileCount(playerA, "Frontline Devastator", 1);
assertPermanentCount(playerB, "Ruin Rat", 1);
assertLife(playerB, 18);
}
}

View file

@ -8,7 +8,11 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
public class EternalizeTest extends CardTestPlayerBase {
private String sentinel = "Steadfast Sentinel";
// Creature - Human Cleric {3}{W} 2/3
// Vigilance
// Eternalize ({4}{W}{W}, Exile this card from your graveyard: Create a token that's a copy of it,
// except it's a 4/4 black Zombie Human Cleric with no mana cost. Eternalize only as a sorcery.)
private final String sentinel = "Steadfast Sentinel";
@Test
public void testEternalize() {
@ -22,4 +26,26 @@ public class EternalizeTest extends CardTestPlayerBase {
assertPowerToughness(playerA, sentinel, 4, 4);
assertAbility(playerA, sentinel, VigilanceAbility.getInstance(), true);
}
@Test
public void testEternalizeAndFatalPush() {
addCard(Zone.GRAVEYARD, playerA, sentinel, 1);
addCard(Zone.BATTLEFIELD, playerA, "Plains", 10);
// Destroy target creature if it has converted mana cost 2 or less.
// Revolt - Destroy that creature if it has converted mana cost 4 or less
// instead if a permanent you controlled left the battlefield this turn.
addCard(Zone.HAND, playerB, "Fatal Push"); // Instant {B}
addCard(Zone.BATTLEFIELD, playerB, "Swamp", 1);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Eternalize");
castSpell(1, PhaseStep.BEGIN_COMBAT, playerB, "Fatal Push", sentinel);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertGraveyardCount(playerB, "Fatal Push", 1);
assertPermanentCount(playerA, sentinel, 0);
assertExileCount(playerA, sentinel, 1);
}
}

View file

@ -0,0 +1,70 @@
/*
* 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 org.mage.test.cards.control;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX
*/
public class BronzeBombshellTest extends CardTestPlayerBase {
@Test
public void testEndlessWhispers() {
// When a player other than Bronze Bombshell's owner controls it, that player sacrifices it.
// If the player does, Bronze Bombshell deals 7 damage to him or her.
addCard(Zone.BATTLEFIELD, playerA, "Bronze Bombshell", 1);
// Each creature has "When this creature dies, choose target opponent.
// That player puts this card from its owner's graveyard onto the battlefield
// under his or her control at the beginning of the next end step."
addCard(Zone.BATTLEFIELD, playerA, "Endless Whispers", 1);
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 3);
// Destroy target creature or planeswalker..
addCard(Zone.HAND, playerA, "Hero's Downfall"); // {1}{B}{B}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hero's Downfall", "Bronze Bombshell");
addTarget(playerA, playerB);
setStopAt(2, PhaseStep.UPKEEP);
execute();
assertGraveyardCount(playerA, "Hero's Downfall", 1);
assertGraveyardCount(playerA, "Bronze Bombshell", 1);
assertLife(playerA, 20);
assertLife(playerB, 13);
}
}

View file

@ -1,7 +1,29 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
* 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 org.mage.test.game.ends;

View file

@ -0,0 +1,77 @@
/*
* 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 org.mage.test.game.ends;
import mage.constants.PhaseStep;
import mage.constants.TurnPhase;
import mage.constants.Zone;
import org.junit.Assert;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LeveöX
*/
public class PhageTheUntouchableTest extends CardTestPlayerBase {
@Test
public void TestWithEndlessWhispers() {
// Each creature has "When this creature dies, choose target opponent.
// That player puts this card from its owner's graveyard onto the battlefield
// under his or her control at the beginning of the next end step."
addCard(Zone.BATTLEFIELD, playerA, "Endless Whispers");
// Destroy target creature or planeswalker..
addCard(Zone.HAND, playerA, "Hero's Downfall"); // {1}{B}{B}
// When Phage the Untouchable enters the battlefield, if you didn't cast it from your hand, you lose the game.
// Whenever Phage deals combat damage to a creature, destroy that creature. It can't be regenerated.
// Whenever Phage deals combat damage to a player, that player loses the game.
addCard(Zone.HAND, playerA, "Phage the Untouchable"); // Creature {3}{B}{B}{B}{B} 4/4
addCard(Zone.BATTLEFIELD, playerA, "Swamp", 10);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Phage the Untouchable");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Hero's Downfall", "Phage the Untouchable");
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 20);
assertGraveyardCount(playerA, "Hero's Downfall", 1);
assertPermanentCount(playerB, "Phage the Untouchable", 1);
Assert.assertTrue("Game has ended.", currentGame.hasEnded());
Assert.assertTrue("Player A has won.", playerA.hasWon());
Assert.assertTrue("Game ist At end phase", currentGame.getPhase().getType().equals(TurnPhase.END));
}
}

View file

@ -74,22 +74,17 @@ public class AttackedByCreatureTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
UUID playerId = game.getCombat().getDefendingPlayerId(event.getSourceId(), game);
UUID defendingPlayer = game.getCombat().getDefendingPlayerId(event.getSourceId(), game);
Permanent attackingCreature = game.getPermanent(event.getSourceId());
if (getControllerId().equals(playerId) && attackingCreature != null) {
if (setTargetPointer != SetTargetPointer.NONE) {
for (Effect effect : this.getEffects()) {
if (getControllerId().equals(defendingPlayer) && attackingCreature != null) {
switch (setTargetPointer) {
case PERMANENT:
effect.setTargetPointer(new FixedTarget(attackingCreature.getId()));
this.getEffects().setTargetPointer(new FixedTarget(attackingCreature, game));
break;
case PLAYER:
effect.setTargetPointer(new FixedTarget(attackingCreature.getControllerId()));
this.getEffects().setTargetPointer(new FixedTarget(attackingCreature.getControllerId()));
break;
}
}
}
return true;
}
return false;

View file

@ -24,8 +24,7 @@
* 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.common;
import mage.abilities.TriggeredAbilityImpl;
@ -84,9 +83,7 @@ public class AttacksCreatureYouControlTriggeredAbility extends TriggeredAbilityI
Permanent sourcePermanent = game.getPermanent(event.getSourceId());
if (sourcePermanent != null && filter.match(sourcePermanent, sourceId, controllerId, game)) {
if (setTargetPointer) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getSourceId()));
}
return true;
}

View file

@ -71,9 +71,7 @@ public class BecomesBlockedAllTriggeredAbility extends TriggeredAbilityImpl {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null && filter.match(permanent, getSourceId(), getControllerId(), game)) {
if (setTargetPointer) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getTargetId()));
}
return true;
}

View file

@ -68,9 +68,7 @@ public class BecomesBlockedByCreatureTriggeredAbility extends TriggeredAbilityIm
if (event.getTargetId().equals(this.getSourceId())) {
Permanent blocker = game.getPermanent(event.getSourceId());
if (filter.match(blocker, game)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getSourceId()));
}
this.getEffects().setTargetPointer(new FixedTarget(blocker, game));
return true;
}
}

View file

@ -8,7 +8,6 @@ package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.Effect;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
@ -20,8 +19,6 @@ import mage.target.targetpointer.FixedTarget;
*/
public class BecomesMonstrousTriggeredAbility extends TriggeredAbilityImpl {
protected FilterCreaturePermanent filter = new FilterCreaturePermanent();
public BecomesMonstrousTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect, false);
}
@ -43,11 +40,9 @@ public class BecomesMonstrousTriggeredAbility extends TriggeredAbilityImpl {
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent permanent = game.getPermanent(event.getTargetId());
if (filter.match(permanent, sourceId, controllerId, game)
&& (permanent.getControllerId().equals(this.controllerId))) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getTargetId()));
}
if (permanent != null && permanent.isCreature()
&& (permanent.getControllerId().equals(getControllerId()))) {
this.getEffects().setTargetPointer(new FixedTarget(permanent, game));
return true;
}
return false;
@ -55,6 +50,6 @@ public class BecomesMonstrousTriggeredAbility extends TriggeredAbilityImpl {
@Override
public String getRule() {
return "Whenever " + filter.getMessage() + " becomes monstrous, " + super.getRule();
return "Whenever a creature you control becomes monstrous, " + super.getRule();
}
}

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.common;
import mage.abilities.TriggeredAbilityImpl;
@ -38,10 +37,12 @@ import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
public class BeginningOfDrawTriggeredAbility extends TriggeredAbilityImpl {
private TargetController targetController;
/**
* The Ability sets if no target is defined the target pointer to the active player of the current draw phase
* The Ability sets if no target is defined the target pointer to the active
* player of the current draw phase
*
* @param effect
* @param targetController
@ -78,18 +79,14 @@ public class BeginningOfDrawTriggeredAbility extends TriggeredAbilityImpl {
boolean yours = event.getPlayerId().equals(this.controllerId);
if (yours) {
if (getTargets().isEmpty()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
}
}
return yours;
case OPPONENT:
if (game.getPlayer(this.controllerId).hasOpponent(event.getPlayerId(), game)) {
if (getTargets().isEmpty()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
}
return true;
}
@ -97,9 +94,7 @@ public class BeginningOfDrawTriggeredAbility extends TriggeredAbilityImpl {
case NOT_YOU:
if (!this.controllerId.equals(event.getPlayerId())) {
if (getTargets().isEmpty()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
}
return true;
}
@ -110,9 +105,7 @@ public class BeginningOfDrawTriggeredAbility extends TriggeredAbilityImpl {
Permanent attachedTo = game.getPermanent(attachment.getAttachedTo());
if (attachedTo != null && attachedTo.getControllerId().equals(event.getPlayerId())) {
if (getTargets().isEmpty()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
}
return true;
}
@ -120,9 +113,7 @@ public class BeginningOfDrawTriggeredAbility extends TriggeredAbilityImpl {
break;
case ANY:
if (getTargets().isEmpty()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
}
this.getEffects().setTargetPointer(new FixedTarget(event.getPlayerId()));
}
return true;
}

View file

@ -24,8 +24,7 @@
* 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.ArrayList;
@ -34,6 +33,7 @@ import java.util.List;
import java.util.Set;
import mage.abilities.Mode;
import mage.constants.Outcome;
import mage.target.targetpointer.TargetPointer;
/**
*
@ -41,10 +41,11 @@ import mage.constants.Outcome;
*/
public class Effects extends ArrayList<Effect> {
public Effects() {}
public Effects() {
}
public Effects(final Effects effects) {
for (Effect effect: effects) {
for (Effect effect : effects) {
this.add(effect.copy());
}
}
@ -64,7 +65,7 @@ public class Effects extends ArrayList<Effect> {
public String getText(Mode mode) {
StringBuilder sbText = new StringBuilder();
String lastRule = null;
for (Effect effect: this) {
for (Effect effect : this) {
String endString = "";
String nextRule = effect.getText(mode);
if (nextRule != null) {
@ -72,7 +73,7 @@ public class Effects extends ArrayList<Effect> {
endString = " ";
} else if (nextRule.startsWith(",") || nextRule.startsWith(" ")) {
endString = "";
} else if (lastRule != null && lastRule.length()> 3) {
} else if (lastRule != null && lastRule.length() > 3) {
if (!lastRule.endsWith(".") && !lastRule.endsWith("<br>")) {
endString = ". ";
}
@ -84,19 +85,19 @@ public class Effects extends ArrayList<Effect> {
}
lastRule = nextRule;
}
if (lastRule != null && lastRule.length()> 3 &&
!lastRule.endsWith(".") &&
!lastRule.endsWith("\"") &&
!lastRule.startsWith("<b>Level ") &&
!lastRule.endsWith(".)") &&
!lastRule.endsWith("</i>") ) {
if (lastRule != null && lastRule.length() > 3
&& !lastRule.endsWith(".")
&& !lastRule.endsWith("\"")
&& !lastRule.startsWith("<b>Level ")
&& !lastRule.endsWith(".)")
&& !lastRule.endsWith("</i>")) {
sbText.append('.');
}
return sbText.toString();
}
public boolean hasOutcome(Outcome outcome) {
for (Effect effect: this) {
for (Effect effect : this) {
if (effect.getOutcome() == outcome) {
return true;
}
@ -106,7 +107,7 @@ public class Effects extends ArrayList<Effect> {
public List<Outcome> getOutcomes() {
Set<Outcome> outcomes = new HashSet<>();
for (Effect effect: this) {
for (Effect effect : this) {
outcomes.add(effect.getOutcome());
}
return new ArrayList<>(outcomes);
@ -114,11 +115,10 @@ public class Effects extends ArrayList<Effect> {
public int getOutcomeTotal() {
int total = 0;
for (Effect effect: this) {
for (Effect effect : this) {
if (effect.getOutcome().isGood()) {
total++;
}
else {
} else {
total--;
}
}
@ -126,8 +126,18 @@ public class Effects extends ArrayList<Effect> {
}
public void newId() {
for (Effect effect: this) {
for (Effect effect : this) {
effect.newId();
}
}
public void setTargetPointer(TargetPointer targetPointer) {
if (targetPointer == null) {
return;
}
for (Effect effect : this) {
effect.setTargetPointer(targetPointer.copy());
}
}
}

View file

@ -73,7 +73,7 @@ public class LoseLifeDefendingPlayerEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player defender = null;
Player defender;
if (attackerIsSource) {
defender = game.getPlayer(game.getCombat().getDefendingPlayerId(source.getSourceId(), game));
} else {

View file

@ -1,11 +1,15 @@
package mage.abilities.keyword;
import java.util.UUID;
import mage.abilities.common.BecomesBlockedTriggeredAbility;
import mage.abilities.effects.common.LoseLifeDefendingPlayerEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
public class AfflictAbility extends BecomesBlockedTriggeredAbility {
private int lifeLoss;
private final int lifeLoss;
@Override
public AfflictAbility copy() {
@ -13,11 +17,23 @@ public class AfflictAbility extends BecomesBlockedTriggeredAbility {
}
public AfflictAbility(int amount) {
super(new LoseLifeDefendingPlayerEffect(amount, true)
super(new LoseLifeTargetEffect(amount)
.setText("Afflict " + amount + " <i>(Whenever this creature becomes blocked, defending player loses " + amount + " life.)</i>"), false);
lifeLoss = amount;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (super.checkTrigger(event, game)) {
UUID defenderId = game.getCombat().getDefendingPlayerId(getSourceId(), game);
if (defenderId != null) {
this.getEffects().setTargetPointer(new FixedTarget(defenderId));
return true;
}
}
return false;
}
public AfflictAbility(final AfflictAbility afflictAbility) {
super(afflictAbility);
lifeLoss = afflictAbility.lifeLoss;

View file

@ -55,7 +55,6 @@ public class DarettiScrapSavantEmblem extends Emblem {
setName("Emblem Daretti");
this.setExpansionSetCodeForImage("C14");
this.getAbilities().add(new DarettiScrapSavantTriggeredAbility());
}
}
@ -87,9 +86,7 @@ class DarettiScrapSavantTriggeredAbility extends TriggeredAbilityImpl {
&& zEvent.getFromZone() == Zone.BATTLEFIELD
&& zEvent.getTarget().isArtifact()
&& zEvent.getTarget().getOwnerId().equals(this.controllerId)) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(zEvent.getTargetId()));
}
this.getEffects().setTargetPointer(new FixedTarget(zEvent.getTargetId()));
return true;
}
return false;