Merge pull request #25 from magefree/master

Merge https://github.com/magefree/mage
This commit is contained in:
Zzooouhh 2017-12-25 15:36:08 +01:00 committed by GitHub
commit 002a3e84ef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
47 changed files with 2437 additions and 245 deletions

View file

@ -429,17 +429,41 @@ public class MageFrame extends javax.swing.JFrame implements MageClient {
}
}
private boolean isChrismasTime(){
// from december 15 to january 15
Calendar cal = Calendar.getInstance();
int currentYear = cal.get(Calendar.YEAR);
Date currentTime = cal.getTime();
Date chrisFrom = new GregorianCalendar(currentYear, Calendar.DECEMBER, 15).getTime();
Date chrisTo = new GregorianCalendar(currentYear + 1, Calendar.JANUARY, 15 + 1).getTime();
return currentTime.after(chrisFrom) && currentTime.before(chrisTo);
}
private void addMageLabel() {
if (liteMode || grayMode) {
return;
}
String filename = "/label-xmage.png";
String filename;
float ratio;
if (isChrismasTime()){
// chrismass logo
LOGGER.info("Yo Ho Ho, Merry Christmas and a Happy New Year");
filename = "/label-xmage-christmas.png";
ratio = 539.0f / 318.0f;
}else{
// standard logo
filename = "/label-xmage.png";
ratio = 509.0f / 288.0f;
}
try {
InputStream is = this.getClass().getResourceAsStream(filename);
float ratio = 1179.0f / 678.0f;
titleRectangle = new Rectangle(540, (int) (640 / ratio));
if (is != null) {
titleRectangle = new Rectangle(540, (int) (640 / ratio));
BufferedImage image = ImageIO.read(is);
//ImageIcon resized = new ImageIcon(image.getScaledInstance(titleRectangle.width, titleRectangle.height, java.awt.Image.SCALE_SMOOTH));
title = new JLabel();

Binary file not shown.

After

Width:  |  Height:  |  Size: 141 KiB

View file

@ -489,7 +489,9 @@ public class ComputerPlayer6 extends ComputerPlayer /*implements Player*/ {
maxSeconds = 3600;
}
logger.debug("maxThink: " + maxSeconds + " seconds ");
return task.get(maxSeconds, TimeUnit.SECONDS);
if (task.get(maxSeconds, TimeUnit.SECONDS) != null) {
return task.get(maxSeconds, TimeUnit.SECONDS);
}
} catch (TimeoutException e) {
logger.info("simulating - timed out");
task.cancel(true);

View file

@ -0,0 +1,131 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageAllControlledTargetEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
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.TargetCardInYourGraveyard;
import mage.target.common.TargetOpponent;
/**
*
* @author LevelX2
*/
public class AngrathMinotaurPirate extends CardImpl {
public AngrathMinotaurPirate(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{B}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ANGRATH);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5));
// +2: Angrath, Minotaur Pirate deals 1 damage to target opponent and each creature that player controls.
Effects effects1 = new Effects();
effects1.add(new DamageTargetEffect(1));
effects1.add(new DamageAllControlledTargetEffect(1, new FilterCreaturePermanent()).setText("and each creature that player controls"));
LoyaltyAbility ability1 = new LoyaltyAbility(effects1, +2);
ability1.addTarget(new TargetOpponent());
this.addAbility(ability1);
// -3: Return target Pirate card from your graveyard to the battlefield.
FilterCard filterPirateCard = new FilterCreatureCard("pirate card from your graveyard");
filterPirateCard.add(new SubtypePredicate(SubType.PIRATE));
Ability ability2 = new LoyaltyAbility(new ReturnFromGraveyardToBattlefieldTargetEffect()
.setText("Return target Pirate card from your graveyard to the battlefield"), -3);
ability2.addTarget(new TargetCardInYourGraveyard(filterPirateCard));
this.addAbility(ability2);
// -11: Destroy all creature target opponent controls. Angrath, Minotaur Pirate deals damage to that player equal to their total power.
Ability ability3 = new LoyaltyAbility(new AngrathMinotaurPirateThirdAbilityEffect(), -11);
ability3.addTarget(new TargetOpponent());
this.addAbility(ability3);
}
public AngrathMinotaurPirate(final AngrathMinotaurPirate card) {
super(card);
}
@Override
public AngrathMinotaurPirate copy() {
return new AngrathMinotaurPirate(this);
}
}
class AngrathMinotaurPirateThirdAbilityEffect extends OneShotEffect {
public AngrathMinotaurPirateThirdAbilityEffect() {
super(Outcome.DestroyPermanent);
this.staticText = "Destroy all creature target opponent controls. {this} deals damage to that player equal to their total power";
}
public AngrathMinotaurPirateThirdAbilityEffect(final AngrathMinotaurPirateThirdAbilityEffect effect) {
super(effect);
}
@Override
public AngrathMinotaurPirateThirdAbilityEffect copy() {
return new AngrathMinotaurPirateThirdAbilityEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player targetOpponent = game.getPlayer(getTargetPointer().getFirst(game, source));
if (targetOpponent != null) {
int powerSum = 0;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getSourceId(), game)) {
permanent.destroy(source.getSourceId(), game, false);
powerSum += permanent.getPower().getValue();
}
game.applyEffects();
targetOpponent.damage(powerSum, source.getSourceId(), game, false, true);
}
return true;
}
}

View file

@ -0,0 +1,82 @@
/*
* 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.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.common.continuous.BoostSourceEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
/**
*
* @author LevelX2
*/
public class AngrathsAmbusher extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
static {
filter.add(new CardTypePredicate(CardType.PLANESWALKER));
filter.add(new SubtypePredicate(SubType.ANGRATH));
}
public AngrathsAmbusher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{B}");
this.subtype.add(SubType.ORC);
this.subtype.add(SubType.PIRATE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Angrath's Ambusher gets +2/+0 as long as you control an Angrath planeswalker.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new ConditionalContinuousEffect(new BoostSourceEffect(2, 0, Duration.WhileOnBattlefield),
new PermanentsOnTheBattlefieldCondition(filter),
"{this} gets +2/+0 as long as you control an Angrath planeswalker")));
}
public AngrathsAmbusher(final AngrathsAmbusher card) {
super(card);
}
@Override
public AngrathsAmbusher copy() {
return new AngrathsAmbusher(this);
}
}

View file

@ -0,0 +1,81 @@
/*
* 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.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.target.TargetPlayer;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.SecondTargetPointer;
/**
*
* @author LevelX2
*/
public class AngrathsFury extends CardImpl {
private final static FilterCard filter = new FilterCard("Angrath, Minotaur Pirate");
static {
filter.add(new NamePredicate(filter.getMessage()));
}
public AngrathsFury(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{3}{B}{R}");
// Destroy target creature.
this.getSpellAbility().addEffect(new DestroyTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent());
// Angrath's Fury deals 3 damage to target player.
this.getSpellAbility().addEffect(new DamageTargetEffect(3).setTargetPointer(new SecondTargetPointer())
.setText("{this} deals 3 damage to target player"));
this.getSpellAbility().addTarget(new TargetPlayer());
// You may search your library and/or graveyard for a card named Angrath, Minotaur Pirate, reveal it, and put it into your hand. If you search your library this way, shuffle it.
this.getSpellAbility().addEffect(new SearchLibraryGraveyardPutInHandEffect(filter)
.setText("You may search your library and/or graveyard for a card named Angrath, Minotaur Pirate, reveal it, and put it into your hand. If you search your library this way, shuffle it"));
}
public AngrathsFury(final AngrathsFury card) {
super(card);
}
@Override
public AngrathsFury copy() {
return new AngrathsFury(this);
}
}

View file

@ -43,7 +43,7 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.StaticFilters;
import mage.game.command.emblems.ArlinnEmbracedByTheMoonEmblem;
import mage.target.common.TargetCreatureOrPlayer;
@ -53,8 +53,6 @@ import mage.target.common.TargetCreatureOrPlayer;
*/
public class ArlinnEmbracedByTheMoon extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures you control");
public ArlinnEmbracedByTheMoon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "");
this.addSuperType(SuperType.LEGENDARY);
@ -66,10 +64,10 @@ public class ArlinnEmbracedByTheMoon extends CardImpl {
this.transformable = true;
// +1: Creatures you control get +1/+1 and gain trample until end of turn.
Effect effect = new BoostControlledEffect(1, 1, Duration.EndOfTurn, filter);
Effect effect = new BoostControlledEffect(1, 1, Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE);
effect.setText("Creatures you control get +1/+1");
LoyaltyAbility ability = new LoyaltyAbility(effect, 1);
effect = new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, filter);
effect = new GainAbilityControlledEffect(TrampleAbility.getInstance(), Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE);
effect.setText("and gain trample until end of turn");
ability.addEffect(effect);
this.addAbility(ability);

View file

@ -44,7 +44,6 @@ import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetCard;
/**
@ -113,8 +112,8 @@ class AugurOfBolasEffect extends OneShotEffect {
if (number == 1) {
card = topCards.getCards(new FilterInstantOrSorceryCard(), source.getSourceId(), source.getControllerId(), game).iterator().next();
} else {
Target target = new TargetCard(Zone.LIBRARY, new FilterInstantOrSorceryCard());
controller.chooseTarget(outcome, target, source, game);
TargetCard target = new TargetCard(Zone.LIBRARY, new FilterInstantOrSorceryCard());
controller.chooseTarget(outcome, topCards, target, source, game);
card = topCards.get(target.getFirstTarget(), game);
}
if (card != null) {

View file

@ -28,7 +28,6 @@
package mage.cards.b;
import java.util.*;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.effects.ContinuousEffect;
@ -40,8 +39,10 @@ import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.FilterPermanent;
import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.targetpointer.FixedTarget;
@ -52,7 +53,7 @@ import mage.target.targetpointer.FixedTarget;
public class BlatantThievery extends CardImpl {
public BlatantThievery(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{4}{U}{U}{U}");
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{4}{U}{U}{U}");
// For each opponent, gain control of target permanent that player controls.
this.getSpellAbility().addEffect(new BlatantThieveryEffect());
@ -66,7 +67,15 @@ public class BlatantThievery extends CardImpl {
public void adjustTargets(Ability ability, Game game) {
if (ability instanceof SpellAbility) {
ability.getTargets().clear();
ability.addTarget(new BlatantThieveryTarget(game.getOpponents(ability.getControllerId()).size()));
for (UUID opponentId : game.getOpponents(ability.getControllerId())) {
Player opponent = game.getPlayer(opponentId);
if (opponent != null) {
FilterPermanent filter = new FilterPermanent("Permanent of player " + opponent.getName());
filter.add(new ControllerIdPredicate(opponentId));
TargetPermanent targetPermanent = new TargetPermanent(filter);
ability.addTarget(targetPermanent);
}
}
}
}
@ -94,117 +103,13 @@ class BlatantThieveryEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
for (UUID targetId : getTargetPointer().getTargets(game, source)) {
ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame);
effect.setTargetPointer(new FixedTarget(targetId));
game.addEffect(effect, source);
}
return true;
}
}
class BlatantThieveryTarget extends TargetPermanent {
Map<UUID, UUID> targetOpponent = new HashMap<>();
public BlatantThieveryTarget(int opponents) {
super(opponents, opponents, new FilterPermanent("a permanent for each opponent"), false);
}
public BlatantThieveryTarget(final BlatantThieveryTarget target) {
super(target);
this.targetOpponent.putAll(target.targetOpponent);
}
@Override
public boolean canTarget(UUID controllerId, UUID objectId, Ability source, Game game) {
Permanent targetObject = game.getPermanent(objectId);
if (targetObject == null || !game.getOpponents(source.getControllerId()).contains(targetObject.getControllerId())) {
return false;
}
// If a permanent changes controller after being targeted but before this spell resolves, you won't gain control of that permanent.
if (targetOpponent.containsKey(objectId)) {
if (!targetOpponent.get(objectId).equals(targetObject.getControllerId())) {
return false;
}
} else {
// if already a target from this opponent exists, another can't be target
if (targetOpponent.values().contains(targetObject.getControllerId())) {
return false;
}
}
return super.canTarget(controllerId, objectId, source, game);
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> opponents = new HashSet<>();
for (UUID targetId : getTargets()) {
Permanent oldTargets = game.getPermanent(targetId);
if (oldTargets != null) {
opponents.add(oldTargets.getControllerId());
}
}
Set<UUID> possibleTargets = new HashSet<>();
MageObject mageObject = game.getObject(sourceId);
if (mageObject == null) {
return possibleTargets;
}
for (UUID opponentId : game.getOpponents(sourceControllerId)) {
if (opponents.contains(opponentId)) {
// Target for this opponent already selected
continue;
}
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(opponentId)) {
if (permanent.canBeTargetedBy(mageObject, sourceControllerId, game)) {
possibleTargets.add(permanent.getId());
}
}
}
return possibleTargets;
}
@Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
for (UUID opponentId : game.getOpponents(sourceControllerId)) {
boolean targetAvailable = false;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(opponentId)) {
if (!targets.containsKey(permanent.getId())) {
MageObject mageObject = game.getObject(sourceId);
if (mageObject != null && permanent.canBeTargetedBy(mageObject, sourceControllerId, game)) {
targetAvailable = true;
break;
}
} else {
targetAvailable = true;
break;
}
}
if (!targetAvailable) {
return false;
for (Target target : source.getTargets()) {
if (target.getFirstTarget() != null) {
ContinuousEffect effect = new GainControlTargetEffect(Duration.EndOfGame);
effect.setTargetPointer(new FixedTarget(target.getFirstTarget()));
game.addEffect(effect, source);
}
}
return true;
}
@Override
public void addTarget(UUID objectId, int amount, Ability source, Game game, boolean skipEvent) {
Permanent targetObject = game.getPermanent(objectId);
if (targetObject != null) {
targetOpponent.put(objectId, targetObject.getControllerId());
}
super.addTarget(objectId, amount, source, game, skipEvent);
}
@Override
public void remove(UUID id) {
super.remove(id);
targetOpponent.remove(id);
}
@Override
public BlatantThieveryTarget copy() {
return new BlatantThieveryTarget(this);
}
}

View file

@ -27,16 +27,19 @@
*/
package mage.cards.c;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.repository.CardInfo;
import mage.constants.CardType;
import mage.cards.repository.CardRepository;
import mage.constants.Duration;
import static mage.filter.predicate.permanent.ControllerControlsIslandPredicate.filter;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
@ -78,18 +81,25 @@ class NumberOfCapitalsInTextOfTargetCreatureCount implements DynamicValue {
Permanent permanent = game.getPermanent(sourceAbility.getTargets().get(0).getFirstTarget());
if (permanent != null) {
int capitals = 0;
for (String line : permanent.getRules()) {
line = line.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
line = line.replaceAll("\\{this\\}", permanent.getName());
capitals += line.length() - line.replaceAll("[A-Z]", "").length();
List<CardInfo> cards = CardRepository.instance.findCards(permanent.getName());
if (cards != null) {
for (CardInfo cardInfo : cards) {
Card dummy = cardInfo != null ? cardInfo.getCard() : null;
for (String line : dummy.getRules()) {
line = line.replaceAll("(?i)<i.*?</i>", ""); // Ignoring reminder text in italic
line = line.replaceAll("\\{this\\}", permanent.getName());
capitals += line.length() - line.replaceAll("[A-Z]", "").length();
}
return -1 * capitals;
}
}
return -1 * capitals;
}
return 0;
}
@Override
public String getMessage() {
return filter.getMessage() + " that player controls";
return "target creature gets -x/-x until end of turn, where x is the number of times a capital letter appears in its rules text. (ignore reminder text and flavor text.)";
}
}

View file

@ -0,0 +1,90 @@
/*
* 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.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.UnattachedTriggeredAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DestroyEquippedEffect;
import mage.abilities.effects.common.continuous.AddCardSubtypeAttachedEffect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
/**
*
* @author LevelX2
*/
public class CaptainsHook extends CardImpl {
public CaptainsHook(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+0
Effect effect = new BoostEquippedEffect(2, 0);
effect.setText("Equipped creature gets +2/+0");
Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, effect);
// has menace,
effect = new GainAbilityAttachedEffect(new MenaceAbility(), AttachmentType.EQUIPMENT);
effect.setText(", has menace");
ability.addEffect(effect);
//, and is a Pirate in addition to its other creature types
effect = new AddCardSubtypeAttachedEffect(SubType.PIRATE, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT);
effect.setText(", and is a Pirate in addition to its other creature types");
ability.addEffect(effect);
this.addAbility(ability);
// Whenever Captain's Hook becomes unattached from a permanent, destroy that permanent.
this.addAbility(new UnattachedTriggeredAbility(new DestroyEquippedEffect(), false));
// Equip {1}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(1)));
}
public CaptainsHook(final CaptainsHook card) {
super(card);
}
@Override
public CaptainsHook copy() {
return new CaptainsHook(this);
}
}

View file

@ -41,6 +41,7 @@ import mage.game.Controllable;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
@ -90,11 +91,14 @@ class ChannelHarmEffect extends PreventionEffectImpl {
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player sourceController = game.getPlayer(source.getControllerId());
PreventionEffectData preventionData = preventDamageAction(event, source, game);
if (preventionData.getPreventedDamage() > 0) {
Permanent targetCreature = game.getPermanent(source.getFirstTarget());
if (targetCreature != null) {
targetCreature.damage(preventionData.getPreventedDamage(), source.getSourceId(), game, false, true);
if (sourceController != null && sourceController.chooseUse(outcome, "Would you like to have " + preventionData.getPreventedDamage() + " damage dealt to " + targetCreature.getLogName() + "?", source, game)) {
targetCreature.damage(preventionData.getPreventedDamage(), source.getSourceId(), game, false, true);
}
}
}
return true;

View file

@ -0,0 +1,125 @@
/*
* 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.l;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.common.StaticValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.discard.DiscardCardYouChooseTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.Cards;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TargetController;
import mage.filter.FilterCard;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInHand;
import mage.target.targetpointer.FixedTarget;
/**
*
* @author L_J
*/
public class LastRites extends CardImpl {
public LastRites(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.SORCERY},"{2}{B}");
// Discard any number of cards. Target player reveals his or her hand, then you choose a nonland card from it for each card discarded this way. That player discards those cards.
this.getSpellAbility().addEffect(new LastRitesEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
public LastRites(final LastRites card) {
super(card);
}
@Override
public LastRites copy() {
return new LastRites(this);
}
}
class LastRitesEffect extends OneShotEffect {
LastRitesEffect() {
super(Outcome.Discard);
this.staticText = "Discard any number of cards. Target player reveals his or her hand, then you choose a nonland card from it for each card discarded this way. That player discards those cards";
}
LastRitesEffect(final LastRitesEffect effect) {
super(effect);
}
@Override
public LastRitesEffect copy() {
return new LastRitesEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(this.getTargetPointer().getFirst(game, source));
if (controller != null && targetPlayer != null) {
Cards cardsInHand = controller.getHand().copy();
TargetCard target = new TargetCardInHand(0, cardsInHand.size(), new FilterCard("cards to discard"));
controller.chooseTarget(outcome, cardsInHand, target, source, game);
int discardCount = target.getTargets().size();
if (discardCount > 0) {
for (UUID cardId : target.getTargets()) {
Card card = game.getCard(cardId);
if (card != null) {
controller.discard(card, source, game);
}
}
if (targetPlayer != null) {
FilterCard filter = new FilterCard((discardCount > 1 ? "" : "a") + " nonland card" + (discardCount > 1 ? "s" : ""));
filter.add(Predicates.not(new CardTypePredicate(CardType.LAND)));
StaticValue discardValue = new StaticValue(discardCount);
Effect effect = new DiscardCardYouChooseTargetEffect(discardValue, filter, TargetController.ANY);
effect.setTargetPointer(new FixedTarget(targetPlayer.getId()));
effect.apply(game, source);
} else {
return false;
}
}
return true;
}
return false;
}
}

View file

@ -34,7 +34,6 @@ import mage.abilities.costs.Cost;
import mage.abilities.costs.common.DiscardTargetCost;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
@ -44,7 +43,7 @@ import mage.constants.Zone;
import mage.filter.common.FilterLandCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.ZoneChangeEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
@ -55,7 +54,7 @@ import mage.target.common.TargetCardInHand;
public class MoxDiamond extends CardImpl {
public MoxDiamond(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{0}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{0}");
// If Mox Diamond would enter the battlefield, you may discard a land card instead. If you do, put Mox Diamond onto the battlefield. If you don't, put it into its owner's graveyard.
this.addAbility(new SimpleStaticAbility(Zone.ALL, new MoxDiamondReplacementEffect()));
@ -95,43 +94,36 @@ class MoxDiamondReplacementEffect extends ReplacementEffectImpl {
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(source.getControllerId());
if (player != null){
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
TargetCardInHand target = new TargetCardInHand(new FilterLandCard());
Cost cost = new DiscardTargetCost(target);
if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game) &&
player.chooseUse(outcome, "Discard land? (Otherwise Mox Diamond goes to graveyard)", source, game) &&
player.chooseTarget(Outcome.Discard, target, source, game)){
if (cost.canPay(source, source.getSourceId(), source.getControllerId(), game)
&& player.chooseUse(outcome, "Discard land? (Otherwise Mox Diamond goes to graveyard)", source, game)
&& player.chooseTarget(Outcome.Discard, target, source, game)) {
player.discard(game.getCard(target.getFirstTarget()), source, game);
return false;
}
else{
Card card = game.getCard(event.getTargetId());
if (card != null) {
player.moveCards(card, Zone.GRAVEYARD, source, game);
} else {
Permanent permanent = game.getPermanent(event.getTargetId());
if (permanent != null) {
player.moveCards(permanent, Zone.GRAVEYARD, source, game);
}
return true;
}
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (source.getSourceId().equals(event.getTargetId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if(zEvent.getToZone() == Zone.BATTLEFIELD){
return true;
}
}
return false;
return source.getSourceId().equals(event.getTargetId());
}
}

View file

@ -96,10 +96,15 @@ class OddOrEvenEffect extends OneShotEffect {
// Check the number of words in the name (based on number of spaces)
if (creature != null) {
String name = creature.getName();
int spaces = name.length() - name.replace(" ", "").length();
boolean nameIsOdd = (spaces % 2 == 0);
if (this.odd && nameIsOdd || !this.odd && !nameIsOdd) {
if (name.equalsIgnoreCase("") && this.odd == false) {
creature.destroy(source.getSourceId(), game, false);
} else {
int spaces = name.length() - name.replace(" ", "").length();
boolean nameIsOdd = (spaces % 2 == 0);
if (this.odd && nameIsOdd || !this.odd && !nameIsOdd) {
creature.destroy(source.getSourceId(), game, 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.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
/**
*
* @author L_J
*/
public class SpiritualFocus extends CardImpl {
public SpiritualFocus(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}");
// Whenever a spell or ability an opponent controls causes you to discard a card, you gain 2 life and you may draw a card.
this.addAbility(new SpiritualFocusTriggeredAbility());
}
public SpiritualFocus(final SpiritualFocus card) {
super(card);
}
@Override
public SpiritualFocus copy() {
return new SpiritualFocus(this);
}
}
class SpiritualFocusTriggeredAbility extends TriggeredAbilityImpl {
public SpiritualFocusTriggeredAbility() {
super(Zone.BATTLEFIELD, new GainLifeEffect(2), false);
this.addEffect(new SpiritualFocusDrawCardEffect());
}
public SpiritualFocusTriggeredAbility(final SpiritualFocusTriggeredAbility ability) {
super(ability);
}
@Override
public SpiritualFocusTriggeredAbility copy() {
return new SpiritualFocusTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == EventType.DISCARDED_CARD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
StackObject stackObject = game.getStack().getStackObject(event.getSourceId());
if (stackObject != null) {
if (game.getOpponents(this.getControllerId()).contains(stackObject.getControllerId())) {
Permanent permanent = game.getPermanent(getSourceId());
if (permanent != null) {
if (permanent.getControllerId() == event.getPlayerId()) {
return true;
}
}
}
}
return false;
}
@Override
public String getRule() {
return "Whenever a spell or ability an opponent controls causes you to discard a card, you gain 2 life and you may draw a card.";
}
}
class SpiritualFocusDrawCardEffect extends OneShotEffect {
public SpiritualFocusDrawCardEffect() {
super(Outcome.DrawCard);
}
public SpiritualFocusDrawCardEffect(final SpiritualFocusDrawCardEffect effect) {
super(effect);
}
@Override
public SpiritualFocusDrawCardEffect copy() {
return new SpiritualFocusDrawCardEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
Player player = game.getPlayer(source.getControllerId());
if (player != null && permanent != null) {
if (player.chooseUse(outcome, "Draw a card (" + permanent.getLogName() + ')', source, game)) {
player.drawCards(1, game);
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,60 @@
/*
* 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.UUID;
import mage.MageInt;
import mage.constants.SubType;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author LevelX2
*/
public class SwabGoblin extends CardImpl {
public SwabGoblin(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{R}");
this.subtype.add(SubType.GOBLIN);
this.subtype.add(SubType.PIRATE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
}
public SwabGoblin(final SwabGoblin card) {
super(card);
}
@Override
public SwabGoblin copy() {
return new SwabGoblin(this);
}
}

View file

@ -0,0 +1,99 @@
/*
* 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.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.MyTurnCondition;
import mage.abilities.costs.common.RevealSourceFromYourHandCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DestroyAllEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.filter.predicate.permanent.CounterPredicate;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class TetzimocPrimalDeath extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature your opponents control with a prey counter on it");
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
filter.add(new CounterPredicate(CounterType.PREY));
}
public TetzimocPrimalDeath(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ELDER);
this.subtype.add(SubType.DINOSAUR);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
// {B}, Reveal Tetzimoc, Primal Death from your hand: Put a prey counter on target creature. Activate this ability only during your turn.
Ability ability = new ActivateIfConditionActivatedAbility(Zone.HAND, new AddCountersTargetEffect(CounterType.PREY.createInstance()), new ManaCostsImpl("{B}"), MyTurnCondition.instance);
ability.addTarget(new TargetCreaturePermanent());
ability.addCost(new RevealSourceFromYourHandCost());
this.addAbility(ability);
// When Tetzimoc, Primal Death enters the battlefield, destroy each creature your opponents control with a prey counter on it.
this.addAbility(new EntersBattlefieldTriggeredAbility(
new DestroyAllEffect(filter).setText("destroy each creature your opponents control with a prey counter on it"), false));
}
public TetzimocPrimalDeath(final TetzimocPrimalDeath card) {
super(card);
}
@Override
public TetzimocPrimalDeath copy() {
return new TetzimocPrimalDeath(this);
}
}

View file

@ -0,0 +1,179 @@
/*
* 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.t;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.common.TapTargetCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.BrainiacToken;
import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent;
/**
*
* @author spjspj
*/
public class TheBigIdea extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(SubType.BRAINIAC, "Brainiac creatures");
static {
filter.add(Predicates.not(new TappedPredicate()));
}
public TheBigIdea(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{R}{R}");
addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.BRAINIAC);
this.subtype.add(SubType.VILLAIN);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// 2{BR}{BR}, T: Roll a six-sided dice. Create a number of 1/1 red Brainiac creature tokens equal to the result.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new TheBigIdeaEffect(), new ManaCostsImpl("{2}{B/R}{B/R}"));
ability.addCost(new TapSourceCost());
this.addAbility(ability);
// Tap three untapped Brainiacs you control: The next time you would roll a six-sided die, instead roll two six-sided dice and use the total of those results.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TheBigIdeaReplacementEffect(), new TapTargetCost(new TargetControlledCreaturePermanent(3, 3, filter, true))));
}
public TheBigIdea(final TheBigIdea card) {
super(card);
}
@Override
public TheBigIdea copy() {
return new TheBigIdea(this);
}
}
class TheBigIdeaReplacementEffect extends ReplacementEffectImpl {
TheBigIdeaReplacementEffect() {
super(Duration.EndOfTurn, Outcome.Damage);
staticText = "The next time you would roll a six-sided die, instead roll two six-sided dice and use the total of those results";
}
TheBigIdeaReplacementEffect(final TheBigIdeaReplacementEffect effect) {
super(effect);
}
@Override
public TheBigIdeaReplacementEffect copy() {
return new TheBigIdeaReplacementEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player controller = game.getPlayer(source.getControllerId());
if (event.getData() != null) {
String data = event.getData();
int numSides = Integer.parseInt(data);
if (numSides != 6) {
return false;
}
}
if (controller != null) {
discard();
int amount = controller.rollDice(game, 6);
event.setAmount(event.getAmount() + amount);
return true;
}
return false;
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.ROLL_DICE;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (!this.used) {
return source.getControllerId().equals(event.getPlayerId());
}
return false;
}
}
class TheBigIdeaEffect extends OneShotEffect {
public TheBigIdeaEffect() {
super(Outcome.PutCreatureInPlay);
this.staticText = "Roll a six-sided dice. Create a number of 1/1 red Brainiac creature tokens equal to the result";
}
public TheBigIdeaEffect(final TheBigIdeaEffect effect) {
super(effect);
}
@Override
public TheBigIdeaEffect copy() {
return new TheBigIdeaEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Permanent permanent = game.getPermanent(source.getSourceId());
if (controller != null && permanent != null) {
int amount = controller.rollDice(game, 6);
return new CreateTokenEffect(new BrainiacToken(), amount).apply(game, source);
}
return false;
}
}

View file

@ -0,0 +1,129 @@
/*
* 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.t;
import java.util.Optional;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.common.BeginningOfDrawTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.SuperType;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
* @author LevelX2
*/
public class TheImmortalSun extends CardImpl {
public TheImmortalSun(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{6}");
this.addSuperType(SuperType.LEGENDARY);
// Players can't activate loyalty abilities of planeswalkers.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TheImmortalSunCantActivateEffect()));
// At the beginning of your draw step, draw an additional card.
this.addAbility(new BeginningOfDrawTriggeredAbility(new DrawCardSourceControllerEffect(1), TargetController.YOU, false));
// Spells you cast cost {1} less to cast.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SpellsCostReductionControllerEffect(new FilterCard("Spells you cast"), 1)));
// Creatures you control get +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield)));
}
public TheImmortalSun(final TheImmortalSun card) {
super(card);
}
@Override
public TheImmortalSun copy() {
return new TheImmortalSun(this);
}
}
class TheImmortalSunCantActivateEffect extends ContinuousRuleModifyingEffectImpl {
public TheImmortalSunCantActivateEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
staticText = "Players can't activate loyalty abilities of planeswalkers";
}
public TheImmortalSunCantActivateEffect(final TheImmortalSunCantActivateEffect effect) {
super(effect);
}
@Override
public TheImmortalSunCantActivateEffect copy() {
return new TheImmortalSunCantActivateEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public String getInfoMessage(Ability source, GameEvent event, Game game) {
MageObject mageObject = game.getObject(source.getSourceId());
if (mageObject != null) {
return "You can't activate loyalty abilities of planeswalkers (" + mageObject.getIdName() + ").";
}
return null;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) {
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (permanent == null) {
return false;
}
if (permanent.isPlaneswalker()) {
Optional<Ability> ability = game.getAbility(event.getTargetId(), event.getSourceId());
return ability.isPresent() && (ability.get() instanceof LoyaltyAbility);
}
}
return false;
}
}

View file

@ -0,0 +1,133 @@
/*
* 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.t;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
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.events.DamageEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class TreacherousLink extends CardImpl {
public TreacherousLink(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{B}");
this.subtype.add(SubType.AURA);
// Enchant creature
TargetPermanent auraTarget = new TargetCreaturePermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// All damage that would be dealt to enchanted creature is dealt to its controller instead.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TreacherousLinkEffect()));
}
public TreacherousLink(final TreacherousLink card) {
super(card);
}
@Override
public TreacherousLink copy() {
return new TreacherousLink(this);
}
}
class TreacherousLinkEffect extends ReplacementEffectImpl {
public TreacherousLinkEffect() {
super(Duration.WhileOnBattlefield, Outcome.RedirectDamage);
staticText = "All damage that would be dealt to enchanted creature is dealt to its controller instead";
}
public TreacherousLinkEffect(final TreacherousLinkEffect effect) {
super(effect);
}
@Override
public TreacherousLinkEffect copy() {
return new TreacherousLinkEffect(this);
}
@Override
public boolean checksEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGE_CREATURE;
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
DamageEvent damageEvent = (DamageEvent) event;
Permanent enchantedCreature = game.getPermanentOrLKIBattlefield(damageEvent.getTargetId());
Player controller = game.getPlayer(enchantedCreature.getControllerId());
if (enchantedCreature != null && controller != null) {
controller.damage(damageEvent.getAmount(), damageEvent.getSourceId(), game, damageEvent.isCombatDamage(), damageEvent.isPreventable(), damageEvent.getAppliedEffects());
return true;
}
return false;
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
Permanent enchantment = game.getPermanentOrLKIBattlefield(source.getSourceId());
Player controller = game.getPlayer(source.getControllerId());
DamageEvent damageEvent = (DamageEvent) event;
if (controller != null && enchantment != null) {
Permanent enchantedCreature = game.getPermanentOrLKIBattlefield(enchantment.getAttachedTo());
if (enchantedCreature != null) {
return enchantedCreature.getId() == damageEvent.getTargetId();
}
}
return false;
}
}

View file

@ -0,0 +1,65 @@
/*
* 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.MageInt;
import mage.constants.SubType;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
/**
*
* @author LevelX2
*/
public class VampireChampion extends CardImpl {
public VampireChampion(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{B}");
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Deathtouch
this.addAbility(DeathtouchAbility.getInstance());
}
public VampireChampion(final VampireChampion card) {
super(card);
}
@Override
public VampireChampion copy() {
return new VampireChampion(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.v;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseNewTargetsTargetEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.ReturnToHandTargetEffect;
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect.FaceDownType;
import mage.abilities.effects.common.discard.DiscardControllerEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.filter.FilterStackObject;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.NumberOfTargetsPredicate;
import mage.filter.predicate.permanent.TokenPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.TargetStackObject;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author spjspj
*/
public class VeryCrypticCommand extends CardImpl {
private static final FilterStackObject filter = new FilterStackObject("spell or ability with a single target");
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("nontoken creature");
static {
filter.add(new NumberOfTargetsPredicate(1));
filter2.add(Predicates.not(new TokenPredicate()));
}
public VeryCrypticCommand(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{U}{U}");
// Choose two -
this.getSpellAbility().getModes().setMinModes(2);
this.getSpellAbility().getModes().setMaxModes(2);
// Return target permanent to its controller<EFBFBD>s hand.
this.getSpellAbility().addEffect(new ReturnToHandTargetEffect());
this.getSpellAbility().addTarget(new TargetPermanent());
// Draw two cards, then discard a card.
Mode mode = new Mode();
mode.getEffects().add(new DrawCardSourceControllerEffect(2));
Effect effect = new DiscardControllerEffect(1);
effect.setText(", then discard a card");
mode.getEffects().add(effect);
this.getSpellAbility().getModes().addMode(mode);
// Change the target of target spell with a single target.
mode = new Mode();
mode.getEffects().add(new ChooseNewTargetsTargetEffect(true, true));
mode.getTargets().add(new TargetStackObject(filter));
this.getSpellAbility().getModes().addMode(mode);
// Turn over target nontoken creature.
mode = new Mode();
mode.getEffects().add(new TurnOverEffect());
mode.getTargets().add(new TargetCreaturePermanent(filter2));
this.getSpellAbility().getModes().addMode(mode);
}
public VeryCrypticCommand(final VeryCrypticCommand card) {
super(card);
}
@Override
public VeryCrypticCommand copy() {
return new VeryCrypticCommand(this);
}
}
class TurnOverEffect extends OneShotEffect {
TurnOverEffect() {
super(Outcome.Benefit);
this.staticText = "Turn over target nontoken creature";
}
TurnOverEffect(final TurnOverEffect effect) {
super(effect);
}
@Override
public TurnOverEffect copy() {
return new TurnOverEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(source.getFirstTarget());
if (creature != null) {
if (creature.isFaceDown(game)) {
creature.turnFaceUp(game, source.getControllerId());
} else {
creature.turnFaceDown(game, source.getControllerId());
MageObjectReference objectReference = new MageObjectReference(creature.getId(), creature.getZoneChangeCounter(game), game);
game.addEffect(new BecomesFaceDownCreatureEffect(null, objectReference, Duration.Custom, FaceDownType.MANUAL), source);
}
return true;
}
return false;
}
}

View file

@ -0,0 +1,90 @@
/*
* 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.LoyaltyAbility;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.effects.common.LoseGameTargetPlayerEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.DeathtouchAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author LevelX2
*/
public class VraskaSchemingGorgon extends CardImpl {
public VraskaSchemingGorgon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{4}{B}{B}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.VRASKA);
this.addAbility(new PlanswalkerEntersWithLoyalityCountersAbility(5));
// +2: Creatures you control get +1/+0 until end of turn.
Effect effect = new BoostControlledEffect(1, 0, Duration.EndOfTurn, StaticFilters.FILTER_PERMANENT_CREATURE);
effect.setText("Creatures you control get +1/+0");
this.addAbility(new LoyaltyAbility(effect, 2));
// -3: Destroy target creature.
LoyaltyAbility loyaltyAbility = new LoyaltyAbility(new DestroyTargetEffect(), -3);
loyaltyAbility.addTarget(new TargetCreaturePermanent());
this.addAbility(loyaltyAbility);
// -10: Until end of turn, creatures you control gain deathtouch and "Whenever this creature deals damage to an opponent, that player loses the game."
loyaltyAbility = new LoyaltyAbility(new GainAbilityControlledEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn)
.setText("Until end of turn, creatures you control gain deathtouch"), -10);
TriggeredAbility triggeredAbility = new DealsCombatDamageToAPlayerTriggeredAbility(new LoseGameTargetPlayerEffect(), false, true, true);
loyaltyAbility.addEffect(new GainAbilityControlledEffect(triggeredAbility, Duration.EndOfTurn)
.setText("and \"Whenever this creature deals damage to an opponent, that player loses the game.\""));
this.addAbility(loyaltyAbility);
}
public VraskaSchemingGorgon(final VraskaSchemingGorgon card) {
super(card);
}
@Override
public VraskaSchemingGorgon copy() {
return new VraskaSchemingGorgon(this);
}
}

View file

@ -0,0 +1,85 @@
/*
* 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.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.AttacksOrBlocksTriggeredAbility;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.target.common.TargetOpponent;
/**
*
* @author LevelX2
*/
public class VraskasConquistador extends CardImpl {
private static final FilterControlledPermanent filter = new FilterControlledPermanent();
static {
filter.add(new CardTypePredicate(CardType.PLANESWALKER));
filter.add(new SubtypePredicate(SubType.VRASKA));
}
public VraskasConquistador(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}");
this.subtype.add(SubType.VAMPIRE);
this.subtype.add(SubType.SOLDIER);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Whenever Vraska's Conquistador attacks or blocks, if you control a Vraska planeswalker, target opponent loses 2 life and you gain 2 life.
TriggeredAbility ability = new AttacksOrBlocksTriggeredAbility(new LoseLifeTargetEffect(2), false);
ability.addEffect(new GainLifeEffect(2).setText("and you gain 2 life"));
ability.addTarget(new TargetOpponent());
this.addAbility(new ConditionalTriggeredAbility(
ability, new PermanentsOnTheBattlefieldCondition(filter),
"Whenever {this} attacks or blocks, if you control a Vraska planeswalker, target opponent loses 2 life and you gain 2 life."));
}
public VraskasConquistador(final VraskasConquistador card) {
super(card);
}
@Override
public VraskasConquistador copy() {
return new VraskasConquistador(this);
}
}

View file

@ -0,0 +1,72 @@
/*
* 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.LoseLifeTargetEffect;
import mage.abilities.effects.common.search.SearchLibraryGraveyardPutInHandEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.filter.FilterCard;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.target.common.TargetOpponent;
/**
*
* @author LevelX2
*/
public class VraskasScorn extends CardImpl {
private final static FilterCard filter = new FilterCard("Vraska, Scheming Gorgon");
static {
filter.add(new NamePredicate(filter.getMessage()));
}
public VraskasScorn(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}");
// Target opponent loses 4 life.
this.getSpellAbility().addEffect(new LoseLifeTargetEffect(4));
this.getSpellAbility().addTarget(new TargetOpponent());
// You may search your library and/or graveyard for a card named Vraska, Scheming Gorgon, reveal it, and put it into your hand. If you search your library this way, shuffle it.
this.getSpellAbility().addEffect(new SearchLibraryGraveyardPutInHandEffect(filter)
.setText("You may search your library and/or graveyard for a card named Vraska, Scheming Gorgon, reveal it, and put it into your hand. If you search your library this way, shuffle it"));
}
public VraskasScorn(final VraskasScorn card) {
super(card);
}
@Override
public VraskasScorn copy() {
return new VraskasScorn(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.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.LoseAbilityTargetEffect;
import mage.abilities.keyword.FirstStrikeAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.ChoiceImpl;
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.players.Player;
import mage.target.common.TargetCreaturePermanent;
/**
*
* @author L_J
*/
public class WalkingSponge extends CardImpl {
public WalkingSponge(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{U}");
this.subtype.add(SubType.SPONGE);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {T}: Target creature loses your choice of flying, first strike, or trample until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new WalkingSpongeEffect(), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
}
public WalkingSponge(final WalkingSponge card) {
super(card);
}
@Override
public WalkingSponge copy() {
return new WalkingSponge(this);
}
}
class WalkingSpongeEffect extends OneShotEffect {
WalkingSpongeEffect() {
super(Outcome.Benefit);
this.staticText = "Target creature loses your choice of flying, first strike, or trample until end of turn";
}
WalkingSpongeEffect(final WalkingSpongeEffect effect) {
super(effect);
}
@Override
public WalkingSpongeEffect copy() {
return new WalkingSpongeEffect(this);
}
@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) {
ChoiceImpl chooseAbility = new ChoiceImpl();
chooseAbility.setMessage("What ability do you wish to remove? (default is Flying)");
Set<String> choice = new LinkedHashSet<>();
choice.add("Flying");
choice.add("First strike");
choice.add("Trample");
chooseAbility.setChoices(choice);
// since the player can't pick "no ability", let's default to the first option
Ability ability = FlyingAbility.getInstance();
if (player.choose(Outcome.UnboostCreature, chooseAbility, game)) {
String chosenAbility = chooseAbility.getChoice();
// if (chosenAbility.equals("Flying")) {
// ability = FlyingAbility.getInstance();
// }
if (chosenAbility.equals("First strike")) {
ability = FirstStrikeAbility.getInstance();
}
else if (chosenAbility.equals("Trample")) {
ability = TrampleAbility.getInstance();
}
}
game.informPlayers(player.getLogName() + " has chosen " + ability.getRule());
ContinuousEffect effect = new LoseAbilityTargetEffect(ability, Duration.EndOfTurn);
game.addEffect(effect, source);
return true;
}
return false;
}
}

View file

@ -311,6 +311,7 @@ public class MercadianMasques extends ExpansionSet {
cards.add(new SetCardInfo("Soul Channeling", 163, Rarity.COMMON, mage.cards.s.SoulChanneling.class));
cards.add(new SetCardInfo("Specter's Wail", 164, Rarity.COMMON, mage.cards.s.SpectersWail.class));
cards.add(new SetCardInfo("Spidersilk Armor", 273, Rarity.COMMON, mage.cards.s.SpidersilkArmor.class));
cards.add(new SetCardInfo("Spiritual Focus", 49, Rarity.RARE, mage.cards.s.SpiritualFocus.class));
cards.add(new SetCardInfo("Spontaneous Generation", 274, Rarity.RARE, mage.cards.s.SpontaneousGeneration.class));
cards.add(new SetCardInfo("Squall", 275, Rarity.COMMON, mage.cards.s.Squall.class));
cards.add(new SetCardInfo("Squallmonger", 276, Rarity.UNCOMMON, mage.cards.s.Squallmonger.class));

View file

@ -206,6 +206,7 @@ public class Odyssey extends ExpansionSet {
cards.add(new SetCardInfo("Krosan Avenger", 247, Rarity.COMMON, mage.cards.k.KrosanAvenger.class));
cards.add(new SetCardInfo("Krosan Beast", 248, Rarity.RARE, mage.cards.k.KrosanBeast.class));
cards.add(new SetCardInfo("Laquatus's Creativity", 88, Rarity.UNCOMMON, mage.cards.l.LaquatussCreativity.class));
cards.add(new SetCardInfo("Last Rites", 146, Rarity.COMMON, mage.cards.l.LastRites.class));
cards.add(new SetCardInfo("Lava Blister", 200, Rarity.UNCOMMON, mage.cards.l.LavaBlister.class));
cards.add(new SetCardInfo("Leaf Dancer", 249, Rarity.COMMON, mage.cards.l.LeafDancer.class));
cards.add(new SetCardInfo("Lieutenant Kirtar", 29, Rarity.RARE, mage.cards.l.LieutenantKirtar.class));

View file

@ -62,6 +62,7 @@ public class PDSGraveborn extends ExpansionSet {
cards.add(new SetCardInfo("Faceless Butcher", 3, Rarity.COMMON, mage.cards.f.FacelessButcher.class));
cards.add(new SetCardInfo("Hidden Horror", 2, Rarity.UNCOMMON, mage.cards.h.HiddenHorror.class));
cards.add(new SetCardInfo("Inkwell Leviathan", 10, Rarity.RARE, mage.cards.i.InkwellLeviathan.class));
cards.add(new SetCardInfo("Last Rites", 21, Rarity.COMMON, mage.cards.l.LastRites.class));
cards.add(new SetCardInfo("Polluted Mire", 26, Rarity.COMMON, mage.cards.p.PollutedMire.class));
cards.add(new SetCardInfo("Putrid Imp", 1, Rarity.COMMON, mage.cards.p.PutridImp.class));
cards.add(new SetCardInfo("Reanimate", 15, Rarity.UNCOMMON, mage.cards.r.Reanimate.class));

View file

@ -1,65 +1,78 @@
/*
* 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;
import mage.cards.ExpansionSet;
import mage.constants.Rarity;
import mage.constants.SetType;
/**
*
* @author fireshoes
*/
public class RivalsOfIxalan extends ExpansionSet {
private static final RivalsOfIxalan instance = new RivalsOfIxalan();
public static RivalsOfIxalan getInstance() {
return instance;
}
private RivalsOfIxalan() {
super("Rivals of Ixalan", "RIX", ExpansionSet.buildDate(2018, 1, 19), SetType.EXPANSION);
this.blockName = "Ixalan";
this.parentSet = Ixalan.getInstance();
this.hasBoosters = true;
this.hasBasicLands = false;
this.numBoosterLands = 1;
this.numBoosterCommon = 11;
this.numBoosterUncommon = 3;
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;
cards.add(new SetCardInfo("Brass's Bounty", 94, Rarity.RARE, mage.cards.b.BrasssBounty.class));
cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class));
cards.add(new SetCardInfo("Silvergill Adept", 53, Rarity.UNCOMMON, mage.cards.s.SilvergillAdept.class));
cards.add(new SetCardInfo("Storm the Vault", 173, Rarity.RARE, mage.cards.s.StormTheVault.class));
cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class));
cards.add(new SetCardInfo("Vona's Hunger", 90, Rarity.RARE, mage.cards.v.VonasHunger.class));
}
}
/*
* 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;
import mage.cards.ExpansionSet;
import mage.constants.Rarity;
import mage.constants.SetType;
/**
*
* @author fireshoes
*/
public class RivalsOfIxalan extends ExpansionSet {
private static final RivalsOfIxalan instance = new RivalsOfIxalan();
public static RivalsOfIxalan getInstance() {
return instance;
}
private RivalsOfIxalan() {
super("Rivals of Ixalan", "RIX", ExpansionSet.buildDate(2018, 1, 19), SetType.EXPANSION);
this.blockName = "Ixalan";
this.parentSet = Ixalan.getInstance();
this.hasBoosters = true;
this.hasBasicLands = false;
this.numBoosterLands = 1;
this.numBoosterCommon = 11;
this.numBoosterUncommon = 3;
this.numBoosterRare = 1;
this.ratioBoosterMythic = 8;
cards.add(new SetCardInfo("Angrath's Ambusher", 202, Rarity.UNCOMMON, mage.cards.a.AngrathsAmbusher.class));
cards.add(new SetCardInfo("Angrath's Fury", 204, Rarity.RARE, mage.cards.a.AngrathsFury.class));
cards.add(new SetCardInfo("Angrath, Minotaur Pirate", 201, Rarity.MYTHIC, mage.cards.a.AngrathMinotaurPirate.class));
cards.add(new SetCardInfo("Brass's Bounty", 94, Rarity.RARE, mage.cards.b.BrasssBounty.class));
cards.add(new SetCardInfo("Captain's Hook", 177, Rarity.RARE, mage.cards.c.CaptainsHook.class));
cards.add(new SetCardInfo("Cinder Barrens", 205, Rarity.RARE, mage.cards.c.CinderBarrens.class));
cards.add(new SetCardInfo("Evolving Wilds", 186, Rarity.RARE, mage.cards.e.EvolvingWilds.class));
cards.add(new SetCardInfo("Ghalta, Primal Hunger", 130, Rarity.RARE, mage.cards.g.GhaltaPrimalHunger.class));
cards.add(new SetCardInfo("Silvergill Adept", 53, Rarity.UNCOMMON, mage.cards.s.SilvergillAdept.class));
cards.add(new SetCardInfo("Storm the Vault", 173, Rarity.RARE, mage.cards.s.StormTheVault.class));
cards.add(new SetCardInfo("Swab Goblin", 203, Rarity.COMMON, mage.cards.s.SwabGoblin.class));
cards.add(new SetCardInfo("Tetzimoc, Primal Death", 86, Rarity.RARE, mage.cards.t.TetzimocPrimalDeath.class));
cards.add(new SetCardInfo("The Immortal Sun", 180, Rarity.MYTHIC, mage.cards.t.TheImmortalSun.class));
cards.add(new SetCardInfo("Vampire Champion", 198, Rarity.COMMON, mage.cards.v.VampireChampion.class));
cards.add(new SetCardInfo("Vault of Catlacan", 173, Rarity.RARE, mage.cards.v.VaultOfCatlacan.class));
cards.add(new SetCardInfo("Vona's Hunger", 90, Rarity.RARE, mage.cards.v.VonasHunger.class));
cards.add(new SetCardInfo("Vraska's Conquistador", 199, Rarity.UNCOMMON, mage.cards.v.VraskasConquistador.class));
cards.add(new SetCardInfo("Vraska's Scorn", 200, Rarity.RARE, mage.cards.v.VraskasScorn.class));
cards.add(new SetCardInfo("Vraska, Scheming Gorgon", 197, Rarity.MYTHIC, mage.cards.v.VraskaSchemingGorgon.class));
}
}

View file

@ -79,6 +79,7 @@ public class Unstable extends ExpansionSet {
cards.add(new SetCardInfo("Sword of Dungeons & Dragons", 1, Rarity.MYTHIC, mage.cards.s.SwordOfDungeonsAndDragons.class));
cards.add(new SetCardInfo("Target Minotaur", 98, Rarity.COMMON, mage.cards.t.TargetMinotaur.class));
cards.add(new SetCardInfo("Time Out", 48, Rarity.COMMON, mage.cards.t.TimeOut.class));
cards.add(new SetCardInfo("Very Cryptic Command", 49, Rarity.RARE, mage.cards.v.VeryCrypticCommand.class));
cards.add(new SetCardInfo("Willing Test Subject", 126, Rarity.COMMON, mage.cards.w.WillingTestSubject.class));
cards.add(new SetCardInfo("capital offense", 52, Rarity.COMMON, mage.cards.c.CapitalOffense.class));
}

View file

@ -175,6 +175,7 @@ public class UrzasLegacy extends ExpansionSet {
cards.add(new SetCardInfo("Ticking Gnomes", 136, Rarity.UNCOMMON, mage.cards.t.TickingGnomes.class));
cards.add(new SetCardInfo("Tinker", 45, Rarity.UNCOMMON, mage.cards.t.Tinker.class));
cards.add(new SetCardInfo("Tragic Poet", 24, Rarity.COMMON, mage.cards.t.TragicPoet.class));
cards.add(new SetCardInfo("Treacherous Link", 71, Rarity.UNCOMMON, mage.cards.t.TreacherousLink.class));
cards.add(new SetCardInfo("Treefolk Mystic", 114, Rarity.COMMON, mage.cards.t.TreefolkMystic.class));
cards.add(new SetCardInfo("Treetop Village", 143, Rarity.UNCOMMON, mage.cards.t.TreetopVillage.class));
cards.add(new SetCardInfo("Unearth", 72, Rarity.COMMON, mage.cards.u.Unearth.class));
@ -183,6 +184,7 @@ public class UrzasLegacy extends ExpansionSet {
cards.add(new SetCardInfo("Viashino Heretic", 95, Rarity.UNCOMMON, mage.cards.v.ViashinoHeretic.class));
cards.add(new SetCardInfo("Viashino Sandscout", 96, Rarity.COMMON, mage.cards.v.ViashinoSandscout.class));
cards.add(new SetCardInfo("Vigilant Drake", 46, Rarity.COMMON, mage.cards.v.VigilantDrake.class));
cards.add(new SetCardInfo("Walking Sponge", 47, Rarity.UNCOMMON, mage.cards.w.WalkingSponge.class));
cards.add(new SetCardInfo("Weatherseed Elf", 115, Rarity.COMMON, mage.cards.w.WeatherseedElf.class));
cards.add(new SetCardInfo("Weatherseed Faeries", 48, Rarity.COMMON, mage.cards.w.WeatherseedFaeries.class));
cards.add(new SetCardInfo("Weatherseed Treefolk", 116, Rarity.RARE, mage.cards.w.WeatherseedTreefolk.class));

View file

@ -0,0 +1,39 @@
package org.mage.test.cards.abilities.enters;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class AugurOfBolasTest extends CardTestPlayerBase {
/*
Aether Figment {1}{U}
Creature - Illusion
1/1
Kicker {3} (You may pay an additional as you cast this spell.)
Aether Figment can't be blocked.
If Aether Figment was kicked, it enters the battlefield with two +1/+1 counters on it.
*/
@Test
public void testEnteringWithCounters() {
addCard(Zone.LIBRARY, playerA, "Lightning Bolt", 3);
skipInitShuffling();
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
// When Augur of Bolas enters the battlefield, look at the top three cards of your library.
// You may reveal an instant or sorcery card from among them and put it into your hand. Put the rest on the bottom of your library in any order.
addCard(Zone.HAND, playerA, "Augur of Bolas"); // Creature {1}{U}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Augur of Bolas");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Augur of Bolas", 1);
assertHandCount(playerA, "Lightning Bolt", 1);
}
}

View file

@ -816,4 +816,41 @@ public class MorphTest extends CardTestPlayerBase {
assertPermanentCount(playerA, "", 0);
}
/**
* The Ur-Dragon reduces cost of face down morph Dragons Simple to reproduce
* - Dragons with Morph/Megamorph such as Quicksilver Dragon cost {2} to
* play face-down instead of the normal {3}. Other non-Dragon morph costs
* are unchanged.
*/
@Test
public void testNoCostReductionOfFaceDownCastCreature() {
/*
Quicksilver Dragon {4}{U}{U}
Creature - Dragon
5/5
Flying
{U}: If target spell has only one target and that target is Quicksilver Dragon, change that spell's target to another creature.
Morph {4}{U}
*/
addCard(Zone.HAND, playerA, "Quicksilver Dragon");
addCard(Zone.BATTLEFIELD, playerA, "Island", 3);
// Eminence - As long as The Ur-Dragon is in the command zone or on the battlefield, other Dragon spells you cast cost {1} less to cast.
// Flying
// Whenever one or more Dragons you control attack, draw that many cards, then you may put a permanent card from your hand onto the battlefield
addCard(Zone.BATTLEFIELD, playerA, "The Ur-Dragon", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Quicksilver Dragon");
setChoice(playerA, "Yes"); // cast it face down as 2/2 creature
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "", 1);
assertHandCount(playerA, 0);
assertTappedCount("Island", true, 3);
}
}

View file

@ -0,0 +1,94 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package org.mage.test.cards.copy;
import mage.constants.PhaseStep;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*
* @author LevelX2
*/
public class MirrorworksTest extends CardTestPlayerBase {
/**
* If you play Mox Diamond, with Mirrorworks in play, and create a token
* copy, and you have no lands in hand, the Mox will enter the battlefield
* as usual instead of the graveyard.
*/
@Test
public void TestCopyWithoutLand() {
addCard(Zone.HAND, playerA, "Mountain", 1);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
// If Mox Diamond would enter the battlefield, you may discard a land card instead. If you do, put Mox Diamond onto the battlefield. If you don't, put it into its owner's graveyard.
// {T}: Add one mana of any color to your mana pool.
addCard(Zone.HAND, playerA, "Mox Diamond", 1); // Artifact {0}
// Whenever another nontoken artifact enters the battlefield under your control, you may pay {2}.
// If you do, create a token that's a copy of that artifact.
addCard(Zone.BATTLEFIELD, playerA, "Mirrorworks", 1); // Artifact {5}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mox Diamond");
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Mox Diamond", 1);
assertTappedCount("Island", true, 2);
assertGraveyardCount(playerA, "Mountain", 1);
}
@Test
public void TestCorrectCopy() {
addCard(Zone.HAND, playerA, "Mountain", 2);
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
// If Mox Diamond would enter the battlefield, you may discard a land card instead. If you do, put Mox Diamond onto the battlefield. If you don't, put it into its owner's graveyard.
// {T}: Add one mana of any color to your mana pool.
addCard(Zone.HAND, playerA, "Mox Diamond", 1); // Artifact {0}
// Whenever another nontoken artifact enters the battlefield under your control, you may pay {2}.
// If you do, create a token that's a copy of that artifact.
addCard(Zone.BATTLEFIELD, playerA, "Mirrorworks", 1); // Artifact {5}
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Mox Diamond");
setChoice(playerA, "Yes");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Mox Diamond", 2);
assertGraveyardCount(playerA, "Mountain", 2);
}
}

View file

@ -0,0 +1,93 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package org.mage.test.multiplayer;
import java.io.FileNotFoundException;
import mage.constants.MultiplayerAttackOption;
import mage.constants.PhaseStep;
import mage.constants.RangeOfInfluence;
import mage.constants.Zone;
import mage.game.FreeForAll;
import mage.game.Game;
import mage.game.GameException;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestMultiPlayerBase;
/**
*
* @author LevelX2
*/
public class BlatantThieveryTest extends CardTestMultiPlayerBase {
@Override
protected Game createNewGameAndPlayers() throws GameException, FileNotFoundException {
Game game = new FreeForAll(MultiplayerAttackOption.MULTIPLE, RangeOfInfluence.ALL, 0, 20);
// Player order: A -> D -> C -> B
playerA = createPlayer(game, playerA, "PlayerA");
playerB = createPlayer(game, playerB, "PlayerB");
playerC = createPlayer(game, playerC, "PlayerC");
playerD = createPlayer(game, playerD, "PlayerD");
return game;
}
@Test
public void NormalTest() {
// For each opponent, gain control of target permanent that player controls.
addCard(Zone.HAND, playerA, "Blatant Thievery"); // Sorcery {4}{U}{U}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 7);
// Player order: A -> D -> C -> B
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 2);
addCard(Zone.BATTLEFIELD, playerC, "Walking Corpse", 2);
addCard(Zone.BATTLEFIELD, playerD, "Pillarfield Ox", 2);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blatant Thievery");
addTarget(playerA, "Silvercoat Lion");
addTarget(playerA, "Walking Corpse");
addTarget(playerA, "Pillarfield Ox");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPermanentCount(playerA, "Walking Corpse", 1);
assertPermanentCount(playerA, "Pillarfield Ox", 1);
assertPermanentCount(playerB, "Silvercoat Lion", 1);
assertPermanentCount(playerC, "Walking Corpse", 1);
assertPermanentCount(playerD, "Pillarfield Ox", 1);
}
@Test
public void ControlChangeTest() {
// For each opponent, gain control of target permanent that player controls.
addCard(Zone.HAND, playerA, "Blatant Thievery"); // Sorcery {4}{U}{U}{U}
addCard(Zone.BATTLEFIELD, playerA, "Island", 7);
addCard(Zone.HAND, playerB, "Act of Aggression"); // Instant {3}{M}{M}
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 5);
// Player order: A -> D -> C -> B
addCard(Zone.BATTLEFIELD, playerB, "Silvercoat Lion", 1);
addCard(Zone.BATTLEFIELD, playerC, "Walking Corpse", 1);
addCard(Zone.BATTLEFIELD, playerD, "Pillarfield Ox", 1);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Blatant Thievery");
addTarget(playerA, "Silvercoat Lion");
addTarget(playerA, "Walking Corpse");
addTarget(playerA, "Pillarfield Ox");
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerB, "Act of Aggression", "Pillarfield Ox", "Blatant Thievery");
setStopAt(1, PhaseStep.BEGIN_COMBAT);
execute();
assertGraveyardCount(playerA, "Blatant Thievery", 1);
assertGraveyardCount(playerB, "Act of Aggression", 1);
assertPermanentCount(playerA, "Silvercoat Lion", 1);
assertPermanentCount(playerA, "Walking Corpse", 1);
assertPermanentCount(playerB, "Pillarfield Ox", 1);
}
}

View file

@ -33,6 +33,7 @@ import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/**
@ -43,14 +44,20 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
protected boolean setTargetPointer;
protected String text;
protected boolean onlyOpponents;
public DealsCombatDamageToAPlayerTriggeredAbility(Effect effect, boolean optional) {
this(effect, optional, false);
}
public DealsCombatDamageToAPlayerTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer) {
this(effect, optional, setTargetPointer, false);
}
public DealsCombatDamageToAPlayerTriggeredAbility(Effect effect, boolean optional, boolean setTargetPointer, boolean onlyOpponents) {
super(Zone.BATTLEFIELD, effect, optional);
this.setTargetPointer = setTargetPointer;
this.onlyOpponents = onlyOpponents;
}
public DealsCombatDamageToAPlayerTriggeredAbility(Effect effect, boolean optional, String text, boolean setTargetPointer) {
@ -63,6 +70,7 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
super(ability);
this.text = ability.text;
this.setTargetPointer = ability.setTargetPointer;
this.onlyOpponents = ability.onlyOpponents;
}
@Override
@ -79,6 +87,12 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getSourceId().equals(getSourceId())
&& ((DamagedPlayerEvent) event).isCombatDamage()) {
if (onlyOpponents) {
Player controller = game.getPlayer(getControllerId());
if (controller == null || !controller.hasOpponent(event.getPlayerId(), game)) {
return false;
}
}
if (setTargetPointer) {
for (Effect effect : this.getAllEffects()) {
effect.setTargetPointer(new FixedTarget(event.getPlayerId()));
@ -93,7 +107,7 @@ public class DealsCombatDamageToAPlayerTriggeredAbility extends TriggeredAbility
@Override
public String getRule() {
if (text == null || text.isEmpty()) {
return "Whenever {this} deals combat damage to a player, " + super.getRule();
return "Whenever {this} deals combat damage to " + (onlyOpponents ? "an opponent, " : "a player, ") + super.getRule();
}
return text;
}

View file

@ -24,16 +24,15 @@
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
*/
package mage.abilities.effects;
import java.io.Serializable;
import java.util.UUID;
import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.game.Game;
import mage.target.targetpointer.TargetPointer;
@ -44,18 +43,31 @@ import mage.target.targetpointer.TargetPointer;
public interface Effect extends Serializable {
UUID getId();
void newId();
String getText(Mode mode);
Effect setText(String staticText);
boolean apply(Game game, Ability source);
Outcome getOutcome();
void setOutcome(Outcome outcome);
EffectType getEffectType();
void setTargetPointer(TargetPointer targetPointer);
Effect setTargetPointer(TargetPointer targetPointer);
TargetPointer getTargetPointer();
void setValue(String key, Object value);
Object getValue(String key);
void setApplyEffectsAfter();
boolean applyEffectsAfter();
Effect copy();

View file

@ -24,20 +24,18 @@
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
*/
package mage.abilities.effects;
import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.abilities.MageSingleton;
import mage.abilities.Mode;
import mage.target.targetpointer.FirstTargetPointer;
import mage.target.targetpointer.TargetPointer;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import mage.abilities.MageSingleton;
import mage.abilities.Mode;
import mage.constants.EffectType;
import mage.constants.Outcome;
import mage.target.targetpointer.FirstTargetPointer;
import mage.target.targetpointer.TargetPointer;
/**
*
@ -106,8 +104,9 @@ public abstract class EffectImpl implements Effect {
}
@Override
public void setTargetPointer(TargetPointer targetPointer) {
public Effect setTargetPointer(TargetPointer targetPointer) {
this.targetPointer = targetPointer;
return this;
}
@Override
@ -141,8 +140,8 @@ public abstract class EffectImpl implements Effect {
}
/**
* If set, the game.applyEffects() method will be called to apply the effects before the
* next effect (of the same ability) will resolve.
* If set, the game.applyEffects() method will be called to apply the
* effects before the next effect (of the same ability) will resolve.
*/
@Override
public void setApplyEffectsAfter() {

View file

@ -0,0 +1,51 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.abilities.effects.common;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
import mage.game.permanent.Permanent;
/**
*
* @author LevelX2
*/
public class DestroyEquippedEffect extends OneShotEffect {
public DestroyEquippedEffect() {
super(Outcome.DestroyPermanent);
staticText = "destroy that permanent";
}
public DestroyEquippedEffect(final DestroyEquippedEffect effect) {
super(effect);
}
@Override
public DestroyEquippedEffect copy() {
return new DestroyEquippedEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) {
UUID uuid = getTargetPointer().getFirst(game, source);
Permanent permanent = game.getPermanent(uuid);
if (permanent == null) {
permanent = game.getPermanent(equipment.getAttachedTo());
}
if (permanent != null) {
return permanent.destroy(source.getSourceId(), game, false);
}
}
return false;
}
}

View file

@ -230,6 +230,7 @@ public class MorphAbility extends StaticAbility implements AlternativeSourceCost
spellColor.setGreen(false);
spellColor.setWhite(false);
spellColor.setBlue(false);
spell.getSubtype(game).clear();
} else {
spell.setFaceDown(false, game);
}

View file

@ -56,7 +56,7 @@ public class SquirrellinkAbility extends StaticAbility implements MageSingleton
@Override
public String getRule() {
return "Squirrellink <i>(Damage dealt by this creature also causes you to create that many 1/1/ green Squirrel creature tokens.)</i>";
return "Squirrellink <i>(Damage dealt by this creature also causes you to create that many 1/1 green Squirrel creature tokens.)</i>";
}
@Override

View file

@ -179,7 +179,7 @@ public enum SubType {
KAVU("Kavu", SubTypeSet.CreatureType),
KELDOR("KelDor", SubTypeSet.CreatureType, true),
KILLBOT("Killbot", SubTypeSet.CreatureType, true), // Unstable
KIRIN("Kirin", SubTypeSet.CreatureType),
KIRIN("Kirin", SubTypeSet.CreatureType),
KITHKIN("Kithkin", SubTypeSet.CreatureType),
KNIGHT("Knight", SubTypeSet.CreatureType),
KOBOLD("Kobold", SubTypeSet.CreatureType),
@ -328,6 +328,7 @@ public enum SubType {
VAMPIRE("Vampire", SubTypeSet.CreatureType),
VEDALKEN("Vedalken", SubTypeSet.CreatureType),
VIASHINO("Viashino", SubTypeSet.CreatureType),
VILLAIN("Villain", SubTypeSet.CreatureType, true), // Unstable
VOLVER("Volver", SubTypeSet.CreatureType),
//W
WALL("Wall", SubTypeSet.CreatureType),
@ -352,6 +353,7 @@ public enum SubType {
ZUBERA("Zubera", SubTypeSet.CreatureType),
// Planeswalker
AJANI("Ajani", SubTypeSet.PlaneswalkerType),
ANGRATH("Angrath", SubTypeSet.PlaneswalkerType),
ARLINN("Arlinn", SubTypeSet.PlaneswalkerType),
ASHIOK("Ashiok", SubTypeSet.PlaneswalkerType),
AURRA("Aurra", SubTypeSet.PlaneswalkerType, true), // Star Wars

View file

@ -107,6 +107,7 @@ public enum CounterType {
POLYP("polyp"),
POISON("poison"),
PRESSURE("pressure"),
PREY("prey"),
REPAIR("repair"),
QUEST("quest"),
SCREAM("scream"),

View file

@ -0,0 +1,48 @@
/*
* 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.game.permanent.token;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.MageInt;
/**
*
* @author spjspj
*/
public class BrainiacToken extends Token {
public BrainiacToken() {
super("Brainiac", "1/1 red Brainiac creature token");
cardType.add(CardType.CREATURE);
color.setRed(true);
subtype.add(SubType.BRAINIAC);
power = new MageInt(1);
toughness = new MageInt(1);
}
}

View file

@ -32777,3 +32777,6 @@ Wall of Fortune|Unstable|50|C|{1}{U}|Artifact Creature - Wall|0|4|Defender$You m
Wild Crocodile|Unstable|125|C|{1}{G}|Host Creature - Crocodile|1|1|When this creature enters the battlefield, search your library for a basic land card, reveal it, put it into your hand, then shuffle your library.|
Willing Test Subject|Unstable|126|C|{2}{G}|Creature- Spider Monkey Scientist|2|2|Reach$Whenever you roll a 4 or higher on a die, put a +1/+1 counter on Willing Test Subject.$6: Roll a six-sided die.|
Garbage Elemental|Unstable|82|U|{4}{R}|Creature - Elemental|3|2|Battle cry <i>(Whenever this creature attacks, each other attacking creature gets +1/+0 until end of turn.)</i>$When Garbage Elemental enters the battlefield, roll two six-sided dice. Create a number of 1/1 red Goblin creature tokens equal to the difference between those results.|
Oddly Uneven|Unstable|15|R|{3}{W}{W}|Sorcery|||Choose one --$* Destroy each creature with an odd number of words in its name. (Hyphenated words are one word.)$* Destroy each creature with an even number of words in its name.|
capital offense|Unstable|52|C|{2}{B}{B}|Instant|||target creature gets -x/-x until end of turn, where x is the number of times a capital letter appears in its rules text. (ignore reminder text and flavor text.)
Very Cryptic Command|Unstable|49|R|{1}{U}{U}{U}|Instant|||Choose two - Return target permanent to its controllers hand.; Draw two cards, then discard a card.; Change the target of target spell with a single target.; Turn over target nontoken creature.|