[JOU] Added 6 cards. Fixed some bugs for JOU cards.

This commit is contained in:
LevelX2 2014-04-17 16:40:18 +02:00
parent 4e53ff73ea
commit 6d89011e47
16 changed files with 891 additions and 47 deletions

View file

@ -126,7 +126,7 @@ class AthreosGodOfPassageReturnEffect extends OneShotEffect<AthreosGodOfPassageR
Player opponent = game.getPlayer(source.getFirstTarget());
boolean paid = false;
if (opponent != null) {
if (opponent.chooseUse(outcome, new StringBuilder("Pay 3 live or ").append(creature.getName()).append(" returns to ").append(controller.getName()).append("'s hand?").toString(), game)) {
if (opponent.chooseUse(outcome, new StringBuilder("Pay 3 live to prevent that ").append(creature.getName()).append(" returns to ").append(controller.getName()).append("'s hand?").toString(), game)) {
Cost cost = new PayLifeCost(3);
if (!cost.pay(source, game, source.getSourceId(), opponent.getId(), false)) {
paid = true;

View file

@ -0,0 +1,189 @@
/*
* 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.journeyintonyx;
import java.util.LinkedList;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterNonlandPermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
import mage.game.ExileZone;
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.TargetPermanent;
/**
*
* @author LevelX2
*/
public class BanishingLight extends CardImpl<BanishingLight> {
private final static FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent an opponent controls");
static {
filter.add(new ControllerPredicate(TargetController.OPPONENT));
}
public BanishingLight(UUID ownerId) {
super(ownerId, 5, "Banishing Light", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}");
this.expansionSetCode = "JOU";
this.color.setWhite(true);
// When Banishing Light enters the battlefield, exile target nonland permanent an opponent controls until Banishing Light leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new BanishingLightExileEffect());
ability.addTarget(new TargetPermanent(filter, true));
this.addAbility(ability);
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
// has a DiesTriggeredAll ability it triggers for the dying / battlefield leaving source object, what shouldn't happen)
this.addAbility(new BanishingLightReturnExiledAbility());
}
public BanishingLight(final BanishingLight card) {
super(card);
}
@Override
public BanishingLight copy() {
return new BanishingLight(this);
}
}
class BanishingLightExileEffect extends OneShotEffect<BanishingLightExileEffect> {
public BanishingLightExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile target nonland permanent an opponent controls until {this} leaves the battlefield. <i>(That permanent returns under its owner's control.)</i>";
}
public BanishingLightExileEffect(final BanishingLightExileEffect effect) {
super(effect);
}
@Override
public BanishingLightExileEffect copy() {
return new BanishingLightExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If Banishing Light leaves the battlefield before its triggered ability resolves,
// the target won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(source.getSourceId(), permanent.getName()).apply(game, source);
}
return false;
}
}
/**
* Returns the exiled card as source permanent leaves battlefield
* Uses no stack
* @author LevelX2
*/
class BanishingLightReturnExiledAbility extends TriggeredAbilityImpl<BanishingLightReturnExiledAbility> {
public BanishingLightReturnExiledAbility() {
super(Zone.BATTLEFIELD, new ReturnExiledCreatureEffect());
this.usesStack = false;
this.setRuleVisible(false);
}
public BanishingLightReturnExiledAbility(final BanishingLightReturnExiledAbility ability) {
super(ability);
}
@Override
public BanishingLightReturnExiledAbility copy() {
return new BanishingLightReturnExiledAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
return true;
}
}
return false;
}
}
class ReturnExiledCreatureEffect extends OneShotEffect<ReturnExiledCreatureEffect> {
public ReturnExiledCreatureEffect() {
super(Outcome.Benefit);
this.staticText = "Return exiled permanent";
}
public ReturnExiledCreatureEffect(final ReturnExiledCreatureEffect effect) {
super(effect);
}
@Override
public ReturnExiledCreatureEffect copy() {
return new ReturnExiledCreatureEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ExileZone exile = game.getExile().getExileZone(source.getSourceId());
Card sourceCard = game.getCard(source.getSourceId());
if (exile != null && sourceCard != null) {
LinkedList<UUID> cards = new LinkedList<>(exile);
for (UUID cardId : cards) {
Card card = game.getCard(cardId);
card.moveToZone(Zone.BATTLEFIELD, source.getSourceId(), game, false);
game.informPlayers(new StringBuilder(sourceCard.getName()).append(": ").append(card.getName()).append(" returns to battlefield from exile").toString());
}
exile.clear();
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,196 @@
/*
* 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.journeyintonyx;
import java.util.LinkedList;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterNonlandCard;
import mage.game.ExileZone;
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.TargetCard;
import mage.target.common.TargetOpponent;
import mage.util.CardUtil;
/**
*
* @author LevelX2
*/
public class BrainMaggot extends CardImpl<BrainMaggot> {
public BrainMaggot(UUID ownerId) {
super(ownerId, 62, "Brain Maggot", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{B}");
this.expansionSetCode = "JOU";
this.subtype.add("Insect");
this.color.setBlack(true);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// When Brain Maggot enters the battlefield, target opponent reveals his or her hand and you choose a nonland card from it. Exile that card until Brain Maggot leaves the battlefield.
Ability ability = new EntersBattlefieldTriggeredAbility(new BrainMaggotExileEffect());
ability.addTarget(new TargetOpponent(true));
this.addAbility(ability);
// Implemented as triggered effect that doesn't uses the stack (implementation with watcher does not work correctly because if the returned creature
// has a DiesTriggeredAll ability it triggers for the dying / battlefield leaving source object, what shouldn't happen)
this.addAbility(new BrainMaggotReturnExiledAbility());
}
public BrainMaggot(final BrainMaggot card) {
super(card);
}
@Override
public BrainMaggot copy() {
return new BrainMaggot(this);
}
}
class BrainMaggotExileEffect extends OneShotEffect<BrainMaggotExileEffect> {
public BrainMaggotExileEffect() {
super(Outcome.Benefit);
this.staticText = "target opponent reveals his or her hand and you choose a nonland card from it. Exile that card until {this} leaves the battlefield";
}
public BrainMaggotExileEffect(final BrainMaggotExileEffect effect) {
super(effect);
}
@Override
public BrainMaggotExileEffect copy() {
return new BrainMaggotExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(this.getTargetPointer().getFirst(game, source));
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && opponent != null && sourcePermanent != null) {
opponent.revealCards(sourcePermanent.getName(), opponent.getHand(), game);
TargetCard target = new TargetCard(Zone.HAND, new FilterNonlandCard("nonland card to exile"));
target.setRequired(true);
if (controller.choose(Outcome.Exile, opponent.getHand(), target, game)) {
Card card = opponent.getHand().get(target.getFirstTarget(), game);
// If source permanent leaves the battlefield before its triggered ability resolves, the target card won't be exiled.
if (card != null && game.getState().getZone(source.getSourceId()) == Zone.BATTLEFIELD) {
controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName(), source.getSourceId(), game, Zone.HAND);
}
}
}
return false;
}
}
/**
* Returns the exiled card as source permanent leaves battlefield
* Uses no stack
* @author LevelX2
*/
class BrainMaggotReturnExiledAbility extends TriggeredAbilityImpl<BrainMaggotReturnExiledAbility> {
public BrainMaggotReturnExiledAbility() {
super(Zone.BATTLEFIELD, new BrainMaggotReturnExiledCreatureEffect());
this.usesStack = false;
this.setRuleVisible(false);
}
public BrainMaggotReturnExiledAbility(final BrainMaggotReturnExiledAbility ability) {
super(ability);
}
@Override
public BrainMaggotReturnExiledAbility copy() {
return new BrainMaggotReturnExiledAbility(this);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(this.getSourceId())) {
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
if (zEvent.getFromZone() == Zone.BATTLEFIELD) {
return true;
}
}
return false;
}
}
class BrainMaggotReturnExiledCreatureEffect extends OneShotEffect<BrainMaggotReturnExiledCreatureEffect> {
public BrainMaggotReturnExiledCreatureEffect() {
super(Outcome.Benefit);
this.staticText = "Return exiled nonland card to its owner's hand";
}
public BrainMaggotReturnExiledCreatureEffect(final BrainMaggotReturnExiledCreatureEffect effect) {
super(effect);
}
@Override
public BrainMaggotReturnExiledCreatureEffect copy() {
return new BrainMaggotReturnExiledCreatureEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ExileZone exile = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (exile != null && sourcePermanent != null) {
LinkedList<UUID> cards = new LinkedList<>(exile);
for (UUID cardId : cards) {
Card card = game.getCard(cardId);
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED);
}
exile.clear();
return true;
}
}
return false;
}
}

View file

@ -0,0 +1,114 @@
/*
* Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those of the
* authors and should not be interpreted as representing official policies, either expressed
* or implied, of BetaSteward_at_googlemail.com.
*/
package mage.sets.journeyintonyx;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.effects.common.search.SearchTargetGraveyardHandLibraryForCardNameAndExileEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetEnchantmentPermanent;
/**
*
* @author LevelX2
*/
public class Deicide extends CardImpl<Deicide> {
public Deicide(UUID ownerId) {
super(ownerId, 7, "Deicide", Rarity.RARE, new CardType[]{CardType.INSTANT}, "{1}{W}");
this.expansionSetCode = "JOU";
this.color.setWhite(true);
// Exile target enchantment. If the exiled card is a God card, search its controller's graveyard, hand, and library for any number of cards with the same name as that card and exile them, then that player shuffles his or her library.
this.getSpellAbility().addEffect(new DeicideExileEffect());
this.getSpellAbility().addTarget(new TargetEnchantmentPermanent(true));
}
public Deicide(final Deicide card) {
super(card);
}
@Override
public Deicide copy() {
return new Deicide(this);
}
}
class DeicideExileEffect extends SearchTargetGraveyardHandLibraryForCardNameAndExileEffect {
public DeicideExileEffect() {
super(true, "its controller's","any number of cards with the same name as that card");
}
public DeicideExileEffect(final DeicideExileEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
Card sourceCard = game.getCard(source.getSourceId());
if (controller != null && sourceCard != null) {
Permanent targetEnchantment = game.getPermanent(getTargetPointer().getFirst(game, source));
if (targetEnchantment != null) {
controller.moveCardToExileWithInfo(targetEnchantment, null, null, source.getSourceId(), game, Zone.BATTLEFIELD);
Card exiledCard = game.getCard(targetEnchantment.getId());
if (exiledCard.hasSubtype("God")) {
Player enchantmentController = game.getPlayer(targetEnchantment.getControllerId());
return super.applySearchAndExile(game, source, exiledCard.getName(), enchantmentController.getId());
}
}
}
return false;
}
@Override
public DeicideExileEffect copy() {
return new DeicideExileEffect(this);
}
@Override
public String getText(Mode mode) {
StringBuilder sb = new StringBuilder();
sb.append("Exile target enchantment. If the exiled card is a God card, ");
sb.append(super.getText(mode));
return sb.toString();
}
}

View file

@ -0,0 +1,74 @@
/*
* 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.journeyintonyx;
import java.util.UUID;
import mage.abilities.common.DiesCreatureTriggeredAbility;
import mage.abilities.effects.common.SacrificeOpponentsEffect;
import mage.abilities.keyword.FlashAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.ControllerPredicate;
/**
*
* @author LevelX2
*/
public class DictateOfErebos extends CardImpl<DictateOfErebos> {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature you control");
static {
filter.add(new ControllerPredicate(TargetController.YOU));
}
public DictateOfErebos(UUID ownerId) {
super(ownerId, 63, "Dictate of Erebos", Rarity.RARE, new CardType[]{CardType.ENCHANTMENT}, "{3}{B}{B}");
this.expansionSetCode = "JOU";
this.color.setBlack(true);
// Flash
this.addAbility(FlashAbility.getInstance());
// Whenever a creature you control dies, each opponent sacrifices a creature.
this.addAbility(new DiesCreatureTriggeredAbility(new SacrificeOpponentsEffect(new FilterControlledCreaturePermanent("a creature")), false, filter));
}
public DictateOfErebos(final DictateOfErebos card) {
super(card);
}
@Override
public DictateOfErebos copy() {
return new DictateOfErebos(this);
}
}

View file

@ -53,7 +53,7 @@ public class FontOfReturn extends CardImpl<FontOfReturn> {
this.color.setBlack(true);
// {3}{B}, Sacrifice Font of Return: Return up to three target creature cards from your graveyard to your hand.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{1}{G}"));
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{3}{B}"));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetCardInYourGraveyard(0, 3, new FilterCreatureCard("creature cards from your graveyard")));
this.addAbility(ability);

View file

@ -59,6 +59,7 @@ import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FirstTargetPointer;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
@ -118,31 +119,33 @@ class GodsendTriggeredAbility extends TriggeredAbilityImpl<GodsendTriggeredAbili
if (event.getType().equals(GameEvent.EventType.DECLARED_BLOCKERS)) {
Permanent equipment = game.getPermanentOrLKIBattlefield((this.getSourceId()));
if (equipment != null && equipment.getAttachedTo()!= null) {
Permanent equippedPermanent = game.getPermanentOrLKIBattlefield((this.getSourceId()));
Permanent equippedPermanent = game.getPermanentOrLKIBattlefield((equipment.getAttachedTo()));
if (equippedPermanent != null) {
possibleTargets.clear();
if (equippedPermanent.isAttacking()) {
for (CombatGroup group: game.getCombat().getBlockingGroups()) {
if (group.getAttackers().contains(this.getSourceId())) {
String targetName = "";
if (equippedPermanent.isAttacking()) {
for (CombatGroup group: game.getCombat().getGroups()) {
if (group.getAttackers().contains(equippedPermanent.getId())) {
possibleTargets.addAll(group.getBlockers());
}
}
}
if (equippedPermanent.getBlocking() > 0) {
for (CombatGroup group: game.getCombat().getBlockingGroups()) {
if (group.getBlockers().contains(this.getSourceId())) {
targetName = "a creature blocking attacker ";
} else if (equippedPermanent.getBlocking() > 0) {
for (CombatGroup group: game.getCombat().getGroups()) {
if (group.getBlockers().contains(equippedPermanent.getId())) {
possibleTargets.addAll(group.getAttackers());
}
}
}
if (possibleTargets.size() > 0) {
if (possibleTargets.size() == 1) {
this.getTargets().clear();
targetName = "a creature blocked by creature ";
}
if (possibleTargets.size() > 0) {
this.getTargets().clear();
if (possibleTargets.size() == 1) {
this.getEffects().get(0).setTargetPointer(new FixedTarget(possibleTargets.iterator().next()));
} else {
FilterCreaturePermanent filter = new FilterCreaturePermanent("one blocking or blocked creature");
this.getEffects().get(0).setTargetPointer(new FirstTargetPointer());
targetName = new StringBuilder(targetName).append("equipped by ").append(equipment.getName()).toString();
FilterCreaturePermanent filter = new FilterCreaturePermanent(targetName);
List<PermanentIdPredicate> uuidPredicates = new ArrayList<>();
for (UUID creatureId : possibleTargets) {
uuidPredicates.add(new PermanentIdPredicate(creatureId));
@ -150,6 +153,7 @@ class GodsendTriggeredAbility extends TriggeredAbilityImpl<GodsendTriggeredAbili
filter.add(Predicates.or(uuidPredicates));
this.getTargets().add(new TargetCreaturePermanent(filter, true));
}
return true;
}
}
}
@ -218,6 +222,12 @@ class GodsendReplacementEffect extends ReplacementEffectImpl<GodsendReplacementE
@Override
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
Player player = game.getPlayer(event.getPlayerId());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (player != null && sourcePermanent != null) {
game.informPlayer(player, new StringBuilder("You can't cast this spell because a card with the same name is exiled by ")
.append(sourcePermanent.getName()).append(".").toString());
}
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.sets.journeyintonyx;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.ExileSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.PutTopCardOfLibraryIntoGraveControllerEffect;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.target.common.TargetCardInYourGraveyard;
/**
*
* @author LevelX2
*/
public class NyxWeaver extends CardImpl<NyxWeaver> {
public NyxWeaver(UUID ownerId) {
super(ownerId, 153, "Nyx Weaver", Rarity.UNCOMMON, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "{1}{B}{G}");
this.expansionSetCode = "JOU";
this.subtype.add("Spider");
this.color.setGreen(true);
this.color.setBlack(true);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
// Reach
this.addAbility(ReachAbility.getInstance());
// At the beginning of your upkeep, put the top two cards of your library into your graveyard.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(new PutTopCardOfLibraryIntoGraveControllerEffect(2), TargetController.YOU, false));
// {1}{B}{G}, Exile Nyx Weaver: Return target card from your graveyard to your hand.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnFromGraveyardToHandTargetEffect(), new ManaCostsImpl("{1}{B}{G}"));
ability.addCost(new ExileSourceCost());
ability.addTarget(new TargetCardInYourGraveyard(true));
this.addAbility(ability);
}
public NyxWeaver(final NyxWeaver card) {
super(card);
}
@Override
public NyxWeaver copy() {
return new NyxWeaver(this);
}
}

View file

@ -0,0 +1,91 @@
/*
* 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.journeyintonyx;
import java.util.UUID;
import mage.MageInt;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.keyword.ReachAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.permanent.token.Token;
/**
*
* @author LevelX2
*/
public class RenownedWeaver extends CardImpl<RenownedWeaver> {
public RenownedWeaver(UUID ownerId) {
super(ownerId, 137, "Renowned Weaver", Rarity.COMMON, new CardType[]{CardType.CREATURE}, "{G}");
this.expansionSetCode = "JOU";
this.subtype.add("Human");
this.subtype.add("Shaman");
this.color.setGreen(true);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
// {1}{G}, Sacrifice Renowned Weaver: Put a 1/3 green Spider enchantment creature token with reach onto the battlefield.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new CreateTokenEffect(new RenownedWeaverSpiderToken(), 1), new ManaCostsImpl("{1}{G}")) ;
ability.addCost(new SacrificeSourceCost());
this.addAbility(ability);
}
public RenownedWeaver(final RenownedWeaver card) {
super(card);
}
@Override
public RenownedWeaver copy() {
return new RenownedWeaver(this);
}
}
class RenownedWeaverSpiderToken extends Token {
public RenownedWeaverSpiderToken() {
super("Spider", "1/3 green Spider enchantment creature token with reach");
this.setOriginalExpansionSetCode("JOU");
cardType.add(CardType.ENCHANTMENT);
cardType.add(CardType.CREATURE);
color.setColor(ObjectColor.GREEN);
subtype.add("Spider");
power = new MageInt(1);
toughness = new MageInt(3);
this.addAbility(ReachAbility.getInstance());
}
}

View file

@ -42,6 +42,7 @@ import mage.constants.Zone;
import mage.filter.common.FilterNonlandCard;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.common.TargetOpponent;
@ -101,17 +102,18 @@ class TidehollowScullerExileEffect extends OneShotEffect<TidehollowScullerExileE
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Player targetPlayer = game.getPlayer(source.getFirstTarget());
if (player != null && targetPlayer != null) {
targetPlayer.revealCards("Tidehollow Sculler", targetPlayer.getHand(), game);
Player controller = game.getPlayer(source.getControllerId());
Player opponent = game.getPlayer(source.getFirstTarget());
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
if (controller != null && opponent != null && sourcePermanent != null) {
opponent.revealCards(sourcePermanent.getName(), opponent.getHand(), game);
TargetCard target = new TargetCard(Zone.PICK, new FilterNonlandCard("nonland card to exile"));
target.setRequired(true);
if (player.choose(Outcome.Exile, targetPlayer.getHand(), target, game)) {
Card card = targetPlayer.getHand().get(target.getFirstTarget(), game);
if (controller.choose(Outcome.Exile, opponent.getHand(), target, game)) {
Card card = opponent.getHand().get(target.getFirstTarget(), game);
if (card != null) {
card.moveToExile(CardUtil.getCardExileZoneId(game, source), "Tidehollow Sculler", source.getSourceId(), game);
controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getName(), source.getSourceId(), game, Zone.HAND);
}
}
@ -141,14 +143,17 @@ class TidehollowScullerLeaveEffect extends OneShotEffect<TidehollowScullerLeaveE
@Override
public boolean apply(Game game, Ability source) {
ExileZone exZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
if (exZone != null) {
for (Card card : exZone.getCards(game)) {
if (card != null) {
card.moveToZone(Zone.HAND, source.getId(), game, false);
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
ExileZone exZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
if (exZone != null) {
for (Card card : exZone.getCards(game)) {
if (card != null) {
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, Zone.EXILED);
}
}
}
return true;
return true;
}
}
return false;
}

View file

@ -64,13 +64,13 @@ public class PutTopCardOfLibraryIntoGraveControllerEffect extends OneShotEffect<
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player != null) {
int cardsCount = Math.min(numberCards, player.getLibrary().size());
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
int cardsCount = Math.min(numberCards, controller.getLibrary().size());
for (int i = 0; i < cardsCount; i++) {
Card card = player.getLibrary().removeFromTop(game);
Card card = controller.getLibrary().removeFromTop(game);
if (card != null) {
card.moveToZone(Zone.GRAVEYARD, source.getId(), game, true);
controller.moveCardToGraveyardWithInfo(card, source.getSourceId(), game, Zone.LIBRARY);
}
}
return true;

View file

@ -79,8 +79,8 @@ public abstract class SearchTargetGraveyardHandLibraryForCardNameAndExileEffect
}
public boolean applySearchAndExile(Game game, Ability source, String cardName, UUID targetPlayerId) {
Player player = game.getPlayer(source.getControllerId());
if (cardName != null && player != null) {
Player controller = game.getPlayer(source.getControllerId());
if (cardName != null && controller != null) {
Player targetPlayer = game.getPlayer(targetPlayerId);
if (targetPlayer != null) {
FilterCard filter = new FilterCard("card named " + cardName);
@ -91,13 +91,13 @@ public abstract class SearchTargetGraveyardHandLibraryForCardNameAndExileEffect
if (cardsCount > 0) {
filter.setMessage("card named " + cardName + " in the graveyard of " + targetPlayer.getName());
TargetCardInGraveyard target = new TargetCardInGraveyard((graveyardExileOptional ? 0 :cardsCount), cardsCount, filter);
if (player.choose(Outcome.Exile, targetPlayer.getGraveyard(), target, game)) {
if (controller.choose(Outcome.Exile, targetPlayer.getGraveyard(), target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card targetCard = targetPlayer.getGraveyard().get(targetId, game);
if (targetCard != null) {
targetPlayer.getGraveyard().remove(targetCard);
targetCard.moveToZone(Zone.EXILED, source.getId(), game, false);
controller.moveCardToExileWithInfo(targetCard, null, null, source.getSourceId(), game, Zone.GRAVEYARD);
}
}
}
@ -108,19 +108,19 @@ public abstract class SearchTargetGraveyardHandLibraryForCardNameAndExileEffect
if (cardsCount > 0) {
filter.setMessage("card named " + cardName + " in the hand of " + targetPlayer.getName());
TargetCardInHand target = new TargetCardInHand(0, cardsCount, filter);
if (player.choose(Outcome.Exile, targetPlayer.getHand(), target, game)) {
if (controller.choose(Outcome.Exile, targetPlayer.getHand(), target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card targetCard = targetPlayer.getHand().get(targetId, game);
if (targetCard != null) {
targetPlayer.getHand().remove(targetCard);
targetCard.moveToZone(Zone.EXILED, source.getId(), game, false);
controller.moveCardToExileWithInfo(targetCard, null, null, source.getSourceId(), game, Zone.HAND);
}
}
}
} else {
if (targetPlayer.getHand().size() > 0) {
player.lookAtCards(targetPlayer.getName() + " hand", targetPlayer.getHand(), game);
controller.lookAtCards(targetPlayer.getName() + " hand", targetPlayer.getHand(), game);
}
}
@ -131,17 +131,17 @@ public abstract class SearchTargetGraveyardHandLibraryForCardNameAndExileEffect
if (cardsCount > 0) {
filter.setMessage("card named " + cardName + " in the library of " + targetPlayer.getName());
TargetCardInLibrary target = new TargetCardInLibrary(0, cardsCount, filter);
if (player.choose(Outcome.Exile, cardsInLibrary, target, game)) {
if (controller.choose(Outcome.Exile, cardsInLibrary, target, game)) {
List<UUID> targets = target.getTargets();
for (UUID targetId : targets) {
Card targetCard = targetPlayer.getLibrary().remove(targetId, game);
if (targetCard != null) {
targetCard.moveToZone(Zone.EXILED, source.getId(), game, false);
controller.moveCardToExileWithInfo(targetCard, null, null, source.getSourceId(), game, Zone.LIBRARY);
}
}
}
} else {
player.lookAtCards(targetPlayer.getName() + " library", cardsInLibrary, game);
controller.lookAtCards(targetPlayer.getName() + " library", cardsInLibrary, game);
}
targetPlayer.shuffleLibrary(game);

View file

@ -2132,7 +2132,7 @@ public abstract class PlayerImpl<T extends PlayerImpl<T>> implements Player, Ser
game.informPlayers(new StringBuilder(this.getName())
.append(" puts ").append(card.getName()).append(" ")
.append(fromZone != null ? new StringBuilder("from ").append(fromZone.toString().toLowerCase(Locale.ENGLISH)).append(" "):"")
.append("into his or her hand").toString());
.append(card.getOwnerId().equals(this.getId()) ? "into his or her hand":"into its owner's hand").toString());
result = true;
}
return result;

View file

@ -46,6 +46,11 @@ public class TargetCardInYourGraveyard extends TargetCard<TargetCardInYourGravey
this(1, 1, new FilterCard("card from your graveyard"));
}
public TargetCardInYourGraveyard(boolean required) {
this();
this.setRequired(required);
}
public TargetCardInYourGraveyard(FilterCard filter, boolean required) {
this(filter);
this.setRequired(required);

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.target.common;
import mage.filter.common.FilterEnchantmentPermanent;
import mage.target.TargetPermanent;
/**
*
* @author LevelX2
*
* @param <T>
*/
public class TargetEnchantmentPermanent<T extends TargetEnchantmentPermanent<T>> extends TargetPermanent<TargetEnchantmentPermanent<T>> {
public TargetEnchantmentPermanent(boolean required) {
this();
this.setRequired(required);
}
public TargetEnchantmentPermanent() {
this(1, 1, new FilterEnchantmentPermanent(), false);
}
public TargetEnchantmentPermanent(FilterEnchantmentPermanent filter) {
this(1, 1, filter, false);
}
public TargetEnchantmentPermanent(int numTargets) {
this(numTargets, numTargets, new FilterEnchantmentPermanent(), false);
}
public TargetEnchantmentPermanent(int minNumTargets, int maxNumTargets, FilterEnchantmentPermanent filter, boolean notTarget) {
super(minNumTargets, maxNumTargets, filter, notTarget);
this.targetName = filter.getMessage();
}
public TargetEnchantmentPermanent(final TargetEnchantmentPermanent target) {
super(target);
}
@Override
public TargetEnchantmentPermanent copy() {
return new TargetEnchantmentPermanent(this);
}
}

View file

@ -23227,3 +23227,9 @@ Font of Return|Journey into Nyx|71|C|{1}{B}|Enchantment|||{3}{B}, Sacrifice Font
Golden Hind|Journey into Nyx|124|C|{1}{G}|Creature - Elk|2|1|T: Add {G} to your mana pool.|
Harness by Force|Journey into Nyx|100|R|{1}{R}{R}|Sorcery|||Strive - Harness by Force costs 2R more to cast for each target beyond the first.$Gain control of any number of target creatures until end of turn. Untap those creatures. They gain haste until end of turn.|
Strength of the Fallen|Journey into Nyx|143|U|{1}{G}|Enchantment|||Constellation - Whenever Strength of the Fallen or another entchantment enters the battlefield under your control, target creature gets +X/+X until end of turn, where X is the number of creature cards in your graveyard.|
Banishing Light|Journey into Nyx|5|U|{2}{W}|Enchantment|||When Banishing Light enters the battlefield, exile target nonland permanent an opponent controls until Banishing Light leaves the battlefield.|
Dictate of Erebos|Journey into Nyx|63|R|{3}{B}{B}|Enchantment|||Flash$Whenever a creature you control dies, each opponent sacrifices a creature.|
Brain Maggot|Journey into Nyx|62|U|{1}{B}|Enchantment Creature - Insect|1|1|When Brain Maggot enters the battlefield, target opponent reveals his or her hand and you choose a nonland card from it. Exile that card until Brain Maggot leaves the battlefield.|
Nyx Weaver|Journey into Nyx|153|U|{1}{B}{G}|Enchantment Creature - Spider|2|3|Reach$At the beginning of your upkeep, put the top two cards of your library into your graveyard.$1BG, Exile Nyx Weaver: Return target card from your graveyard to your hand.|
Renowned Weaver|Journey into Nyx|137|C|{G}|Creature - Human Shaman|1|1|{1}{G}, Sacrifice Renowned Weaver: Put a 1/3 green Spider enchantment creature token with reach onto the battlefield.|
Deicide|Journey into Nyx|7|R|{1}{W}|Instant|||Exile target enchantment. If the exiled card is a God card, search its controller's graveyard, hand, and library for any number of cards with the same name as that card and exile them, then that player shuffles his or her library.|