mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
* From among cards exiled - fixed that some cards can cause game error, (NPE fix, example: Rod of Absorption);
This commit is contained in:
parent
f5223b010b
commit
3030feaaf1
14 changed files with 109 additions and 75 deletions
|
@ -117,8 +117,8 @@ class ColfenorsPlansPlayCardEffect extends AsThoughEffectImpl {
|
|||
@Override
|
||||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
if (affectedControllerId.equals(source.getControllerId()) && game.getState().getZone(objectId) == Zone.EXILED) {
|
||||
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return zone != null && zone.contains(objectId);
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return exileZone != null && exileZone.contains(objectId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ import mage.cards.Cards;
|
|||
import mage.cards.CardsImpl;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
@ -125,10 +126,11 @@ class JelevaNephaliasCastEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller == null) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
if (controller == null || exileZone == null) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)));
|
||||
Cards cards = new CardsImpl(exileZone);
|
||||
return CardUtil.castSpellWithAttributesForFree(
|
||||
controller, source, game, cards,
|
||||
StaticFilters.FILTER_CARD_INSTANT_OR_SORCERY
|
||||
|
|
|
@ -16,6 +16,7 @@ import mage.cards.CardsImpl;
|
|||
import mage.constants.*;
|
||||
import mage.filter.FilterCard;
|
||||
import mage.filter.predicate.mageobject.ManaValuePredicate;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInLibrary;
|
||||
|
@ -121,10 +122,16 @@ class KahoMinamoHistorianCastEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Cards cards = new CardsImpl(game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)));
|
||||
if (controller == null || cards.isEmpty()) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
if (controller == null || exileZone == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Cards cards = new CardsImpl(exileZone);
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
FilterCard filter = new FilterCard();
|
||||
filter.add(new ManaValuePredicate(ComparisonType.EQUAL_TO, source.getManaCostsToPay().getX()));
|
||||
return CardUtil.castSpellWithAttributesForFree(controller, source, game, cards, filter);
|
||||
|
|
|
@ -186,27 +186,29 @@ class KarnLiberatedDelayedEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
if (controller != null) {
|
||||
ExileZone exile = game.getExile().getExileZone(exileId);
|
||||
if (exile != null) {
|
||||
// Creatures put onto the battlefield due to Karn's ability will have been under their controller's control continuously
|
||||
// since the beginning of the first turn. They can attack and their activated abilities with {T} in the cost can be activated.
|
||||
Cards cards = new CardsImpl(exile); // needed because putOntoTheBattlefield removes from exile
|
||||
if (!cards.isEmpty()) {
|
||||
controller.moveCards(cards, Zone.BATTLEFIELD, source, game);
|
||||
for (Card card : cards.getCards(game)) {
|
||||
if (card != null) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
((PermanentImpl) permanent).removeSummoningSickness();
|
||||
}
|
||||
}
|
||||
}
|
||||
ExileZone exileZone = game.getExile().getExileZone(exileId);
|
||||
if (controller == null || exileZone == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Creatures put onto the battlefield due to Karn's ability will have been under their controller's control continuously
|
||||
// since the beginning of the first turn. They can attack and their activated abilities with {T} in the cost can be activated.
|
||||
Cards cards = new CardsImpl(exileZone); // needed because putOntoTheBattlefield removes from exile
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
controller.moveCards(cards, Zone.BATTLEFIELD, source, game);
|
||||
for (Card card : cards.getCards(game)) {
|
||||
if (card != null) {
|
||||
Permanent permanent = game.getPermanent(card.getId());
|
||||
if (permanent != null) {
|
||||
((PermanentImpl) permanent).removeSummoningSickness();
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -121,8 +121,8 @@ class KheruMindEaterEffect extends AsThoughEffectImpl {
|
|||
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
|
||||
Card card = game.getCard(objectId);
|
||||
if (affectedControllerId.equals(source.getControllerId()) && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
|
||||
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return zone != null && zone.contains(card.getId());
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return exileZone != null && exileZone.contains(card.getId());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -143,9 +143,9 @@ class KingNarfisBetrayalSecondEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
if (zone != null) {
|
||||
for (Card card : zone.getCards(game)) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
if (exileZone != null) {
|
||||
for (Card card : exileZone.getCards(game)) {
|
||||
CardUtil.makeCardPlayable(game, source, card, Duration.EndOfTurn, true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -136,11 +136,11 @@ class LegionsInitiativeReturnFromExileEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
ExileZone exile = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source, -1));
|
||||
if (player == null || exile == null || exile.isEmpty()) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source, -1));
|
||||
if (player == null || exileZone == null || exileZone.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(exile);
|
||||
Cards cards = new CardsImpl(exileZone);
|
||||
player.moveCards(cards, Zone.BATTLEFIELD, source, game);
|
||||
List<Permanent> permanents = cards.stream().map(game::getPermanent).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
if (permanents.isEmpty()) {
|
||||
|
|
|
@ -156,11 +156,11 @@ class LivingLoreCastEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source, -2));
|
||||
return controller != null
|
||||
&& exileZone != null
|
||||
&& !exileZone.isEmpty()
|
||||
&& CardUtil.castSpellWithAttributesForFree(
|
||||
controller, source, game, new CardsImpl(exileZone), StaticFilters.FILTER_CARD
|
||||
);
|
||||
if (controller == null || exileZone == null || exileZone.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return CardUtil.castSpellWithAttributesForFree(controller, source, game,
|
||||
new CardsImpl(exileZone), StaticFilters.FILTER_CARD);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,26 @@
|
|||
|
||||
package mage.cards.m;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
import mage.MageObject;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
|
||||
import mage.abilities.common.DrawCardControllerTriggeredAbility;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.Cards;
|
||||
import mage.cards.CardsImpl;
|
||||
import mage.cards.*;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.constants.Zone;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public final class MoonringMirror extends CardImpl {
|
||||
|
@ -31,7 +28,7 @@ public final class MoonringMirror extends CardImpl {
|
|||
protected static final String VALUE_PREFIX = "ExileZones";
|
||||
|
||||
public MoonringMirror(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
|
||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
|
||||
|
||||
// Whenever you draw a card, exile the top card of your library face down.
|
||||
this.addAbility(new DrawCardControllerTriggeredAbility(new MoonringMirrorExileEffect(), false));
|
||||
|
@ -110,26 +107,35 @@ class MoonringMirrorEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
MageObject sourceObject = source.getSourceObject(game);
|
||||
if (controller != null && sourceObject != null) {
|
||||
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
Cards cardsToHand = null;
|
||||
if (game.getExile().getExileZone(exileZoneId) != null && !game.getExile().getExileZone(exileZoneId).isEmpty()) {
|
||||
cardsToHand = new CardsImpl(game.getExile().getExileZone(exileZoneId));
|
||||
}
|
||||
for (Card card : controller.getHand().getCards(game)) {
|
||||
if (controller == null || sourceObject == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UUID exileZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
|
||||
ExileZone exileZone = game.getExile().getExileZone(exileZoneId);
|
||||
|
||||
Cards cardsToHand = null;
|
||||
if (exileZone != null && !exileZone.isEmpty()) {
|
||||
cardsToHand = new CardsImpl(exileZone);
|
||||
}
|
||||
|
||||
// hand
|
||||
for (Card card : controller.getHand().getCards(game)) {
|
||||
card.setFaceDown(true, game);
|
||||
}
|
||||
controller.moveCardsToExile(controller.getHand().getCards(game), source, game, false, exileZoneId, sourceObject.getIdName());
|
||||
|
||||
if (cardsToHand != null) {
|
||||
controller.moveCards(cardsToHand.getCards(game), Zone.HAND, source, game, false, true, false, null);
|
||||
}
|
||||
|
||||
exileZone = game.getExile().getExileZone(exileZoneId);
|
||||
if (exileZone != null && !exileZone.isEmpty()) {
|
||||
for (Card card : game.getExile().getExileZone(exileZoneId).getCards(game)) {
|
||||
card.setFaceDown(true, game);
|
||||
}
|
||||
controller.moveCardsToExile(controller.getHand().getCards(game), source, game, false, exileZoneId, sourceObject.getIdName());
|
||||
if (cardsToHand != null) {
|
||||
controller.moveCards(cardsToHand.getCards(game), Zone.HAND, source, game, false, true, false, null);
|
||||
}
|
||||
if (game.getExile().getExileZone(exileZoneId) != null) {
|
||||
for (Card card : game.getExile().getExileZone(exileZoneId).getCards(game)) {
|
||||
card.setFaceDown(true, game);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,8 +126,8 @@ class NightveilSpecterEffect extends AsThoughEffectImpl {
|
|||
objectId = theCard.getMainCard().getId();// for split cards
|
||||
|
||||
if (affectedControllerId.equals(source.getControllerId()) && game.getState().getZone(objectId) == Zone.EXILED) {
|
||||
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return zone != null && zone.contains(objectId);
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return exileZone != null && exileZone.contains(objectId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import mage.abilities.effects.common.CopyEffect;
|
|||
import mage.cards.*;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
@ -67,11 +68,17 @@ class OlagLudevicsHubrisEffect extends ReplacementEffectImpl {
|
|||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Cards cards = new CardsImpl(game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)));
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
|
||||
if (exileZone == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Cards cards = new CardsImpl(exileZone);
|
||||
cards.removeIf(uuid -> !game.getCard(uuid).isCreature(game));
|
||||
if (cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Card copyFromCard = getCard(cards, source, game);
|
||||
if (copyFromCard == null) {
|
||||
return false;
|
||||
|
|
|
@ -15,6 +15,7 @@ import mage.constants.Duration;
|
|||
import mage.constants.Outcome;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
|
@ -167,10 +168,16 @@ class RodOfAbsorptionCastEffect extends OneShotEffect {
|
|||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Cards cards = new CardsImpl(game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)));
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
|
||||
if (exileZone == null || exileZone.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
Cards cards = new CardsImpl(exileZone);
|
||||
if (player == null || cards.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
CardUtil.castMultipleWithAttributeForFree(
|
||||
player, source, game, cards, StaticFilters.FILTER_CARD, Integer.MAX_VALUE,
|
||||
new RodOfAbsorptionTracker(source.getManaCostsToPay().getX())
|
||||
|
|
|
@ -16,6 +16,7 @@ import mage.filter.StaticFilters;
|
|||
import mage.filter.predicate.ObjectSourcePlayer;
|
||||
import mage.filter.predicate.ObjectSourcePlayerPredicate;
|
||||
import mage.filter.predicate.Predicates;
|
||||
import mage.game.ExileZone;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
|
@ -132,10 +133,12 @@ class ShellOfTheLastKappaCastEffect extends OneShotEffect {
|
|||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||
if (controller == null || sourcePermanent == null) {
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getExileZoneId(game, source));
|
||||
if (controller == null || sourcePermanent == null || exileZone == null) {
|
||||
return false;
|
||||
}
|
||||
Cards cards = new CardsImpl(game.getExile().getExileZone(CardUtil.getExileZoneId(game, source)));
|
||||
|
||||
Cards cards = new CardsImpl(exileZone);
|
||||
return CardUtil.castSpellWithAttributesForFree(controller, source, game, cards, StaticFilters.FILTER_CARD);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -126,9 +126,9 @@ class TheaterOfHorrorsCastEffect extends AsThoughEffectImpl {
|
|||
&& watcher.getAllOppLifeLost(source.getControllerId(), game) > 0
|
||||
&& affectedControllerId.equals(source.getControllerId())
|
||||
&& game.getState().getZone(objectId) == Zone.EXILED) {
|
||||
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return zone != null
|
||||
&& zone.contains(objectId);
|
||||
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
|
||||
return exileZone != null
|
||||
&& exileZone.contains(objectId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue