Added Chainer, Dementia Master; Concerted Effort; Spellweaver Helix; Thought Lash and Tithe.

Fixed OpponentControlsMoreCondition spelling.
This commit is contained in:
emerald000 2015-10-04 01:57:37 -04:00
parent f24a1b3898
commit 208a890d1d
13 changed files with 903 additions and 36 deletions

View file

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

View file

@ -28,7 +28,7 @@
package mage.sets.commander2014;
import java.util.UUID;
import mage.abilities.condition.common.OpponentControllsMoreCondition;
import mage.abilities.condition.common.OpponentControlsMoreCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
@ -60,7 +60,7 @@ public class GiftOfEstates extends CardImpl {
// If an opponent controls more lands than you, search your library for up to three Plains cards, reveal them, and put them into your hand. Then shuffle your library.
this.getSpellAbility().addEffect(new ConditionalOneShotEffect(
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 3, filter), true),
new OpponentControllsMoreCondition(new FilterLandPermanent("lands"))));
new OpponentControlsMoreCondition(new FilterLandPermanent("lands"))));
}
public GiftOfEstates(final GiftOfEstates card) {

View file

@ -29,7 +29,7 @@ package mage.sets.legends;
import java.util.UUID;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.OpponentControllsMoreCondition;
import mage.abilities.condition.common.OpponentControlsMoreCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
@ -53,7 +53,7 @@ public class LandTax extends CardImpl {
// At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library.
this.addAbility(new ConditionalTriggeredAbility(
new BeginningOfUpkeepTriggeredAbility(new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, 3, new FilterBasicLandCard()), true), TargetController.YOU, true),
new OpponentControllsMoreCondition(new FilterLandPermanent("lands")),
new OpponentControlsMoreCondition(new FilterLandPermanent("lands")),
"At the beginning of your upkeep, if an opponent controls more lands than you, you may search your library for up to three basic land cards, reveal them, and put them into your hand. If you do, shuffle your library"
));

View file

@ -0,0 +1,182 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.masterseditionii;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileFromTopOfLibraryCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.keyword.CumulativeUpkeepAbility;
import mage.cards.CardImpl;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.players.Player;
/**
*
* @author emerald000
*/
public class ThoughtLash extends CardImpl {
public ThoughtLash(UUID ownerId) {
super(ownerId, 70, "Thought Lash", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}{U}");
this.expansionSetCode = "ME2";
// Cumulative upkeep - Exile the top card of your library.
this.addAbility(new CumulativeUpkeepAbility(new ExileFromTopOfLibraryCost(1)));
// When a player doesn't pay Thought Lash's cumulative upkeep, that player exiles all cards from his or her library.
this.addAbility(new ThoughtLashTriggeredAbility());
// Exile the top card of your library: Prevent the next 1 damage that would be dealt to you this turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ThoughtLashPreventionEffect(), new ExileFromTopOfLibraryCost(1)));
}
public ThoughtLash(final ThoughtLash card) {
super(card);
}
@Override
public ThoughtLash copy() {
return new ThoughtLash(this);
}
}
class ThoughtLashTriggeredAbility extends TriggeredAbilityImpl {
ThoughtLashTriggeredAbility() {
super(Zone.BATTLEFIELD, new ThoughtLashExileLibraryEffect(), false);
}
ThoughtLashTriggeredAbility(final ThoughtLashTriggeredAbility ability) {
super(ability);
}
@Override
public ThoughtLashTriggeredAbility copy() {
return new ThoughtLashTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DIDNT_PAY_CUMULATIVE_UPKEEP;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getSourceId() == this.getSourceId();
}
@Override
public String getRule() {
return "When a player doesn't pay {this}'s cumulative upkeep, that player exiles all cards from his or her library.";
}
}
class ThoughtLashExileLibraryEffect extends OneShotEffect {
ThoughtLashExileLibraryEffect() {
super(Outcome.Detriment);
this.staticText = "that player exiles all cards from his or her library";
}
ThoughtLashExileLibraryEffect(final ThoughtLashExileLibraryEffect effect) {
super(effect);
}
@Override
public ThoughtLashExileLibraryEffect copy() {
return new ThoughtLashExileLibraryEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Cards cards = new CardsImpl();
cards.addAll(controller.getLibrary().getTopCards(game, controller.getLibrary().size()));
controller.moveCards(cards, Zone.LIBRARY, Zone.EXILED, source, game);
return true;
}
return false;
}
}
class ThoughtLashPreventionEffect extends PreventionEffectImpl {
ThoughtLashPreventionEffect() {
super(Duration.EndOfTurn);
this.staticText = "Prevent the next 1 damage that would be dealt to you this turn";
}
ThoughtLashPreventionEffect(final ThoughtLashPreventionEffect effect) {
super(effect);
}
@Override
public ThoughtLashPreventionEffect copy() {
return new ThoughtLashPreventionEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
GameEvent preventEvent = new GameEvent(GameEvent.EventType.PREVENT_DAMAGE,
source.getControllerId(), source.getSourceId(), source.getControllerId(), event.getAmount(), false);
if (!game.replaceEvent(preventEvent)) {
int damage = event.getAmount();
if (damage > 0) {
event.setAmount(damage - 1);
this.used = true;
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.PREVENTED_DAMAGE,
source.getControllerId(), source.getSourceId(), source.getControllerId(), 1));
}
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
return !this.used && super.applies(event, source, game) && event.getTargetId().equals(source.getControllerId());
}
}

View file

@ -0,0 +1,231 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.mirrodin;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.target.common.TargetCardInASingleGraveyard;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
/**
*
* @author emerald000
*/
public class SpellweaverHelix extends CardImpl {
private static final FilterCard filter = new FilterCard("sorcery cards from a single graveyard");
static {
filter.add(new CardTypePredicate(CardType.SORCERY));
}
public SpellweaverHelix(UUID ownerId) {
super(ownerId, 247, "Spellweaver Helix", Rarity.RARE, new CardType[]{CardType.ARTIFACT}, "{3}");
this.expansionSetCode = "MRD";
// Imprint - When Spellweaver Helix enters the battlefield, you may exile two target sorcery cards from a single graveyard.
Ability ability = new EntersBattlefieldTriggeredAbility(new SpellweaverHelixImprintEffect(), true, "Imprint — ");
ability.addTarget(new TargetCardInASingleGraveyard(2, 2, filter));
this.addAbility(ability);
// Whenever a player casts a card, if it has the same name as one of the cards exiled with Spellweaver Helix, you may copy the other. If you do, you may cast the copy without paying its mana cost.
this.addAbility(new SpellweaverHelixTriggeredAbility());
}
public SpellweaverHelix(final SpellweaverHelix card) {
super(card);
}
@java.lang.Override
public SpellweaverHelix copy() {
return new SpellweaverHelix(this);
}
}
class SpellweaverHelixImprintEffect extends OneShotEffect {
SpellweaverHelixImprintEffect() {
super(Outcome.Exile);
this.staticText = "you may exile two target sorcery cards from a single graveyard";
}
SpellweaverHelixImprintEffect(final SpellweaverHelixImprintEffect effect) {
super(effect);
}
@java.lang.Override
public SpellweaverHelixImprintEffect copy() {
return new SpellweaverHelixImprintEffect(this);
}
@java.lang.Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
for (UUID targetId : this.getTargetPointer().getTargets(game, source)) {
Card card = game.getCard(targetId);
if (card != null) {
controller.moveCardsToExile(card, source, game, true, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), source.getSourceObject(game).getIdName());
if (sourcePermanent != null) {
sourcePermanent.imprint(targetId, game);
}
}
}
return true;
}
return false;
}
}
class SpellweaverHelixTriggeredAbility extends TriggeredAbilityImpl {
SpellweaverHelixTriggeredAbility() {
super(Zone.BATTLEFIELD, new SpellweaverHelixCastEffect(), false);
}
SpellweaverHelixTriggeredAbility(final SpellweaverHelixTriggeredAbility ability) {
super(ability);
}
@java.lang.Override
public SpellweaverHelixTriggeredAbility copy() {
return new SpellweaverHelixTriggeredAbility(this);
}
@java.lang.Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.SPELL_CAST;
}
@java.lang.Override
public boolean checkTrigger(GameEvent event, Game game) {
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell != null && spell.getCard() != null && !spell.getCard().isCopy()) {
for (Effect effect : this.getEffects()) {
effect.setTargetPointer(new FixedTarget(spell.getId()));
}
return true;
}
return false;
}
@java.lang.Override
public boolean checkInterveningIfClause(Game game) {
Spell spell = game.getStack().getSpell(this.getEffects().get(0).getTargetPointer().getFirst(game, this));
if (spell != null) {
String spellName = spell.getName();
Permanent sourcePermanent = game.getPermanent(this.getSourceId());
if (sourcePermanent != null) {
for (UUID imprintId : sourcePermanent.getImprinted()) {
Card card = game.getCard(imprintId);
if (card != null && card.getName().equals(spellName)) {
((SpellweaverHelixCastEffect) this.getEffects().get(0)).setSpellName(spellName);
return true;
}
}
}
}
return false;
}
@java.lang.Override
public String getRule() {
return "Whenever a player casts a card, if it has the same name as one of the cards exiled with Spellweaver Helix, you may copy the other. If you do, you may cast the copy without paying its mana cost.";
}
}
class SpellweaverHelixCastEffect extends OneShotEffect {
private String spellName = "";
SpellweaverHelixCastEffect() {
super(Outcome.Benefit);
this.staticText = "you may copy the other. If you do, you may cast the copy without paying its mana cost";
}
SpellweaverHelixCastEffect(final SpellweaverHelixCastEffect effect) {
super(effect);
this.spellName = effect.spellName;
}
@java.lang.Override
public SpellweaverHelixCastEffect copy() {
return new SpellweaverHelixCastEffect(this);
}
public void setSpellName(String spellName) {
this.spellName = spellName;
}
@java.lang.Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (sourcePermanent != null) {
boolean foundSpellWithSameName = false;
for (UUID imprintId : sourcePermanent.getImprinted()) {
Card card = game.getCard(imprintId);
if (card != null) {
if (!foundSpellWithSameName && card.getName().equals(spellName)) {
foundSpellWithSameName = true;
}
else {
if (controller.chooseUse(Outcome.Copy, "Copy " + card.getIdName(), source, game)) {
Card copy = game.copyCard(card, source, source.getControllerId());
if (controller.chooseUse(Outcome.PlayForFree, "Cast " + copy.getIdName() + " without paying its mana cost?", source, game)) {
controller.cast(copy.getSpellAbility(), game, true);
}
}
}
}
}
}
return true;
}
return false;
}
}

View file

@ -35,7 +35,7 @@ import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.OpponentControllsMoreCondition;
import mage.abilities.condition.common.OpponentControlsMoreCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
@ -67,7 +67,7 @@ public class WeatheredWayfarer extends CardImpl {
Zone.BATTLEFIELD,
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(new FilterLandCard()), true, true),
new ManaCostsImpl("{W}"),
new OpponentControllsMoreCondition(new FilterLandPermanent("lands")));
new OpponentControlsMoreCondition(new FilterLandPermanent("lands")));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}

View file

@ -0,0 +1,164 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.ravnica;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.FearAbility;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.LandwalkAbility;
import mage.abilities.keyword.ProtectionAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author emerald000
*/
public class ConcertedEffort extends CardImpl {
public ConcertedEffort(UUID ownerId) {
super(ownerId, 8, "Concerted Effort", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
this.expansionSetCode = "RAV";
// At the beginning of each upkeep, creatures you control gain flying until end of turn if a creature you control has flying. The same is true for fear, first strike, double strike, landwalk, protection, trample, and vigilance.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new ConcertedEffortEffect(), TargetController.ANY, false));
}
public ConcertedEffort(final ConcertedEffort card) {
super(card);
}
@Override
public ConcertedEffort copy() {
return new ConcertedEffort(this);
}
}
class ConcertedEffortEffect extends OneShotEffect {
private static final FilterCreaturePermanent filterFlying = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filterFear = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filterFirstStrike = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filterDoubleStrike = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filterLandwalk = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filterProtection = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filterTrample = new FilterCreaturePermanent();
private static final FilterCreaturePermanent filterVigilance = new FilterCreaturePermanent();
static {
filterFlying.add(new AbilityPredicate(FlyingAbility.class));
filterFear.add(new AbilityPredicate(FearAbility.class));
filterFirstStrike.add(new AbilityPredicate(FirstStrikeAbility.class));
filterDoubleStrike.add(new AbilityPredicate(DoubleStrikeAbility.class));
filterLandwalk.add(new AbilityPredicate(LandwalkAbility.class));
filterProtection.add(new AbilityPredicate(ProtectionAbility.class));
filterTrample.add(new AbilityPredicate(TrampleAbility.class));
filterVigilance.add(new AbilityPredicate(VigilanceAbility.class));
}
ConcertedEffortEffect() {
super(Outcome.BoostCreature);
this.staticText = "creatures you control gain flying until end of turn if a creature you control has flying. The same is true for fear, first strike, double strike, landwalk, protection, trample, and vigilance";
}
ConcertedEffortEffect(final ConcertedEffortEffect effect) {
super(effect);
}
@Override
public ConcertedEffortEffect copy() {
return new ConcertedEffortEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
// Flying
if (game.getBattlefield().contains(filterFlying, source.getControllerId(), 1, game)) {
game.addEffect(new GainAbilityAllEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), source);
}
// Fear
if (game.getBattlefield().contains(filterFear, source.getControllerId(), 1, game)) {
game.addEffect(new GainAbilityAllEffect(FearAbility.getInstance(), Duration.EndOfTurn), source);
}
// First strike
if (game.getBattlefield().contains(filterFirstStrike, source.getControllerId(), 1, game)) {
game.addEffect(new GainAbilityAllEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn), source);
}
// Double strike
if (game.getBattlefield().contains(filterDoubleStrike, source.getControllerId(), 1, game)) {
game.addEffect(new GainAbilityAllEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn), source);
}
// Landwalk
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filterLandwalk, source.getControllerId(), game)) {
for (Ability ability : permanent.getAbilities(game)) {
if (ability instanceof LandwalkAbility) {
game.addEffect(new GainAbilityAllEffect(ability, Duration.EndOfTurn), source);
}
}
}
// Protection
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filterProtection, source.getControllerId(), game)) {
for (Ability ability : permanent.getAbilities(game)) {
if (ability instanceof ProtectionAbility) {
game.addEffect(new GainAbilityAllEffect(ability, Duration.EndOfTurn), source);
}
}
}
// Trample
if (game.getBattlefield().contains(filterTrample, source.getControllerId(), 1, game)) {
game.addEffect(new GainAbilityAllEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), source);
}
// Vigilance
if (game.getBattlefield().contains(filterVigilance, source.getControllerId(), 1, game)) {
game.addEffect(new GainAbilityAllEffect(VigilanceAbility.getInstance(), Duration.EndOfTurn), source);
}
return true;
}
}

View file

@ -33,7 +33,7 @@ import mage.constants.CardType;
import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.OpponentControllsMoreCondition;
import mage.abilities.condition.common.OpponentControlsMoreCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.search.SearchLibraryPutInPlayEffect;
import mage.abilities.keyword.FirstStrikeAbility;
@ -63,7 +63,7 @@ public class KnightOfTheWhiteOrchid extends CardImpl {
// When Knight of the White Orchid enters the battlefield, if an opponent controls more lands than you, you may search your library for a Plains card, put it onto the battlefield, then shuffle your library.
this.addAbility(new ConditionalTriggeredAbility(
new EntersBattlefieldTriggeredAbility(new SearchLibraryPutInPlayEffect(new TargetCardInLibrary(0, 1, new FilterBySubtypeCard("Plains")), false), true),
new OpponentControllsMoreCondition(new FilterLandPermanent("lands")),
new OpponentControlsMoreCondition(new FilterLandPermanent("lands")),
"When {this} enters the battlefield, if an opponent controls more lands than you, you may search your library for a Plains card, put it onto the battlefield, then shuffle your library"));
}

View file

@ -0,0 +1,144 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.torment;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.LeavesBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.PayLifeCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileAllEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.abilities.effects.common.continuous.BecomesColorTargetEffect;
import mage.abilities.effects.common.continuous.BecomesSubtypeTargetEffect;
import mage.abilities.effects.common.continuous.BoostAllEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInGraveyard;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author emerald000
*/
public class ChainerDementiaMaster extends CardImpl {
private static final FilterCreaturePermanent filterCreature = new FilterCreaturePermanent("Nightmare creatures");
private static final FilterPermanent filterPermanent = new FilterPermanent("Nightmares");
static {
filterCreature.add(new SubtypePredicate("Nightmare"));
filterPermanent.add(new SubtypePredicate("Nightmare"));
}
public ChainerDementiaMaster(UUID ownerId) {
super(ownerId, 56, "Chainer, Dementia Master", Rarity.RARE, new CardType[]{CardType.CREATURE}, "{3}{B}{B}");
this.expansionSetCode = "TOR";
this.supertype.add("Legendary");
this.subtype.add("Human");
this.subtype.add("Minion");
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Nightmare creatures get +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostAllEffect(1, 1, Duration.WhileOnBattlefield, filterCreature, false)));
// {B}{B}{B}, Pay 3 life: Put target creature card from a graveyard onto the battlefield under your control. That creature is black and is a Nightmare in addition to its other creature types.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChainerDementiaMasterEffect(), new ManaCostsImpl<>("{B}{B}{B}"));
ability.addCost(new PayLifeCost(3));
ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card from a graveyard")));
this.addAbility(ability);
// When Chainer, Dementia Master leaves the battlefield, exile all Nightmares.
this.addAbility(new LeavesBattlefieldTriggeredAbility(new ExileAllEffect(filterPermanent), false));
}
public ChainerDementiaMaster(final ChainerDementiaMaster card) {
super(card);
}
@Override
public ChainerDementiaMaster copy() {
return new ChainerDementiaMaster(this);
}
}
class ChainerDementiaMasterEffect extends OneShotEffect {
ChainerDementiaMasterEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Put target creature card from a graveyard onto the battlefield under your control. That creature is black and is a Nightmare in addition to its other creature types";
}
ChainerDementiaMasterEffect(final ChainerDementiaMasterEffect effect) {
super(effect);
}
@Override
public ChainerDementiaMasterEffect copy() {
return new ChainerDementiaMasterEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
UUID cardId = this.getTargetPointer().getFirst(game, source);
new ReturnFromGraveyardToBattlefieldTargetEffect().apply(game, source);
Permanent permanent = game.getPermanent(cardId);
if (permanent != null) {
ContinuousEffectImpl effect = new BecomesColorTargetEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
effect = new BecomesSubtypeTargetEffect(Duration.WhileOnBattlefield, new ArrayList<>(Arrays.asList("Nightmare")), false);
effect.setTargetPointer(new FixedTarget(permanent, game));
game.addEffect(effect, source);
}
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.sets.visions;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.filter.FilterCard;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetOpponent;
/**
*
* @author emerald000
*/
public class Tithe extends CardImpl {
public Tithe(UUID ownerId) {
super(ownerId, 84, "Tithe", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{W}");
this.expansionSetCode = "VIS";
// Search your library for a Plains card. If target opponent controls more lands than you, you may search your library for an additional Plains card. Reveal those cards and put them into your hand. Then shuffle your library.
this.getSpellAbility().addEffect(new TitheEffect());
this.getSpellAbility().addTarget(new TargetOpponent());
}
public Tithe(final Tithe card) {
super(card);
}
@Override
public Tithe copy() {
return new Tithe(this);
}
}
class TitheEffect extends OneShotEffect {
private static final FilterCard filter = new FilterCard("Plains");
static {
filter.add(new SubtypePredicate("Plains"));
}
TitheEffect() {
super(Outcome.Benefit);
this.staticText = "Search your library for a Plains card. If target opponent controls more lands than you, you may search your library for an additional Plains card. Reveal those cards and put them into your hand. Then shuffle your library";
}
TitheEffect(final TitheEffect effect) {
super(effect);
}
@Override
public TitheEffect copy() {
return new TitheEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
int numYourLands = game.getBattlefield().countAll(new FilterLandPermanent(), source.getControllerId(), game);
int numOpponentLands = game.getBattlefield().countAll(new FilterLandPermanent(), this.getTargetPointer().getFirst(game, source), game);
new SearchLibraryPutInHandEffect(new TargetCardInLibrary(0, (numOpponentLands > numYourLands ? 2 : 1), filter), true).apply(game, source);
return true;
}
}

View file

@ -39,11 +39,11 @@ import mage.game.Game;
* @author LevelX2
*/
public class OpponentControllsMoreCondition implements Condition {
public class OpponentControlsMoreCondition implements Condition {
private final FilterPermanent filter;
public OpponentControllsMoreCondition(FilterPermanent filter) {
public OpponentControlsMoreCondition(FilterPermanent filter) {
this.filter = filter;
}

View file

@ -25,8 +25,6 @@
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.abilities.keyword;
import mage.abilities.Ability;
@ -41,6 +39,8 @@ import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
@ -48,8 +48,6 @@ import mage.players.Player;
*
* @author Plopman
*/
public class CumulativeUpkeepAbility extends BeginningOfUpkeepTriggeredAbility {
private Cost cumulativeCost;
@ -83,7 +81,7 @@ public class CumulativeUpkeepAbility extends BeginningOfUpkeepTriggeredAbility {
class CumulativeUpkeepEffect extends OneShotEffect {
private Cost cumulativeCost;
private final Cost cumulativeCost;
CumulativeUpkeepEffect(Cost cumulativeCost) {
super(Outcome.Sacrifice);
@ -95,46 +93,44 @@ class CumulativeUpkeepEffect extends OneShotEffect {
this.cumulativeCost = effect.cumulativeCost.copy();
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (player != null && permanent != null) {
int ageCounter = permanent.getCounters().getCount(CounterType.AGE);
if(cumulativeCost instanceof ManaCost){
ManaCostsImpl totalCost = new ManaCostsImpl();
for(int i = 0 ; i < ageCounter; i++){
if (cumulativeCost instanceof ManaCost) {
ManaCostsImpl totalCost = new ManaCostsImpl<>();
for (int i = 0; i < ageCounter; i++) {
totalCost.add((ManaCost) cumulativeCost.copy());
}
if (player.chooseUse(Outcome.Benefit, "Pay " + totalCost.getText() + "?", source, game)) {
totalCost.clearPaid();
if (totalCost.payOrRollback(source, game, source.getSourceId(), source.getControllerId())){
if (totalCost.payOrRollback(source, game, source.getSourceId(), source.getControllerId())) {
return true;
}
}
game.fireEvent(new GameEvent(EventType.DIDNT_PAY_CUMULATIVE_UPKEEP, permanent.getId(), permanent.getId(), player.getId(), ageCounter, false));
permanent.sacrifice(source.getSourceId(), game);
return true;
}
else{
CostsImpl totalCost = new CostsImpl();
for(int i = 0 ; i < ageCounter; i++){
} else {
CostsImpl<Cost> totalCost = new CostsImpl<>();
for (int i = 0; i < ageCounter; i++) {
totalCost.add(cumulativeCost.copy());
}
if (player.chooseUse(Outcome.Benefit, totalCost.getText() + "?", source, game)) {
totalCost.clearPaid();
int bookmark = game.bookmarkState();
if (totalCost.pay(source, game, source.getSourceId(), source.getControllerId(), false)){
if (totalCost.pay(source, game, source.getSourceId(), source.getControllerId(), false)) {
return true;
}
else{
} else {
game.restoreState(bookmark, source.getRule());
}
}
game.fireEvent(new GameEvent(EventType.DIDNT_PAY_CUMULATIVE_UPKEEP, permanent.getId(), permanent.getId(), player.getId(), ageCounter, false));
permanent.sacrifice(source.getSourceId(), game);
return true;
}
}
return false;
}

View file

@ -185,6 +185,7 @@ public class GameEvent implements Serializable {
ENCHANT_PLAYER, ENCHANTED_PLAYER,
CAN_TAKE_MULLIGAN,
FLIP_COIN, COIN_FLIPPED, SCRY, FATESEAL,
DIDNT_PAY_CUMULATIVE_UPKEEP,
//permanent events
ENTERS_THE_BATTLEFIELD,
TAP, TAPPED, TAPPED_FOR_MANA,
@ -241,7 +242,6 @@ public class GameEvent implements Serializable {
//combat events
COMBAT_DAMAGE_APPLIED,
SELECTED_ATTACKER, SELECTED_BLOCKER;
}
public GameEvent(EventType type, UUID targetId, UUID sourceId, UUID playerId) {