* Fixed that as thought effects could wrongly only apply to the ability controller.

This commit is contained in:
LevelX2 2014-09-17 15:57:06 +02:00
parent b3c0cc10b0
commit f9f49e9c00
11 changed files with 77 additions and 95 deletions

View file

@ -29,22 +29,27 @@
package mage.sets.betrayersofkamigawa; package mage.sets.betrayersofkamigawa;
import java.util.UUID; import java.util.UUID;
import mage.MageObject;
import mage.constants.*;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardsImpl; import mage.constants.AsThoughEffectType;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.players.Library; import mage.players.Library;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -92,15 +97,18 @@ class OrnateKanzashiEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(targetPointer.getFirst(game, source)); Player opponent = game.getPlayer(targetPointer.getFirst(game, source));
if (player != null && player.getLibrary().size() > 0) { MageObject sourceObject = game.getObject(source.getSourceId());
Library library = player.getLibrary(); if (sourceObject != null && opponent != null) {
Card card = library.removeFromTop(game); if (opponent.getLibrary().size() > 0) {
card.moveToExile(source.getSourceId(), "Ornate Kanzashi", source.getSourceId(), game); Library library = opponent.getLibrary();
Card card = library.getFromTop(game);
if (card != null) { if (card != null) {
player.revealCards("Card to play", new CardsImpl(card), game); opponent.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getLogName(), source.getSourceId(), game, Zone.LIBRARY);
game.addEffect(new OrnateKanzashiCastFromExileEffect(card.getId()), source); ContinuousEffect effect = new OrnateKanzashiCastFromExileEffect(card.getId());
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
}
} }
return true; return true;
} }
@ -110,17 +118,13 @@ class OrnateKanzashiEffect extends OneShotEffect {
class OrnateKanzashiCastFromExileEffect extends AsThoughEffectImpl { class OrnateKanzashiCastFromExileEffect extends AsThoughEffectImpl {
private UUID cardId;
public OrnateKanzashiCastFromExileEffect(UUID cardId) { public OrnateKanzashiCastFromExileEffect(UUID cardId) {
super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may play card from exile"; staticText = "You may play that card from exile this turn";
this.cardId = cardId;
} }
public OrnateKanzashiCastFromExileEffect(final OrnateKanzashiCastFromExileEffect effect) { public OrnateKanzashiCastFromExileEffect(final OrnateKanzashiCastFromExileEffect effect) {
super(effect); super(effect);
cardId = effect.cardId;
} }
@Override @Override
@ -134,26 +138,7 @@ class OrnateKanzashiCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { return source.getControllerId().equals(affectedControllerId) && objectId.equals(getTargetPointer().getFirst(game, source));
Card card = game.getCard(this.cardId);
if (card != null && game.getState().getZone(this.cardId) == Zone.EXILED) {
Player player = game.getPlayer(source.getControllerId());
if (player != null && player.chooseUse(Outcome.Benefit, "Play this card?", game)) {
if (card.getCardType().contains(CardType.LAND)) {
// If the revealed card is a land, you can play it only if it's your turn and you haven't yet played a land this turn.
if (game.getActivePlayerId().equals(player.getId()) && player.getLandsPlayed() < player.getLandsPerTurn()) {
return player.playLand(card, game);
}
} else {
Ability ability = card.getSpellAbility();
if (ability != null && ability instanceof SpellAbility) {
return player.cast((SpellAbility) ability, game, false);
}
}
}
}
}
return false;
} }
} }

View file

@ -40,7 +40,6 @@ import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.effects.common.ExileFromZoneTargetEffect; import mage.abilities.effects.common.ExileFromZoneTargetEffect;
import mage.abilities.effects.common.RegenerateSourceEffect; import mage.abilities.effects.common.RegenerateSourceEffect;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
@ -118,16 +117,12 @@ class FiendOfTheShadowsEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); if (affectedControllerId.equals(source.getControllerId())) {
if (card != null) { ExileZone zone = game.getExile().getExileZone(exileId);
ExileZone zone = game.getExile().getExileZone(exileId); if (zone != null && zone.contains(objectId)) {
if (zone != null && zone.contains(card.getId())) {
if (card.getCardType().contains(CardType.INSTANT) || game.canPlaySorcery(source.getControllerId())) {
card.setControllerId(source.getControllerId());
return true; return true;
} }
}
} }
return false; return false;
} }

View file

@ -114,8 +114,10 @@ class HavengulLichPlayEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return targetPointer.getFirst(game, source).equals(sourceId) && game.getState().getZone(sourceId) == Zone.GRAVEYARD; return source.getControllerId().equals(affectedControllerId)
&& targetPointer.getFirst(game, source).equals(objectId)
&& game.getState().getZone(objectId) == Zone.GRAVEYARD;
} }
} }

View file

@ -37,6 +37,7 @@ import mage.constants.Outcome;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -56,6 +57,7 @@ import mage.players.Player;
import mage.target.Target; import mage.target.Target;
import mage.target.TargetCard; import mage.target.TargetCard;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import mage.util.CardUtil;
/** /**
* Gatecrash FAQ (01.2013) * Gatecrash FAQ (01.2013)
@ -99,12 +101,11 @@ public class BaneAlleyBroker extends CardImpl {
this.power = new MageInt(0); this.power = new MageInt(0);
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// {tap}: Draw a card, then exile a card from your hand face down. // {tap}: Draw a card, then exile a card from your hand face down.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BaneAlleyBrokerDrawExileEffect(), new TapSourceCost())); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BaneAlleyBrokerDrawExileEffect(), new TapSourceCost()));
// You may look at cards exiled with Bane Alley Broker. // You may look at cards exiled with Bane Alley Broker.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BaneAlleyBrokerLookAtCardEffect())); this.addAbility(new SimpleStaticAbility(Zone.ALL, new BaneAlleyBrokerLookAtCardEffect()));
// {U}{B}, {tap}: Return a card exiled with Bane Alley Broker to its owner's hand. // {U}{B}, {tap}: Return a card exiled with Bane Alley Broker to its owner's hand.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{U}{B}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandTargetEffect(), new ManaCostsImpl("{U}{B}"));
@ -143,15 +144,10 @@ class BaneAlleyBrokerDrawExileEffect extends OneShotEffect {
Target target = new TargetCardInHand(new FilterCard("card to exile")); Target target = new TargetCardInHand(new FilterCard("card to exile"));
if (player.chooseTarget(outcome, target, source, game)) { if (player.chooseTarget(outcome, target, source, game)) {
Card card = game.getCard(target.getFirstTarget()); Card card = game.getCard(target.getFirstTarget());
Card sourceCard = game.getCard(source.getSourceId()); MageObject sourceObject = game.getObject(source.getSourceId());
if (card != null && sourceCard != null) { if (card != null && sourceObject != null) {
card.setFaceDown(true); card.setFaceDown(true);
UUID exileId = (UUID) game.getState().getValue(new StringBuilder("exileZone").append(source.getSourceId()).append(sourceCard.getZoneChangeCounter()).toString()); return card.moveToExile(CardUtil.getCardExileZoneId(game, source), new StringBuilder(sourceObject.getLogName()).toString(), source.getSourceId(), game);
if (exileId == null) {
exileId = UUID.randomUUID();
game.getState().setValue(new StringBuilder("exileZone").append(source.getSourceId()).append(sourceCard.getZoneChangeCounter()).toString(), exileId);
}
return card.moveToExile(exileId, new StringBuilder(sourceCard.getName()).append("(").append(sourceCard.getZoneChangeCounter()).append(")").toString(), source.getSourceId(), game);
} }
} }
} }
@ -176,10 +172,10 @@ class TargetCardInBaneAlleyBrokerExile extends TargetCard {
@Override @Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) { public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> possibleTargets = new HashSet<UUID>(); Set<UUID> possibleTargets = new HashSet<>();
Card sourceCard = game.getCard(sourceId); Card sourceCard = game.getCard(sourceId);
if (sourceCard != null) { if (sourceCard != null) {
UUID exileId = (UUID) game.getState().getValue(new StringBuilder("exileZone").append(sourceId).append(sourceCard.getZoneChangeCounter()).toString()); UUID exileId = CardUtil.getCardExileZoneId(game, sourceId);
ExileZone exile = game.getExile().getExileZone(exileId); ExileZone exile = game.getExile().getExileZone(exileId);
if (exile != null && exile.size() > 0) { if (exile != null && exile.size() > 0) {
possibleTargets.addAll(exile); possibleTargets.addAll(exile);
@ -192,7 +188,7 @@ class TargetCardInBaneAlleyBrokerExile extends TargetCard {
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
Card sourceCard = game.getCard(sourceId); Card sourceCard = game.getCard(sourceId);
if (sourceCard != null) { if (sourceCard != null) {
UUID exileId = (UUID) game.getState().getValue(new StringBuilder("exileZone").append(sourceId).append(sourceCard.getZoneChangeCounter()).toString()); UUID exileId = CardUtil.getCardExileZoneId(game, sourceId);
ExileZone exile = game.getExile().getExileZone(exileId); ExileZone exile = game.getExile().getExileZone(exileId);
if (exile != null && exile.size() > 0) { if (exile != null && exile.size() > 0) {
return true; return true;
@ -208,7 +204,7 @@ class TargetCardInBaneAlleyBrokerExile extends TargetCard {
ExileZone exile = null; ExileZone exile = null;
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());
if (sourceCard != null) { if (sourceCard != null) {
UUID exileId = (UUID) game.getState().getValue(new StringBuilder("exileZone").append(source.getSourceId()).append(sourceCard.getZoneChangeCounter()).toString()); UUID exileId = CardUtil.getCardExileZoneId(game, source);
exile = game.getExile().getExileZone(exileId); exile = game.getExile().getExileZone(exileId);
} }
if (exile != null && exile.contains(id)) { if (exile != null && exile.contains(id)) {
@ -246,20 +242,22 @@ class BaneAlleyBrokerLookAtCardEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); if (affectedControllerId.equals(source.getControllerId())) {
if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) { Card card = game.getCard(objectId);
Card sourceCard = game.getCard(source.getSourceId()); if (card != null) {
if (sourceCard == null) { MageObject sourceObject = game.getObject(source.getSourceId());
return false; if (sourceObject == null) {
} return false;
UUID exileId = (UUID) game.getState().getValue(new StringBuilder("exileZone").append(source.getSourceId()).append(sourceCard.getZoneChangeCounter()).toString()); }
ExileZone exile = game.getExile().getExileZone(exileId); UUID exileId = CardUtil.getCardExileZoneId(game, source);
if (exile != null && exile.contains(sourceId)) { ExileZone exile = game.getExile().getExileZone(exileId);
Cards cards = new CardsImpl(card); if (exile != null && exile.contains(objectId)) {
Player controller = game.getPlayer(source.getControllerId()); Cards cards = new CardsImpl(card);
if (controller != null) { Player controller = game.getPlayer(source.getControllerId());
controller.lookAtCards("Exiled with " + sourceCard.getName(), cards, game); if (controller != null) {
controller.lookAtCards("Exiled with " + sourceObject.getLogName(), cards, game);
}
} }
} }
} }

View file

@ -112,10 +112,12 @@ class GlaringSpotlightEffect extends AsThoughEffectImpl {
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Permanent creature = game.getPermanent(sourceId); if (affectedControllerId.equals(source.getControllerId())) {
if (creature != null) { Permanent creature = game.getPermanent(sourceId);
if (game.getOpponents(source.getControllerId()).contains(creature.getControllerId())) { if (creature != null) {
return true; if (game.getOpponents(source.getControllerId()).contains(creature.getControllerId())) {
return true;
}
} }
} }
return false; return false;

View file

@ -149,10 +149,9 @@ class NightveilSpecterEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(objectId);
Player controller = game.getPlayer(source.getControllerId()); if (affectedControllerId.equals(source.getControllerId()) && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
if (controller != null && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {
ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); ExileZone zone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source));
return zone != null && zone.contains(card.getId()); return zone != null && zone.contains(card.getId());
} }

View file

@ -117,7 +117,7 @@ class QuickenAsThoughEffect extends AsThoughEffectImpl {
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (quickenWatcher.isQuickenSpellActive(source.getSourceId(), zoneChangeCounter)) { if (quickenWatcher.isQuickenSpellActive(source.getSourceId(), zoneChangeCounter)) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (card != null && card.getCardType().contains(CardType.SORCERY) && card.getOwnerId().equals(source.getControllerId())) { if (card != null && card.getCardType().contains(CardType.SORCERY) && source.getControllerId().equals(affectedControllerId)) {
return card.getSpellAbility().isInUseableZone(game, card, false); return card.getSpellAbility().isInUseableZone(game, card, false);
} }
} }

View file

@ -124,7 +124,7 @@ class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl {
public PropheticFlamespeakerCastFromExileEffect() { public PropheticFlamespeakerCastFromExileEffect() {
super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit); super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.EndOfTurn, Outcome.Benefit);
staticText = "You may play card from exile"; staticText = "You may play the card from exile";
} }
public PropheticFlamespeakerCastFromExileEffect(final PropheticFlamespeakerCastFromExileEffect effect) { public PropheticFlamespeakerCastFromExileEffect(final PropheticFlamespeakerCastFromExileEffect effect) {
@ -142,7 +142,8 @@ class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) { public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
return sourceId.equals(getTargetPointer().getFirst(game, source)) && game.getState().getZone(sourceId) == Zone.EXILED; return source.getControllerId().equals(affectedControllerId) &&
objectId.equals(getTargetPointer().getFirst(game, source));
} }
} }

View file

@ -72,7 +72,7 @@ public class AlternativeCostSourceAbility extends StaticAbility implements Alter
* *
* @param cost alternate cost to pay * @param cost alternate cost to pay
* @param condition only if the condition is true it's possible to use the alternate costs * @param condition only if the condition is true it's possible to use the alternate costs
* @param rule if set used as rule text * @param rule if != null used as rule text
* @param filter filters the cards this alternate cost can be applied to * @param filter filters the cards this alternate cost can be applied to
* @param onlyMana if true only the mana costs are replaced by this costs, other costs stay untouched * @param onlyMana if true only the mana costs are replaced by this costs, other costs stay untouched
*/ */

View file

@ -435,7 +435,7 @@ public class ContinuousEffects implements Serializable {
for (AsThoughEffect effect: asThoughEffectsList) { for (AsThoughEffect effect: asThoughEffectsList) {
HashSet<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId()); HashSet<Ability> abilities = asThoughEffectsMap.get(type).getAbility(effect.getId());
for (Ability ability : abilities) { for (Ability ability : abilities) {
if (controllerId.equals(ability.getControllerId())) { //if (controllerId.equals(ability.getControllerId())) { must be checked in the applies method
if (affectedAbility == null) { if (affectedAbility == null) {
if (effect.applies(objectId, ability, controllerId, game)) { if (effect.applies(objectId, ability, controllerId, game)) {
return true; return true;
@ -445,7 +445,7 @@ public class ContinuousEffects implements Serializable {
return true; return true;
} }
} }
} //}
} }
} }
return false; return false;

View file

@ -490,7 +490,7 @@ public class CardUtil {
uniqueString.append(text); uniqueString.append(text);
} }
uniqueString.append(cardId); uniqueString.append(cardId);
Card card = game.getCard(cardId); Card card = game.getCard(cardId); // if called for a token, the id is enough
if (card != null) { if (card != null) {
uniqueString.append(card.getZoneChangeCounter()); uniqueString.append(card.getZoneChangeCounter());
} }