1
0
Fork 0
mirror of https://github.com/correl/mage.git synced 2025-04-06 17:00:12 -09:00

Merge pull request from Zzooouhh/master

Implemented old cards
This commit is contained in:
LevelX2 2018-05-07 00:52:56 +02:00 committed by GitHub
commit 1ab3d24e7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
24 changed files with 1446 additions and 5 deletions

View file

@ -0,0 +1,114 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.CantBeTargetedAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterSpell;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author MTGfan & L_J
*/
public class AntiMagicAura extends CardImpl {
public AntiMagicAura(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature can't be the target of spells and can't be enchanted by other Auras.
CantBeTargetedAttachedEffect cantTargetEffect = new CantBeTargetedAttachedEffect(new FilterSpell("spells"), Duration.WhileOnBattlefield, AttachmentType.AURA, TargetController.ANY);
Ability ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, cantTargetEffect);
ability2.addEffect(new AntiMagicAuraRuleEffect());
this.addAbility(ability2);
}
public AntiMagicAura(final AntiMagicAura card) {
super(card);
}
@Override
public AntiMagicAura copy() {
return new AntiMagicAura(this);
}
}
// 9/25/2006 ruling: If Consecrate Land enters the battlefield attached to a land thats enchanted by other Auras, those Auras are put into their owners graveyards.
class AntiMagicAuraRuleEffect extends ContinuousRuleModifyingEffectImpl {
public AntiMagicAuraRuleEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "and can't be enchanted by other Auras";
}
public AntiMagicAuraRuleEffect(final AntiMagicAuraRuleEffect effect) {
super(effect);
}
@Override
public AntiMagicAuraRuleEffect copy() {
return new AntiMagicAuraRuleEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == EventType.ATTACH || event.getType() == EventType.STAY_ATTACHED;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent sourceObject = game.getPermanent(source.getSourceId());
if (sourceObject != null && sourceObject.getAttachedTo() != null) {
if (event.getTargetId().equals(sourceObject.getAttachedTo())) {
return !event.getSourceId().equals(source.getSourceId());
}
}
return false;
}
}

View file

@ -0,0 +1,140 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.c;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EndOfCombatTriggeredAbility;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SimpleEvasionAbility;
import mage.abilities.condition.common.AttackedOrBlockedThisCombatSourceCondition;
import mage.abilities.condition.common.IsStepCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalActivatedAbility;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import mage.counters.Counter;
import mage.counters.CounterType;
import mage.counters.Counters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.watchers.common.AttackedOrBlockedThisCombatWatcher;
/**
*
* @author escplan9, MarcoMarin & L_J
*/
public class ClockworkSteed extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("artifact creatures");
static {
filter.add(new CardTypePredicate(CardType.ARTIFACT));
}
public ClockworkSteed(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{4}");
this.subtype.add(SubType.HORSE);
this.power = new MageInt(0);
this.toughness = new MageInt(3);
// Clockwork Steed enters the battlefield with four +1/+0 counters on it.
this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.P1P0.createInstance(4)), "with four +1/+0 counters on it"));
// Clockwork Steed can't be blocked by artifact creatures.
this.addAbility(new SimpleEvasionAbility(new CantBeBlockedByCreaturesSourceEffect(filter, Duration.WhileOnBattlefield)));
// At end of combat, if Clockwork Steed attacked or blocked this combat, remove a +1/+0 counter from it.
this.addAbility(new ConditionalTriggeredAbility(
new EndOfCombatTriggeredAbility(new RemoveCounterSourceEffect(CounterType.P1P0.createInstance()), false),
AttackedOrBlockedThisCombatSourceCondition.instance,
"At end of combat, if {this} attacked or blocked this combat, remove a +1/+0 counter from it."),
new AttackedOrBlockedThisCombatWatcher()
);
// {X}, {tap}: Put up to X +1/+0 counters on Clockwork Steed. This ability can't cause the total number of +1/+0 counters on Clockwork Steed to be greater than four. Activate this ability only during your upkeep.
Ability ability = new ConditionalActivatedAbility(
Zone.BATTLEFIELD,
new ClockworkSteedAddCountersSourceEffect(
CounterType.P1P0.createInstance(),
new ManacostVariableValue(),
true, true
),
new ManaCostsImpl("{X}"),
new IsStepCondition(PhaseStep.UPKEEP),
null
);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
public ClockworkSteed(final ClockworkSteed card) {
super(card);
}
@Override
public ClockworkSteed copy() {
return new ClockworkSteed(this);
}
}
class ClockworkSteedAddCountersSourceEffect extends AddCountersSourceEffect {
public ClockworkSteedAddCountersSourceEffect(Counter counter, DynamicValue amount, boolean informPlayers, boolean putOnCard) {
super(counter, amount, informPlayers, putOnCard);
staticText = "Put up to X +1/+0 counters on {this}. This ability can't cause the total number of +1/+0 counters on {this} to be greater than four.";
}
@Override
public boolean apply(Game game, Ability source) {
//record how many counters
Counters permCounters = game.getPermanent(source.getSourceId()).getCounters(game);
int countersWas = permCounters.getCount(CounterType.P1P0);
if (countersWas < 4) {
super.apply(game, source);
if (permCounters.getCount(CounterType.P1P0) > 4) {
permCounters.removeCounter(CounterType.P1P0, permCounters.getCount(CounterType.P1P0) - 4);
}//if countersWas < 4 then counter is min(current,4); there is no setCounters function tho
}//else this is a rare case of a Steed getting boosted by outside sources :) Which is the sole purpose of this if, for the benefit of this rare but not impossible case :p
return true;
}
}

View file

@ -100,10 +100,11 @@ class DrainPowerEffect extends OneShotEffect {
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (targetPlayer != null) {
List<Permanent> ignorePermanents = new ArrayList<>();
Map<Permanent, List<ActivatedManaAbilityImpl>> manaAbilitiesMap = new HashMap<>();
TargetPermanent target = null;
while (true) {
Map<Permanent, List<ActivatedManaAbilityImpl>> manaAbilitiesMap = new HashMap<>();
manaAbilitiesMap.clear();
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, targetPlayer.getId(), game)) {
if (!ignorePermanents.contains(permanent)) {
List<ActivatedManaAbilityImpl> manaAbilities = new ArrayList<>();
@ -111,7 +112,6 @@ class DrainPowerEffect extends OneShotEffect {
for (Ability ability : permanent.getAbilities()) {
if (ability instanceof ActivatedAbility && ability.getAbilityType() == AbilityType.MANA) {
ActivatedManaAbilityImpl manaAbility = (ActivatedManaAbilityImpl) ability;
// TODO: make Rhystic Cave untappable due to its instant speed limitation (this is a Rhystic Cave canActivate bug)
if (manaAbility != null && manaAbility.canActivate(targetPlayer.getId(), game)) {
// canActivate can't check for mana abilities that require a mana cost, if the payment isn't possible (Cabal Coffers etc)
// so it's necessary to filter them out manually - might be buggy in some fringe cases
@ -168,7 +168,6 @@ class DrainPowerEffect extends OneShotEffect {
// 106.12. One card (Drain Power) causes one player to lose unspent mana and another to add the mana lost this way. (Note that these may be the same player.)
// This empties the former players mana pool and causes the mana emptied this way to be put into the latter players mana pool. Which permanents, spells, and/or
// abilities produced that mana are unchanged, as are any restrictions or additional effects associated with any of that mana.
// TODO: retain riders associated with drained mana
List<ManaPoolItem> manaItems = targetPlayer.getManaPool().getManaItems();
targetPlayer.getManaPool().emptyPool(game);
for (ManaPoolItem manaPoolItem : manaItems) {

View file

@ -0,0 +1,117 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.f;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.ZoneChangeTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.SacrificeEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author L_J
*/
public class FuneralMarch extends CardImpl {
public FuneralMarch(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}{B}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Benefit));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// When enchanted creature leaves the battlefield, its controller sacrifices a creature.
this.addAbility(new FuneralMarchTriggeredAbility());
}
public FuneralMarch(final FuneralMarch card) {
super(card);
}
@Override
public FuneralMarch copy() {
return new FuneralMarch(this);
}
}
class FuneralMarchTriggeredAbility extends ZoneChangeTriggeredAbility {
public FuneralMarchTriggeredAbility() {
super(Zone.BATTLEFIELD, null, new SacrificeEffect(StaticFilters.FILTER_PERMANENT_CREATURE, 1, "its controller"), "When enchanted creature leaves the battlefield, ", false);
}
public FuneralMarchTriggeredAbility(final FuneralMarchTriggeredAbility ability) {
super(ability);
}
@Override
public FuneralMarchTriggeredAbility copy() {
return new FuneralMarchTriggeredAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(this.getSourceId());
if (enchantment != null && enchantment.getAttachedTo() != null && event.getTargetId().equals(enchantment.getAttachedTo())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if ((fromZone == null || zEvent.getFromZone() == fromZone) && (toZone == null || zEvent.getToZone() == toZone)) {
for (Effect effect : getEffects()) {
if (zEvent.getTarget() != null) {
Permanent attachedTo = (Permanent) game.getLastKnownInformation(enchantment.getAttachedTo(), Zone.BATTLEFIELD, enchantment.getAttachedToZoneChangeCounter());
if (attachedTo != null) {
effect.setTargetPointer(new FixedTarget(attachedTo.getControllerId()));
}
}
}
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,211 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.g;
import java.util.EnumSet;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.continuous.ExchangeControlTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetControlledPermanent;
/**
*
* @author LevelX2 & L_J
*/
public class GauntletsOfChaos extends CardImpl {
public GauntletsOfChaos(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
// {5}, Sacrifice Gauntlets of Chaos: Exchange control of target artifact, creature, or land you control and target permanent an opponent controls that shares one of those types with it. If those permanents are exchanged this way, destroy all Auras attached to them.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ExchangeControlTargetEffect(Duration.EndOfGame,
"exchange control of target artifact, creature, or land you control and target permanent an opponent controls that shares one of those types with it."
+ " If those permanents are exchanged this way, destroy all Auras attached to them", false, true, true),
new ManaCostsImpl("{5}")
);
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new GauntletsOfChaosFirstTarget());
ability.addTarget(new GauntletsOfChaosSecondTarget());
this.addAbility(ability);
}
public GauntletsOfChaos(final GauntletsOfChaos card) {
super(card);
}
@Override
public GauntletsOfChaos copy() {
return new GauntletsOfChaos(this);
}
}
class GauntletsOfChaosFirstTarget extends TargetControlledPermanent {
public GauntletsOfChaosFirstTarget() {
super();
this.filter = this.filter.copy();
filter.add(Predicates.or(
new CardTypePredicate(CardType.ARTIFACT),
new CardTypePredicate(CardType.CREATURE),
new CardTypePredicate(CardType.LAND)));
setTargetName("artifact, creature, or land you control");
}
public GauntletsOfChaosFirstTarget(final GauntletsOfChaosFirstTarget target) {
super(target);
}
@Override
public boolean canTarget(UUID controllerId, UUID id, Ability source, Game game) {
if (super.canTarget(controllerId, id, source, game)) {
Set<CardType> cardTypes = getOpponentPermanentCardTypes(source.getSourceId(), controllerId, game);
Permanent permanent = game.getPermanent(id);
for (CardType type : permanent.getCardType()) {
if (cardTypes.contains(type)) {
return true;
}
}
}
return false;
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
// get all cardtypes from opponents permanents
Set<CardType> cardTypes = getOpponentPermanentCardTypes(sourceId, sourceControllerId, game);
Set<UUID> possibleTargets = new HashSet<>();
MageObject targetSource = game.getObject(sourceId);
for (Permanent permanent: game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
for (CardType type : permanent.getCardType()) {
if (cardTypes.contains(type)) {
possibleTargets.add(permanent.getId());
break;
}
}
}
}
return possibleTargets;
}
@Override
public GauntletsOfChaosFirstTarget copy() {
return new GauntletsOfChaosFirstTarget(this);
}
private EnumSet<CardType> getOpponentPermanentCardTypes(UUID sourceId, UUID sourceControllerId, Game game) {
Player controller = game.getPlayer(sourceControllerId);
EnumSet<CardType> cardTypes =EnumSet.noneOf(CardType.class);
if (controller != null) {
for (Permanent permanent: game.getBattlefield().getActivePermanents(sourceControllerId, game)) {
if (controller.hasOpponent(permanent.getControllerId(), game)) {
cardTypes.addAll(permanent.getCardType());
}
}
}
return cardTypes;
}
}
class GauntletsOfChaosSecondTarget extends TargetPermanent {
private Permanent firstTarget = null;
public GauntletsOfChaosSecondTarget() {
super();
this.filter = this.filter.copy();
filter.add(new ControllerPredicate(TargetController.OPPONENT));
setTargetName("permanent an opponent controls that shares one of those types with it");
}
public GauntletsOfChaosSecondTarget(final GauntletsOfChaosSecondTarget target) {
super(target);
this.firstTarget = target.firstTarget;
}
@Override
public boolean canTarget(UUID id, Ability source, Game game) {
if (super.canTarget(id, source, game)) {
Permanent target1 = game.getPermanent(source.getFirstTarget());
Permanent opponentPermanent = game.getPermanent(id);
if (target1 != null && opponentPermanent != null) {
return target1.shareTypes(opponentPermanent);
}
}
return false;
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> possibleTargets = new HashSet<>();
if (firstTarget != null) {
MageObject targetSource = game.getObject(sourceId);
for (Permanent permanent : game.getBattlefield().getActivePermanents(filter, sourceControllerId, sourceId, game)) {
if (!targets.containsKey(permanent.getId()) && permanent.canBeTargetedBy(targetSource, sourceControllerId, game)) {
if (permanent.shareTypes(firstTarget)) {
possibleTargets.add(permanent.getId());
}
}
}
}
return possibleTargets;
}
@Override
public boolean chooseTarget(Outcome outcome, UUID playerId, Ability source, Game game) {
firstTarget = game.getPermanent(source.getFirstTarget());
return super.chooseTarget(Outcome.Damage, playerId, source, game);
}
@Override
public GauntletsOfChaosSecondTarget copy() {
return new GauntletsOfChaosSecondTarget(this);
}
}

View file

@ -0,0 +1,108 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.g;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.EndOfCombatTriggeredAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Outcome;
import mage.counters.BoostCounter;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.BlockedByIdPredicate;
import mage.filter.predicate.permanent.BlockingAttackerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author L_J
*/
public class GreaterWerewolf extends CardImpl {
public GreaterWerewolf(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(2);
this.toughness = new MageInt(4);
// At end of combat, put a -0/-2 counter on each creature blocking or blocked by Greater Werewolf.
this.addAbility(new EndOfCombatTriggeredAbility(new GreaterWerewolfEffect(), false));
}
public GreaterWerewolf(final GreaterWerewolf card) {
super(card);
}
@Override
public GreaterWerewolf copy() {
return new GreaterWerewolf(this);
}
}
class GreaterWerewolfEffect extends OneShotEffect {
public GreaterWerewolfEffect() {
super(Outcome.Detriment);
this.staticText = "put a -0/-2 counter on each creature blocking or blocked by {this}";
}
public GreaterWerewolfEffect(final GreaterWerewolfEffect effect) {
super(effect);
}
@Override
public GreaterWerewolfEffect copy() {
return new GreaterWerewolfEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (sourcePermanent != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(Predicates.or(new BlockedByIdPredicate(sourcePermanent.getId()), new BlockingAttackerIdPredicate(sourcePermanent.getId())));
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) {
Effect effect = new AddCountersTargetEffect(new BoostCounter(0, -2), Outcome.UnboostCreature);
effect.setTargetPointer(new FixedTarget(permanent.getId()));
effect.apply(game, source);
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,110 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.i;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.combat.CantBlockAttachedEffect;
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class IronclawCurse extends CardImpl {
public IronclawCurse(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{R}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.UnboostCreature));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Enchanted creature gets 0/-1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEnchantedEffect(0, -1, Duration.WhileOnBattlefield)));
// Enchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new IronclawCurseEffect()));
}
public IronclawCurse(final IronclawCurse card) {
super(card);
}
@Override
public IronclawCurse copy() {
return new IronclawCurse(this);
}
}
class IronclawCurseEffect extends CantBlockAttachedEffect {
public IronclawCurseEffect() {
super(AttachmentType.AURA);
this.staticText = "Enchanted creature can't block creatures with power equal to or greater than the enchanted creature's toughness";
}
public IronclawCurseEffect(final IronclawCurseEffect effect) {
super(effect);
}
@Override
public IronclawCurseEffect copy() {
return new IronclawCurseEffect(this);
}
@Override
public boolean canBlock(Permanent attacker, Permanent blocker, Ability source, Game game) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo());
if (enchantment != null && enchantment.getAttachedTo() != null) {
return !(attacker.getPower().getValue() >= enchantedCreature.getToughness().getValue());
}
return true;
}
}

View file

@ -0,0 +1,93 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.r;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.BecomesTappedAttachedTriggeredAbility;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.GainLifeTargetEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.common.FilterArtifactPermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.target.TargetPermanent;
import mage.target.TargetPlayer;
/**
*
* @author L_J
*/
public class RelicBind extends CardImpl {
private static final FilterArtifactPermanent filter = new FilterArtifactPermanent("artifact an opponent controls");
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
}
public RelicBind(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{U}");
this.subtype.add(SubType.AURA);
// Enchant artifact an opponent controls
TargetPermanent auraTarget = new TargetPermanent(filter);
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// Whenever enchanted artifact becomes tapped, choose one
// Relic Bind deals 1 damage to target player.
Ability ability2 = new BecomesTappedAttachedTriggeredAbility(new DamageTargetEffect(1), "enchanted artifact");
ability2.addTarget(new TargetPlayer());
// Target player gains 1 life.
Mode mode = new Mode();
mode.getEffects().add(new GainLifeTargetEffect(1));
mode.getTargets().add(new TargetPlayer());
ability2.addMode(mode);
this.addAbility(ability2);
}
public RelicBind(final RelicBind card) {
super(card);
}
@Override
public RelicBind copy() {
return new RelicBind(this);
}
}

View file

@ -0,0 +1,145 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.s;
import java.util.Optional;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.SacrificeSourceUnlessPaysEffect;
import mage.abilities.effects.common.combat.CantAttackBlockAttachedEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J (based on jeffwadsworth)
*/
public class SerraBestiary extends CardImpl {
public SerraBestiary(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}{W}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Removal));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// At the beginning of your upkeep, sacrifice Serra Bestiary unless you pay {W}{W}.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new SacrificeSourceUnlessPaysEffect(new ManaCostsImpl("{W}{W}")), TargetController.YOU, false));
// Enchanted creature can't attack or block, and its activated abilities with {T} in their costs can't be activated.
Ability ability2 = new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackBlockAttachedEffect(AttachmentType.AURA));
ability2.addEffect(new SerraBestiaryRuleModifyingEffect());
this.addAbility(ability2);
}
public SerraBestiary(final SerraBestiary card) {
super(card);
}
@Override
public SerraBestiary copy() {
return new SerraBestiary(this);
}
}
class SerraBestiaryRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl {
public SerraBestiaryRuleModifyingEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = ", and its activated abilities with {T} in their costs can't be activated";
}
public SerraBestiaryRuleModifyingEffect(final SerraBestiaryRuleModifyingEffect effect) {
super(effect);
}
@Override
public SerraBestiaryRuleModifyingEffect copy() {
return new SerraBestiaryRuleModifyingEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
Permanent enchantedCreature = game.getPermanent(enchantment.getAttachedTo());
if (enchantment != null && enchantment.getAttachedTo() != null) {
MageObject object = game.getObject(event.getSourceId());
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
if (ability.isPresent()
&& object != null
&& object.isCreature()
&& object.getId().equals(enchantedCreature.getId())
&& game.getState().getPlayersInRange(source.getControllerId(), game).contains(event.getPlayerId())) {
if (ability.get().getCosts().stream().anyMatch((cost) -> (cost instanceof TapSourceCost))) {
return true;
}
}
}
return false;
}
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
return "Enchanted creature can't use its activated abilities that use {tap} in their costs.";
}
}

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.cards.v;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.delayed.AtTheEndOfCombatDelayedTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.watchers.common.BlockedAttackerWatcher;
/**
*
* @author LevelX2
*/
public class VenomousBreath extends CardImpl {
public VenomousBreath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{3}{G}");
// Choose target creature. At this turn's next end of combat, destroy all creatures that blocked or were blocked by it this turn.
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
this.getSpellAbility().addEffect(new InfoEffect("Choose target creature"));
this.getSpellAbility().addEffect(new VenomousBreathCreateDelayedTriggeredAbilityEffect());
this.getSpellAbility().addWatcher(new BlockedAttackerWatcher());
}
public VenomousBreath(final VenomousBreath card) {
super(card);
}
@Override
public VenomousBreath copy() {
return new VenomousBreath(this);
}
}
class VenomousBreathCreateDelayedTriggeredAbilityEffect extends OneShotEffect {
public VenomousBreathCreateDelayedTriggeredAbilityEffect() {
super(Outcome.Benefit);
this.staticText = "At this turn's next end of combat, destroy all creatures that blocked or were blocked by it this turn";
}
public VenomousBreathCreateDelayedTriggeredAbilityEffect(final VenomousBreathCreateDelayedTriggeredAbilityEffect effect) {
super(effect);
}
@Override
public VenomousBreathCreateDelayedTriggeredAbilityEffect copy() {
return new VenomousBreathCreateDelayedTriggeredAbilityEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
if (!source.getTargets().isEmpty() && source.getFirstTarget() != null) {
MageObjectReference mor = new MageObjectReference(source.getFirstTarget(), game);
AtTheEndOfCombatDelayedTriggeredAbility delayedAbility = new AtTheEndOfCombatDelayedTriggeredAbility(new VenomousBreathEffect(mor));
game.addDelayedTriggeredAbility(delayedAbility, source);
return true;
}
return false;
}
}
class VenomousBreathEffect extends OneShotEffect {
MageObjectReference targetCreature;
public VenomousBreathEffect(MageObjectReference targetCreature) {
super(Outcome.DestroyPermanent);
this.targetCreature = targetCreature;
}
public VenomousBreathEffect(final VenomousBreathEffect effect) {
super(effect);
targetCreature = effect.targetCreature;
}
@Override
public VenomousBreathEffect copy() {
return new VenomousBreathEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null && targetCreature != null) {
BlockedAttackerWatcher watcher = (BlockedAttackerWatcher) game.getState().getWatchers().get(BlockedAttackerWatcher.class.getSimpleName());
if (watcher != null) {
List<Permanent> toDestroy = new ArrayList<>();
for (Permanent creature : game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), source.getSourceId(), game)) {
if (!creature.getId().equals(targetCreature.getSourceId())) {
if (watcher.creatureHasBlockedAttacker(new MageObjectReference(creature, game), targetCreature, game) || watcher.creatureHasBlockedAttacker(targetCreature, new MageObjectReference(creature, game), game)) {
toDestroy.add(creature);
}
}
}
for (Permanent creature : toDestroy) {
creature.destroy(source.getSourceId(), game, false);
}
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,59 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.v;
import java.util.UUID;
import mage.abilities.effects.common.LookLibraryTopCardTargetPlayerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.target.TargetPlayer;
/**
*
* @author L_J
*/
public class Visions extends CardImpl {
public Visions(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{W}");
// Look at the top five cards of target player's library. You may then have that player shuffle that library.
this.getSpellAbility().addEffect(new LookLibraryTopCardTargetPlayerEffect(5, false, true));
this.getSpellAbility().addTarget(new TargetPlayer());
}
public Visions(final Visions card) {
super(card);
}
@Override
public Visions copy() {
return new Visions(this);
}
}

View file

@ -0,0 +1,134 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.w;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.BlocksTriggeredAbility;
import mage.abilities.effects.RestrictionEffect;
import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.TurnPhase;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author L_J (based on LevelX2)
*/
public class WallOfDust extends CardImpl {
public WallOfDust(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.WALL);
this.power = new MageInt(1);
this.toughness = new MageInt(4);
// Defender
this.addAbility(DefenderAbility.getInstance());
// Whenever Wall of Dust blocks a creature, that creature can't attack during its controller's next turn.
this.addAbility(new BlocksTriggeredAbility(new WallOfDustRestrictionEffect(), false, true));
}
public WallOfDust(final WallOfDust card) {
super(card);
}
@Override
public WallOfDust copy() {
return new WallOfDust(this);
}
}
class WallOfDustRestrictionEffect extends RestrictionEffect {
int nextTurnTargetController = 0;
protected MageObjectReference targetPermanentReference;
public WallOfDustRestrictionEffect() {
super(Duration.Custom);
staticText = "that creature can't attack during its controller's next turn";
}
public WallOfDustRestrictionEffect(final WallOfDustRestrictionEffect effect) {
super(effect);
this.nextTurnTargetController = effect.nextTurnTargetController;
this.targetPermanentReference = effect.targetPermanentReference;
}
@Override
public WallOfDustRestrictionEffect copy() {
return new WallOfDustRestrictionEffect(this);
}
@Override
public boolean isInactive(Ability source, Game game) {
if (targetPermanentReference == null) {
return true;
}
Permanent targetPermanent = targetPermanentReference.getPermanent(game);
if (targetPermanent == null) {
return true;
}
if (nextTurnTargetController == 0 && startingTurn != game.getTurnNum() && game.getActivePlayerId().equals(targetPermanent.getControllerId())) {
nextTurnTargetController = game.getTurnNum();
}
return game.getPhase().getType() == TurnPhase.END && nextTurnTargetController > 0 && game.getTurnNum() > nextTurnTargetController;
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
if (getTargetPointer().getFirst(game, source) == null) {
discard();
} else {
targetPermanentReference = new MageObjectReference(getTargetPointer().getFirst(game, source), game);
}
}
@Override
public boolean applies(Permanent permanent, Ability source, Game game) {
if (permanent.getId().equals(getTargetPointer().getFirst(game, source))) {
if (game.getActivePlayerId().equals(permanent.getControllerId())) {
return true;
}
}
return false;
}
public boolean canAttack(Game game) {
return false;
}
}

View file

@ -95,6 +95,7 @@ public class Chronicles extends ExpansionSet {
cards.add(new SetCardInfo("Flash Flood", 21, Rarity.COMMON, mage.cards.f.FlashFlood.class));
cards.add(new SetCardInfo("Fountain of Youth", 78, Rarity.COMMON, mage.cards.f.FountainOfYouth.class));
cards.add(new SetCardInfo("Gabriel Angelfire", 111, Rarity.RARE, mage.cards.g.GabrielAngelfire.class));
cards.add(new SetCardInfo("Gauntlets of Chaos", 79, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class));
cards.add(new SetCardInfo("Ghazban Ogre", 37, Rarity.COMMON, mage.cards.g.GhazbanOgre.class));
cards.add(new SetCardInfo("Goblin Artisans", 48, Rarity.UNCOMMON, mage.cards.g.GoblinArtisans.class));
cards.add(new SetCardInfo("Goblin Digging Team", 49, Rarity.COMMON, mage.cards.g.GoblinDiggingTeam.class));

View file

@ -43,6 +43,7 @@ public class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Ambush Party", 208, Rarity.COMMON, mage.cards.a.AmbushParty.class));
cards.add(new SetCardInfo("Amulet of Kroog", 347, Rarity.COMMON, mage.cards.a.AmuletOfKroog.class));
cards.add(new SetCardInfo("An-Havva Constable", 139, Rarity.RARE, mage.cards.a.AnHavvaConstable.class));
cards.add(new SetCardInfo("Anti-Magic Aura", 72, Rarity.UNCOMMON, mage.cards.a.AntiMagicAura.class));
cards.add(new SetCardInfo("Angry Mob", 280, Rarity.UNCOMMON, mage.cards.a.AngryMob.class));
cards.add(new SetCardInfo("Animate Dead", 2, Rarity.UNCOMMON, mage.cards.a.AnimateDead.class));
cards.add(new SetCardInfo("Animate Wall", 281, Rarity.RARE, mage.cards.a.AnimateWall.class));
@ -101,6 +102,7 @@ public class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("City of Brass", 413, Rarity.RARE, mage.cards.c.CityOfBrass.class));
cards.add(new SetCardInfo("Clay Statue", 355, Rarity.COMMON, mage.cards.c.ClayStatue.class));
cards.add(new SetCardInfo("Clockwork Beast", 356, Rarity.RARE, mage.cards.c.ClockworkBeast.class));
cards.add(new SetCardInfo("Clockwork Steed", 257, Rarity.UNCOMMON, mage.cards.c.ClockworkSteed.class));
cards.add(new SetCardInfo("Cockatrice", 146, Rarity.RARE, mage.cards.c.Cockatrice.class));
cards.add(new SetCardInfo("Colossus of Sardia", 358, Rarity.RARE, mage.cards.c.ColossusOfSardia.class));
cards.add(new SetCardInfo("Conquer", 216, Rarity.UNCOMMON, mage.cards.c.Conquer.class));
@ -185,10 +187,12 @@ public class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Foxfire", 157, Rarity.COMMON, mage.cards.f.Foxfire.class));
cards.add(new SetCardInfo("Fountain of Youth", 372, Rarity.UNCOMMON, mage.cards.f.FountainOfYouth.class));
cards.add(new SetCardInfo("Frozen Shade", 25, Rarity.COMMON, mage.cards.f.FrozenShade.class));
cards.add(new SetCardInfo("Funeral March", 26, Rarity.COMMON, mage.cards.f.FuneralMarch.class));
cards.add(new SetCardInfo("Fungusaur", 158, Rarity.RARE, mage.cards.f.Fungusaur.class));
cards.add(new SetCardInfo("Fyndhorn Elder", 159, Rarity.UNCOMMON, mage.cards.f.FyndhornElder.class));
cards.add(new SetCardInfo("Game of Chaos", 232, Rarity.RARE, mage.cards.g.GameOfChaos.class));
cards.add(new SetCardInfo("Gaseous Form", 90, Rarity.COMMON, mage.cards.g.GaseousForm.class));
cards.add(new SetCardInfo("Gauntlets of Chaos", 373, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class));
cards.add(new SetCardInfo("Ghazban Ogre", 160, Rarity.COMMON, mage.cards.g.GhazbanOgre.class));
cards.add(new SetCardInfo("Giant Growth", 161, Rarity.COMMON, mage.cards.g.GiantGrowth.class));
cards.add(new SetCardInfo("Giant Spider", 162, Rarity.COMMON, mage.cards.g.GiantSpider.class));
@ -203,6 +207,7 @@ public class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Goblin Warrens", 238, Rarity.RARE, mage.cards.g.GoblinWarrens.class));
cards.add(new SetCardInfo("Grapeshot Catapult", 375, Rarity.COMMON, mage.cards.g.GrapeshotCatapult.class));
cards.add(new SetCardInfo("Greater Realm of Preservation", 307, Rarity.UNCOMMON, mage.cards.g.GreaterRealmOfPreservation.class));
cards.add(new SetCardInfo("Greater Werewolf", 28, Rarity.UNCOMMON, mage.cards.g.GreaterWerewolf.class));
cards.add(new SetCardInfo("Grizzly Bears", 163, Rarity.COMMON, mage.cards.g.GrizzlyBears.class));
cards.add(new SetCardInfo("Havenwood Battleground", 421, Rarity.UNCOMMON, mage.cards.h.HavenwoodBattleground.class));
cards.add(new SetCardInfo("Heal", 308, Rarity.COMMON, mage.cards.h.Heal.class));
@ -231,6 +236,7 @@ public class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Infinite Hourglass", 378, Rarity.RARE, mage.cards.i.InfiniteHourglass.class));
cards.add(new SetCardInfo("Initiates of the Ebon Hand", 31, Rarity.COMMON, InitiatesOfTheEbonHand.class));
cards.add(new SetCardInfo("Instill Energy", 166, Rarity.UNCOMMON, mage.cards.i.InstillEnergy.class));
cards.add(new SetCardInfo("Ironclaw Curse", 244, Rarity.RARE, mage.cards.i.IronclawCurse.class));
cards.add(new SetCardInfo("Ironclaw Orcs", 245, Rarity.COMMON, mage.cards.i.IronclawOrcs.class));
cards.add(new SetCardInfo("Ironroot Treefolk", 167, Rarity.COMMON, mage.cards.i.IronrootTreefolk.class));
cards.add(new SetCardInfo("Iron Star", 379, Rarity.UNCOMMON, mage.cards.i.IronStar.class));
@ -373,6 +379,7 @@ public class FifthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Segovian Leviathan", 122, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class));
cards.add(new SetCardInfo("Sengir Autocrat", 55, Rarity.RARE, mage.cards.s.SengirAutocrat.class));
cards.add(new SetCardInfo("Serpent Generator", 397, Rarity.RARE, mage.cards.s.SerpentGenerator.class));
cards.add(new SetCardInfo("Serra Bestiary", 336, Rarity.UNCOMMON, mage.cards.s.SerraBestiary.class));
cards.add(new SetCardInfo("Serra Paladin", 337, Rarity.UNCOMMON, mage.cards.s.SerraPaladin.class));
cards.add(new SetCardInfo("Shanodin Dryads", 187, Rarity.COMMON, mage.cards.s.ShanodinDryads.class));
cards.add(new SetCardInfo("Shapeshifter", 398, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class));

View file

@ -148,6 +148,7 @@ public class FourthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Prodigal Sorcerer", 94, Rarity.COMMON, mage.cards.p.ProdigalSorcerer.class));
cards.add(new SetCardInfo("Psionic Entity", 95, Rarity.RARE, mage.cards.p.PsionicEntity.class));
cards.add(new SetCardInfo("Psychic Venom", 96, Rarity.COMMON, mage.cards.p.PsychicVenom.class));
cards.add(new SetCardInfo("Relic Bind", 97, Rarity.RARE, mage.cards.r.RelicBind.class));
cards.add(new SetCardInfo("Sea Serpent", 98, Rarity.COMMON, mage.cards.s.SeaSerpent.class));
cards.add(new SetCardInfo("Segovian Leviathan", 99, Rarity.UNCOMMON, mage.cards.s.SegovianLeviathan.class));
cards.add(new SetCardInfo("Sindbad", 100, Rarity.UNCOMMON, mage.cards.s.Sindbad.class));
@ -294,6 +295,7 @@ public class FourthEdition extends ExpansionSet {
cards.add(new SetCardInfo("The Brute", 226, Rarity.COMMON, mage.cards.t.TheBrute.class));
cards.add(new SetCardInfo("Tunnel", 227, Rarity.UNCOMMON, mage.cards.t.Tunnel.class));
cards.add(new SetCardInfo("Uthden Troll", 228, Rarity.UNCOMMON, mage.cards.u.UthdenTroll.class));
cards.add(new SetCardInfo("Wall of Dust", 229, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class));
cards.add(new SetCardInfo("Wall of Fire", 230, Rarity.UNCOMMON, mage.cards.w.WallOfFire.class));
cards.add(new SetCardInfo("Wall of Stone", 231, Rarity.UNCOMMON, mage.cards.w.WallOfStone.class));
cards.add(new SetCardInfo("Winds of Change", 232, Rarity.RARE, mage.cards.w.WindsOfChange.class));
@ -350,6 +352,7 @@ public class FourthEdition extends ExpansionSet {
cards.add(new SetCardInfo("Spirit Link", 51, Rarity.UNCOMMON, mage.cards.s.SpiritLink.class));
cards.add(new SetCardInfo("Swords to Plowshares", 52, Rarity.UNCOMMON, mage.cards.s.SwordsToPlowshares.class));
cards.add(new SetCardInfo("Tundra Wolves", 53, Rarity.COMMON, mage.cards.t.TundraWolves.class));
cards.add(new SetCardInfo("Visions", 54, Rarity.UNCOMMON, mage.cards.v.Visions.class));
cards.add(new SetCardInfo("Wall of Swords", 55, Rarity.UNCOMMON, mage.cards.w.WallOfSwords.class));
cards.add(new SetCardInfo("White Knight", 56, Rarity.UNCOMMON, mage.cards.w.WhiteKnight.class));
cards.add(new SetCardInfo("White Ward", 57, Rarity.UNCOMMON, mage.cards.w.WhiteWard.class));

View file

@ -103,6 +103,7 @@ public class Homelands extends ExpansionSet {
cards.add(new SetCardInfo("Chain Stasis", 28, Rarity.RARE, mage.cards.c.ChainStasis.class));
cards.add(new SetCardInfo("Chandler", 88, Rarity.COMMON, mage.cards.c.Chandler.class));
cards.add(new SetCardInfo("Clockwork Gnomes", 127, Rarity.COMMON, mage.cards.c.ClockworkGnomes.class));
cards.add(new SetCardInfo("Clockwork Steed", 128, Rarity.UNCOMMON, mage.cards.c.ClockworkSteed.class));
cards.add(new SetCardInfo("Clockwork Swarm", 129, Rarity.COMMON, mage.cards.c.ClockworkSwarm.class));
cards.add(new SetCardInfo("Coral Reef", 29, Rarity.COMMON, mage.cards.c.CoralReef.class));
cards.add(new SetCardInfo("Dark Maze", 30, Rarity.COMMON, mage.cards.d.DarkMaze.class, NON_FULL_USE_VARIOUS));
@ -126,14 +127,17 @@ public class Homelands extends ExpansionSet {
cards.add(new SetCardInfo("Folk of An-Havva", 58, Rarity.COMMON, FolkOfAnHavva.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Folk of An-Havva", 59, Rarity.COMMON, FolkOfAnHavva.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Forget", 32, Rarity.RARE, mage.cards.f.Forget.class));
cards.add(new SetCardInfo("Funeral March", 11, Rarity.UNCOMMON, mage.cards.f.FuneralMarch.class));
cards.add(new SetCardInfo("Ghost Hounds", 12, Rarity.UNCOMMON, mage.cards.g.GhostHounds.class));
cards.add(new SetCardInfo("Grandmother Sengir", 13, Rarity.RARE, mage.cards.g.GrandmotherSengir.class));
cards.add(new SetCardInfo("Greater Werewolf", 14, Rarity.UNCOMMON, mage.cards.g.GreaterWerewolf.class));
cards.add(new SetCardInfo("Hazduhr the Abbot", 110, Rarity.RARE, mage.cards.h.HazduhrTheAbbot.class));
cards.add(new SetCardInfo("Headstone", 15, Rarity.COMMON, mage.cards.h.Headstone.class));
cards.add(new SetCardInfo("Hungry Mist", 60, Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Hungry Mist", 61, Rarity.COMMON, mage.cards.h.HungryMist.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ihsan's Shade", 16, Rarity.UNCOMMON, mage.cards.i.IhsansShade.class));
cards.add(new SetCardInfo("Irini Sengir", 17, Rarity.UNCOMMON, mage.cards.i.IriniSengir.class));
cards.add(new SetCardInfo("Ironclaw Curse", 96, Rarity.RARE, mage.cards.i.IronclawCurse.class));
cards.add(new SetCardInfo("Jinx", 36, Rarity.COMMON, mage.cards.j.Jinx.class));
cards.add(new SetCardInfo("Joven", 97, Rarity.COMMON, mage.cards.j.Joven.class));
cards.add(new SetCardInfo("Joven's Tools", 133, Rarity.UNCOMMON, mage.cards.j.JovensTools.class));
@ -166,6 +170,7 @@ public class Homelands extends ExpansionSet {
cards.add(new SetCardInfo("Sengir Bats", 20, Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Sengir Bats", 21, Rarity.COMMON, SengirBats.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Serra Aviary", 118, Rarity.RARE, mage.cards.s.SerraAviary.class));
cards.add(new SetCardInfo("Serra Bestiary", 119, Rarity.UNCOMMON, mage.cards.s.SerraBestiary.class));
cards.add(new SetCardInfo("Serra Paladin", 121, Rarity.COMMON, mage.cards.s.SerraPaladin.class));
cards.add(new SetCardInfo("Serrated Arrows", 135, Rarity.COMMON, mage.cards.s.SerratedArrows.class));
cards.add(new SetCardInfo("Shrink", 70, Rarity.COMMON, mage.cards.s.Shrink.class, NON_FULL_USE_VARIOUS));

View file

@ -346,6 +346,7 @@ public class IceAge extends ExpansionSet {
cards.add(new SetCardInfo("Updraft", 105, Rarity.UNCOMMON, mage.cards.u.Updraft.class));
cards.add(new SetCardInfo("Urza's Bauble", 318, Rarity.UNCOMMON, mage.cards.u.UrzasBauble.class));
cards.add(new SetCardInfo("Veldt", 358, Rarity.RARE, mage.cards.v.Veldt.class));
cards.add(new SetCardInfo("Venomous Breath", 161, Rarity.UNCOMMON, mage.cards.v.VenomousBreath.class));
cards.add(new SetCardInfo("Vertigo", 222, Rarity.UNCOMMON, mage.cards.v.Vertigo.class));
cards.add(new SetCardInfo("Vexing Arcanix", 319, Rarity.RARE, mage.cards.v.VexingArcanix.class));
cards.add(new SetCardInfo("Vibrating Sphere", 320, Rarity.RARE, mage.cards.v.VibratingSphere.class));

View file

@ -66,6 +66,7 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Amrou Kithkin", 172, Rarity.COMMON, mage.cards.a.AmrouKithkin.class));
cards.add(new SetCardInfo("Angelic Voices", 173, Rarity.RARE, mage.cards.a.AngelicVoices.class));
cards.add(new SetCardInfo("Angus Mackenzie", 257, Rarity.RARE, mage.cards.a.AngusMackenzie.class));
cards.add(new SetCardInfo("Anti-Magic Aura", 45, Rarity.COMMON, mage.cards.a.AntiMagicAura.class));
cards.add(new SetCardInfo("Arboria", 88, Rarity.UNCOMMON, mage.cards.a.Arboria.class));
cards.add(new SetCardInfo("Arcades Sabboth", 258, Rarity.RARE, mage.cards.a.ArcadesSabboth.class));
cards.add(new SetCardInfo("Arena of the Ancients", 215, Rarity.RARE, mage.cards.a.ArenaOfTheAncients.class));
@ -131,6 +132,7 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Frost Giant", 146, Rarity.UNCOMMON, mage.cards.f.FrostGiant.class));
cards.add(new SetCardInfo("Gabriel Angelfire", 266, Rarity.RARE, mage.cards.g.GabrielAngelfire.class));
cards.add(new SetCardInfo("Gaseous Form", 59, Rarity.COMMON, mage.cards.g.GaseousForm.class));
cards.add(new SetCardInfo("Gauntlets of Chaos", 222, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class));
cards.add(new SetCardInfo("Ghosts of the Damned", 12, Rarity.COMMON, mage.cards.g.GhostsOfTheDamned.class));
cards.add(new SetCardInfo("Giant Strength", 147, Rarity.COMMON, mage.cards.g.GiantStrength.class));
cards.add(new SetCardInfo("Giant Turtle", 102, Rarity.COMMON, mage.cards.g.GiantTurtle.class));
@ -235,6 +237,7 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Red Mana Battery", 236, Rarity.UNCOMMON, mage.cards.r.RedManaBattery.class));
cards.add(new SetCardInfo("Reincarnation", 115, Rarity.UNCOMMON, mage.cards.r.Reincarnation.class));
cards.add(new SetCardInfo("Relic Barrier", 237, Rarity.UNCOMMON, mage.cards.r.RelicBarrier.class));
cards.add(new SetCardInfo("Relic Bind", 71, Rarity.UNCOMMON, mage.cards.r.RelicBind.class));
cards.add(new SetCardInfo("Remove Enchantments", 202, Rarity.COMMON, mage.cards.r.RemoveEnchantments.class));
cards.add(new SetCardInfo("Remove Soul", 72, Rarity.COMMON, mage.cards.r.RemoveSoul.class));
cards.add(new SetCardInfo("Reset", 73, Rarity.UNCOMMON, mage.cards.r.Reset.class));
@ -293,8 +296,10 @@ public class Legends extends ExpansionSet {
cards.add(new SetCardInfo("Urborg", 255, Rarity.UNCOMMON, mage.cards.u.Urborg.class));
cards.add(new SetCardInfo("Vaevictis Asmadi", 309, Rarity.RARE, mage.cards.v.VaevictisAsmadi.class));
cards.add(new SetCardInfo("Vampire Bats", 39, Rarity.COMMON, mage.cards.v.VampireBats.class));
cards.add(new SetCardInfo("Visions", 210, Rarity.UNCOMMON, mage.cards.v.Visions.class));
cards.add(new SetCardInfo("Walking Dead", 40, Rarity.COMMON, mage.cards.w.WalkingDead.class));
cards.add(new SetCardInfo("Wall of Caltrops", 211, Rarity.COMMON, mage.cards.w.WallOfCaltrops.class));
cards.add(new SetCardInfo("Wall of Dust", 165, Rarity.UNCOMMON, mage.cards.w.WallOfDust.class));
cards.add(new SetCardInfo("Wall of Earth", 166, Rarity.COMMON, mage.cards.w.WallOfEarth.class));
cards.add(new SetCardInfo("Wall of Heat", 167, Rarity.COMMON, mage.cards.w.WallOfHeat.class));
cards.add(new SetCardInfo("Wall of Light", 212, Rarity.UNCOMMON, mage.cards.w.WallOfLight.class));

View file

@ -98,6 +98,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Burnout", 121, Rarity.UNCOMMON, mage.cards.b.Burnout.class));
cards.add(new SetCardInfo("Carapace", 155, Rarity.COMMON, mage.cards.c.Carapace.class));
cards.add(new SetCardInfo("Caribou Range", 8, Rarity.RARE, mage.cards.c.CaribouRange.class));
cards.add(new SetCardInfo("Clockwork Steed", 205, Rarity.UNCOMMON, mage.cards.c.ClockworkSteed.class));
cards.add(new SetCardInfo("Combat Medic", 9, Rarity.COMMON, CombatMedic.class));
cards.add(new SetCardInfo("Conquer", 122, Rarity.UNCOMMON, mage.cards.c.Conquer.class));
cards.add(new SetCardInfo("Counterspell", 44, Rarity.UNCOMMON, mage.cards.c.Counterspell.class));
@ -138,6 +139,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Forgotten Lore", 164, Rarity.UNCOMMON, mage.cards.f.ForgottenLore.class));
cards.add(new SetCardInfo("Foul Familiar", 90, Rarity.COMMON, mage.cards.f.FoulFamiliar.class));
cards.add(new SetCardInfo("Fumarole", 194, Rarity.UNCOMMON, mage.cards.f.Fumarole.class));
cards.add(new SetCardInfo("Funeral March", 91, Rarity.COMMON, mage.cards.f.FuneralMarch.class));
cards.add(new SetCardInfo("Fungal Bloom", 165, Rarity.RARE, mage.cards.f.FungalBloom.class));
cards.add(new SetCardInfo("Fyndhorn Pollen", 166, Rarity.RARE, mage.cards.f.FyndhornPollen.class));
cards.add(new SetCardInfo("Gangrenous Zombies", 92, Rarity.COMMON, mage.cards.g.GangrenousZombies.class));
@ -178,7 +180,7 @@ public class MastersEditionII extends ExpansionSet {
cards.add(new SetCardInfo("Krovikan Fetish", 100, Rarity.COMMON, mage.cards.k.KrovikanFetish.class));
cards.add(new SetCardInfo("Krovikan Horror", 101, Rarity.RARE, mage.cards.k.KrovikanHorror.class));
cards.add(new SetCardInfo("Krovikan Sorcerer", 51, Rarity.COMMON, mage.cards.k.KrovikanSorcerer.class));
cards.add(new SetCardInfo("Lat-Nam's Legacy", 52, Rarity.COMMON, mage.cards.l.LatNamsLegacy.class));
cards.add(new SetCardInfo("Lat-Nam's Legacy", 52, Rarity.COMMON, mage.cards.l.LatNamsLegacy.class));
cards.add(new SetCardInfo("Leaping Lizard", 171, Rarity.COMMON, mage.cards.l.LeapingLizard.class));
cards.add(new SetCardInfo("Lim-Dul's High Guard", 103, Rarity.UNCOMMON, LimDulsHighGuard.class));
cards.add(new SetCardInfo("Lodestone Bauble", 213, Rarity.RARE, mage.cards.l.LodestoneBauble.class));

View file

@ -126,6 +126,7 @@ public class MastersEditionIII extends ExpansionSet {
cards.add(new SetCardInfo("Frost Giant", 101, Rarity.UNCOMMON, mage.cards.f.FrostGiant.class));
cards.add(new SetCardInfo("Gabriel Angelfire", 148, Rarity.RARE, mage.cards.g.GabrielAngelfire.class));
cards.add(new SetCardInfo("Gaea's Touch", 120, Rarity.UNCOMMON, mage.cards.g.GaeasTouch.class));
cards.add(new SetCardInfo("Gauntlets of Chaos", 196, Rarity.RARE, mage.cards.g.GauntletsOfChaos.class));
cards.add(new SetCardInfo("Ghostly Visit", 67, Rarity.COMMON, mage.cards.g.GhostlyVisit.class));
cards.add(new SetCardInfo("Ghosts of the Damned", 68, Rarity.COMMON, mage.cards.g.GhostsOfTheDamned.class));
cards.add(new SetCardInfo("Giant Growth", 121, Rarity.COMMON, mage.cards.g.GiantGrowth.class));

View file

@ -254,6 +254,7 @@ public class MastersEditionIV extends ExpansionSet {
cards.add(new SetCardInfo("Serendib Djinn", 61, Rarity.RARE, mage.cards.s.SerendibDjinn.class));
cards.add(new SetCardInfo("Serra Angel", 25, Rarity.UNCOMMON, mage.cards.s.SerraAngel.class));
cards.add(new SetCardInfo("Serra Aviary", 26, Rarity.UNCOMMON, mage.cards.s.SerraAviary.class));
cards.add(new SetCardInfo("Serra Bestiary", 27, Rarity.COMMON, mage.cards.s.SerraBestiary.class));
cards.add(new SetCardInfo("Shapeshifter", 226, Rarity.UNCOMMON, mage.cards.s.Shapeshifter.class));
cards.add(new SetCardInfo("Shivan Dragon", 136, Rarity.RARE, mage.cards.s.ShivanDragon.class));
cards.add(new SetCardInfo("Sinkhole", 97, Rarity.RARE, mage.cards.s.Sinkhole.class));

View file

@ -360,6 +360,7 @@ public class MercadianMasques extends ExpansionSet {
cards.add(new SetCardInfo("Unmask", 168, Rarity.RARE, mage.cards.u.Unmask.class));
cards.add(new SetCardInfo("Uphill Battle", 222, Rarity.UNCOMMON, mage.cards.u.UphillBattle.class));
cards.add(new SetCardInfo("Vendetta", 170, Rarity.COMMON, mage.cards.v.Vendetta.class));
cards.add(new SetCardInfo("Venomous Breath", 281, Rarity.UNCOMMON, mage.cards.v.VenomousBreath.class));
cards.add(new SetCardInfo("Venomous Dragonfly", 282, Rarity.COMMON, mage.cards.v.VenomousDragonfly.class));
cards.add(new SetCardInfo("Vernal Equinox", 283, Rarity.RARE, mage.cards.v.VernalEquinox.class));
cards.add(new SetCardInfo("Vine Dryad", 284, Rarity.RARE, mage.cards.v.VineDryad.class));

View file

@ -47,11 +47,13 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
protected int amount;
protected boolean putToGraveyard;
protected boolean mayShuffleAfter; // for Visions
public LookLibraryTopCardTargetPlayerEffect(int amount) {
super(Outcome.Benefit);
this.amount = amount;
this.putToGraveyard = false;
this.mayShuffleAfter = false;
setText();
}
@ -59,6 +61,15 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
super(Outcome.Benefit);
this.amount = amount;
this.putToGraveyard = putToGraveyard;
this.mayShuffleAfter = false;
setText();
}
public LookLibraryTopCardTargetPlayerEffect(int amount, boolean putToGraveyard, boolean mayShuffleAfter) {
super(Outcome.Benefit);
this.amount = amount;
this.putToGraveyard = putToGraveyard;
this.mayShuffleAfter = mayShuffleAfter;
setText();
}
@ -70,6 +81,7 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
super(effect);
amount = effect.amount;
putToGraveyard = effect.putToGraveyard;
mayShuffleAfter = effect.mayShuffleAfter;
}
@Override
@ -95,6 +107,11 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
}
}
}
if (mayShuffleAfter) {
if (player.chooseUse(Outcome.Benefit, (player == targetPlayer ? "Shuffle your library?" : "Do you want the chosen player to shuffle his or her library?"), source, game)) {
targetPlayer.shuffleLibrary(source, game);
}
}
return true;
}
return false;
@ -118,6 +135,9 @@ public class LookLibraryTopCardTargetPlayerEffect extends OneShotEffect {
}
sb.append(" into that player's graveyard");
}
if (mayShuffleAfter) {
sb.append(". You may then have that player shuffle that library");
}
this.staticText = sb.toString();
}
}

View file

@ -39,6 +39,9 @@ import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
@ -50,6 +53,7 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
private String rule;
private boolean withSource;
private boolean withSecondTarget;
private boolean destroyAttachedAuras;
private Map<UUID, Integer> zoneChangeCounter = new HashMap<>();
private Map<UUID, UUID> lockedControllers = new HashMap<>();
@ -62,9 +66,14 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
}
public ExchangeControlTargetEffect(Duration duration, String rule, boolean withSource, boolean withSecondTarget) {
this(duration, rule, withSource, withSecondTarget, false);
}
public ExchangeControlTargetEffect(Duration duration, String rule, boolean withSource, boolean withSecondTarget, boolean destroyAttachedAuras) {
super(duration, Layer.ControlChangingEffects_2, SubLayer.NA, Outcome.GainControl);
this.withSource = withSource;
this.withSecondTarget = withSecondTarget;
this.destroyAttachedAuras = destroyAttachedAuras;
this.rule = rule;
}
@ -73,6 +82,7 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
this.rule = effect.rule;
this.withSource = effect.withSource;
this.withSecondTarget = effect.withSecondTarget;
this.destroyAttachedAuras = effect.destroyAttachedAuras;
this.lockedControllers = new HashMap<>(effect.lockedControllers);
this.zoneChangeCounter = new HashMap<>(effect.zoneChangeCounter);
}
@ -141,6 +151,16 @@ public class ExchangeControlTargetEffect extends ContinuousEffectImpl {
}
permanent.changeControllerId(lockedControllers.get(permanent.getId()), game);
permanent.getAbilities().setControllerId(lockedControllers.get(permanent.getId()));
if (destroyAttachedAuras) {
FilterPermanent filter = new FilterPermanent();
filter.add(new SubtypePredicate(SubType.AURA));
for (UUID attachmentId : new HashSet<>(permanent.getAttachments())) {
Permanent attachment = game.getPermanent(attachmentId);
if (attachment != null && filter.match(attachment, game)) {
attachment.destroy(source.getSourceId(), game, false);
}
}
}
}
if (!toDelete.isEmpty()) {
for (UUID uuid : toDelete) {