Merge origin/master

This commit is contained in:
Matt Oslan 2016-08-30 10:03:47 -04:00
commit 930430b2c2
37 changed files with 58298 additions and 28735 deletions

View file

@ -31,13 +31,13 @@ import mage.constants.CardType;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility; import mage.abilities.common.BeginningOfYourEndStepTriggeredAbility;
import mage.abilities.condition.common.OneControlledCreatureCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.CreateTokenEffect; import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.game.permanent.token.DemonToken; import mage.game.permanent.token.DemonToken;
import java.util.UUID; import java.util.UUID;
import mage.abilities.condition.common.CreatureCountCondition;
import mage.constants.TargetController;
/** /**
* @author noxx * @author noxx
@ -52,7 +52,7 @@ public class DemonicRising extends CardImpl {
// At the beginning of your end step, if you control exactly one creature, put a 5/5 black Demon creature token with flying onto the battlefield. // At the beginning of your end step, if you control exactly one creature, put a 5/5 black Demon creature token with flying onto the battlefield.
TriggeredAbility ability = new BeginningOfYourEndStepTriggeredAbility(new CreateTokenEffect(new DemonToken()), false); TriggeredAbility ability = new BeginningOfYourEndStepTriggeredAbility(new CreateTokenEffect(new DemonToken()), false);
this.addAbility(new ConditionalTriggeredAbility(ability, OneControlledCreatureCondition.getInstance(), ruleText)); this.addAbility(new ConditionalTriggeredAbility(ability, new CreatureCountCondition(1, TargetController.YOU), ruleText));
} }
public DemonicRising(final DemonicRising card) { public DemonicRising(final DemonicRising card) {

View file

@ -30,7 +30,7 @@ package mage.sets.avacynrestored;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.OneControlledCreatureCondition; import mage.abilities.condition.common.CreatureCountCondition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
@ -41,6 +41,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
/** /**
@ -56,10 +57,10 @@ public class HomicidalSeclusion extends CardImpl {
// As long as you control exactly one creature, that creature gets +3/+1 and has lifelink. // As long as you control exactly one creature, that creature gets +3/+1 and has lifelink.
ContinuousEffect boostEffect = new BoostControlledEffect(3, 1, Duration.WhileOnBattlefield); ContinuousEffect boostEffect = new BoostControlledEffect(3, 1, Duration.WhileOnBattlefield);
Effect effect = new ConditionalContinuousEffect(boostEffect, new OneControlledCreatureCondition(), rule); Effect effect = new ConditionalContinuousEffect(boostEffect, new CreatureCountCondition(1, TargetController.YOU), rule);
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
ContinuousEffect lifelinkEffect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield); ContinuousEffect lifelinkEffect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield);
effect = new ConditionalContinuousEffect(lifelinkEffect, new OneControlledCreatureCondition(), "and has lifelink"); effect = new ConditionalContinuousEffect(lifelinkEffect, new CreatureCountCondition(1, TargetController.YOU), "and has lifelink");
ability.addEffect(effect); ability.addEffect(effect);
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -30,7 +30,6 @@ package mage.sets.avacynrestored;
import mage.constants.*; import mage.constants.*;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.OneControlledCreatureCondition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
@ -41,8 +40,8 @@ import mage.abilities.keyword.IntimidateAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID; import java.util.UUID;
import mage.abilities.condition.common.CreatureCountCondition;
/** /**
* @author noxx * @author noxx
@ -56,7 +55,6 @@ public class PredatorsGambit extends CardImpl {
this.expansionSetCode = "AVR"; this.expansionSetCode = "AVR";
this.subtype.add("Aura"); this.subtype.add("Aura");
// Enchant creature // Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent(); TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
@ -70,7 +68,7 @@ public class PredatorsGambit extends CardImpl {
// Enchanted creature has intimidate as long as its controller controls no other creatures. // Enchanted creature has intimidate as long as its controller controls no other creatures.
ContinuousEffect effect = new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.AURA); ContinuousEffect effect = new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.AURA);
ConditionalContinuousEffect intimidate = new ConditionalContinuousEffect(effect, new OneControlledCreatureCondition(), rule); ConditionalContinuousEffect intimidate = new ConditionalContinuousEffect(effect, new CreatureCountCondition(1, TargetController.YOU), rule);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, intimidate)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, intimidate));
} }

View file

@ -28,19 +28,13 @@
package mage.sets.bornofthegods; package mage.sets.bornofthegods;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.effects.common.ShuffleIntoLibraryTargetEffect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
/** /**
@ -49,11 +43,10 @@ import mage.target.TargetPermanent;
*/ */
public class UnravelTheAEther extends CardImpl { public class UnravelTheAEther extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(); private static final FilterPermanent filter = new FilterPermanent("artifact or enchantment");
static { static {
filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.ENCHANTMENT)));
new CardTypePredicate(CardType.ENCHANTMENT)));
} }
public UnravelTheAEther(UUID ownerId) { public UnravelTheAEther(UUID ownerId) {
@ -61,9 +54,8 @@ public class UnravelTheAEther extends CardImpl {
this.expansionSetCode = "BNG"; this.expansionSetCode = "BNG";
// Choose target artifact or enchantment. Its owner shuffles it into his or her library. // Choose target artifact or enchantment. Its owner shuffles it into his or her library.
this.getSpellAbility().addEffect(new UnravelTheAEtherShuffleIntoLibraryEffect()); this.getSpellAbility().addEffect(new ShuffleIntoLibraryTargetEffect());
Target target = new TargetPermanent(1, 1, filter, false); this.getSpellAbility().addTarget(new TargetPermanent(1, 1, filter, true));
this.getSpellAbility().addTarget(target);
} }
public UnravelTheAEther(final UnravelTheAEther card) { public UnravelTheAEther(final UnravelTheAEther card) {
@ -75,32 +67,3 @@ public class UnravelTheAEther extends CardImpl {
return new UnravelTheAEther(this); return new UnravelTheAEther(this);
} }
} }
class UnravelTheAEtherShuffleIntoLibraryEffect extends OneShotEffect {
public UnravelTheAEtherShuffleIntoLibraryEffect() {
super(Outcome.Detriment);
this.staticText = "Choose target artifact or enchantment. Its owner shuffles it into his or her library";
}
public UnravelTheAEtherShuffleIntoLibraryEffect(final UnravelTheAEtherShuffleIntoLibraryEffect effect) {
super(effect);
}
@Override
public UnravelTheAEtherShuffleIntoLibraryEffect copy() {
return new UnravelTheAEtherShuffleIntoLibraryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) {
if (permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true)) {
game.getPlayer(permanent.getOwnerId()).shuffleLibrary(source, game);
return true;
}
}
return false;
}
}

View file

@ -28,26 +28,21 @@
package mage.sets.commander2014; package mage.sets.commander2014;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
import mage.abilities.common.CanBeYourCommanderAbility; import mage.abilities.common.CanBeYourCommanderAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.common.StaticValue; import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.common.GetEmblemEffect; import mage.abilities.effects.common.GetEmblemEffect;
import mage.abilities.effects.common.LookLibraryAndPickControllerEffect; import mage.abilities.effects.common.LookLibraryAndPickControllerEffect;
import mage.abilities.effects.common.UntapTargetEffect; import mage.abilities.effects.common.UntapTargetEffect;
import mage.abilities.effects.common.continuous.ActivateAbilitiesAnyTimeYouCouldCastInstantEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.game.Game;
import mage.game.command.Emblem; import mage.game.command.Emblem;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
@ -96,42 +91,6 @@ class TeferiTemporalArchmageEmblem extends Emblem {
// "You may activate loyalty abilities of planeswalkers you control on any player's turn any time you could cast an instant." // "You may activate loyalty abilities of planeswalkers you control on any player's turn any time you could cast an instant."
public TeferiTemporalArchmageEmblem() { public TeferiTemporalArchmageEmblem() {
this.setName("EMBLEM: Teferi, Temporal Archmage"); this.setName("EMBLEM: Teferi, Temporal Archmage");
this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new TeferiTemporalArchmageAsThoughEffect())); this.getAbilities().add(new SimpleStaticAbility(Zone.COMMAND, new ActivateAbilitiesAnyTimeYouCouldCastInstantEffect(LoyaltyAbility.class, "loyalty abilities of planeswalkers you control on any player's turn")));
} }
} }
class TeferiTemporalArchmageAsThoughEffect extends AsThoughEffectImpl {
public TeferiTemporalArchmageAsThoughEffect() {
super(AsThoughEffectType.ACTIVATE_AS_INSTANT, Duration.EndOfGame, Outcome.Benefit);
staticText = "You may activate loyalty abilities of planeswalkers you control on any player's turn any time you could cast an instant";
}
public TeferiTemporalArchmageAsThoughEffect(final TeferiTemporalArchmageAsThoughEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public TeferiTemporalArchmageAsThoughEffect copy() {
return new TeferiTemporalArchmageAsThoughEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game) {
if (affectedAbility.getControllerId().equals(source.getControllerId()) && affectedAbility instanceof LoyaltyAbility) {
return true;
}
return false;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return false; // Not used
}
}

View file

@ -29,18 +29,13 @@ package mage.sets.darksteel;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.common.continuous.ActivateAbilitiesAnyTimeYouCouldCastInstantEffect;
import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game;
/** /**
* *
@ -57,7 +52,7 @@ public class LeoninShikari extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// You may activate equip abilities any time you could cast an instant. // You may activate equip abilities any time you could cast an instant.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new LeoninShikariEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ActivateAbilitiesAnyTimeYouCouldCastInstantEffect(EquipAbility.class, "equip abilities")));
} }
public LeoninShikari(final LeoninShikari card) { public LeoninShikari(final LeoninShikari card) {
@ -69,35 +64,3 @@ public class LeoninShikari extends CardImpl {
return new LeoninShikari(this); return new LeoninShikari(this);
} }
} }
class LeoninShikariEffect extends AsThoughEffectImpl {
LeoninShikariEffect() {
super(AsThoughEffectType.ACTIVATE_AS_INSTANT, Duration.EndOfGame, Outcome.Benefit);
staticText = "You may activate equip abilities any time you could cast an instant";
}
LeoninShikariEffect(final LeoninShikariEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public LeoninShikariEffect copy() {
return new LeoninShikariEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game) {
return affectedAbility.getControllerId().equals(source.getControllerId()) && affectedAbility instanceof EquipAbility;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return false; // Not used
}
}

View file

@ -30,7 +30,7 @@ package mage.sets.dragonsoftarkir;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.OneControlledCreatureCondition; import mage.abilities.condition.common.CreatureCountCondition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
@ -42,6 +42,7 @@ import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
@ -57,14 +58,16 @@ public class DeadlyWanderings extends CardImpl {
// As long as you control exactly one creature, that creature gets +2/+0 and has deathtouch and lifelink. // As long as you control exactly one creature, that creature gets +2/+0 and has deathtouch and lifelink.
ContinuousEffect boostEffect = new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield); ContinuousEffect boostEffect = new BoostControlledEffect(2, 0, Duration.WhileOnBattlefield);
Effect effect = new ConditionalContinuousEffect(boostEffect, new OneControlledCreatureCondition(), Effect effect = new ConditionalContinuousEffect(boostEffect, new CreatureCountCondition(1, TargetController.YOU),
"As long as you control exactly one creature, that creature gets +2/+0"); "As long as you control exactly one creature, that creature gets +2/+0");
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect); Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
ContinuousEffect deathtouchEffect = new GainAbilityControlledEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent()); ContinuousEffect deathtouchEffect = new GainAbilityControlledEffect(DeathtouchAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent());
effect = new ConditionalContinuousEffect(deathtouchEffect, new OneControlledCreatureCondition(), "and has deathtouch"); effect = new ConditionalContinuousEffect(deathtouchEffect, new CreatureCountCondition(1, TargetController.YOU),
"and has deathtouch");
ability.addEffect(effect); ability.addEffect(effect);
ContinuousEffect lifelinkEffect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent()); ContinuousEffect lifelinkEffect = new GainAbilityControlledEffect(LifelinkAbility.getInstance(), Duration.WhileOnBattlefield, new FilterCreaturePermanent());
effect = new ConditionalContinuousEffect(lifelinkEffect, new OneControlledCreatureCondition(), "and lifelink"); effect = new ConditionalContinuousEffect(lifelinkEffect, new CreatureCountCondition(1, TargetController.YOU),
"and lifelink");
ability.addEffect(effect); ability.addEffect(effect);
this.addAbility(ability); this.addAbility(ability);
} }

View file

@ -38,7 +38,7 @@ import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.OneControlledCreatureCondition; import mage.abilities.condition.common.CreatureCountCondition;
import mage.abilities.costs.mana.ManaCosts; import mage.abilities.costs.mana.ManaCosts;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalRestrictionEffect; import mage.abilities.decorator.ConditionalRestrictionEffect;
@ -53,6 +53,7 @@ import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -73,7 +74,7 @@ public class JeskaiInfiltrator extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Jeskai Infiltrator can't be blocked as long as you control no other creatures. // Jeskai Infiltrator can't be blocked as long as you control no other creatures.
Effect effect = new ConditionalRestrictionEffect(new CantBeBlockedSourceEffect(), new OneControlledCreatureCondition()); Effect effect = new ConditionalRestrictionEffect(new CantBeBlockedSourceEffect(), new CreatureCountCondition(1, TargetController.YOU));
effect.setText("{this} can't be blocked as long as you control no other creatures"); effect.setText("{this} can't be blocked as long as you control no other creatures");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));

View file

@ -32,7 +32,7 @@ import mage.abilities.Ability;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.condition.common.NoCreatureCondition; import mage.abilities.condition.common.CreatureCountCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.SacrificeEffect; import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.SacrificeSourceEffect;
@ -62,13 +62,12 @@ public class CallToTheGrave extends CardImpl {
super(ownerId, 85, "Call to the Grave", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}"); super(ownerId, 85, "Call to the Grave", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{4}{B}");
this.expansionSetCode = "M12"; this.expansionSetCode = "M12";
// At the beginning of each player's upkeep, that player sacrifices a non-Zombie creature. // At the beginning of each player's upkeep, that player sacrifices a non-Zombie creature.
Ability ability = new BeginningOfUpkeepTriggeredAbility(new SacrificeEffect(filter, 1, "that player "), TargetController.ANY, false); Ability ability = new BeginningOfUpkeepTriggeredAbility(new SacrificeEffect(filter, 1, "that player "), TargetController.ANY, false);
this.addAbility(ability); this.addAbility(ability);
// At the beginning of the end step, if no creatures are on the battlefield, sacrifice Call to the Grave. // At the beginning of the end step, if no creatures are on the battlefield, sacrifice Call to the Grave.
TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()); TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect());
this.addAbility(new ConditionalTriggeredAbility(triggered, new NoCreatureCondition(), ruleText)); this.addAbility(new ConditionalTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText));
} }
public CallToTheGrave(final CallToTheGrave card) { public CallToTheGrave(final CallToTheGrave card) {

View file

@ -29,7 +29,7 @@ package mage.sets.magic2014;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
@ -45,8 +45,6 @@ import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate; import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.players.Player; import mage.players.Player;
/** /**
@ -66,12 +64,11 @@ public class PathOfBravery extends CardImpl {
super(ownerId, 26, "Path of Bravery", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}"); super(ownerId, 26, "Path of Bravery", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
this.expansionSetCode = "M14"; this.expansionSetCode = "M14";
// As long as your life total is greater than or equal to your starting life total, creatures you control get +1/+1. // As long as your life total is greater than or equal to your starting life total, creatures you control get +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true), new LifeCondition(), rule))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filter, true), new LifeCondition(), rule)));
// Whenever one or more creatures you control attack, you gain life equal to the number of attacking creatures. // Whenever one or more creatures you control attack, you gain life equal to the number of attacking creatures.
this.addAbility(new PathOfBraveryTriggeredAbility()); this.addAbility(new AttacksWithCreaturesTriggeredAbility(new PathOfBraveryEffect(), 1));
} }
@ -103,37 +100,6 @@ class LifeCondition implements Condition {
} }
} }
class PathOfBraveryTriggeredAbility extends TriggeredAbilityImpl {
public PathOfBraveryTriggeredAbility() {
super(Zone.BATTLEFIELD, new PathOfBraveryEffect(), false);
}
public PathOfBraveryTriggeredAbility(final PathOfBraveryTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return !game.getCombat().noAttackers() && event.getPlayerId().equals(controllerId);
}
@Override
public PathOfBraveryTriggeredAbility copy() {
return new PathOfBraveryTriggeredAbility(this);
}
@Override
public String getRule() {
return "Whenever one or more creatures you control attack, " + super.getRule();
}
}
class PathOfBraveryEffect extends OneShotEffect { class PathOfBraveryEffect extends OneShotEffect {
private int attackers; private int attackers;

View file

@ -28,16 +28,11 @@
package mage.sets.magic2015; package mage.sets.magic2015;
import java.util.UUID; import java.util.UUID;
import mage.abilities.TriggeredAbilityImpl; import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
/** /**
* *
@ -49,9 +44,8 @@ public class MilitaryIntelligence extends CardImpl {
super(ownerId, 69, "Military Intelligence", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}"); super(ownerId, 69, "Military Intelligence", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{1}{U}");
this.expansionSetCode = "M15"; this.expansionSetCode = "M15";
// Whenever you attack with two or more creatures, draw a card. // Whenever you attack with two or more creatures, draw a card.
this.addAbility(new MilitaryIntelligenceTriggeredAbility(new DrawCardSourceControllerEffect(1))); this.addAbility(new AttacksWithCreaturesTriggeredAbility(new DrawCardSourceControllerEffect(1), 2));
} }
public MilitaryIntelligence(final MilitaryIntelligence card) { public MilitaryIntelligence(final MilitaryIntelligence card) {
@ -63,34 +57,3 @@ public class MilitaryIntelligence extends CardImpl {
return new MilitaryIntelligence(this); return new MilitaryIntelligence(this);
} }
} }
class MilitaryIntelligenceTriggeredAbility extends TriggeredAbilityImpl {
public MilitaryIntelligenceTriggeredAbility(Effect effect) {
super(Zone.BATTLEFIELD, effect);
}
public MilitaryIntelligenceTriggeredAbility(final MilitaryIntelligenceTriggeredAbility ability) {
super(ability);
}
@Override
public MilitaryIntelligenceTriggeredAbility copy() {
return new MilitaryIntelligenceTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return game.getCombat().getAttackers().size() >= 2 && game.getCombat().getAttackerId().equals(getControllerId());
}
@Override
public String getRule() {
return new StringBuilder("Whenever you attack with two or more creatures, ").append(super.getRule()).toString() ;
}
}

View file

@ -29,27 +29,25 @@ package mage.sets.mirrodin;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.EquippedSourceCondition; import mage.abilities.condition.common.EquippedSourceCondition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.cost.CostModificationEffectImpl; import mage.abilities.effects.common.cost.AbilitiesCostReductionControllerEffect;
import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.*; import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate; import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.util.CardUtil;
/** /**
* *
* @author Jason E. Wall * @author Jason E. Wall
*
*/ */
public class AuriokSteelshaper extends CardImpl { public class AuriokSteelshaper extends CardImpl {
private static final FilterCreaturePermanent soldiersOrKnights = new FilterCreaturePermanent(); private static final FilterCreaturePermanent soldiersOrKnights = new FilterCreaturePermanent();
static { static {
@ -68,7 +66,7 @@ public class AuriokSteelshaper extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Equip costs you pay cost {1} less. // Equip costs you pay cost {1} less.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AuriokSteelshaperCostReductionEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AbilitiesCostReductionControllerEffect(EquipAbility.class, "Equip")));
// As long as Auriok Steelshaper is equipped, each creature you control that's a Soldier or a Knight gets +1/+1. // As long as Auriok Steelshaper is equipped, each creature you control that's a Soldier or a Knight gets +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
@ -87,32 +85,3 @@ public class AuriokSteelshaper extends CardImpl {
return new AuriokSteelshaper(this); return new AuriokSteelshaper(this);
} }
} }
class AuriokSteelshaperCostReductionEffect extends CostModificationEffectImpl {
public AuriokSteelshaperCostReductionEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
staticText = "Equip costs you pay cost {1} less";
}
public AuriokSteelshaperCostReductionEffect(AuriokSteelshaperCostReductionEffect effect) {
super(effect);
}
@java.lang.Override
public AuriokSteelshaperCostReductionEffect copy() {
return new AuriokSteelshaperCostReductionEffect(this);
}
@java.lang.Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
CardUtil.reduceCost(abilityToModify, 1);
return true;
}
@java.lang.Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify.getControllerId().equals(source.getControllerId()) &&
(abilityToModify instanceof EquipAbility);
}
}

View file

@ -29,18 +29,12 @@ package mage.sets.morningtide;
import java.util.UUID; import java.util.UUID;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.abilities.effects.common.ShuffleIntoLibraryTargetEffect;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.filter.FilterPermanent; import mage.filter.FilterPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
/** /**
@ -49,21 +43,18 @@ import mage.target.TargetPermanent;
*/ */
public class Deglamer extends CardImpl { public class Deglamer extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(); private static final FilterPermanent filter = new FilterPermanent("artifact or enchantment");
static { static {
filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), filter.add(Predicates.or(new CardTypePredicate(CardType.ARTIFACT), new CardTypePredicate(CardType.ENCHANTMENT)));
new CardTypePredicate(CardType.ENCHANTMENT)));
} }
public Deglamer(UUID ownerId) { public Deglamer(UUID ownerId) {
super(ownerId, 118, "Deglamer", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{G}"); super(ownerId, 118, "Deglamer", Rarity.COMMON, new CardType[]{CardType.INSTANT}, "{1}{G}");
this.expansionSetCode = "MOR"; this.expansionSetCode = "MOR";
// Choose target artifact or enchantment. Its owner shuffles it into his or her library. // Choose target artifact or enchantment. Its owner shuffles it into his or her library.
this.getSpellAbility().addEffect(new DeglamerShuffleIntoLibraryEffect()); this.getSpellAbility().addEffect(new ShuffleIntoLibraryTargetEffect());
Target target = new TargetPermanent(1,1,filter,true); this.getSpellAbility().addTarget(new TargetPermanent(1, 1, filter, true));
this.getSpellAbility().addTarget(target);
} }
public Deglamer(final Deglamer card) { public Deglamer(final Deglamer card) {
@ -74,33 +65,4 @@ public class Deglamer extends CardImpl {
public Deglamer copy() { public Deglamer copy() {
return new Deglamer(this); return new Deglamer(this);
} }
} }
class DeglamerShuffleIntoLibraryEffect extends OneShotEffect {
public DeglamerShuffleIntoLibraryEffect() {
super(Outcome.Detriment);
this.staticText = "Choose target artifact or enchantment. Its owner shuffles it into his or her library";
}
public DeglamerShuffleIntoLibraryEffect(final DeglamerShuffleIntoLibraryEffect effect) {
super(effect);
}
@Override
public DeglamerShuffleIntoLibraryEffect copy() {
return new DeglamerShuffleIntoLibraryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) {
if (permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true) ) {
game.getPlayer(permanent.getOwnerId()).shuffleLibrary(source, game);
return true;
}
}
return false;
}
}

View file

@ -95,7 +95,9 @@ class GratuitousViolenceReplacementEffect extends ReplacementEffectImpl {
@Override @Override
public boolean applies(GameEvent event, Ability source, Game game) { public boolean applies(GameEvent event, Ability source, Game game) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId()); Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
return permanent != null && permanent.getControllerId().equals(source.getControllerId()); return permanent != null
&& permanent.getCardType().contains(CardType.CREATURE)
&& permanent.getControllerId().equals(source.getControllerId());
} }
@Override @Override

View file

@ -31,7 +31,7 @@ import java.util.UUID;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.NoCreatureCondition; import mage.abilities.condition.common.CreatureCountCondition;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DamageEverythingEffect; import mage.abilities.effects.common.DamageEverythingEffect;
@ -39,6 +39,7 @@ import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
@ -47,7 +48,7 @@ import mage.game.events.GameEvent;
* @author fireshoes * @author fireshoes
*/ */
public class Pyrohemia extends CardImpl { public class Pyrohemia extends CardImpl {
private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pyrohemia."; private static final String ruleText = "At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pyrohemia.";
public Pyrohemia(UUID ownerId) { public Pyrohemia(UUID ownerId) {
@ -56,8 +57,8 @@ public class Pyrohemia extends CardImpl {
// At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pyrohemia. // At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pyrohemia.
TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()); TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect());
this.addAbility(new ConditionalTriggeredAbility(triggered, new NoCreatureCondition(), ruleText)); this.addAbility(new ConditionalTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText));
// {R}: Pyrohemia deals 1 damage to each creature and each player. // {R}: Pyrohemia deals 1 damage to each creature and each player.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageEverythingEffect(1), new ManaCostsImpl("{R}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageEverythingEffect(1), new ManaCostsImpl("{R}")));
} }

View file

@ -34,6 +34,7 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LookLibraryTopCardTargetPlayerEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.Cards; import mage.cards.Cards;
@ -62,7 +63,7 @@ public class LurkingInformant extends CardImpl {
// <i>({UB} can be paid with either {U} or {B}.)</i> // <i>({UB} can be paid with either {U} or {B}.)</i>
// {2}, {tap}: Look at the top card of target player's library. You may put that card into that player's graveyard. // {2}, {tap}: Look at the top card of target player's library. You may put that card into that player's graveyard.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LurkingInformantEffect(), new GenericManaCost(2)); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new LookLibraryTopCardTargetPlayerEffect(1, true), new GenericManaCost(2));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addTarget(new TargetPlayer()); ability.addTarget(new TargetPlayer());
this.addAbility(ability); this.addAbility(ability);
@ -77,42 +78,3 @@ public class LurkingInformant extends CardImpl {
return new LurkingInformant(this); return new LurkingInformant(this);
} }
} }
class LurkingInformantEffect extends OneShotEffect {
public LurkingInformantEffect() {
super(Outcome.Detriment);
staticText = "Look at the top card of target player's library. You may put that card into his or her graveyard";
}
public LurkingInformantEffect(final LurkingInformantEffect effect) {
super(effect);
}
@Override
public LurkingInformantEffect copy() {
return new LurkingInformantEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player player = game.getPlayer(source.getFirstTarget());
if (controller != null && player != null) {
Card card = player.getLibrary().getFromTop(game);
if (card != null) {
Cards cards = new CardsImpl();
cards.add(card);
controller.lookAtCards("Lurking Informant", cards, game);
if (controller.chooseUse(outcome, "Do you wish to put card into the player's graveyard?", source, game)) {
controller.moveCardToGraveyardWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
} else {
game.informPlayers(controller.getLogName() + " puts the card back on top of the library.");
}
return true;
}
}
return false;
}
}

View file

@ -28,18 +28,10 @@
package mage.sets.starter1999; package mage.sets.starter1999;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.effects.common.LookLibraryTopCardTargetPlayerEffect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetPlayer; import mage.target.TargetPlayer;
/** /**
@ -53,7 +45,7 @@ public class EyeSpy extends CardImpl {
this.expansionSetCode = "S99"; this.expansionSetCode = "S99";
// Look at the top card of target player's library. You may put that card into his or her graveyard. // Look at the top card of target player's library. You may put that card into his or her graveyard.
this.getSpellAbility().addEffect(new EyeSpyEffect()); this.getSpellAbility().addEffect(new LookLibraryTopCardTargetPlayerEffect(1, true));
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
} }
@ -66,42 +58,3 @@ public class EyeSpy extends CardImpl {
return new EyeSpy(this); return new EyeSpy(this);
} }
} }
class EyeSpyEffect extends OneShotEffect {
public EyeSpyEffect() {
super(Outcome.Detriment);
staticText = "Look at the top card of target player's library. You may put that card into his or her graveyard";
}
public EyeSpyEffect(final EyeSpyEffect effect) {
super(effect);
}
@Override
public EyeSpyEffect copy() {
return new EyeSpyEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player player = game.getPlayer(source.getFirstTarget());
if (controller != null && player != null) {
Card card = player.getLibrary().getFromTop(game);
if (card != null) {
Cards cards = new CardsImpl();
cards.add(card);
controller.lookAtCards("Eye Spy", cards, game);
if (controller.chooseUse(outcome, "Do you wish to put card into the player's graveyard?", source, game)) {
controller.moveCardToGraveyardWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
} else {
game.informPlayers(controller.getLogName() + " puts the card back on top of the library.");
}
return true;
}
}
return false;
}
}

View file

@ -33,7 +33,7 @@ import mage.constants.CardType;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.NoCreatureOpponentCondition; import mage.abilities.condition.common.CreatureCountCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DamageControllerEffect; import mage.abilities.effects.common.DamageControllerEffect;
import mage.abilities.keyword.FirstStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility;
@ -58,10 +58,12 @@ public class Kezzerdrix extends CardImpl {
// First strike // First strike
this.addAbility(FirstStrikeAbility.getInstance()); this.addAbility(FirstStrikeAbility.getInstance());
// At the beginning of your upkeep, if your opponents control no creatures, Kezzerdrix deals 4 damage to you. // At the beginning of your upkeep, if your opponents control no creatures, Kezzerdrix deals 4 damage to you.
ConditionalTriggeredAbility ability = new ConditionalTriggeredAbility(new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DamageControllerEffect(4), TargetController.YOU, false), NoCreatureOpponentCondition.getInstance(), "At the beginning of your upkeep, if your opponents control no creatures, {this} deals 4 damage to you."); this.addAbility(new ConditionalTriggeredAbility(
this.addAbility(ability); new BeginningOfUpkeepTriggeredAbility(Zone.BATTLEFIELD, new DamageControllerEffect(4), TargetController.YOU, false),
new CreatureCountCondition(0, TargetController.OPPONENT),
"At the beginning of your upkeep, if your opponents control no creatures, {this} deals 4 damage to you."));
} }
public Kezzerdrix(final Kezzerdrix card) { public Kezzerdrix(final Kezzerdrix card) {

View file

@ -27,6 +27,7 @@
*/ */
package mage.sets.theros; package mage.sets.theros;
import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -55,21 +56,22 @@ public class ErebossEmissary extends CardImpl {
super(ownerId, 86, "Erebos's Emissary", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{B}"); super(ownerId, 86, "Erebos's Emissary", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{3}{B}");
this.expansionSetCode = "THS"; this.expansionSetCode = "THS";
this.subtype.add("Snake"); this.subtype.add("Snake");
this.power = new MageInt(3); this.power = new MageInt(3);
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Bestow {5}{B} // Bestow {5}{B}
this.addAbility(new BestowAbility(this, "{5}{B}")); this.addAbility(new BestowAbility(this, "{5}{B}"));
// Discard a creature card: Erebos's Emissary gets +2/+2 until end of turn. If Erebos's Emissary is an Aura, enchanted creature gets +2/+2 until end of turn instead. // Discard a creature card: Erebos's Emissary gets +2/+2 until end of turn. If Erebos's Emissary is an Aura, enchanted creature gets +2/+2 until end of turn instead.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
new BoostEnchantedEffect(2,2, Duration.EndOfTurn), new BoostEnchantedEffect(2, 2, Duration.EndOfTurn),
new BoostSourceEffect(2,2, Duration.EndOfTurn), new BoostSourceEffect(2, 2, Duration.EndOfTurn),
new SourceHasSubtypeCondition("Aura"), new SourceHasSubtypeCondition(Arrays.asList("Aura")),
"{this} gets +2/+2 until end of turn. If Erebos's Emissary is an Aura, enchanted creature gets +2/+2 until end of turn instead"), "{this} gets +2/+2 until end of turn. If Erebos's Emissary is an Aura, enchanted creature gets +2/+2 until end of turn instead"),
new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard())))); new DiscardTargetCost(new TargetCardInHand(new FilterCreatureCard()))));
// Enchanted creature gets +3/+3 // Enchanted creature gets +3/+3
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3,3, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(3, 3, Duration.WhileOnBattlefield)));
} }
public ErebossEmissary(final ErebossEmissary card) { public ErebossEmissary(final ErebossEmissary card) {

View file

@ -34,12 +34,13 @@ import mage.constants.Rarity;
import mage.abilities.TriggeredAbility; import mage.abilities.TriggeredAbility;
import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.condition.common.NoCreatureCondition; import mage.abilities.condition.common.CreatureCountCondition;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalTriggeredAbility; import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.DamageEverythingEffect; import mage.abilities.effects.common.DamageEverythingEffect;
import mage.abilities.effects.common.SacrificeSourceEffect; import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.constants.TargetController;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
@ -55,10 +56,9 @@ public class Pestilence extends CardImpl {
super(ownerId, 147, "Pestilence", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); super(ownerId, 147, "Pestilence", Rarity.COMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}");
this.expansionSetCode = "USG"; this.expansionSetCode = "USG";
// At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pestilence. // At the beginning of the end step, if no creatures are on the battlefield, sacrifice Pestilence.
TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect()); TriggeredAbility triggered = new OnEventTriggeredAbility(GameEvent.EventType.END_TURN_STEP_PRE, "beginning of the end step", true, new SacrificeSourceEffect());
this.addAbility(new ConditionalTriggeredAbility(triggered, new NoCreatureCondition(), ruleText)); this.addAbility(new ConditionalTriggeredAbility(triggered, new CreatureCountCondition(0, TargetController.ANY), ruleText));
// {B}: Pestilence deals 1 damage to each creature and each player. // {B}: Pestilence deals 1 damage to each creature and each player.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageEverythingEffect(1), new ManaCostsImpl("{B}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new DamageEverythingEffect(1), new ManaCostsImpl("{B}")));

View file

@ -7,6 +7,7 @@ package org.mage.test.cards.abilities.keywords;
import mage.constants.PhaseStep; import mage.constants.PhaseStep;
import mage.constants.Zone; import mage.constants.Zone;
import org.junit.Ignore;
import org.junit.Test; import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase; import org.mage.test.serverside.base.CardTestPlayerBase;
@ -16,9 +17,9 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
*/ */
public class ProwlTest extends CardTestPlayerBase { public class ProwlTest extends CardTestPlayerBase {
@Ignore // have not figured out how to have the test API cast a card using Prowl yet
@Test @Test
public void testBasicProwlCasting() { public void testBasicProwlCasting() {
// Auntie's Snitch {2}{B} Creature Goblin Rogue (3/1) // Auntie's Snitch {2}{B} Creature Goblin Rogue (3/1)
// Auntie's Snitch can't block. // Auntie's Snitch can't block.
// Prowl {1}{B} (You may cast this for its prowl cost if you dealt combat damage to a player this turn with a Goblin or Rogue.) // Prowl {1}{B} (You may cast this for its prowl cost if you dealt combat damage to a player this turn with a Goblin or Rogue.)
@ -46,6 +47,7 @@ public class ProwlTest extends CardTestPlayerBase {
* Reported bug: Prowl is not taking into consideration other cost reducing effects. For instance Goblin Warchief * Reported bug: Prowl is not taking into consideration other cost reducing effects. For instance Goblin Warchief
* does not reduce the Prowl cost of other Goblin cards with Prowl ability. * does not reduce the Prowl cost of other Goblin cards with Prowl ability.
*/ */
@Ignore // have not figured out how to have the test API cast a card using Prowl yet
@Test @Test
public void testProwlWithCostDiscount() { public void testProwlWithCostDiscount() {

View file

@ -0,0 +1,56 @@
package org.mage.test.cards.single;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author cg5
*/
public class GratuitousViolenceTest extends CardTestPlayerBase {
@Test
public void testDoublesDamageFromCreatures() {
// Enchantment: If a creature you control would deal damage to a creature
// or player, it deals double that damage to that creature or player instead.
addCard(Zone.BATTLEFIELD, playerA, "Gratuitous Violence");
addCard(Zone.BATTLEFIELD, playerA, "Elvish Visionary"); // 1/1
attack(1, playerA, "Elvish Visionary");
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerB, 18);
}
@Test
public void testIgnoresNonCreatures() {
// Legendary Enchantment - 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.
addCard(Zone.BATTLEFIELD, playerA, "Honden of Infinite Rage");
addCard(Zone.BATTLEFIELD, playerA, "Gratuitous Violence");
addTarget(playerA, playerB);
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
execute();
// Honden should deal 1 damage at upkeep (since playerA only
// has one Shrine). GV should not double this.
assertLife(playerB, 19);
}
@Test
public void testIgnoresInstants() {
addCard(Zone.BATTLEFIELD, playerA, "Gratuitous Violence");
addCard(Zone.BATTLEFIELD, playerA, "Mountain");
addCard(Zone.HAND, playerA, "Lightning Bolt");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Lightning Bolt", playerB);
setStopAt(1, PhaseStep.POSTCOMBAT_MAIN);
execute();
assertLife(playerB, 17);
}
}

View file

@ -0,0 +1,71 @@
/*
* 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.
*/
package mage.abilities.common;
import java.util.UUID;
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;
/**
*
* @author Styxo
*/
public class AttacksWithCreaturesTriggeredAbility extends TriggeredAbilityImpl {
private FilterCreaturePermanent filter;
private int minAttackers;
public AttacksWithCreaturesTriggeredAbility(Effect effect, int minAttackers) {
this(effect, minAttackers, new FilterCreaturePermanent("creatures"));
}
public AttacksWithCreaturesTriggeredAbility(Effect effect, int minAttackers, FilterCreaturePermanent filter) {
super(Zone.BATTLEFIELD, effect);
this.filter = filter;
this.minAttackers = minAttackers;
}
public AttacksWithCreaturesTriggeredAbility(final AttacksWithCreaturesTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
this.minAttackers = ability.minAttackers;
}
@Override
public AttacksWithCreaturesTriggeredAbility copy() {
return new AttacksWithCreaturesTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DECLARED_ATTACKERS;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
int attackerCount = 0;
for (UUID attacker : game.getCombat().getAttackers()) {
if (filter.match(game.getPermanent(attacker), game)) {
attackerCount++;
}
}
return attackerCount >= minAttackers && game.getCombat().getAttackerId().equals(getControllerId());
}
@Override
public String getRule() {
StringBuilder sb = new StringBuilder("Whenever you attack with " + minAttackers + " or more ");
sb.append(filter.getMessage());
sb.append(", ");
sb.append(super.getRule());
return sb.toString();
}
}

View file

@ -0,0 +1,82 @@
/*
* 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.
*/
package mage.abilities.condition.common;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
/**
*
* @author Styxo
*/
public class CreatureCountCondition implements Condition {
private FilterCreaturePermanent filter;
private int creatureCount;
private TargetController targetController;
public CreatureCountCondition(FilterCreaturePermanent filter, int creatureCount, TargetController targetController) {
this.filter = filter;
this.creatureCount = creatureCount;
this.targetController = targetController;
}
public CreatureCountCondition(int creatureCount, TargetController targetController) {
this.filter = new FilterCreaturePermanent();
this.creatureCount = creatureCount;
this.targetController = targetController;
}
@Override
public boolean apply(Game game, Ability source) {
switch (targetController) {
case YOU:
return game.getBattlefield().countAll(filter, source.getControllerId(), game) == creatureCount;
case OPPONENT:
for (UUID opponent : game.getOpponents(source.getControllerId())) {
if (game.getBattlefield().countAll(filter, opponent, game) != creatureCount) {
return false;
}
}
return true;
case ANY:
return game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) == creatureCount;
default:
throw new UnsupportedOperationException("Value for targetController not supported: " + targetController.toString());
}
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
switch (targetController) {
case YOU:
sb.append("you");
break;
case OPPONENT:
sb.append("your opponents");
break;
case ANY:
sb.append("if ");
sb.append(creatureCount);
sb.append(" ");
sb.append(filter.getMessage());
sb.append(" are on the battlefield");
return sb.toString();
}
sb.append(" control exactly ");
sb.append(creatureCount);
sb.append(" ");
sb.append(filter.getMessage());
return sb.toString();
}
}

View file

@ -1,52 +0,0 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
/**
* @author noxx
*/
public class NoControlledCreatureCondition implements Condition {
private static NoControlledCreatureCondition fInstance = new NoControlledCreatureCondition();
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public static Condition getInstance() {
return fInstance;
}
@Override
public boolean apply(Game game, Ability source) {
return game.getBattlefield().countAll(filter, source.getControllerId(), game) == 0;
}
}

View file

@ -1,52 +0,0 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
/**
* @author nantuko
*/
public class NoCreatureCondition implements Condition {
private static final NoCreatureCondition fInstance = new NoCreatureCondition();
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public static Condition getInstance() {
return fInstance;
}
@Override
public boolean apply(Game game, Ability source) {
return game.getBattlefield().count(filter, source.getSourceId(), source.getControllerId(), game) == 0;
}
}

View file

@ -1,62 +0,0 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.condition.common;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
/**
* @author jeff
*/
public class NoCreatureOpponentCondition implements Condition {
private static NoCreatureOpponentCondition fInstance = new NoCreatureOpponentCondition();
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public static Condition getInstance() {
return fInstance;
}
@Override
public boolean apply(Game game, Ability source) {
int condition = 0;
for (UUID opponent : game.getOpponents(source.getControllerId())) {
if (game.getBattlefield().countAll(filter, opponent, game) == 0) {
condition++;
}
}
if (condition == 0)
return false;
else return true;
}
}

View file

@ -1,58 +0,0 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.condition.common;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
/**
* @author noxx
*/
public class OneControlledCreatureCondition implements Condition {
private static final OneControlledCreatureCondition fInstance = new OneControlledCreatureCondition();
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public static Condition getInstance() {
return fInstance;
}
@Override
public boolean apply(Game game, Ability source) {
return game.getBattlefield().countAll(filter, source.getControllerId(), game) == 1;
}
@Override
public String toString() {
return "you control exactly one creature";
}
}

View file

@ -1,5 +1,7 @@
package mage.abilities.condition.common; package mage.abilities.condition.common;
import java.util.List;
import java.util.Set;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.condition.Condition; import mage.abilities.condition.Condition;
import mage.game.Game; import mage.game.Game;
@ -11,17 +13,21 @@ import mage.game.permanent.Permanent;
*/ */
public class SourceHasSubtypeCondition implements Condition { public class SourceHasSubtypeCondition implements Condition {
private final String subtype; private final List<String> subtypes;
public SourceHasSubtypeCondition(String subtype) { public SourceHasSubtypeCondition(List<String> subtypes) {
this.subtype = subtype; this.subtypes = subtypes;
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) { if (permanent != null) {
return permanent.hasSubtype(subtype); for (String subtype : subtypes) {
if (permanent.hasSubtype(subtype)) {
return true;
}
}
} }
return false; return false;
} }

View file

@ -30,9 +30,11 @@ package mage.abilities.effects.common;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.Cards; import mage.cards.Cards;
import mage.cards.CardsImpl; import mage.cards.CardsImpl;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.CardUtil; import mage.util.CardUtil;
@ -44,10 +46,19 @@ import mage.util.CardUtil;
public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect { public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
protected int amount; protected int amount;
protected boolean putToGraveyard;
public LookLibraryTopCardTargetPlayerEffect(int amount) { public LookLibraryTopCardTargetPlayerEffect(int amount) {
super(Outcome.Benefit); super(Outcome.Benefit);
this.amount = amount; this.amount = amount;
this.putToGraveyard = false;
setText();
}
public LookLibraryTopCardTargetPlayerEffect(int amount, boolean putToGraveyard) {
super(Outcome.Benefit);
this.amount = amount;
this.putToGraveyard = putToGraveyard;
setText(); setText();
} }
@ -58,6 +69,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
public LookLibraryTopCardTargetPlayerEffect(final LookLibraryTopCardTargetPlayerEffect effect) { public LookLibraryTopCardTargetPlayerEffect(final LookLibraryTopCardTargetPlayerEffect effect) {
super(effect); super(effect);
amount = effect.amount; amount = effect.amount;
putToGraveyard = effect.putToGraveyard;
} }
@Override @Override
@ -74,21 +86,38 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
Cards cards = new CardsImpl(); Cards cards = new CardsImpl();
cards.addAll(targetPlayer.getLibrary().getTopCards(game, amount)); cards.addAll(targetPlayer.getLibrary().getTopCards(game, amount));
player.lookAtCards(sourceObject.getName(), cards, game); player.lookAtCards(sourceObject.getName(), cards, game);
if (putToGraveyard) {
for (Card card : cards.getCards(game)) {
if (player.chooseUse(outcome, "Do you wish to put card into the player's graveyard?", source, game)) {
player.moveCardToGraveyardWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
} else {
game.informPlayers(player.getLogName() + " puts the card back on top of the library.");
}
}
}
return true; return true;
} }
return false; return false;
} }
private void setText() { private void setText() {
StringBuilder sb = new StringBuilder("look at the top "); StringBuilder sb = new StringBuilder("look at the top ");
if (amount > 1) { if (amount > 1) {
sb.append(CardUtil.numberToText(amount)); sb.append(CardUtil.numberToText(amount));
sb.append(" cards "); sb.append(" cards ");
} } else {
else {
sb.append(" card "); sb.append(" card ");
} }
sb.append("of target player's library"); sb.append("of target player's library");
if (putToGraveyard) {
sb.append(". You may put ");
if (amount > 1) {
sb.append("those cards");
} else {
sb.append("that card");
}
sb.append(" into that player's graveyard");
}
this.staticText = sb.toString(); this.staticText = sb.toString();
} }
} }

View file

@ -0,0 +1,60 @@
/*
* 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.
*/
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author Styxo
*/
public class ShuffleIntoLibraryTargetEffect extends OneShotEffect {
public ShuffleIntoLibraryTargetEffect() {
super(Outcome.Detriment);
}
public ShuffleIntoLibraryTargetEffect(String effectText) {
super(Outcome.Detriment);
this.staticText = effectText;
}
public ShuffleIntoLibraryTargetEffect(final ShuffleIntoLibraryTargetEffect effect) {
super(effect);
}
@Override
public ShuffleIntoLibraryTargetEffect copy() {
return new ShuffleIntoLibraryTargetEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(targetPointer.getFirst(game, source));
if (permanent != null) {
if (permanent.moveToZone(Zone.LIBRARY, source.getSourceId(), game, true)) {
game.getPlayer(permanent.getOwnerId()).shuffleLibrary(source, game);
return true;
}
}
return false;
}
@Override
public String getText(Mode mode) {
if (staticText != null && !staticText.isEmpty()) {
return staticText;
} else {
return "choose target " + mode.getTargets().get(0).getTargetName() + ". Its owner shuffles it into his or her library";
}
}
}

View file

@ -0,0 +1,59 @@
/*
* 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.
*/
package mage.abilities.effects.common.continuous;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.constants.AsThoughEffectType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Game;
/**
*
* @author Styxo
*/
public class ActivateAbilitiesAnyTimeYouCouldCastInstantEffect extends AsThoughEffectImpl {
private Class activatedAbility;
public ActivateAbilitiesAnyTimeYouCouldCastInstantEffect(Class activatedAbility, String activatedAbilityName) {
super(AsThoughEffectType.ACTIVATE_AS_INSTANT, Duration.EndOfGame, Outcome.Benefit);
this.activatedAbility = activatedAbility;
staticText = "You may activate " + activatedAbilityName + " any time you could cast an instant";
}
public ActivateAbilitiesAnyTimeYouCouldCastInstantEffect(final ActivateAbilitiesAnyTimeYouCouldCastInstantEffect effect) {
super(effect);
this.activatedAbility = effect.activatedAbility;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public ActivateAbilitiesAnyTimeYouCouldCastInstantEffect copy() {
return new ActivateAbilitiesAnyTimeYouCouldCastInstantEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability affectedAbility, Ability source, Game game) {
if (affectedAbility.getControllerId().equals(source.getControllerId())
&& activatedAbility.isInstance(affectedAbility)) {
return true;
}
return false;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return false; // Not used
}
}

View file

@ -0,0 +1,50 @@
/*
* 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.
*/
package mage.abilities.effects.common.cost;
import mage.abilities.Ability;
import mage.constants.CostModificationType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.game.Game;
import mage.util.CardUtil;
/**
*
* @author Styxo
*/
public class AbilitiesCostReductionControllerEffect extends CostModificationEffectImpl {
private Class activatedAbility;
public AbilitiesCostReductionControllerEffect(Class activatedAbility, String activatedAbilityName) {
super(Duration.WhileOnBattlefield, Outcome.Benefit, CostModificationType.REDUCE_COST);
this.activatedAbility = activatedAbility;
staticText = activatedAbilityName + " costs you pay cost {1} less";
}
public AbilitiesCostReductionControllerEffect(AbilitiesCostReductionControllerEffect effect) {
super(effect);
this.activatedAbility = effect.activatedAbility;
}
@java.lang.Override
public AbilitiesCostReductionControllerEffect copy() {
return new AbilitiesCostReductionControllerEffect(this);
}
@java.lang.Override
public boolean apply(Game game, Ability source, Ability abilityToModify) {
CardUtil.reduceCost(abilityToModify, 1);
return true;
}
@java.lang.Override
public boolean applies(Ability abilityToModify, Ability source, Game game) {
return abilityToModify.getControllerId().equals(source.getControllerId())
&& activatedAbility.isInstance(abilityToModify);
}
}

View file

@ -25,7 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed * authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com. * or implied, of BetaSteward_at_googlemail.com.
*/ */
package mage.target.common; package mage.target.common;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
@ -44,6 +43,10 @@ public class TargetControlledCreaturePermanent extends TargetControlledPermanent
this(numTargets, numTargets, new FilterControlledCreaturePermanent(), false); this(numTargets, numTargets, new FilterControlledCreaturePermanent(), false);
} }
public TargetControlledCreaturePermanent(int minNumTargets, int maxNumTargets) {
this(minNumTargets, maxNumTargets, new FilterControlledCreaturePermanent(), false);
}
public TargetControlledCreaturePermanent(FilterControlledCreaturePermanent filter) { public TargetControlledCreaturePermanent(FilterControlledCreaturePermanent filter) {
super(1, 1, filter, false); super(1, 1, filter, false);
} }

View file

@ -0,0 +1,43 @@
"""
Purpose: Removes duplicate CardName|CardSet|CardNumber| entries from mtg-cards-data.txt that crop up
@author: escplan9 (Derek Monturo - dmontur1 at gmail dot com)
@version: 1.0
Written in Python 3.x, should work in Python 2.x as well.
"""
import re
"""
example line from file:
Aven Mimeomancer|Alara Reborn|2|R|{1}{W}{U}|Creature - Bird Wizard|3|1|Flying$At the beginning of your upkeep, you may put a feather counter on target creature. If you do, that creature is 3/1 and has flying for as long as it has a feather counter on it.|
With the reg-ex pattern below, separates into 2 match groups
match-group-1: Aven Mimeomancer|Alara Reborn|2|
match-group-2: (remainder of the line up to the \r\n)
"""
reg_ptn = re.compile(r'([a-zA-Z].*[|][a-zA-Z].*[|]\d+[|])(.*[\r\n])')
orig_txt_filename = 'mtg-cards-data.txt'
card_dict = {}
new_contents = ''
with open(orig_txt_filename) as orig_txt_file:
for line in orig_txt_file:
matchObj = re.match(reg_ptn, line)
if matchObj is not None:
matchGroups = matchObj.groups()
if len(matchGroups) > 0:
card_set_num = matchGroups[0]
if card_set_num not in card_dict.keys(): # only add unique card-set-number entries to new-contents
card_dict[card_set_num] = True
new_contents += line
else:
new_contents += line
else:
new_contents += line
# generate new file with the de-duped contents
new_txt_filename = 'unduped-cards-data.txt'
with open(new_txt_filename, "w") as new_txt_file:
new_txt_file.write(new_contents)

File diff suppressed because it is too large Load diff

57751
Utils/mtg-cards-data_old.txt Normal file

File diff suppressed because it is too large Load diff