Some more changes concerning ThoughtAsEffects.

This commit is contained in:
LevelX2 2014-08-09 11:48:40 +02:00
parent d1a8678086
commit 2ca945fabf
45 changed files with 3306 additions and 206 deletions

View file

@ -68,9 +68,9 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player {
protected int maxThink; protected int maxThink;
protected int nodeCount = 0; protected int nodeCount = 0;
protected long thinkTime = 0; protected long thinkTime = 0;
protected transient LinkedList<Ability> actions = new LinkedList<Ability>(); protected transient LinkedList<Ability> actions = new LinkedList<>();
protected transient List<UUID> targets = new ArrayList<UUID>(); protected transient List<UUID> targets = new ArrayList<>();
protected transient List<String> choices = new ArrayList<String>(); protected transient List<String> choices = new ArrayList<>();
protected transient Combat combat; protected transient Combat combat;
protected int currentScore; protected int currentScore;
protected transient SimulationNode root; protected transient SimulationNode root;
@ -86,8 +86,9 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player {
super(player); super(player);
this.maxDepth = player.maxDepth; this.maxDepth = player.maxDepth;
this.currentScore = player.currentScore; this.currentScore = player.currentScore;
if (player.combat != null) if (player.combat != null) {
this.combat = player.combat.copy(); this.combat = player.combat.copy();
}
this.actions.addAll(player.actions); this.actions.addAll(player.actions);
this.targets.addAll(player.targets); this.targets.addAll(player.targets);
this.choices.addAll(player.choices); this.choices.addAll(player.choices);

View file

@ -890,7 +890,7 @@ public class HumanPlayer extends PlayerImpl {
if (ability instanceof PlayLandAbility) { if (ability instanceof PlayLandAbility) {
return true; return true;
} }
if (ability.getManaCostsToPay().convertedManaCost() > 0) { if (!ability.getSourceId().equals(getCastSourceIdWithoutMana()) && ability.getManaCostsToPay().convertedManaCost() > 0) {
return true; return true;
} }
if (ability instanceof ManaAbility) { if (ability instanceof ManaAbility) {

File diff suppressed because it is too large Load diff

View file

@ -276,10 +276,10 @@ public class GameSession extends GameWatcher {
public void kill() { public void kill() {
if (game != null) { if (game != null) {
logger.debug("GameSession.kill before player quit for game"); logger.debug("before game.quit playerId:" + playerId);
game.quit(playerId); game.quit(playerId);
} else { } else {
logger.error("GameSession.kill game object missing playerId: " + (playerId == null ? "[null]":playerId)); logger.error("game object missing playerId: " + (playerId == null ? "[null]":playerId));
} }
} }

View file

@ -77,7 +77,7 @@ public class GamesRoomImpl extends RoomImpl implements GamesRoom, Serializable {
try { try {
update(); update();
} catch (Exception ex) { } catch (Exception ex) {
logger.fatal("Games room update exception!", ex); logger.fatal("Games room update exception! " + ex.toString(), ex);
} }
} }

View file

@ -56,16 +56,16 @@ public class ServerMessagesUtil {
private static final String SERVER_MSG_TXT_FILE = "server.msg.txt"; private static final String SERVER_MSG_TXT_FILE = "server.msg.txt";
private static ScheduledExecutorService updateExecutor; private static ScheduledExecutorService updateExecutor;
private List<String> messages = new ArrayList<String>(); private final List<String> messages = new ArrayList<>();
private ReadWriteLock lock = new ReentrantReadWriteLock(); private final ReadWriteLock lock = new ReentrantReadWriteLock();
private static String pathToExternalMessages = null; private static String pathToExternalMessages = null;
private static boolean ignore = false; private static boolean ignore = false;
private static long startDate; private static long startDate;
private static AtomicInteger gamesStarted = new AtomicInteger(0); private static final AtomicInteger gamesStarted = new AtomicInteger(0);
private static AtomicInteger tournamentsStarted = new AtomicInteger(0); private static final AtomicInteger tournamentsStarted = new AtomicInteger(0);
static { static {
pathToExternalMessages = System.getProperty("messagesPath"); pathToExternalMessages = System.getProperty("messagesPath");
@ -97,7 +97,7 @@ public class ServerMessagesUtil {
private void reloadMessages() { private void reloadMessages() {
log.debug("Reading server messages..."); log.debug("Reading server messages...");
List<String> motdMessages = readFromFile(); List<String> motdMessages = readFromFile();
List<String> newMessages = new ArrayList<String>(); List<String> newMessages = new ArrayList<>();
if (motdMessages != null) { if (motdMessages != null) {
newMessages.addAll(motdMessages); newMessages.addAll(motdMessages);
} }
@ -154,14 +154,14 @@ public class ServerMessagesUtil {
return null; return null;
} }
Scanner scanner = new Scanner(is); Scanner scanner = new Scanner(is);
List<String> messages = new ArrayList<String>(); List<String> newMessages = new ArrayList<>();
while (scanner.hasNextLine()) { while (scanner.hasNextLine()) {
String message = scanner.nextLine(); String message = scanner.nextLine();
if (!message.trim().isEmpty()) { if (!message.trim().isEmpty()) {
messages.add(message.trim()); newMessages.add(message.trim());
} }
} }
return messages; return newMessages;
} }
private String getServerStatistics() { private String getServerStatistics() {

View file

@ -96,7 +96,7 @@ class MisthollowGriffinPlayEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(source.getSourceId())) { if (sourceId.equals(source.getSourceId())) {
Card card = game.getCard(source.getSourceId()); Card card = game.getCard(source.getSourceId());
if (card != null && card.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) { if (card != null && card.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) {

View file

@ -40,6 +40,8 @@ import mage.players.Player;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import java.util.UUID; import java.util.UUID;
import mage.abilities.effects.ContinuousEffect;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -86,20 +88,22 @@ class StolenGoodsEffect 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) { if (opponent != null && opponent.getLibrary().size() > 0) {
Library library = player.getLibrary(); Library library = opponent.getLibrary();
Card card; Card card;
do { do {
card = library.removeFromTop(game); card = library.removeFromTop(game);
if (card != null) { if (card != null) {
card.moveToExile(source.getId(), "Stolen Goods", source.getSourceId(), game); opponent.moveCardToExileWithInfo(card, source.getId(), "Stolen Goods", source.getSourceId(), game, Zone.LIBRARY);
} }
} while (library.size() > 0 && card != null && card.getCardType().contains(CardType.LAND)); } while (library.size() > 0 && card != null && card.getCardType().contains(CardType.LAND));
if (card != null) { if (card != null) {
player.revealCards("Card to cast", new CardsImpl(card), game); opponent.revealCards("Card to cast", new CardsImpl(card), game);
game.addEffect(new StolenGoodsCastFromExileEffect(card.getId()), source); ContinuousEffect effect = new StolenGoodsCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
} }
return true; return true;
} }
@ -109,17 +113,13 @@ class StolenGoodsEffect extends OneShotEffect {
class StolenGoodsCastFromExileEffect extends AsThoughEffectImpl { class StolenGoodsCastFromExileEffect extends AsThoughEffectImpl {
private final UUID cardId; public StolenGoodsCastFromExileEffect() {
public StolenGoodsCastFromExileEffect(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 cast card from exile"; staticText = "You may cast card from exile";
this.cardId = cardId;
} }
public StolenGoodsCastFromExileEffect(final StolenGoodsCastFromExileEffect effect) { public StolenGoodsCastFromExileEffect(final StolenGoodsCastFromExileEffect effect) {
super(effect); super(effect);
cardId = effect.cardId;
} }
@Override @Override
@ -133,14 +133,12 @@ class StolenGoodsCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { if (getTargetPointer().getFirst(game, source).equals(sourceId) && affectedControllerId.equals(source.getControllerId())) {
Card card = game.getCard(this.cardId); Card card = game.getCard(sourceId);
if (card != null && game.getState().getZone(this.cardId) == Zone.EXILED) { if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) {
Player player = game.getPlayer(source.getControllerId()); Player player = game.getPlayer(affectedControllerId);
if (player != null && player.chooseUse(Outcome.Benefit, "Cast the card without paying cost?", game)) { player.setCastSourceIdWithoutMana(sourceId);
player.cast(card.getSpellAbility(), game, true);
}
return true; return true;
} }
} }

View file

@ -134,7 +134,7 @@ class OrnateKanzashiCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { if (sourceId.equals(this.cardId)) {
Card card = game.getCard(this.cardId); Card card = game.getCard(this.cardId);
if (card != null && game.getState().getZone(this.cardId) == Zone.EXILED) { if (card != null && game.getState().getZone(this.cardId) == Zone.EXILED) {

View file

@ -99,7 +99,7 @@ class BlockTappedEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) { if (permanent != null && permanent.getControllerId().equals(source.getControllerId())) {
return true; return true;

View file

@ -99,7 +99,7 @@ class ThousandYearElixirEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Permanent permanent = game.getPermanent(sourceId); Permanent permanent = game.getPermanent(sourceId);
return permanent != null return permanent != null
&& permanent.getCardType().contains(CardType.CREATURE) && permanent.getCardType().contains(CardType.CREATURE)

View file

@ -118,7 +118,7 @@ class FiendOfTheShadowsEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (card != null) { if (card != null) {
ExileZone zone = game.getExile().getExileZone(exileId); ExileZone zone = game.getExile().getExileZone(exileId);

View file

@ -89,7 +89,7 @@ class GravecrawlerPlayEffect extends AsThoughEffectImpl {
public GravecrawlerPlayEffect() { public GravecrawlerPlayEffect() {
super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit); super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit);
staticText = "You may cast Gravecrawler from your graveyard as long as you control a Zombie"; staticText = "You may cast {this} from your graveyard as long as you control a Zombie";
} }
public GravecrawlerPlayEffect(final GravecrawlerPlayEffect effect) { public GravecrawlerPlayEffect(final GravecrawlerPlayEffect effect) {
@ -107,10 +107,10 @@ class GravecrawlerPlayEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(source.getSourceId())) { if (sourceId.equals(source.getSourceId()) && source.getControllerId().equals(affectedControllerId)) {
Card card = game.getCard(source.getSourceId()); Card card = game.getCard(source.getSourceId());
if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD && game.canPlaySorcery(source.getControllerId())) { if (card != null && game.getState().getZone(source.getSourceId()) == Zone.GRAVEYARD) {
if (game.getBattlefield().countAll(filter, source.getControllerId(), game) > 0) { if (game.getBattlefield().countAll(filter, source.getControllerId(), game) > 0) {
return true; return true;
} }

View file

@ -114,16 +114,8 @@ class HavengulLichPlayEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (targetPointer.getFirst(game, source).equals(sourceId)) { return targetPointer.getFirst(game, source).equals(sourceId) && game.getState().getZone(sourceId) == Zone.GRAVEYARD;
if (game.getState().getZone(sourceId) == Zone.GRAVEYARD) {
Card card = game.getCard(sourceId);
if (card != null && card.getSpellAbility() != null && card.getSpellAbility().spellCanBeActivatedRegularlyNow(source.getControllerId(), game)) {
return true;
}
}
}
return false;
} }
} }

View file

@ -113,7 +113,7 @@ class AsThoughNoDefenderEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Permanent nivixCyclops = game.getPermanent(source.getSourceId()); Permanent nivixCyclops = game.getPermanent(source.getSourceId());
if (nivixCyclops != null if (nivixCyclops != null
&& nivixCyclops.getAbilities().containsKey(DefenderAbility.getInstance().getId())) { && nivixCyclops.getAbilities().containsKey(DefenderAbility.getInstance().getId())) {

View file

@ -246,7 +246,7 @@ class BaneAlleyBrokerLookAtCardEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) { if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) {
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());

View file

@ -111,7 +111,7 @@ class GlaringSpotlightEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Permanent creature = game.getPermanent(sourceId); Permanent creature = game.getPermanent(sourceId);
if (creature != null) { if (creature != null) {
if (game.getOpponents(source.getControllerId()).contains(creature.getControllerId())) { if (game.getOpponents(source.getControllerId()).contains(creature.getControllerId())) {

View file

@ -149,7 +149,7 @@ class NightveilSpecterEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) { if (controller != null && card != null && game.getState().getZone(card.getId()) == Zone.EXILED) {

View file

@ -114,7 +114,7 @@ class QuickenAsThoughEffect extends AsThoughEffectImpl {
@Override @Override
public boolean applies(UUID sourceId, Ability source, 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) && card.getOwnerId().equals(source.getControllerId())) {

View file

@ -30,9 +30,9 @@ package mage.sets.journeyintonyx;
import java.util.UUID; import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.SpellAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
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.abilities.keyword.DoubleStrikeAbility; import mage.abilities.keyword.DoubleStrikeAbility;
import mage.abilities.keyword.TrampleAbility; import mage.abilities.keyword.TrampleAbility;
@ -42,13 +42,13 @@ import mage.constants.AsThoughEffectType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.PhaseStep;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.Zone; import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Library; import mage.players.Library;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -110,7 +110,9 @@ class PropheticFlamespeakerExileEffect extends OneShotEffect {
if (card != null) { if (card != null) {
String exileName = new StringBuilder(sourcePermanent.getName()).append(" <this card may be played the turn it was exiled>").toString(); String exileName = new StringBuilder(sourcePermanent.getName()).append(" <this card may be played the turn it was exiled>").toString();
controller.moveCardToExileWithInfo(card, source.getSourceId(), exileName, source.getSourceId(), game, Zone.LIBRARY); controller.moveCardToExileWithInfo(card, source.getSourceId(), exileName, source.getSourceId(), game, Zone.LIBRARY);
game.addEffect(new PropheticFlamespeakerCastFromExileEffect(card.getId()), source); ContinuousEffect effect = new PropheticFlamespeakerCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
} }
return true; return true;
} }
@ -120,17 +122,13 @@ class PropheticFlamespeakerExileEffect extends OneShotEffect {
class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl { class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl {
private final UUID cardId; public PropheticFlamespeakerCastFromExileEffect() {
public PropheticFlamespeakerCastFromExileEffect(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 card from exile";
this.cardId = cardId;
} }
public PropheticFlamespeakerCastFromExileEffect(final PropheticFlamespeakerCastFromExileEffect effect) { public PropheticFlamespeakerCastFromExileEffect(final PropheticFlamespeakerCastFromExileEffect effect) {
super(effect); super(effect);
cardId = effect.cardId;
} }
@Override @Override
@ -144,32 +142,7 @@ class PropheticFlamespeakerCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { return sourceId.equals(getTargetPointer().getFirst(game, source)) && game.getState().getZone(sourceId) == Zone.EXILED;
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 ) {
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 can play still a land this turn.
if (player.canPlayLand()
&& game.getActivePlayerId().equals(player.getId())
&& game.getStack().isEmpty()
&& (game.getStep().getType().equals(PhaseStep.PRECOMBAT_MAIN) || game.getStep().getType().equals(PhaseStep.POSTCOMBAT_MAIN))
&& player.chooseUse(Outcome.Benefit, "Play this card?", game)) {
return player.playLand(card, game);
}
} else {
Ability ability = card.getSpellAbility();
if (ability != null && ability instanceof SpellAbility
&& ((SpellAbility)ability).spellCanBeActivatedRegularlyNow(player.getId(), game)
&& player.chooseUse(Outcome.Benefit, "Play this card?", game)) {
return player.cast((SpellAbility) ability, game, false);
}
}
}
}
}
return false;
} }
} }

View file

@ -248,7 +248,7 @@ class ChandraPyromasterCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (targetPointer.getTargets(game, source).contains(sourceId)) { if (targetPointer.getTargets(game, source).contains(sourceId)) {
return game.getState().getZone(sourceId).equals(Zone.EXILED); return game.getState().getZone(sourceId).equals(Zone.EXILED);
} }

View file

@ -128,7 +128,7 @@ class SavageSummoningAsThoughEffect extends AsThoughEffectImpl {
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (watcher.isSavageSummoningSpellActive()) { if (watcher.isSavageSummoningSpellActive()) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (card != null && card.getCardType().contains(CardType.CREATURE) && card.getOwnerId().equals(source.getControllerId())) { if (card != null && card.getCardType().contains(CardType.CREATURE) && card.getOwnerId().equals(source.getControllerId())) {

View file

@ -140,7 +140,7 @@ class ActOnImpulseMayPlayExiledEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null && card != null && game.getState().getZone(sourceId) == Zone.EXILED) { if (controller != null && card != null && game.getState().getZone(sourceId) == Zone.EXILED) {

View file

@ -138,7 +138,7 @@ class PraetorsGraspPlayEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(cardId)) { if (sourceId.equals(cardId)) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
@ -177,7 +177,7 @@ class PraetorsGraspRevealEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(cardId)) { if (sourceId.equals(cardId)) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());

View file

@ -104,7 +104,7 @@ class OgreJailbreakerEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(source.getSourceId()) && gateCondition.apply(game, source)) { if (sourceId.equals(source.getSourceId()) && gateCondition.apply(game, source)) {
return true; return true;
} }

View file

@ -46,8 +46,6 @@ import java.util.UUID;
*/ */
public class WarmongersChariot extends CardImpl { public class WarmongersChariot extends CardImpl {
private static final String staticText = "As long as equipped creature has defender, it can attack as though it didn't have defender";
public WarmongersChariot(UUID ownerId) { public WarmongersChariot(UUID ownerId) {
super(ownerId, 226, "Warmonger's Chariot", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}"); super(ownerId, 226, "Warmonger's Chariot", Rarity.UNCOMMON, new CardType[]{CardType.ARTIFACT}, "{2}");
this.expansionSetCode = "ROE"; this.expansionSetCode = "ROE";
@ -95,7 +93,7 @@ class WarmongersChariotEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Permanent equipment = game.getPermanent(source.getSourceId()); Permanent equipment = game.getPermanent(source.getSourceId());
if (equipment != null && equipment.getAttachedTo() != null) { if (equipment != null && equipment.getAttachedTo() != null) {
Permanent creature = game.getPermanent(equipment.getAttachedTo()); Permanent creature = game.getPermanent(equipment.getAttachedTo());

View file

@ -152,7 +152,7 @@ class KnacksawCliqueCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { if (sourceId.equals(this.cardId)) {
Card card = game.getCard(this.cardId); Card card = game.getCard(this.cardId);
if (card != null && game.getState().getExile().getExileZone(exileId).contains(cardId)) { if (card != null && game.getState().getExile().getExileZone(exileId).contains(cardId)) {

View file

@ -95,7 +95,7 @@ class CanBlockAsThoughtIthadShadowEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
return sourceId.equals(source.getSourceId()); return sourceId.equals(source.getSourceId());
} }

View file

@ -34,6 +34,7 @@ import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
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.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect; import mage.abilities.effects.common.combat.CantBeBlockedByCreaturesSourceEffect;
import mage.cards.Card; import mage.cards.Card;
@ -49,6 +50,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.mageobject.PowerPredicate; import mage.filter.predicate.mageobject.PowerPredicate;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
/** /**
@ -129,7 +131,9 @@ class DaxosOfMeletisEffect extends OneShotEffect {
// allow to cast the card // allow to cast the card
game.addEffect(new DaxosOfMeletisCastFromExileEffect(card.getId(), exileId), source); game.addEffect(new DaxosOfMeletisCastFromExileEffect(card.getId(), exileId), source);
// and you may spend mana as though it were mana of any color to cast it // and you may spend mana as though it were mana of any color to cast it
game.addEffect(new DaxosOfMeletisSpendAnyManaEffect(card.getId()), source); ContinuousEffect effect = new DaxosOfMeletisSpendAnyManaEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
} }
} }
return true; return true;
@ -168,32 +172,20 @@ class DaxosOfMeletisCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { return sourceId.equals(cardId) && game.getState().getExile().getExileZone(exileId).contains(cardId);
Card card = game.getCard(this.cardId);
if (card != null && game.getState().getExile().getExileZone(exileId).contains(cardId)) {
if (card.getSpellAbility() != null && card.getSpellAbility().spellCanBeActivatedRegularlyNow(source.getControllerId(), game)) {
return true;
}
}
}
return false;
} }
} }
class DaxosOfMeletisSpendAnyManaEffect extends AsThoughEffectImpl { class DaxosOfMeletisSpendAnyManaEffect extends AsThoughEffectImpl {
private final UUID cardId; public DaxosOfMeletisSpendAnyManaEffect() {
public DaxosOfMeletisSpendAnyManaEffect(UUID cardId) {
super(AsThoughEffectType.SPEND_ANY_MANA, Duration.EndOfTurn, Outcome.Benefit); super(AsThoughEffectType.SPEND_ANY_MANA, Duration.EndOfTurn, Outcome.Benefit);
staticText = "you may spend mana as though it were mana of any color to cast it"; staticText = "you may spend mana as though it were mana of any color to cast it";
this.cardId = cardId;
} }
public DaxosOfMeletisSpendAnyManaEffect(final DaxosOfMeletisSpendAnyManaEffect effect) { public DaxosOfMeletisSpendAnyManaEffect(final DaxosOfMeletisSpendAnyManaEffect effect) {
super(effect); super(effect);
this.cardId = effect.cardId;
} }
@Override @Override
@ -207,7 +199,7 @@ class DaxosOfMeletisSpendAnyManaEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
return sourceId.equals(this.cardId); return sourceId.equals(getTargetPointer().getFirst(game, source));
} }
} }

View file

@ -30,6 +30,7 @@ package mage.sets.theros;
import java.util.UUID; import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
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;
@ -44,6 +45,7 @@ import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import mage.target.common.TargetOpponent; import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
/** /**
@ -100,13 +102,13 @@ class PsychicIntrusionExileEffect extends OneShotEffect {
Player opponent = game.getPlayer(targetPointer.getFirst(game, source)); Player opponent = game.getPlayer(targetPointer.getFirst(game, source));
if (opponent != null) { if (opponent != null) {
opponent.revealCards("Psychic Intrusion", opponent.getHand(), game); opponent.revealCards("Psychic Intrusion", opponent.getHand(), game);
Player you = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (you != null) { if (controller != null) {
int cardsGraveyard = opponent.getGraveyard().count(filter, game); int cardsGraveyard = opponent.getGraveyard().count(filter, game);
int cardsHand = opponent.getHand().count(filter, game); int cardsHand = opponent.getHand().count(filter, game);
boolean fromHand = false; boolean fromHand = false;
if (cardsGraveyard > 0 && cardsHand > 0) { if (cardsGraveyard > 0 && cardsHand > 0) {
if (you.chooseUse(Outcome.Detriment, "Exile card from opponents Hand?", game)) { if (controller.chooseUse(Outcome.Detriment, "Exile card from opponents Hand?", game)) {
fromHand = true; fromHand = true;
} }
} else { } else {
@ -117,15 +119,15 @@ class PsychicIntrusionExileEffect extends OneShotEffect {
Card card = null; Card card = null;
if (cardsHand > 0 && fromHand) { if (cardsHand > 0 && fromHand) {
TargetCard target = new TargetCard(Zone.PICK, filter); TargetCard target = new TargetCard(Zone.HAND, filter);
if (you.choose(Outcome.Benefit, opponent.getHand(), target, game)) { if (controller.choose(Outcome.Benefit, opponent.getHand(), target, game)) {
card = opponent.getHand().get(target.getFirstTarget(), game); card = opponent.getHand().get(target.getFirstTarget(), game);
} }
} }
if (cardsGraveyard > 0 && !fromHand) { if (cardsGraveyard > 0 && !fromHand) {
TargetCard target = new TargetCard(Zone.PICK, filter); TargetCard target = new TargetCard(Zone.GRAVEYARD, filter);
if (you.choose(Outcome.Benefit, opponent.getGraveyard(), target, game)) { if (controller.choose(Outcome.Benefit, opponent.getGraveyard(), target, game)) {
card = opponent.getGraveyard().get(target.getFirstTarget(), game); card = opponent.getGraveyard().get(target.getFirstTarget(), game);
} }
@ -133,18 +135,15 @@ class PsychicIntrusionExileEffect extends OneShotEffect {
if (card != null) { if (card != null) {
// move card to exile // move card to exile
UUID exileId = CardUtil.getCardExileZoneId(game, source); UUID exileId = CardUtil.getCardExileZoneId(game, source);
card.moveToExile(exileId, "Psychic Intrusion", source.getSourceId(), game); controller.moveCardToExileWithInfo(card, exileId, "Psychic Intrusion", source.getSourceId(), game, fromHand ? Zone.HAND:Zone.GRAVEYARD);
// allow to cast the card // allow to cast the card
game.addEffect(new PsychicIntrusionCastFromExileEffect(card.getId(), exileId), source); ContinuousEffect effect = new PsychicIntrusionCastFromExileEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
// and you may spend mana as though it were mana of any color to cast it // and you may spend mana as though it were mana of any color to cast it
game.addEffect(new PsychicIntrusionSpendAnyManaEffect(card.getId()), source); effect = new PsychicIntrusionSpendAnyManaEffect();
game.informPlayers(new StringBuilder("Psychic Intrusion: ") effect.setTargetPointer(new FixedTarget(card.getId()));
.append(you.getName()) game.addEffect(effect, source);
.append(" exiles ")
.append(card.getName())
.append(" from")
.append(fromHand ? " hand":" graveyard").toString());
} }
return true; return true;
} }
@ -155,20 +154,13 @@ class PsychicIntrusionExileEffect extends OneShotEffect {
class PsychicIntrusionCastFromExileEffect extends AsThoughEffectImpl { class PsychicIntrusionCastFromExileEffect extends AsThoughEffectImpl {
private UUID cardId; public PsychicIntrusionCastFromExileEffect() {
private UUID exileId; super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.Custom, Outcome.Benefit);
public PsychicIntrusionCastFromExileEffect(UUID cardId, UUID exileId) {
super(AsThoughEffectType.CAST_FROM_NON_HAND_ZONE, Duration.EndOfGame, Outcome.Benefit);
staticText = "You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell"; staticText = "You may cast that card for as long as it remains exiled, and you may spend mana as though it were mana of any color to cast that spell";
this.cardId = cardId;
this.exileId = exileId;
} }
public PsychicIntrusionCastFromExileEffect(final PsychicIntrusionCastFromExileEffect effect) { public PsychicIntrusionCastFromExileEffect(final PsychicIntrusionCastFromExileEffect effect) {
super(effect); super(effect);
this.cardId = effect.cardId;
this.exileId = effect.exileId;
} }
@Override @Override
@ -182,13 +174,12 @@ class PsychicIntrusionCastFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { if (sourceId.equals(getTargetPointer().getFirst(game, source))) {
Card card = game.getCard(this.cardId); if (game.getState().getZone(sourceId).equals(Zone.EXILED)) {
if (card != null && game.getState().getExile().getExileZone(exileId).contains(cardId)) { return true;
if (card.getSpellAbility().spellCanBeActivatedRegularlyNow(source.getControllerId(), game)) { } else {
return true; discard();
}
} }
} }
return false; return false;
@ -197,17 +188,13 @@ class PsychicIntrusionCastFromExileEffect extends AsThoughEffectImpl {
class PsychicIntrusionSpendAnyManaEffect extends AsThoughEffectImpl { class PsychicIntrusionSpendAnyManaEffect extends AsThoughEffectImpl {
private UUID cardId; public PsychicIntrusionSpendAnyManaEffect() {
super(AsThoughEffectType.SPEND_ANY_MANA, Duration.Custom, Outcome.Benefit);
public PsychicIntrusionSpendAnyManaEffect(UUID cardId) {
super(AsThoughEffectType.SPEND_ANY_MANA, Duration.EndOfGame, Outcome.Benefit);
staticText = "you may spend mana as though it were mana of any color to cast it"; staticText = "you may spend mana as though it were mana of any color to cast it";
this.cardId = cardId;
} }
public PsychicIntrusionSpendAnyManaEffect(final PsychicIntrusionSpendAnyManaEffect effect) { public PsychicIntrusionSpendAnyManaEffect(final PsychicIntrusionSpendAnyManaEffect effect) {
super(effect); super(effect);
this.cardId = effect.cardId;
} }
@Override @Override
@ -221,9 +208,13 @@ class PsychicIntrusionSpendAnyManaEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { if (sourceId.equals(getTargetPointer().getFirst(game, source))) {
return true; if (game.getState().getZone(sourceId).equals(Zone.EXILED)) {
return true;
} else {
discard();
}
} }
return false; return false;
} }

View file

@ -74,7 +74,6 @@ public class GrinningTotem extends CardImpl {
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addCost(new SacrificeSourceCost()); ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetOpponent()); ability.addTarget(new TargetOpponent());
// ability.addEffect(new GrinningTotemMayPlayEffect());
// At the beginning of your next upkeep, if you haven't played it, put it into its owner's graveyard. // At the beginning of your next upkeep, if you haven't played it, put it into its owner's graveyard.
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new GrinningTotemDelayedTriggeredAbility())); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new GrinningTotemDelayedTriggeredAbility()));
@ -165,7 +164,7 @@ class GrinningTotemMayPlayEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (targetPointer.getTargets(game, source).contains(sourceId)) { if (targetPointer.getTargets(game, source).contains(sourceId)) {
return game.getState().getZone(sourceId).equals(Zone.EXILED); return game.getState().getZone(sourceId).equals(Zone.EXILED);
} }

View file

@ -28,20 +28,27 @@
package mage.sets.worldwake; package mage.sets.worldwake;
import java.util.UUID; import java.util.UUID;
import mage.constants.*;
import mage.MageInt; import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility; import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
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.abilities.keyword.IslandwalkAbility; import mage.abilities.keyword.IslandwalkAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
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.filter.common.FilterArtifactCard; import mage.filter.common.FilterArtifactCard;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetCardInLibrary;
import mage.target.targetpointer.FixedTarget;
/** /**
* *
@ -81,7 +88,7 @@ class ThadaAdelAcquisitorEffect extends OneShotEffect {
ThadaAdelAcquisitorEffect() { ThadaAdelAcquisitorEffect() {
super(Outcome.Exile); super(Outcome.Exile);
staticText = "search that player's library for an artifact card and exile it. Then that player shuffles his or her library. Until end of turn, you may play that card"; staticText = "search that player's library for an artifact card and exile it. Then that player shuffles his or her library. Until end of turn, you may play that card";
} }
ThadaAdelAcquisitorEffect(final ThadaAdelAcquisitorEffect effect) { ThadaAdelAcquisitorEffect(final ThadaAdelAcquisitorEffect effect) {
@ -90,20 +97,21 @@ class ThadaAdelAcquisitorEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player you = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
Player damagedPlayer = game.getPlayer(targetPointer.getFirst(game, source)); Player damagedPlayer = game.getPlayer(targetPointer.getFirst(game, source));
if (you == null || damagedPlayer == null) { MageObject sourceObject = game.getObject(source.getSourceId());
if (controller == null || damagedPlayer == null || sourceObject == null) {
return false; return false;
} }
TargetCardInLibrary target = new TargetCardInLibrary(new FilterArtifactCard()); TargetCardInLibrary target = new TargetCardInLibrary(new FilterArtifactCard());
you.searchLibrary(target, game, damagedPlayer.getId()); if (controller.searchLibrary(target, game, damagedPlayer.getId())) {
if (you.searchLibrary(target, game)) {
if (target.getTargets().size() > 0) { if (target.getTargets().size() > 0) {
UUID cardId = target.getTargets().get(0); Card card = damagedPlayer.getLibrary().remove(target.getFirstTarget(), game);
Card card = damagedPlayer.getLibrary().remove(cardId, game);
if (card != null) { if (card != null) {
card.moveToExile(source.getSourceId(), "Thada Adel", source.getId(), game); controller.moveCardToExileWithInfo(card, source.getSourceId(), sourceObject.getLogName(), source.getSourceId(), game, Zone.LIBRARY);
game.addEffect(new ThadaAdelPlayFromExileEffect(card.getId()), source); ContinuousEffect effect = new ThadaAdelPlayFromExileEffect();
effect.setTargetPointer(new FixedTarget(card.getId()));
game.addEffect(effect, source);
} }
} }
} }
@ -119,17 +127,13 @@ class ThadaAdelAcquisitorEffect extends OneShotEffect {
class ThadaAdelPlayFromExileEffect extends AsThoughEffectImpl { class ThadaAdelPlayFromExileEffect extends AsThoughEffectImpl {
private final UUID cardId; public ThadaAdelPlayFromExileEffect() {
public ThadaAdelPlayFromExileEffect(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 this card from exile"; staticText = "You may play this card from exile";
this.cardId = cardId;
} }
public ThadaAdelPlayFromExileEffect(final ThadaAdelPlayFromExileEffect effect) { public ThadaAdelPlayFromExileEffect(final ThadaAdelPlayFromExileEffect effect) {
super(effect); super(effect);
cardId = effect.cardId;
} }
@Override @Override
@ -143,13 +147,7 @@ class ThadaAdelPlayFromExileEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(this.cardId)) { return sourceId.equals(getTargetPointer().getFirst(game, source)) && game.getState().getZone(sourceId) == Zone.EXILED;
Card card = game.getCard(this.cardId);
if (card != null && game.getState().getZone(this.cardId) == Zone.EXILED) {
return true;
}
}
return false;
} }
} }

View file

@ -34,7 +34,6 @@ import mage.abilities.condition.FixedCondition;
import mage.abilities.effects.AsThoughEffect; import mage.abilities.effects.AsThoughEffect;
import mage.abilities.effects.AsThoughEffectImpl; import mage.abilities.effects.AsThoughEffectImpl;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.EffectType;
import mage.game.Game; import mage.game.Game;
/** /**
@ -100,17 +99,17 @@ public class ConditionalAsThoughEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (lockedInCondition && !(condition instanceof FixedCondition)) { if (lockedInCondition && !(condition instanceof FixedCondition)) {
condition = new FixedCondition(condition.apply(game, source)); condition = new FixedCondition(condition.apply(game, source));
} }
conditionState = condition.apply(game, source); conditionState = condition.apply(game, source);
if (conditionState) { if (conditionState) {
effect.setTargetPointer(this.targetPointer); effect.setTargetPointer(this.targetPointer);
return effect.applies(sourceId, source,game); return effect.applies(sourceId, source, affectedControllerId, game);
} else if (otherwiseEffect != null) { } else if (otherwiseEffect != null) {
otherwiseEffect.setTargetPointer(this.targetPointer); otherwiseEffect.setTargetPointer(this.targetPointer);
return otherwiseEffect.applies(sourceId, source, game); return otherwiseEffect.applies(sourceId, source, affectedControllerId, game);
} }
return false; return false;
} }

View file

@ -40,7 +40,7 @@ import mage.game.Game;
public interface AsThoughEffect extends ContinuousEffect { public interface AsThoughEffect extends ContinuousEffect {
boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game); boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game);
boolean applies(UUID sourceId, Ability source, Game game); boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game);
AsThoughEffectType getAsThoughEffectType(); AsThoughEffectType getAsThoughEffectType();
@Override @Override

View file

@ -57,7 +57,7 @@ public abstract class AsThoughEffectImpl extends ContinuousEffectImpl implements
@Override @Override
public boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game) { public boolean applies(UUID sourceId, Ability affectedAbility, Ability source, Game game) {
return applies(sourceId, source, game); return applies(sourceId, source, affectedAbility.getControllerId(), game);
} }
@Override @Override

View file

@ -440,7 +440,7 @@ public class ContinuousEffects implements Serializable {
for (Ability ability : abilities) { for (Ability ability : abilities) {
if (controllerId.equals(ability.getControllerId())) { if (controllerId.equals(ability.getControllerId())) {
if (affectedAbility == null) { if (affectedAbility == null) {
if (effect.applies(objectId, ability, game)) { if (effect.applies(objectId, ability, controllerId, game)) {
return true; return true;
} }
} else { } else {

View file

@ -72,7 +72,7 @@ public class CanAttackAsThoughtItDidntHaveDefenderAllEffect extends AsThoughEffe
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Permanent permanent = game.getPermanent(sourceId); Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && filter.match(permanent, game)) { if (permanent != null && filter.match(permanent, game)) {
return true; return true;

View file

@ -62,7 +62,7 @@ public class CanAttackAsThoughtItDidntHaveDefenderEffect extends AsThoughEffectI
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
return sourceId.equals(source.getSourceId()); return sourceId.equals(source.getSourceId());
} }

View file

@ -77,7 +77,7 @@ public class CastAsThoughItHadFlashEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (card != null && filter.match(card, game) && card.getSpellAbility().isInUseableZone(game, card, false)) { if (card != null && filter.match(card, game) && card.getSpellAbility().isInUseableZone(game, card, false)) {
if (anyPlayer) { if (anyPlayer) {

View file

@ -73,7 +73,7 @@ public class PlayTheTopCardEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (card != null && filter.match(card, game)) { if (card != null && filter.match(card, game)) {
Player player = game.getPlayer(card.getOwnerId()); Player player = game.getPlayer(card.getOwnerId());

View file

@ -179,7 +179,7 @@ class HideawayLookAtFaceDownCardEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
Card card = game.getCard(sourceId); Card card = game.getCard(sourceId);
if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) { if (card != null && game.getState().getZone(sourceId) == Zone.EXILED) {
Card sourceCard = game.getCard(source.getSourceId()); Card sourceCard = game.getCard(source.getSourceId());

View file

@ -100,7 +100,7 @@ class MadnessPlayEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
if (sourceId.equals(source.getSourceId())) { if (sourceId.equals(source.getSourceId())) {
Card card = game.getCard(source.getSourceId()); Card card = game.getCard(source.getSourceId());
if (card != null && card.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) { if (card != null && card.getOwnerId().equals(source.getControllerId()) && game.getState().getZone(source.getSourceId()) == Zone.EXILED) {

View file

@ -130,7 +130,7 @@ class OfferingAsThoughEffect extends AsThoughEffectImpl {
} }
@Override @Override
public boolean applies(UUID sourceId, Ability source, Game game) { public boolean applies(UUID sourceId, Ability source, UUID affectedControllerId, Game game) {
return false; return false;
} }

View file

@ -479,4 +479,13 @@ public interface Player extends MageItem, Copyable<Player> {
* Free resources on match end * Free resources on match end
*/ */
void cleanUpOnMatchEnd(); void cleanUpOnMatchEnd();
/**
* If the next cast spell has the set sourceId, the spell will
* be cast without mana.
*
* @param sourceId the source that can be cast without mana
*/
void setCastSourceIdWithoutMana(UUID sourceId);
UUID getCastSourceIdWithoutMana();
} }

View file

@ -163,6 +163,9 @@ public abstract class PlayerImpl implements Player, Serializable {
// They neither expire immediately nor last indefinitely. // They neither expire immediately nor last indefinitely.
protected boolean reachedNextTurnAfterLeaving = false; protected boolean reachedNextTurnAfterLeaving = false;
// indicates that a sourceId will be cast without paying mana
protected UUID castSourceIdWithoutMana;
protected UserData userData; protected UserData userData;
/** /**
@ -247,6 +250,8 @@ public abstract class PlayerImpl implements Player, Serializable {
this.passedAllTurns = player.passedAllTurns; this.passedAllTurns = player.passedAllTurns;
this.priorityTimeLeft = player.getPriorityTimeLeft(); this.priorityTimeLeft = player.getPriorityTimeLeft();
this.reachedNextTurnAfterLeaving = player.reachedNextTurnAfterLeaving; this.reachedNextTurnAfterLeaving = player.reachedNextTurnAfterLeaving;
this.castSourceIdWithoutMana = player.castSourceIdWithoutMana;
} }
@Override @Override
@ -303,6 +308,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.passed = player.isPassed(); this.passed = player.isPassed();
this.priorityTimeLeft = player.getPriorityTimeLeft(); this.priorityTimeLeft = player.getPriorityTimeLeft();
this.reachedNextTurnAfterLeaving = player.hasReachedNextTurnAfterLeaving(); this.reachedNextTurnAfterLeaving = player.hasReachedNextTurnAfterLeaving();
this.castSourceIdWithoutMana = player.getCastSourceIdWithoutMana();
} }
@Override @Override
@ -354,7 +360,8 @@ public abstract class PlayerImpl implements Player, Serializable {
this.topCardRevealed = false; this.topCardRevealed = false;
this.setLife(game.getLife(), game); this.setLife(game.getLife(), game);
this.setReachedNextTurnAfterLeaving(false); this.setReachedNextTurnAfterLeaving(false);
game.getState().getWatchers().add(new BloodthirstWatcher(playerId)); game.getState().getWatchers().add(new BloodthirstWatcher(playerId));
this.castSourceIdWithoutMana = null;
} }
/** /**
* called before apply effects * called before apply effects
@ -375,6 +382,7 @@ public abstract class PlayerImpl implements Player, Serializable {
this.canPlayCardsFromGraveyard = false; this.canPlayCardsFromGraveyard = false;
this.topCardRevealed = false; this.topCardRevealed = false;
this.alternativeSourceCosts.clear(); this.alternativeSourceCosts.clear();
this.castSourceIdWithoutMana = null;
} }
@Override @Override
@ -734,6 +742,15 @@ public abstract class PlayerImpl implements Player, Serializable {
return true; return true;
} }
@Override
public void setCastSourceIdWithoutMana(UUID sourceId) {
castSourceIdWithoutMana = sourceId;
}
public UUID getCastSourceIdWithoutMana() {
return castSourceIdWithoutMana;
}
@Override @Override
public boolean cast(SpellAbility ability, Game game, boolean noMana) { public boolean cast(SpellAbility ability, Game game, boolean noMana) {
@ -751,6 +768,11 @@ public abstract class PlayerImpl implements Player, Serializable {
Zone fromZone = game.getState().getZone(card.getId()); Zone fromZone = game.getState().getZone(card.getId());
card.cast(game, fromZone, ability, playerId); card.cast(game, fromZone, ability, playerId);
Spell spell = game.getStack().getSpell(ability.getId()); Spell spell = game.getStack().getSpell(ability.getId());
// some effects set sourceId to cast without paying mana costs
if (ability.getSourceId().equals(getCastSourceIdWithoutMana())) {
noMana = true;
}
setCastSourceIdWithoutMana(null);
if (spell.activate(game, noMana)) { if (spell.activate(game, noMana)) {
GameEvent event = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId); GameEvent event = GameEvent.getEvent(GameEvent.EventType.SPELL_CAST, spell.getSpellAbility().getId(), spell.getSpellAbility().getSourceId(), playerId);
event.setZone(fromZone); event.setZone(fromZone);