diff --git a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java index a6735f6103..8ccbab33cd 100644 --- a/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java +++ b/Mage.Server.Plugins/Mage.Player.AIMinimax/src/mage/player/ai/ComputerPlayer2.java @@ -541,8 +541,9 @@ public class ComputerPlayer2 extends ComputerPlayer implements Player { boolean skip = false; while (true) { Phase currentPhase = game.getPhase(); - if (!skip) + if (!skip) { currentPhase.getStep().endStep(game, activePlayerId); + } game.applyEffects(); switch (currentPhase.getStep().getType()) { case UNTAP: diff --git a/Mage.Sets/src/mage/sets/alarareborn/MeddlingMage.java b/Mage.Sets/src/mage/sets/alarareborn/MeddlingMage.java index 88618d6914..972ce38570 100644 --- a/Mage.Sets/src/mage/sets/alarareborn/MeddlingMage.java +++ b/Mage.Sets/src/mage/sets/alarareborn/MeddlingMage.java @@ -147,7 +147,7 @@ class MeddlingMageReplacementEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast a card with that name (" + mageObject.getLogName() + " in play)."; @@ -156,7 +156,7 @@ class MeddlingMageReplacementEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { diff --git a/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java b/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java index f54638f7cb..5705774db0 100644 --- a/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java +++ b/Mage.Sets/src/mage/sets/avacynrestored/CavernOfSouls.java @@ -231,7 +231,7 @@ class CavernOfSoulsCantCounterEffect extends ContinuousRuleModifiyingEffectImpl } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null) { return "This spell can't be countered because a colored mana from " + sourceObject.getName() + " was spent to cast it."; @@ -240,7 +240,7 @@ class CavernOfSoulsCantCounterEffect extends ContinuousRuleModifiyingEffectImpl } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.COUNTER) { CavernOfSoulsWatcher watcher = (CavernOfSoulsWatcher) game.getState().getWatchers().get("ManaPaidFromCavernOfSoulsWatcher"); Spell spell = game.getStack().getSpell(event.getTargetId()); diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/BoseijuWhoSheltersAll.java b/Mage.Sets/src/mage/sets/championsofkamigawa/BoseijuWhoSheltersAll.java index 958a5039b0..c7d0996471 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/BoseijuWhoSheltersAll.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/BoseijuWhoSheltersAll.java @@ -150,7 +150,7 @@ class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifiyingEff } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null) { return "This spell can't be countered by spells or abilities (" + sourceObject.getName() + ")."; @@ -159,7 +159,7 @@ class BoseijuWhoSheltersAllCantCounterEffect extends ContinuousRuleModifiyingEff } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.COUNTER) { BoseijuWhoSheltersAllWatcher watcher = (BoseijuWhoSheltersAllWatcher) game.getState().getWatchers().get("ManaPaidFromBoseijuWhoSheltersAllWatcher"); Spell spell = game.getStack().getSpell(event.getTargetId()); diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/DosanTheFallingLeaf.java b/Mage.Sets/src/mage/sets/championsofkamigawa/DosanTheFallingLeaf.java index 6bc992836e..a7c72d08b3 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/DosanTheFallingLeaf.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/DosanTheFallingLeaf.java @@ -84,7 +84,7 @@ class DosanTheFallingLeafEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { return event.getType() == GameEvent.EventType.CAST_SPELL && !game.getActivePlayerId().equals(event.getPlayerId()); } diff --git a/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java b/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java index ee627d5c60..21c7815d68 100644 --- a/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java +++ b/Mage.Sets/src/mage/sets/commander/BasandraBattleSeraph.java @@ -112,7 +112,7 @@ class BasandraBattleSeraphEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL && game.getPhase().getType() == TurnPhase.COMBAT) { return true; diff --git a/Mage.Sets/src/mage/sets/commander2013/IllusionistsGambit.java b/Mage.Sets/src/mage/sets/commander2013/IllusionistsGambit.java index e9580753aa..8083fbfc6e 100644 --- a/Mage.Sets/src/mage/sets/commander2013/IllusionistsGambit.java +++ b/Mage.Sets/src/mage/sets/commander2013/IllusionistsGambit.java @@ -91,7 +91,7 @@ class IllusionistsGambitEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType().equals(GameEvent.EventType.CAST_SPELL) && event.getSourceId().equals(source.getSourceId())) { if (game.getTurn().getStepType().equals(PhaseStep.DECLARE_BLOCKERS)) { return !game.getOpponents(source.getControllerId()).contains(game.getActivePlayerId()); diff --git a/Mage.Sets/src/mage/sets/conflux/Banefire.java b/Mage.Sets/src/mage/sets/conflux/Banefire.java index c9119e0c3a..4d54b8b731 100644 --- a/Mage.Sets/src/mage/sets/conflux/Banefire.java +++ b/Mage.Sets/src/mage/sets/conflux/Banefire.java @@ -161,7 +161,7 @@ class BanefireCantCounterEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.COUNTER) { Card card = game.getCard(source.getSourceId()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/darkascension/CurseOfExhaustion.java b/Mage.Sets/src/mage/sets/darkascension/CurseOfExhaustion.java index ab44e02ccb..5a87daad9e 100644 --- a/Mage.Sets/src/mage/sets/darkascension/CurseOfExhaustion.java +++ b/Mage.Sets/src/mage/sets/darkascension/CurseOfExhaustion.java @@ -134,7 +134,7 @@ class CurseOfExhaustionEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { diff --git a/Mage.Sets/src/mage/sets/darkascension/DungeonGeists.java b/Mage.Sets/src/mage/sets/darkascension/DungeonGeists.java index 556ef0ecb4..65bef46602 100644 --- a/Mage.Sets/src/mage/sets/darkascension/DungeonGeists.java +++ b/Mage.Sets/src/mage/sets/darkascension/DungeonGeists.java @@ -27,29 +27,32 @@ */ package mage.sets.darkascension; -import mage.constants.CardType; -import mage.constants.Rarity; -import mage.constants.*; -import mage.constants.Zone; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.keyword.FlyingAbility; import mage.cards.CardImpl; +import mage.constants.CardType; +import mage.constants.Duration; +import mage.constants.Outcome; +import mage.constants.PhaseStep; +import mage.constants.Rarity; +import mage.constants.TargetController; +import mage.constants.WatcherScope; +import mage.constants.Zone; import mage.filter.common.FilterCreaturePermanent; import mage.filter.predicate.permanent.ControllerPredicate; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.common.TargetCreaturePermanent; import mage.watchers.Watcher; -import java.util.UUID; -import mage.game.permanent.Permanent; - /** * * @author BetaSteward @@ -93,10 +96,10 @@ public class DungeonGeists extends CardImpl { } } -class DungeonGeistsEffect extends ReplacementEffectImpl { +class DungeonGeistsEffect extends ContinuousRuleModifiyingEffectImpl { public DungeonGeistsEffect() { - super(Duration.OneUse, Outcome.Detriment); + super(Duration.Custom, Outcome.Detriment, false, false); this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}"; } @@ -114,11 +117,6 @@ class DungeonGeistsEffect extends ReplacementEffectImpl { return false; } - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - @Override public boolean applies(GameEvent event, Ability source, Game game) { // Source must be on the battlefield (it's neccessary to check here because if as response to the enter @@ -131,19 +129,18 @@ class DungeonGeistsEffect extends ReplacementEffectImpl { } if (event.getType() == GameEvent.EventType.LOST_CONTROL) { if (event.getTargetId().equals(source.getSourceId())) { - this.used = true; + discard(); return false; } } if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) { ZoneChangeEvent zEvent = (ZoneChangeEvent)event; if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - this.used = true; + discard(); return false; } } - if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) { if (event.getTargetId().equals(targetPointer.getFirst(game, source))) { return true; diff --git a/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java b/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java index 9c8bd4977d..dd3aa49b39 100644 --- a/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java +++ b/Mage.Sets/src/mage/sets/darkascension/GrafdiggersCage.java @@ -135,7 +135,7 @@ class GrafdiggersCageEffect2 extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { Card card = game.getCard(event.getSourceId()); if (card != null) { diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.java b/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.java index e4c608978f..dbb0406329 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/CouncilOfTheAbsolute.java @@ -158,7 +158,7 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifiyingEffe } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast a card with that name (" + mageObject.getLogName() + " in play)."; @@ -167,7 +167,7 @@ class CouncilOfTheAbsoluteReplacementEffect extends ContinuousRuleModifiyingEffe } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { diff --git a/Mage.Sets/src/mage/sets/dragonsmaze/RenderSilent.java b/Mage.Sets/src/mage/sets/dragonsmaze/RenderSilent.java index 8482f3503a..d78f7383bb 100644 --- a/Mage.Sets/src/mage/sets/dragonsmaze/RenderSilent.java +++ b/Mage.Sets/src/mage/sets/dragonsmaze/RenderSilent.java @@ -138,7 +138,7 @@ class RenderSilentEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast spells this turn (" + mageObject.getLogName() + ")."; @@ -147,7 +147,7 @@ class RenderSilentEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL ) { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); if (player != null && player.getId().equals(event.getPlayerId())) { diff --git a/Mage.Sets/src/mage/sets/eventide/Moonhold.java b/Mage.Sets/src/mage/sets/eventide/Moonhold.java index 8d0c42a8b8..26daf8e0cd 100644 --- a/Mage.Sets/src/mage/sets/eventide/Moonhold.java +++ b/Mage.Sets/src/mage/sets/eventide/Moonhold.java @@ -104,7 +104,7 @@ class MoonholdEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't play land cards this turn (" + mageObject.getLogName() + ")."; @@ -113,7 +113,7 @@ class MoonholdEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.PLAY_LAND && event.getPlayerId().equals(source.getFirstTarget())) { return true; @@ -143,7 +143,7 @@ class MoonholdEffect2 extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't play creature cards this turn (" + mageObject.getLogName() + ")."; @@ -152,7 +152,7 @@ class MoonholdEffect2 extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getPlayerId().equals(source.getFirstTarget())) { Card card = game.getCard(event.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/eventide/TalarasBattalion.java b/Mage.Sets/src/mage/sets/eventide/TalarasBattalion.java index 1e2a6afa6b..d533eaf4b0 100644 --- a/Mage.Sets/src/mage/sets/eventide/TalarasBattalion.java +++ b/Mage.Sets/src/mage/sets/eventide/TalarasBattalion.java @@ -98,7 +98,7 @@ class TalarasBattalionEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getSourceId().equals(source.getSourceId())) { CastGreenSpellThisTurnCondition condition = new CastGreenSpellThisTurnCondition(); diff --git a/Mage.Sets/src/mage/sets/eventide/WardOfBones.java b/Mage.Sets/src/mage/sets/eventide/WardOfBones.java index ee4d7f018c..6e072df973 100644 --- a/Mage.Sets/src/mage/sets/eventide/WardOfBones.java +++ b/Mage.Sets/src/mage/sets/eventide/WardOfBones.java @@ -95,7 +95,7 @@ class WardOfBonesEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't play the land or cast the spell (" + mageObject.getLogName() + " in play)."; @@ -104,7 +104,7 @@ class WardOfBonesEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.PLAY_LAND || event.getType() == GameEvent.EventType.CAST_SPELL && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { diff --git a/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java b/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java index 4c127c2ac0..fb6726fa71 100644 --- a/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java +++ b/Mage.Sets/src/mage/sets/gatecrash/AureliasFury.java @@ -170,7 +170,7 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast noncreature spells this turn (you were dealt damage by " + mageObject.getLogName() + ")"; @@ -179,7 +179,7 @@ class AureliasFuryCantCastEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL ) { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); if (player != null && player.getId().equals(event.getPlayerId())) { diff --git a/Mage.Sets/src/mage/sets/innistrad/Nevermore.java b/Mage.Sets/src/mage/sets/innistrad/Nevermore.java index 60e199e00f..c33012044f 100644 --- a/Mage.Sets/src/mage/sets/innistrad/Nevermore.java +++ b/Mage.Sets/src/mage/sets/innistrad/Nevermore.java @@ -142,7 +142,7 @@ class NevermoreEffect2 extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { diff --git a/Mage.Sets/src/mage/sets/invasion/SpinalEmbrace.java b/Mage.Sets/src/mage/sets/invasion/SpinalEmbrace.java index fe725b9c73..a6e9a88576 100644 --- a/Mage.Sets/src/mage/sets/invasion/SpinalEmbrace.java +++ b/Mage.Sets/src/mage/sets/invasion/SpinalEmbrace.java @@ -108,7 +108,7 @@ class SpinalEmbraceEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType().equals(GameEvent.EventType.CAST_SPELL) && event.getSourceId().equals(source.getSourceId())) { return !game.getTurn().getPhaseType().equals(TurnPhase.COMBAT); } diff --git a/Mage.Sets/src/mage/sets/journeyintonyx/Godsend.java b/Mage.Sets/src/mage/sets/journeyintonyx/Godsend.java index cbb989aebe..e8e64dee96 100644 --- a/Mage.Sets/src/mage/sets/journeyintonyx/Godsend.java +++ b/Mage.Sets/src/mage/sets/journeyintonyx/Godsend.java @@ -222,7 +222,7 @@ class GodsendRuleModifyingEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast this spell because a card with the same name is exiled by " + mageObject.getLogName() + "."; @@ -231,7 +231,7 @@ class GodsendRuleModifyingEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { MageObject object = game.getObject(event.getSourceId()); if (object != null) { diff --git a/Mage.Sets/src/mage/sets/legends/Reset.java b/Mage.Sets/src/mage/sets/legends/Reset.java index 8832cbd809..8dec5a8949 100644 --- a/Mage.Sets/src/mage/sets/legends/Reset.java +++ b/Mage.Sets/src/mage/sets/legends/Reset.java @@ -84,7 +84,7 @@ class ResetReplacementEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType().equals(GameEvent.EventType.CAST_SPELL) && event.getSourceId().equals(source.getSourceId())) { if (game.getTurn().getStepType().equals(PhaseStep.UNTAP) || game.getTurn().getStepType().equals(PhaseStep.UPKEEP) diff --git a/Mage.Sets/src/mage/sets/limitedalpha/Berserk.java b/Mage.Sets/src/mage/sets/limitedalpha/Berserk.java index 9c4e2521af..ea8567ea0a 100644 --- a/Mage.Sets/src/mage/sets/limitedalpha/Berserk.java +++ b/Mage.Sets/src/mage/sets/limitedalpha/Berserk.java @@ -106,7 +106,7 @@ class BerserkReplacementEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType().equals(GameEvent.EventType.CAST_SPELL) && event.getSourceId().equals(source.getSourceId())) { CombatDamageStepStartedWatcher watcher = (CombatDamageStepStartedWatcher) game.getState().getWatchers().get("CombatDamageStepStarted"); return watcher == null || watcher.conditionMet(); diff --git a/Mage.Sets/src/mage/sets/lorwyn/GaddockTeeg.java b/Mage.Sets/src/mage/sets/lorwyn/GaddockTeeg.java index b53701eb86..48c08eb09f 100644 --- a/Mage.Sets/src/mage/sets/lorwyn/GaddockTeeg.java +++ b/Mage.Sets/src/mage/sets/lorwyn/GaddockTeeg.java @@ -98,7 +98,7 @@ class GaddockTeegReplacementEffect4 extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { Card card = game.getCard(event.getSourceId()); if (card != null && !card.getCardType().contains(CardType.CREATURE) && card.getManaCost().convertedManaCost() >= 4) { @@ -132,7 +132,7 @@ class GaddockTeegReplacementEffectX extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { Card card = game.getCard(event.getSourceId()); if (card != null && !card.getCardType().contains(CardType.CREATURE) && card.getManaCost().getText().contains("X")) { diff --git a/Mage.Sets/src/mage/sets/magic2010/Silence.java b/Mage.Sets/src/mage/sets/magic2010/Silence.java index d45d380088..2bdd78fbb6 100644 --- a/Mage.Sets/src/mage/sets/magic2010/Silence.java +++ b/Mage.Sets/src/mage/sets/magic2010/Silence.java @@ -86,7 +86,7 @@ class SilenceEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast spells this turn (" + mageObject.getLogName() + ")."; @@ -95,7 +95,7 @@ class SilenceEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { return true; } diff --git a/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java b/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java index 248f2d98e2..efff118418 100644 --- a/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java +++ b/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java @@ -189,7 +189,7 @@ class AngelicArbiterEffect2 extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL && game.getActivePlayerId().equals(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { Watcher watcher = game.getState().getWatchers().get("OpponentAttacked", source.getControllerId()); if (watcher != null && watcher.conditionMet()) { diff --git a/Mage.Sets/src/mage/sets/magic2011/FrostTitan.java b/Mage.Sets/src/mage/sets/magic2011/FrostTitan.java index 90f9463ad8..f926aae189 100644 --- a/Mage.Sets/src/mage/sets/magic2011/FrostTitan.java +++ b/Mage.Sets/src/mage/sets/magic2011/FrostTitan.java @@ -58,8 +58,11 @@ public class FrostTitan extends CardImpl { this.color.setBlue(true); this.power = new MageInt(6); this.toughness = new MageInt(6); - + + // Whenever Frost Titan becomes the target of a spell or ability an opponent controls, counter that spell or ability unless its controller pays 2. this.addAbility(new FrostTitanAbility1()); + + // Whenever Frost Titan enters the battlefield or attacks, tap target permanent. It doesn't untap during its controller's next untap step. this.addAbility(new FrostTitanAbility2()); } diff --git a/Mage.Sets/src/mage/sets/magic2012/GrandAbolisher.java b/Mage.Sets/src/mage/sets/magic2012/GrandAbolisher.java index 8578241ba7..7d124f80c7 100644 --- a/Mage.Sets/src/mage/sets/magic2012/GrandAbolisher.java +++ b/Mage.Sets/src/mage/sets/magic2012/GrandAbolisher.java @@ -95,7 +95,7 @@ class GrandAbolisherEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { Player activePlayer = game.getPlayer(game.getActivePlayerId()); MageObject mageObject = game.getObject(source.getSourceId()); if (activePlayer != null && mageObject != null) { @@ -106,7 +106,7 @@ class GrandAbolisherEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { boolean spell = event.getType() == GameEvent.EventType.CAST_SPELL; boolean activated = event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; if ((spell || activated) && game.getActivePlayerId().equals(source.getControllerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { diff --git a/Mage.Sets/src/mage/sets/magic2013/GroundSeal.java b/Mage.Sets/src/mage/sets/magic2013/GroundSeal.java index db1cf5f135..1baad6b9e8 100644 --- a/Mage.Sets/src/mage/sets/magic2013/GroundSeal.java +++ b/Mage.Sets/src/mage/sets/magic2013/GroundSeal.java @@ -95,7 +95,7 @@ class GroundSealEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.TARGET) { Card targetCard = game.getCard(event.getTargetId()); StackObject stackObject = (StackObject) game.getStack().getStackObject(event.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/magic2014/FiendslayerPaladin.java b/Mage.Sets/src/mage/sets/magic2014/FiendslayerPaladin.java index 66725a2535..18e0dd32a6 100644 --- a/Mage.Sets/src/mage/sets/magic2014/FiendslayerPaladin.java +++ b/Mage.Sets/src/mage/sets/magic2014/FiendslayerPaladin.java @@ -106,7 +106,7 @@ class FiendslayerPaladinEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (sourcePermanent != null) { return sourcePermanent.getLogName() + " can't be the target of black or red spells opponents control"; @@ -115,7 +115,7 @@ class FiendslayerPaladinEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.TARGET) { Card targetCard = game.getCard(event.getTargetId()); StackObject stackObject = (StackObject) game.getStack().getStackObject(event.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java b/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java index c49352a26d..e5a67ebc78 100644 --- a/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java +++ b/Mage.Sets/src/mage/sets/magic2014/SavageSummoning.java @@ -257,7 +257,7 @@ class SavageSummoningCantCounterEffect extends ContinuousRuleModifiyingEffectImp } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null) { return "This creature spell can't be countered (" + sourceObject.getName() + ")."; @@ -266,7 +266,7 @@ class SavageSummoningCantCounterEffect extends ContinuousRuleModifiyingEffectImp } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.COUNTER) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && watcher.isSpellCastWithThisSavageSummoning(spell.getId(), source.getSourceId(), zoneChangeCounter)) { diff --git a/Mage.Sets/src/mage/sets/magic2014/TidebinderMage.java b/Mage.Sets/src/mage/sets/magic2014/TidebinderMage.java index ab31c99765..5d790d22e6 100644 --- a/Mage.Sets/src/mage/sets/magic2014/TidebinderMage.java +++ b/Mage.Sets/src/mage/sets/magic2014/TidebinderMage.java @@ -32,7 +32,7 @@ import mage.MageInt; import mage.ObjectColor; import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.abilities.effects.common.TapTargetEffect; import mage.cards.CardImpl; import mage.constants.CardType; @@ -98,10 +98,10 @@ public class TidebinderMage extends CardImpl { } } -class TidebinderMageEffect extends ReplacementEffectImpl { +class TidebinderMageEffect extends ContinuousRuleModifiyingEffectImpl { public TidebinderMageEffect() { - super(Duration.OneUse, Outcome.Detriment); + super(Duration.OneUse, Outcome.Detriment, false, false); this.staticText = "That creature doesn't untap during its controller's untap step for as long as you control {this}"; } @@ -119,11 +119,6 @@ class TidebinderMageEffect extends ReplacementEffectImpl { return false; } - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - @Override public boolean applies(GameEvent event, Ability source, Game game) { // Source must be on the battlefield (it's neccessary to check here because if as response to the enter @@ -131,19 +126,19 @@ class TidebinderMageEffect extends ReplacementEffectImpl { // event will happen before this effect is applied ever) Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (sourcePermanent == null || !sourcePermanent.getControllerId().equals(source.getControllerId())) { - this.used = true; + discard(); return false; } if (event.getType() == GameEvent.EventType.LOST_CONTROL) { if (event.getTargetId().equals(source.getSourceId())) { - this.used = true; + discard(); return false; } } if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) { ZoneChangeEvent zEvent = (ZoneChangeEvent)event; if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - this.used = true; + discard(); return false; } } diff --git a/Mage.Sets/src/mage/sets/magic2015/AggressiveMining.java b/Mage.Sets/src/mage/sets/magic2015/AggressiveMining.java index 704916383b..62293b09ce 100644 --- a/Mage.Sets/src/mage/sets/magic2015/AggressiveMining.java +++ b/Mage.Sets/src/mage/sets/magic2015/AggressiveMining.java @@ -99,7 +99,7 @@ class AggressiveMiningEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { return event.getType().equals(GameEvent.EventType.PLAY_LAND) && event.getPlayerId().equals(source.getControllerId()); } diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java index 46a07c083e..1131f2d6ad 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/PhyrexianRevoker.java @@ -145,7 +145,7 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't activate sources with that name (" + mageObject.getLogName() + " in play)."; @@ -154,7 +154,7 @@ class PhyrexianRevokerEffect2 extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode ,Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.ACTIVATE_ABILITY) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { diff --git a/Mage.Sets/src/mage/sets/newphyrexia/ExclusionRitual.java b/Mage.Sets/src/mage/sets/newphyrexia/ExclusionRitual.java index 689f32e7e9..7502e352aa 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/ExclusionRitual.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/ExclusionRitual.java @@ -118,7 +118,7 @@ class ExclusionRitualReplacementEffect extends ContinuousRuleModifiyingEffectImp } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Card card = game.getCard(event.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java b/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java index 7d0b38a928..d737d5509b 100644 --- a/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java +++ b/Mage.Sets/src/mage/sets/ninthedition/StorageMatrix.java @@ -74,7 +74,7 @@ class StorageMatrixRestrictionEffect extends RestrictionEffect { private int turn; private boolean applies; - private static final HashSet choice = new HashSet(); + private static final HashSet choice = new HashSet<>(); static{ choice.add(CardType.ARTIFACT.toString()); choice.add(CardType.CREATURE.toString()); diff --git a/Mage.Sets/src/mage/sets/odyssey/CeaseFire.java b/Mage.Sets/src/mage/sets/odyssey/CeaseFire.java index e43e1911a3..e0ac8ec6d3 100644 --- a/Mage.Sets/src/mage/sets/odyssey/CeaseFire.java +++ b/Mage.Sets/src/mage/sets/odyssey/CeaseFire.java @@ -102,7 +102,7 @@ class CeaseFireEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast creature spells this turn (" + mageObject.getLogName() + ")."; @@ -111,7 +111,7 @@ class CeaseFireEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getPlayerId().equals(source.getFirstTarget())) { MageObject object = game.getObject(event.getSourceId()); if (filter.match((Spell) object, game)) { diff --git a/Mage.Sets/src/mage/sets/odyssey/PardicMiner.java b/Mage.Sets/src/mage/sets/odyssey/PardicMiner.java index 0e4af5d9c0..b5ca0b94af 100644 --- a/Mage.Sets/src/mage/sets/odyssey/PardicMiner.java +++ b/Mage.Sets/src/mage/sets/odyssey/PardicMiner.java @@ -98,7 +98,7 @@ class PardicMinerEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't play lands this turn (" + mageObject.getLogName() + ")."; @@ -107,7 +107,7 @@ class PardicMinerEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.PLAY_LAND && event.getPlayerId().equals(source.getFirstTarget())) { return true; } diff --git a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java index b701074527..9e8c94741c 100644 --- a/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java +++ b/Mage.Sets/src/mage/sets/planarchaos/VoidstoneGargoyle.java @@ -146,7 +146,7 @@ class VoidstoneGargoyleReplacementEffect1 extends ContinuousRuleModifiyingEffect } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast a card with that name (" + mageObject.getLogName() + ")."; @@ -155,7 +155,7 @@ class VoidstoneGargoyleReplacementEffect1 extends ContinuousRuleModifiyingEffect } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { MageObject object = game.getObject(event.getSourceId()); if (object != null && object.getName().equals(game.getState().getValue(source.getSourceId().toString()))) { diff --git a/Mage.Sets/src/mage/sets/planechase2012/IllusoryAngel.java b/Mage.Sets/src/mage/sets/planechase2012/IllusoryAngel.java index 10ebcf1e1a..558c12a2d4 100644 --- a/Mage.Sets/src/mage/sets/planechase2012/IllusoryAngel.java +++ b/Mage.Sets/src/mage/sets/planechase2012/IllusoryAngel.java @@ -88,7 +88,7 @@ class IllusoryAngelEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getSourceId().equals(source.getSourceId())) { CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get("CastSpellLastTurnWatcher"); if (watcher != null && watcher.getAmountOfSpellsPlayerCastOnCurrentTurn(source.getControllerId()) == 0) { diff --git a/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java b/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java index f16e42bd6a..5fcc3564a0 100644 --- a/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java +++ b/Mage.Sets/src/mage/sets/planeshift/OrimsChant.java @@ -101,7 +101,7 @@ class OrimsChantCantCastEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL ) { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); if (player != null && player.getId().equals(event.getPlayerId())) { diff --git a/Mage.Sets/src/mage/sets/returntoravnica/RakdosLordOfRiots.java b/Mage.Sets/src/mage/sets/returntoravnica/RakdosLordOfRiots.java index 022f270fab..bbd582e093 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/RakdosLordOfRiots.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/RakdosLordOfRiots.java @@ -111,7 +111,7 @@ class RakdosLordOfRiotsCantCastEffect extends ContinuousRuleModifiyingEffectImpl } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL && event.getSourceId().equals(source.getSourceId())) { if (new OpponentsLostLifeCount().calculate(game, source) == 0) { return true; diff --git a/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java b/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java index 278cf2d95f..97db251b8a 100644 --- a/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java +++ b/Mage.Sets/src/mage/sets/returntoravnica/VraskaTheUnseen.java @@ -105,11 +105,13 @@ public class VraskaTheUnseen extends CardImpl { class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl { protected Ability ability; + protected int startingTurn; public VraskaTheUnseenGainAbilityEffect(Ability ability) { super(Duration.Custom, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); this.ability = ability; staticText = "Until your next turn, whenever a creature deals combat damage to {this}, destroy that creature"; + startingTurn = 0; } public VraskaTheUnseenGainAbilityEffect(final VraskaTheUnseenGainAbilityEffect effect) { @@ -117,6 +119,12 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl { this.ability = effect.ability.copy(); } + @Override + public void init(Ability source, Game game) { + super.init(source, game); //To change body of generated methods, choose Tools | Templates. + startingTurn = game.getTurnNum(); + } + @Override public VraskaTheUnseenGainAbilityEffect copy() { return new VraskaTheUnseenGainAbilityEffect(this); @@ -134,7 +142,7 @@ class VraskaTheUnseenGainAbilityEffect extends ContinuousEffectImpl { @Override public boolean isInactive(Ability source, Game game) { - if (game.getPhase().getStep().getType() == PhaseStep.UNTAP && game.getStep().getStepPart() == Step.StepPart.PRE) + if (startingTurn != 0 && game.getTurnNum() != startingTurn) { if (game.getActivePlayerId().equals(source.getControllerId())) { return true; @@ -187,7 +195,7 @@ class VraskaTheUnseenTriggeredAbility extends TriggeredAbilityImpl { @Override public String getRule() { - return "Until your next turn, whenever a creature deals combat damage to Vraska the Unseen, destroy that creature"; + return "Until your next turn, whenever a creature deals combat damage to {this}, destroy that creature"; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/scourge/XantidSwarm.java b/Mage.Sets/src/mage/sets/scourge/XantidSwarm.java index a9024e9962..ef8da56be5 100644 --- a/Mage.Sets/src/mage/sets/scourge/XantidSwarm.java +++ b/Mage.Sets/src/mage/sets/scourge/XantidSwarm.java @@ -130,7 +130,7 @@ class XantidSwarmReplacementEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL ) { Player player = game.getPlayer(getTargetPointer().getFirst(game, source)); if (player != null && player.getId().equals(event.getPlayerId())) { diff --git a/Mage.Sets/src/mage/sets/shadowmoor/VexingShusher.java b/Mage.Sets/src/mage/sets/shadowmoor/VexingShusher.java index d128566058..63e87749d0 100644 --- a/Mage.Sets/src/mage/sets/shadowmoor/VexingShusher.java +++ b/Mage.Sets/src/mage/sets/shadowmoor/VexingShusher.java @@ -104,7 +104,7 @@ class VexingShusherCantCounterTargetEffect extends ContinuousRuleModifiyingEffec } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject sourceObject = game.getObject(source.getSourceId()); if (sourceObject != null) { return "This spell can't be countered by spells or abilities (" + sourceObject.getName() + ")."; @@ -113,7 +113,7 @@ class VexingShusherCantCounterTargetEffect extends ContinuousRuleModifiyingEffec } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { return event.getType() == EventType.COUNTER && event.getTargetId().equals(targetPointer.getFirst(game, source)); } diff --git a/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java b/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java index 9452763e31..16ff2fbbc6 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/AjaniVengeant.java @@ -52,6 +52,7 @@ import mage.target.common.TargetCreatureOrPlayer; * @author BetaSteward_at_googlemail.com */ public class AjaniVengeant extends CardImpl { + private static final FilterPermanent filter = new FilterPermanent("lands"); static { @@ -66,11 +67,12 @@ public class AjaniVengeant extends CardImpl { this.color.setWhite(true); this.addAbility(new EntersBattlefieldAbility(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(3)), false)); - + // +1: Target permanent doesn't untap during its controller's next untap step. LoyaltyAbility ability1 = new LoyaltyAbility(new SkipNextUntapTargetEffect(), 1); ability1.addTarget(new TargetPermanent()); this.addAbility(ability1); + // −2: Ajani Vengeant deals 3 damage to target creature or player and you gain 3 life. Effects effects1 = new Effects(); effects1.add(new DamageTargetEffect(3)); effects1.add(new GainLifeEffect(3)); @@ -78,6 +80,7 @@ public class AjaniVengeant extends CardImpl { ability2.addTarget(new TargetCreatureOrPlayer()); this.addAbility(ability2); + // −7: Destroy all lands target player controls. LoyaltyAbility ability3 = new LoyaltyAbility(new DestroyAllControlledTargetEffect(filter), -7); ability3.addTarget(new TargetPlayer()); this.addAbility(ability3); diff --git a/Mage.Sets/src/mage/sets/shardsofalara/EtherswornCanonist.java b/Mage.Sets/src/mage/sets/shardsofalara/EtherswornCanonist.java index a079774b8c..1bcb3c3e10 100644 --- a/Mage.Sets/src/mage/sets/shardsofalara/EtherswornCanonist.java +++ b/Mage.Sets/src/mage/sets/shardsofalara/EtherswornCanonist.java @@ -145,7 +145,7 @@ class EtherswornCanonistReplacementEffect extends ContinuousRuleModifiyingEffect } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { EtherswornCanonistWatcher watcher = (EtherswornCanonistWatcher)game.getState().getWatchers().get("EtherswornCanonistWatcher"); Card card = game.getCard(event.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/tenth/GaeasHerald.java b/Mage.Sets/src/mage/sets/tenth/GaeasHerald.java index db611a9dd0..181220d380 100644 --- a/Mage.Sets/src/mage/sets/tenth/GaeasHerald.java +++ b/Mage.Sets/src/mage/sets/tenth/GaeasHerald.java @@ -95,7 +95,7 @@ class CantCounterEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.COUNTER) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && spell.getCardType().contains(CardType.CREATURE)) { diff --git a/Mage.Sets/src/mage/sets/tenth/SteelGolem.java b/Mage.Sets/src/mage/sets/tenth/SteelGolem.java index ac73f2d531..127e3d05a6 100644 --- a/Mage.Sets/src/mage/sets/tenth/SteelGolem.java +++ b/Mage.Sets/src/mage/sets/tenth/SteelGolem.java @@ -89,7 +89,7 @@ class SteelGolemEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL && event.getPlayerId().equals(source.getControllerId())) { MageObject object = game.getObject(event.getSourceId()); if (object.getCardType().contains(CardType.CREATURE)) { diff --git a/Mage.Sets/src/mage/sets/theros/ShipbreakerKraken.java b/Mage.Sets/src/mage/sets/theros/ShipbreakerKraken.java index 3747c5af88..32ed130560 100644 --- a/Mage.Sets/src/mage/sets/theros/ShipbreakerKraken.java +++ b/Mage.Sets/src/mage/sets/theros/ShipbreakerKraken.java @@ -31,6 +31,7 @@ import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.common.TapTargetEffect; import mage.abilities.keyword.MonstrosityAbility; @@ -84,10 +85,10 @@ public class ShipbreakerKraken extends CardImpl { } } -class ShipbreakerKrakenReplacementEffect extends ReplacementEffectImpl { +class ShipbreakerKrakenReplacementEffect extends ContinuousRuleModifiyingEffectImpl { public ShipbreakerKrakenReplacementEffect() { - super(Duration.OneUse, Outcome.Detriment); + super(Duration.Custom, Outcome.Detriment); this.staticText = "Those creatures don't untap during their controllers' untap steps for as long as you control {this}"; } @@ -105,11 +106,6 @@ class ShipbreakerKrakenReplacementEffect extends ReplacementEffectImpl { return false; } - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - @Override public boolean applies(GameEvent event, Ability source, Game game) { // Source must be on the battlefield (it's neccessary to check here because if as response to the enter @@ -117,19 +113,19 @@ class ShipbreakerKrakenReplacementEffect extends ReplacementEffectImpl { // event will happen before this effect is applied ever) Permanent sourcePermanent = game.getPermanent(source.getSourceId()); if (sourcePermanent == null || !sourcePermanent.getControllerId().equals(source.getControllerId())) { - this.used = true; + discard(); return false; } if (event.getType() == GameEvent.EventType.LOST_CONTROL) { if (event.getTargetId().equals(source.getSourceId())) { - this.used = true; + discard(); return false; } } if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event.getTargetId().equals(source.getSourceId())) { ZoneChangeEvent zEvent = (ZoneChangeEvent)event; if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - this.used = true; + discard(); return false; } } diff --git a/Mage.Sets/src/mage/sets/theros/UnderworldCerberus.java b/Mage.Sets/src/mage/sets/theros/UnderworldCerberus.java index ed568339c2..46d61621e2 100644 --- a/Mage.Sets/src/mage/sets/theros/UnderworldCerberus.java +++ b/Mage.Sets/src/mage/sets/theros/UnderworldCerberus.java @@ -107,7 +107,7 @@ class UnderworldCerberusEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.TARGET) { Card targetCard = game.getCard(event.getTargetId()); StackObject stackObject = (StackObject) game.getStack().getStackObject(event.getSourceId()); diff --git a/Mage.Sets/src/mage/sets/timespiral/SerraAvenger.java b/Mage.Sets/src/mage/sets/timespiral/SerraAvenger.java index 2d782fe54e..597ce17147 100644 --- a/Mage.Sets/src/mage/sets/timespiral/SerraAvenger.java +++ b/Mage.Sets/src/mage/sets/timespiral/SerraAvenger.java @@ -104,7 +104,7 @@ class CantCastSerraAvengerEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.CAST_SPELL && event.getSourceId().equals(source.getSourceId())) { Player controller = game.getPlayer(source.getControllerId()); // it can be cast on other players turn 1 - 3 if some effect let allow you to do this diff --git a/Mage.Sets/src/mage/sets/timespiral/TeferiMageOfZhalfir.java b/Mage.Sets/src/mage/sets/timespiral/TeferiMageOfZhalfir.java index 6de5d6876d..3c8b223186 100644 --- a/Mage.Sets/src/mage/sets/timespiral/TeferiMageOfZhalfir.java +++ b/Mage.Sets/src/mage/sets/timespiral/TeferiMageOfZhalfir.java @@ -146,7 +146,7 @@ class TeferiMageOfZhalfirReplacementEffect extends ContinuousRuleModifiyingEffec } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can cast spells only any time you could cast a sorcery (" + mageObject.getLogName() + ")."; @@ -154,7 +154,7 @@ class TeferiMageOfZhalfirReplacementEffect extends ContinuousRuleModifiyingEffec return null; } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && controller.hasOpponent(event.getPlayerId(), game)) { diff --git a/Mage.Sets/src/mage/sets/torment/LlawanCephalidEmpress.java b/Mage.Sets/src/mage/sets/torment/LlawanCephalidEmpress.java index 5b624050d4..a853b9914d 100644 --- a/Mage.Sets/src/mage/sets/torment/LlawanCephalidEmpress.java +++ b/Mage.Sets/src/mage/sets/torment/LlawanCephalidEmpress.java @@ -124,7 +124,7 @@ class LlawanCephalidRuleModifyingEffect extends ContinuousRuleModifiyingEffectIm } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "You can't cast blue creature spells (" + mageObject.getLogName() + " in play)."; @@ -133,7 +133,7 @@ class LlawanCephalidRuleModifyingEffect extends ContinuousRuleModifiyingEffectIm } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { Player controller = game.getPlayer(source.getControllerId()); if (controller != null && game.isOpponent(controller, event.getPlayerId())) { diff --git a/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java b/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java index a7cc50271a..667995762f 100644 --- a/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java +++ b/Mage.Sets/src/mage/sets/zendikar/IonaShieldOfEmeria.java @@ -130,7 +130,7 @@ class IonaShieldOfEmeriaReplacementEffect extends ContinuousRuleModifiyingEffect } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { ObjectColor chosenColor = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null && chosenColor != null) { @@ -140,7 +140,7 @@ class IonaShieldOfEmeriaReplacementEffect extends ContinuousRuleModifiyingEffect } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { if (game.getOpponents(source.getControllerId()).contains(event.getPlayerId()) ) { ObjectColor chosenColor = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); diff --git a/Mage.Sets/src/mage/sets/zendikar/KorHookmaster.java b/Mage.Sets/src/mage/sets/zendikar/KorHookmaster.java index 19a41fc4e2..2802ff9506 100644 --- a/Mage.Sets/src/mage/sets/zendikar/KorHookmaster.java +++ b/Mage.Sets/src/mage/sets/zendikar/KorHookmaster.java @@ -62,6 +62,8 @@ public class KorHookmaster extends CardImpl { this.power = new MageInt(2); this.toughness = new MageInt(2); + // When Kor Hookmaster enters the battlefield, tap target creature an opponent controls. + // That creature doesn't untap during its controller's next untap step. EntersBattlefieldTriggeredAbility ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); ability.addEffect(new SkipNextUntapTargetEffect()); ability.addTarget(new TargetCreaturePermanent(filter)); diff --git a/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java b/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java index 2724ecc99c..21fc5ca9b8 100644 --- a/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java +++ b/Mage.Sets/src/mage/sets/zendikar/LorthosTheTidemaker.java @@ -36,18 +36,17 @@ import mage.abilities.Ability; import mage.abilities.common.AttacksTriggeredAbility; import mage.abilities.costs.Cost; import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.ContinuousEffect; import mage.abilities.effects.OneShotEffect; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.common.SkipNextUntapTargetEffect; import mage.cards.CardImpl; -import mage.constants.Duration; import mage.constants.Outcome; -import mage.constants.PhaseStep; import mage.filter.FilterPermanent; import mage.game.Game; -import mage.game.events.GameEvent; import mage.game.permanent.Permanent; import mage.players.Player; import mage.target.TargetPermanent; +import mage.target.targetpointer.FixedTarget; /** * @@ -111,7 +110,9 @@ class LorthosTheTideMakerEffect extends OneShotEffect { Permanent permanent = game.getPermanent(target); if (permanent != null) { permanent.tap(game); - game.addEffect(new LorthosTheTideMakerEffect2(permanent.getId()), source); + ContinuousEffect effect = new SkipNextUntapTargetEffect(); + effect.setTargetPointer(new FixedTarget(permanent.getId())); + game.addEffect(effect, source); } } return false; @@ -121,44 +122,3 @@ class LorthosTheTideMakerEffect extends OneShotEffect { return false; } } - -class LorthosTheTideMakerEffect2 extends ReplacementEffectImpl { - - protected UUID permanentId; - - public LorthosTheTideMakerEffect2(UUID permanentId) { - super(Duration.OneUse, Outcome.Detriment); - this.permanentId = permanentId; - } - - public LorthosTheTideMakerEffect2(final LorthosTheTideMakerEffect2 effect) { - super(effect); - permanentId = effect.permanentId; - } - - @Override - public LorthosTheTideMakerEffect2 copy() { - return new LorthosTheTideMakerEffect2(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return false; - } - - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - used = true; - return true; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - if (game.getTurn().getStepType() == PhaseStep.UNTAP - && event.getType() == GameEvent.EventType.UNTAP - && event.getTargetId().equals(permanentId)) { - return true; - } - return false; - } -} \ No newline at end of file diff --git a/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java b/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java index 91c9892259..781b57511e 100644 --- a/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java +++ b/Mage/src/mage/abilities/decorator/ConditionalContinuousRuleModifyingEffect.java @@ -82,17 +82,17 @@ public class ConditionalContinuousRuleModifyingEffect extends ContinuousRuleModi } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (lockedInCondition && !(condition instanceof FixedCondition)) { condition = new FixedCondition(condition.apply(game, source)); } conditionState = condition.apply(game, source); if (conditionState) { effect.setTargetPointer(this.targetPointer); - return effect.applies(event, source, checkPlayableMode, game); + return effect.applies(event, source, game); } else if (otherwiseEffect != null) { otherwiseEffect.setTargetPointer(this.targetPointer); - return otherwiseEffect.applies(event, source, checkPlayableMode, game); + return otherwiseEffect.applies(event, source, game); } return false; } diff --git a/Mage/src/mage/abilities/effects/ContinuousEffects.java b/Mage/src/mage/abilities/effects/ContinuousEffects.java index e86c2c9068..b6966eb4b5 100644 --- a/Mage/src/mage/abilities/effects/ContinuousEffects.java +++ b/Mage/src/mage/abilities/effects/ContinuousEffects.java @@ -593,18 +593,31 @@ public class ContinuousEffects implements Serializable { } } + /** + * Checks if an event wont't happen because of an rule modifying effect + * + * @param event + * @param game + * @param checkPlayableMode true if the event does not really happen but it#s checked if the event would be replaced + * @return + */ public boolean preventedByRuleModification(GameEvent event, Game game, boolean checkPlayableMode) { for (ContinuousRuleModifiyingEffect effect: continuousRuleModifyingEffects) { for (Ability ability : continuousRuleModifyingEffects.getAbility(effect.getId())) { if (!(ability instanceof StaticAbility) || ability.isInUseableZone(game, null, false)) { if (effect.getDuration() != Duration.OneUse || !effect.isUsed()) { - if (effect.applies(event, ability, checkPlayableMode, game)) { + if (effect.applies(event, ability, game)) { if (!checkPlayableMode) { - String message = effect.getInfoMessage(ability, game); + String message = effect.getInfoMessage(ability, event, game); if (message != null && !message.isEmpty()) { - Player player = game.getPlayer(event.getPlayerId()); - if (player != null) { - game.informPlayer(player, message); + if (effect.sendMessageToUser()) { + Player player = game.getPlayer(event.getPlayerId()); + if (player != null) { + game.informPlayer(player, message); + } + } + if (effect.sendMessageToGameLog()) { + game.informPlayers(message); } } } diff --git a/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffect.java b/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffect.java index 2e86f239ee..60e2754368 100644 --- a/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffect.java +++ b/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffect.java @@ -42,18 +42,33 @@ public interface ContinuousRuleModifiyingEffect extends ContinuousEffect { * * @param event the event to check if it may happen * @param source the ability of the effect - * @param checkPlayableMode is the call for checking playables or to prevent a real event * @param game the game * @return */ - boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game); + boolean applies(GameEvent event, Ability source, Game game); + /** + * Defines if the user should get a message about the rule modifying effect + * if he was applied + * + * @return true if user should be informed + */ + boolean sendMessageToUser(); + + /** + * Defines if the a message should be send to game log about the rule modifying effect + * if he was applied + * + * @return true if message should go to game log + */ + boolean sendMessageToGameLog(); /** * Returns a message text that informs the player why he can't do something. * * @param source the ability of the effect + * @param event * @param game the game * @return */ - String getInfoMessage(Ability source, Game game); + String getInfoMessage(Ability source, GameEvent event, Game game); } diff --git a/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffectImpl.java b/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffectImpl.java index 8606e2bcd1..2c5cb86824 100644 --- a/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffectImpl.java +++ b/Mage/src/mage/abilities/effects/ContinuousRuleModifiyingEffectImpl.java @@ -34,6 +34,7 @@ import mage.constants.Duration; import mage.constants.EffectType; import mage.constants.Outcome; import mage.game.Game; +import mage.game.events.GameEvent; /** * @@ -41,6 +42,8 @@ import mage.game.Game; */ public abstract class ContinuousRuleModifiyingEffectImpl extends ContinuousEffectImpl implements ContinuousRuleModifiyingEffect { + protected final boolean messageToUser; + protected final boolean messageToGameLog; protected final String infoMessage; // 613.10 @@ -57,18 +60,26 @@ public abstract class ContinuousRuleModifiyingEffectImpl extends ContinuousEffec // But player isn't asked to choose order of effects if multiple are applied to the same event. public ContinuousRuleModifiyingEffectImpl(Duration duration, Outcome outcome) { + this(duration, outcome, true, false); + } + + public ContinuousRuleModifiyingEffectImpl(Duration duration, Outcome outcome, boolean messageToUser, boolean messageToLog) { super(duration, outcome); this.effectType = EffectType.CONTINUOUS_RULE_MODIFICATION; this.infoMessage = null; + this.messageToUser = messageToUser; + this.messageToGameLog = messageToLog; } public ContinuousRuleModifiyingEffectImpl(final ContinuousRuleModifiyingEffectImpl effect) { super(effect); this.infoMessage = effect.infoMessage; + this.messageToUser = effect.messageToUser; + this.messageToGameLog = effect.messageToGameLog; } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { if (infoMessage == null) { String message; MageObject object = game.getObject(source.getSourceId()); @@ -83,4 +94,15 @@ public abstract class ContinuousRuleModifiyingEffectImpl extends ContinuousEffec } } + @Override + public boolean sendMessageToUser() { + return messageToUser; + } + + @Override + public boolean sendMessageToGameLog() { + return messageToGameLog; + } + + } diff --git a/Mage/src/mage/abilities/effects/common/CantActivateAbilitiesAttachedEffect.java b/Mage/src/mage/abilities/effects/common/CantActivateAbilitiesAttachedEffect.java index d8b27eb95e..c3a3ad2041 100644 --- a/Mage/src/mage/abilities/effects/common/CantActivateAbilitiesAttachedEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantActivateAbilitiesAttachedEffect.java @@ -62,7 +62,7 @@ public class CantActivateAbilitiesAttachedEffect extends ContinuousRuleModifiyin } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.ACTIVATE_ABILITY) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { diff --git a/Mage/src/mage/abilities/effects/common/CantCounterControlledEffect.java b/Mage/src/mage/abilities/effects/common/CantCounterControlledEffect.java index 9d4b81679f..93179db339 100644 --- a/Mage/src/mage/abilities/effects/common/CantCounterControlledEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantCounterControlledEffect.java @@ -81,7 +81,7 @@ public class CantCounterControlledEffect extends ContinuousRuleModifiyingEffectI } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.COUNTER) { Spell spell = game.getStack().getSpell(event.getTargetId()); if (spell != null && spell.getControllerId().equals(source.getControllerId()) diff --git a/Mage/src/mage/abilities/effects/common/CantCounterSourceEffect.java b/Mage/src/mage/abilities/effects/common/CantCounterSourceEffect.java index bd136b89bb..03c5bd2f6e 100644 --- a/Mage/src/mage/abilities/effects/common/CantCounterSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantCounterSourceEffect.java @@ -64,7 +64,7 @@ public class CantCounterSourceEffect extends ContinuousRuleModifiyingEffectImpl } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.COUNTER) { Card card = game.getCard(source.getSourceId()); if (card != null) { diff --git a/Mage/src/mage/abilities/effects/common/CantTargetEffect.java b/Mage/src/mage/abilities/effects/common/CantTargetEffect.java index 386f96b819..a0b3377e0c 100644 --- a/Mage/src/mage/abilities/effects/common/CantTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantTargetEffect.java @@ -82,7 +82,7 @@ public class CantTargetEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.TARGET) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent != null && filterTarget.match(permanent, source.getSourceId(), source.getControllerId(), game)) { diff --git a/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java b/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java index bd6dddf2a9..53732e2fff 100644 --- a/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/CantTargetSourceEffect.java @@ -68,7 +68,7 @@ public class CantTargetSourceEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.TARGET && event.getTargetId().equals(source.getSourceId())) { StackObject sourceObject = game.getStack().getStackObject(event.getSourceId()); if (sourceObject != null && filterSource.match(sourceObject, source.getControllerId(), game)) { diff --git a/Mage/src/mage/abilities/effects/common/EpicEffect.java b/Mage/src/mage/abilities/effects/common/EpicEffect.java index 48516ad6ca..a161e9cc01 100644 --- a/Mage/src/mage/abilities/effects/common/EpicEffect.java +++ b/Mage/src/mage/abilities/effects/common/EpicEffect.java @@ -101,7 +101,7 @@ class EpicReplacementEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { MageObject mageObject = game.getObject(source.getSourceId()); if (mageObject != null) { return "For the rest of the game, you can't cast spells (Epic - " + mageObject.getName() +")"; @@ -110,7 +110,7 @@ class EpicReplacementEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL && source.getControllerId() == event.getPlayerId()) { MageObject object = game.getObject(event.getSourceId()); diff --git a/Mage/src/mage/abilities/effects/common/SkipEnchantedUntapEffect.java b/Mage/src/mage/abilities/effects/common/SkipEnchantedUntapEffect.java index 6a49d8a9c5..7cadb3fd56 100644 --- a/Mage/src/mage/abilities/effects/common/SkipEnchantedUntapEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipEnchantedUntapEffect.java @@ -15,7 +15,7 @@ import mage.game.permanent.Permanent; public class SkipEnchantedUntapEffect extends ContinuousRuleModifiyingEffectImpl { public SkipEnchantedUntapEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); + super(Duration.WhileOnBattlefield, Outcome.Detriment, false, true); staticText = "Enchanted permanent doesn't untap during its controller's untap step"; } @@ -34,7 +34,20 @@ public class SkipEnchantedUntapEffect extends ContinuousRuleModifiyingEffectImpl } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { + Permanent enchantment = game.getPermanent(source.getSourceId()); + if (enchantment != null && enchantment.getAttachedTo() != null) { + Permanent enchanted = game.getPermanent(enchantment.getAttachedTo()); + if (enchanted != null) { + return enchanted.getLogName() + " doesn't untap during its controller's untap step (" + enchantment.getLogName() + ")"; + } + } + return null; + } + + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP) { Permanent enchantment = game.getPermanent(source.getSourceId()); if (enchantment != null && enchantment.getAttachedTo() != null) { diff --git a/Mage/src/mage/abilities/effects/common/SkipNextUntapSourceEffect.java b/Mage/src/mage/abilities/effects/common/SkipNextUntapSourceEffect.java index fd01453fe4..490dcbe1a2 100644 --- a/Mage/src/mage/abilities/effects/common/SkipNextUntapSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipNextUntapSourceEffect.java @@ -1,5 +1,6 @@ package mage.abilities.effects.common; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.constants.Duration; @@ -13,7 +14,7 @@ public class SkipNextUntapSourceEffect extends ContinuousRuleModifiyingEffectImp private int validForTurnNum; public SkipNextUntapSourceEffect() { - super(Duration.Custom, Outcome.Detriment); + super(Duration.Custom, Outcome.Detriment, false, true); staticText = "{this} doesn't untap during your next untap step"; validForTurnNum = 0; } @@ -33,21 +34,40 @@ public class SkipNextUntapSourceEffect extends ContinuousRuleModifiyingEffectImp } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source.getSourceId()); + if (mageObject != null) { + return "{this} doesn't untap (" + mageObject.getLogName() + ")"; + } + return null; + } + + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + // the check for turn number is needed if multiple effects are added to prevent untap in next untap step + // if we don't check for turn number, every turn only one effect would be used instead of correctly only one time + // to skip the untap effect. + + // Discard effect if related to previous turn if (validForTurnNum > 0 && validForTurnNum < game.getTurnNum()) { discard(); return false; } + // remember the turn of the untap step the effect has to be applied if (GameEvent.EventType.UNTAP_STEP.equals(event.getType()) - && game.getActivePlayerId().equals(source.getControllerId())) { + && game.getActivePlayerId().equals(source.getControllerId())) { + if (validForTurnNum == game.getTurnNum()) { // the turn has a secon untap step but the effect is already related to the first untap step + discard(); + return false; + } validForTurnNum = game.getTurnNum(); } + // skip untap action if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == GameEvent.EventType.UNTAP && event.getTargetId().equals(source.getSourceId())) { - if (!checkPlayableMode) { discard(); - } return true; } return false; diff --git a/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java b/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java index 30479fc63a..7d29dc5452 100644 --- a/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipNextUntapTargetEffect.java @@ -28,12 +28,11 @@ package mage.abilities.effects.common; -import java.util.HashSet; -import java.util.Set; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.PhaseStep; @@ -45,13 +44,17 @@ import mage.game.permanent.Permanent; /** * @author BetaSteward_at_googlemail.com */ -public class SkipNextUntapTargetEffect extends ReplacementEffectImpl { +public class SkipNextUntapTargetEffect extends ContinuousRuleModifiyingEffectImpl { - protected Set usedFor = new HashSet<>(); - protected int count; + private int validForTurnNum; + /** + * Attention: This effect won't work with targets controlled by different controllers + * If this is needed, the validForTurnNum has to be saved per controller. + * + */ public SkipNextUntapTargetEffect() { - super(Duration.OneUse, Outcome.Detriment); + super(Duration.Custom, Outcome.Detriment, false, true); } public SkipNextUntapTargetEffect(String text) { @@ -61,10 +64,7 @@ public class SkipNextUntapTargetEffect extends ReplacementEffectImpl { public SkipNextUntapTargetEffect(final SkipNextUntapTargetEffect effect) { super(effect); - for (UUID uuid : effect.usedFor) { - this.usedFor.add(uuid); - } - this.count = effect.count; + this.validForTurnNum = effect.validForTurnNum; } @Override @@ -78,32 +78,53 @@ public class SkipNextUntapTargetEffect extends ReplacementEffectImpl { } @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - // not clear how to turn off the effect for more than one target - // especially as some targets may leave the battlefield since the effect creation - // so handling this in applies method is the only option for now for such cases - if (usedFor.size() >= targetPointer.getTargets(game, source).size()) { - // this won't work for targets disappeared before applies() return true - used = true; + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source.getSourceId()); + Permanent permanentToUntap = game.getPermanent((event.getTargetId())); + if (permanentToUntap != null && mageObject != null) { + return permanentToUntap.getLogName() + " doesn't untap (" + mageObject.getLogName() + ")"; } - return true; + return null; } - + @Override public boolean applies(GameEvent event, Ability source, Game game) { + // the check for turn number is needed if multiple effects are added to prevent untap in next untap step + // if we don't check for turn number, every turn only one effect would be used instead of correctly only one time + // to skip the untap effect. + + // Discard effect if related to previous turn + if (validForTurnNum > 0 && validForTurnNum < game.getTurnNum()) { + discard(); + return false; + } + // remember the turn of the untap step the effect has to be applied + if (GameEvent.EventType.UNTAP_STEP.equals(event.getType())) { + UUID controllerId = null; + for(UUID targetId : getTargetPointer().getTargets(game, source)) { + Permanent permanent = game.getPermanent(targetId); + if (permanent != null) { + controllerId = permanent.getControllerId(); + } + } + if (controllerId == null) { // no more targets on the battlefield, effect can be discarded + discard(); + return false; + } + + if (game.getActivePlayerId().equals(controllerId)) { + if (validForTurnNum == game.getTurnNum()) { // the turn has a second untap step but the effect is already related to the first untap step + discard(); + return false; + } + validForTurnNum = game.getTurnNum(); + } + + } + if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == EventType.UNTAP) { - if (targetPointer.getTargets(game, source).contains(event.getTargetId()) - && !usedFor.contains(event.getTargetId())) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent == null) { - usedFor.add(event.getTargetId()); - return false; - } - if (permanent.getControllerId().equals(game.getActivePlayerId())) { - usedFor.add(event.getTargetId()); - return true; - } - + if (targetPointer.getTargets(game, source).contains(event.getTargetId())) { + return true; } } return false; diff --git a/Mage/src/mage/abilities/effects/common/SkipUntapAllEffect.java b/Mage/src/mage/abilities/effects/common/SkipUntapAllEffect.java index dd0aceee94..0b1962977f 100644 --- a/Mage/src/mage/abilities/effects/common/SkipUntapAllEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipUntapAllEffect.java @@ -30,7 +30,7 @@ package mage.abilities.effects.common; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.PhaseStep; @@ -51,13 +51,13 @@ import mage.players.Player; * @author LevelX2 */ -public class SkipUntapAllEffect extends ReplacementEffectImpl { +public class SkipUntapAllEffect extends ContinuousRuleModifiyingEffectImpl { TargetController targetController; FilterPermanent filter; public SkipUntapAllEffect(Duration duration, TargetController targetController, FilterPermanent filter) { - super(duration, Outcome.Detriment); + super(duration, Outcome.Detriment, false, false); this.targetController = targetController; this.filter = filter; } @@ -78,12 +78,6 @@ public class SkipUntapAllEffect extends ReplacementEffectImpl { return false; } - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - - @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == EventType.UNTAP) { diff --git a/Mage/src/mage/abilities/effects/common/SkipUntapSourceEffect.java b/Mage/src/mage/abilities/effects/common/SkipUntapSourceEffect.java index cf78818763..c7d02d4756 100644 --- a/Mage/src/mage/abilities/effects/common/SkipUntapSourceEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipUntapSourceEffect.java @@ -31,6 +31,7 @@ import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.PhaseStep; import mage.abilities.Ability; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.abilities.effects.ReplacementEffectImpl; import mage.game.Game; import mage.game.events.GameEvent; @@ -40,10 +41,10 @@ import mage.game.events.GameEvent.EventType; * * @author North */ -public class SkipUntapSourceEffect extends ReplacementEffectImpl { +public class SkipUntapSourceEffect extends ContinuousRuleModifiyingEffectImpl { public SkipUntapSourceEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); + super(Duration.WhileOnBattlefield, Outcome.Detriment, false, true); staticText = "{this} doesn't untap during your untap step"; } @@ -61,11 +62,6 @@ public class SkipUntapSourceEffect extends ReplacementEffectImpl { return false; } - @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; - } - @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getTurn().getStepType() == PhaseStep.UNTAP diff --git a/Mage/src/mage/abilities/effects/common/SkipUntapTargetEffect.java b/Mage/src/mage/abilities/effects/common/SkipUntapTargetEffect.java index 4a498cd1d3..a96d71fb91 100644 --- a/Mage/src/mage/abilities/effects/common/SkipUntapTargetEffect.java +++ b/Mage/src/mage/abilities/effects/common/SkipUntapTargetEffect.java @@ -29,9 +29,10 @@ package mage.abilities.effects.common; import java.util.UUID; +import mage.MageObject; import mage.abilities.Ability; import mage.abilities.Mode; -import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.effects.ContinuousRuleModifiyingEffectImpl; import mage.constants.Duration; import mage.constants.Outcome; import mage.constants.PhaseStep; @@ -41,9 +42,10 @@ import mage.game.events.GameEvent.EventType; import mage.game.permanent.Permanent; /** + * * @author BetaSteward_at_googlemail.com */ -public class SkipUntapTargetEffect extends ReplacementEffectImpl { +public class SkipUntapTargetEffect extends ContinuousRuleModifiyingEffectImpl { public SkipUntapTargetEffect(Duration duration) { super(duration, Outcome.Detriment); @@ -64,11 +66,15 @@ public class SkipUntapTargetEffect extends ReplacementEffectImpl { } @Override - public boolean replaceEvent(GameEvent event, Ability source, Game game) { - return true; + public String getInfoMessage(Ability source, GameEvent event, Game game) { + MageObject mageObject = game.getObject(source.getSourceId()); + Permanent permanentToUntap = game.getPermanent((event.getTargetId())); + if (permanentToUntap != null && mageObject != null) { + return permanentToUntap.getLogName() + " doesn't untap (" + mageObject.getLogName() + ")"; + } + return null; } - - + @Override public boolean applies(GameEvent event, Ability source, Game game) { if (game.getTurn().getStepType() == PhaseStep.UNTAP && event.getType() == EventType.UNTAP) { diff --git a/Mage/src/mage/abilities/effects/common/continious/CantCastMoreThanOneSpellEffect.java b/Mage/src/mage/abilities/effects/common/continious/CantCastMoreThanOneSpellEffect.java index 2b6579fffa..f3594f6578 100644 --- a/Mage/src/mage/abilities/effects/common/continious/CantCastMoreThanOneSpellEffect.java +++ b/Mage/src/mage/abilities/effects/common/continious/CantCastMoreThanOneSpellEffect.java @@ -72,7 +72,7 @@ public class CantCastMoreThanOneSpellEffect extends ContinuousRuleModifiyingEffe } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { switch (targetController) { case YOU: diff --git a/Mage/src/mage/abilities/keyword/SplitSecondAbility.java b/Mage/src/mage/abilities/keyword/SplitSecondAbility.java index adf4c99d1b..b80939aadc 100644 --- a/Mage/src/mage/abilities/keyword/SplitSecondAbility.java +++ b/Mage/src/mage/abilities/keyword/SplitSecondAbility.java @@ -49,12 +49,12 @@ class SplitSecondEffect extends ContinuousRuleModifiyingEffectImpl { } @Override - public String getInfoMessage(Ability source, Game game) { + public String getInfoMessage(Ability source, GameEvent event, Game game) { return "You can't cast spells or activate abilities that aren't mana abilities (Split second)."; } @Override - public boolean applies(GameEvent event, Ability source, boolean checkPlayableMode, Game game) { + public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == GameEvent.EventType.CAST_SPELL) { return true; }