From c00e34c0517e205eb081e1663171d8c81df7aa90 Mon Sep 17 00:00:00 2001 From: BetaSteward Date: Wed, 12 Oct 2011 21:44:26 -0400 Subject: [PATCH] over-hauled watchers --- .../championsofkamigawa/AshenSkinZubera.java | 73 +----------------- .../DrippingTongueZubera.java | 71 +---------------- .../championsofkamigawa/EmberFistZubera.java | 74 +----------------- .../FloatingDreamZubera.java | 42 +++++----- .../MyojinOfCleansingFire.java | 9 ++- .../SilentChantZubera.java | 48 ++---------- .../mage/sets/innistrad/AbattoirGhoul.java | 52 +++---------- .../mage/sets/innistrad/BrimstoneVolley.java | 2 +- .../mage/sets/innistrad/CivilizedScholar.java | 2 +- .../mage/sets/innistrad/HomicidalBrute.java | 44 ++++++----- .../sets/innistrad/ReaperFromTheAbyss.java | 2 +- .../sets/innistrad/SkirsdagHighPriest.java | 2 +- .../mage/sets/magic2011/AngelicArbiter.java | 18 +++-- .../sets/magic2011/BloodcrazedGoblin.java | 9 +-- .../sets/mirrodinbesieged/RedSunsZenith.java | 51 +++---------- .../sets/newphyrexia/CathedralMembrane.java | 25 +++--- .../src/mage/sets/newphyrexia/FreshMeat.java | 45 ++++++----- .../mage/sets/riseoftheeldrazi/Vengevine.java | 12 +-- .../sets/scarsofmirrodin/FleshAllergy.java | 42 +++++----- .../sets/scarsofmirrodin/MoltenPsyche.java | 13 +++- .../sets/scarsofmirrodin/SteelHellkite.java | 44 +++++------ .../sets/scarsofmirrodin/TunnelIgnus.java | 36 +++++---- .../src/mage/sets/worldwake/Groundswell.java | 57 ++++---------- .../src/mage/sets/worldwake/SearingBlaze.java | 55 +++++++------- .../src/mage/sets/zendikar/ArchiveTrap.java | 5 +- .../src/mage/sets/zendikar/CobraTrap.java | 22 +++--- .../src/mage/sets/zendikar/MindbreakTrap.java | 44 ++++++----- .../src/mage/sets/zendikar/SummoningTrap.java | 11 +-- Mage/src/mage/Constants.java | 6 ++ .../condition/common/MorbidCondition.java | 2 +- .../NoSpellsWereCastLastTurnCondition.java | 2 +- ...OrMoreSpellsWereCastLastTurnCondition.java | 2 +- .../abilities/keyword/BloodthirstAbility.java | 15 ++-- Mage/src/mage/cards/Card.java | 2 +- Mage/src/mage/cards/CardImpl.java | 14 ++-- Mage/src/mage/game/GameImpl.java | 4 +- .../src/mage/game/events/ZoneChangeEvent.java | 4 + Mage/src/mage/game/stack/Spell.java | 4 +- Mage/src/mage/players/PlayerImpl.java | 5 +- Mage/src/mage/watchers/WatcherImpl.java | 14 +++- Mage/src/mage/watchers/Watchers.java | 70 ++++++++++------- .../watchers/common/BloodthirstWatcher.java | 7 +- .../watchers/common/CastFromHandWatcher.java | 3 +- .../common/CastSpellLastTurnWatcher.java | 3 +- .../watchers/common/DamagedByWatcher.java | 76 +++++++++++++++++++ .../mage/watchers/common/MorbidWatcher.java | 3 +- 46 files changed, 473 insertions(+), 673 deletions(-) create mode 100644 Mage/src/mage/watchers/common/DamagedByWatcher.java diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/AshenSkinZubera.java b/Mage.Sets/src/mage/sets/championsofkamigawa/AshenSkinZubera.java index 8e21e38e9d..4c48df98af 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/AshenSkinZubera.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/AshenSkinZubera.java @@ -30,22 +30,14 @@ package mage.sets.championsofkamigawa; import java.util.UUID; -import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.common.DiscardTargetEffect; -import mage.cards.Card; import mage.cards.CardImpl; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.target.common.TargetOpponent; -import mage.watchers.Watcher; -import mage.watchers.WatcherImpl; /** * @author Loki @@ -60,10 +52,10 @@ public class AshenSkinZubera extends CardImpl { this.color.setBlack(true); this.power = new MageInt(1); this.toughness = new MageInt(2); - Ability ability = new DiesTriggeredAbility(new DiscardTargetEffect(new AshenSkinZuberaDynamicValue())); + Ability ability = new DiesTriggeredAbility(new DiscardTargetEffect(new ZuberasDiedDynamicValue())); ability.addTarget(new TargetOpponent()); this.addAbility(ability); - this.addWatcher(new AshenSkinZuberaWatcher()); + this.addWatcher(new ZuberasDiedWatcher()); } public AshenSkinZubera(final AshenSkinZubera card) { @@ -77,64 +69,3 @@ public class AshenSkinZubera extends CardImpl { } -class AshenSkinZuberaWatcher extends WatcherImpl { - - public int zuberasDiedThisTurn = 0; - - public AshenSkinZuberaWatcher() { - super("ZuberasDiedAshenSkinZubera"); - } - - public AshenSkinZuberaWatcher(final AshenSkinZuberaWatcher watcher) { - super(watcher); - } - - @Override - public AshenSkinZuberaWatcher copy() { - return new AshenSkinZuberaWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent) event).getFromZone() == Constants.Zone.BATTLEFIELD && - ((ZoneChangeEvent) event).getToZone() == Constants.Zone.GRAVEYARD) { - Card card = game.getLastKnownInformation(event.getTargetId(), Constants.Zone.BATTLEFIELD); - if (card != null && card.hasSubtype("Zubera")) { - zuberasDiedThisTurn++; - } - } - } - } - - @Override - public void reset() { - super.reset(); - zuberasDiedThisTurn = 0; - } - -} - -class AshenSkinZuberaDynamicValue implements DynamicValue { - - @Override - public int calculate(Game game, Ability sourceAbility) { - Watcher watcher = game.getState().getWatchers().get(sourceAbility.getControllerId(), "ZuberasDiedAshenSkinZubera"); - return ((AshenSkinZuberaWatcher) watcher).zuberasDiedThisTurn; - } - - @Override - public DynamicValue clone() { - return new AshenSkinZuberaDynamicValue(); - } - - @Override - public String toString() { - return "a"; - } - - @Override - public String getMessage() { - return "Zubera put into a graveyard from play this turn"; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/DrippingTongueZubera.java b/Mage.Sets/src/mage/sets/championsofkamigawa/DrippingTongueZubera.java index e28f5c4386..eafb28ea5a 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/DrippingTongueZubera.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/DrippingTongueZubera.java @@ -30,7 +30,6 @@ package mage.sets.championsofkamigawa; import java.util.UUID; -import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.MageInt; @@ -38,14 +37,10 @@ import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.common.CreateTokenEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.token.SpiritToken; import mage.watchers.Watcher; -import mage.watchers.WatcherImpl; /** * @@ -61,8 +56,8 @@ public class DrippingTongueZubera extends CardImpl { this.color.setGreen(true); this.power = new MageInt(1); this.toughness = new MageInt(2); - this.addAbility(new DiesTriggeredAbility(new CreateTokenEffect(new SpiritToken(), new DrippingTongueZuberaDynamicValue()), false)); - this.addWatcher(new DrippingTongueZuberaWatcher()); + this.addAbility(new DiesTriggeredAbility(new CreateTokenEffect(new SpiritToken(), new ZuberasDiedDynamicValue()), false)); + this.addWatcher(new ZuberasDiedWatcher()); } public DrippingTongueZubera (final DrippingTongueZubera card) { @@ -75,65 +70,3 @@ public class DrippingTongueZubera extends CardImpl { } } - -class DrippingTongueZuberaWatcher extends WatcherImpl { - - public int zuberasDiedThisTurn = 0; - - public DrippingTongueZuberaWatcher() { - super("ZuberasDiedDrippingTongueZubera"); - } - - public DrippingTongueZuberaWatcher(final DrippingTongueZuberaWatcher watcher) { - super(watcher); - } - - @Override - public DrippingTongueZuberaWatcher copy() { - return new DrippingTongueZuberaWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent) event).getFromZone() == Constants.Zone.BATTLEFIELD && - ((ZoneChangeEvent) event).getToZone() == Constants.Zone.GRAVEYARD) { - Card card = game.getLastKnownInformation(event.getTargetId(), Constants.Zone.BATTLEFIELD); - if (card != null && card.hasSubtype("Zubera")) { - zuberasDiedThisTurn++; - } - } - } - } - - @Override - public void reset() { - super.reset(); - zuberasDiedThisTurn = 0; - } - -} - -class DrippingTongueZuberaDynamicValue implements DynamicValue { - - @Override - public int calculate(Game game, Ability sourceAbility) { - Watcher watcher = game.getState().getWatchers().get(sourceAbility.getControllerId(), "ZuberasDiedDrippingTongueZubera"); - return ((DrippingTongueZuberaWatcher) watcher).zuberasDiedThisTurn; - } - - @Override - public DynamicValue clone() { - return new DrippingTongueZuberaDynamicValue(); - } - - @Override - public String toString() { - return "1"; - } - - @Override - public String getMessage() { - return "Zubera put into a graveyard from play this turn"; - } -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/EmberFistZubera.java b/Mage.Sets/src/mage/sets/championsofkamigawa/EmberFistZubera.java index d465d3022a..d7c5767c98 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/EmberFistZubera.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/EmberFistZubera.java @@ -30,22 +30,14 @@ package mage.sets.championsofkamigawa; import java.util.UUID; -import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.effects.common.DamageTargetEffect; -import mage.cards.Card; import mage.cards.CardImpl; -import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.target.common.TargetCreatureOrPlayer; -import mage.watchers.Watcher; -import mage.watchers.WatcherImpl; /** * @@ -61,10 +53,10 @@ public class EmberFistZubera extends CardImpl { this.color.setRed(true); this.power = new MageInt(1); this.toughness = new MageInt(2); - Ability ability = new DiesTriggeredAbility(new DamageTargetEffect(new EmberFistZuberaDynamicValue())); + Ability ability = new DiesTriggeredAbility(new DamageTargetEffect(new ZuberasDiedDynamicValue())); ability.addTarget(new TargetCreatureOrPlayer()); this.addAbility(ability); - this.addWatcher(new EmberFistZuberaWatcher()); + this.addWatcher(new ZuberasDiedWatcher()); } public EmberFistZubera (final EmberFistZubera card) { @@ -78,65 +70,3 @@ public class EmberFistZubera extends CardImpl { } -class EmberFistZuberaWatcher extends WatcherImpl { - - public int zuberasDiedThisTurn = 0; - - public EmberFistZuberaWatcher() { - super("ZuberasDiedEmberFistZubera"); - } - - public EmberFistZuberaWatcher(final EmberFistZuberaWatcher watcher) { - super(watcher); - } - - @Override - public EmberFistZuberaWatcher copy() { - return new EmberFistZuberaWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent) event).getFromZone() == Constants.Zone.BATTLEFIELD && - ((ZoneChangeEvent) event).getToZone() == Constants.Zone.GRAVEYARD) { - Card card = game.getLastKnownInformation(event.getTargetId(), Constants.Zone.BATTLEFIELD); - if (card != null && card.hasSubtype("Zubera")) { - zuberasDiedThisTurn++; - } - } - } - } - - @Override - public void reset() { - super.reset(); - zuberasDiedThisTurn = 0; - } - -} - -class EmberFistZuberaDynamicValue implements DynamicValue { - - @Override - public int calculate(Game game, Ability sourceAbility) { - Watcher watcher = game.getState().getWatchers().get(sourceAbility.getControllerId(), "ZuberasDiedEmberFistZubera"); - return ((EmberFistZuberaWatcher) watcher).zuberasDiedThisTurn; - } - - @Override - public DynamicValue clone() { - return new EmberFistZuberaDynamicValue(); - } - - @Override - public String toString() { - return "1"; - } - - @Override - public String getMessage() { - return "Zubera put into all graveyards from play this turn"; - } -} - diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/FloatingDreamZubera.java b/Mage.Sets/src/mage/sets/championsofkamigawa/FloatingDreamZubera.java index 6378855a47..23b93b5576 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/FloatingDreamZubera.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/FloatingDreamZubera.java @@ -33,6 +33,7 @@ import java.util.UUID; import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.DiesTriggeredAbility; @@ -43,7 +44,6 @@ import mage.cards.CardImpl; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; -import mage.watchers.Watcher; import mage.watchers.WatcherImpl; /** @@ -59,8 +59,8 @@ public class FloatingDreamZubera extends CardImpl { this.color.setBlue(true); this.power = new MageInt(1); this.toughness = new MageInt(2); - this.addAbility(new DiesTriggeredAbility(new DrawCardControllerEffect(new FloatingDreamZuberaDynamicValue()))); - this.addWatcher(new FloatingDreamZuberaWatcher()); + this.addAbility(new DiesTriggeredAbility(new DrawCardControllerEffect(new ZuberasDiedDynamicValue()))); + this.addWatcher(new ZuberasDiedWatcher()); } public FloatingDreamZubera(final FloatingDreamZubera card) { @@ -75,32 +75,30 @@ public class FloatingDreamZubera extends CardImpl { } -class FloatingDreamZuberaWatcher extends WatcherImpl { +class ZuberasDiedWatcher extends WatcherImpl { public int zuberasDiedThisTurn = 0; - public FloatingDreamZuberaWatcher() { - super("ZuberasDiedFloatingDreamZubera"); + public ZuberasDiedWatcher() { + super("ZuberasDied", WatcherScope.GAME); } - public FloatingDreamZuberaWatcher(final FloatingDreamZuberaWatcher watcher) { + public ZuberasDiedWatcher(final ZuberasDiedWatcher watcher) { super(watcher); + this.zuberasDiedThisTurn = watcher.zuberasDiedThisTurn; } @Override - public FloatingDreamZuberaWatcher copy() { - return new FloatingDreamZuberaWatcher(this); + public ZuberasDiedWatcher copy() { + return new ZuberasDiedWatcher(this); } @Override public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent) event).getFromZone() == Constants.Zone.BATTLEFIELD && - ((ZoneChangeEvent) event).getToZone() == Constants.Zone.GRAVEYARD) { - Card card = game.getLastKnownInformation(event.getTargetId(), Constants.Zone.BATTLEFIELD); - if (card != null && card.hasSubtype("Zubera")) { - zuberasDiedThisTurn++; - } + if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) { + Card card = game.getLastKnownInformation(event.getTargetId(), Constants.Zone.BATTLEFIELD); + if (card != null && card.hasSubtype("Zubera")) { + zuberasDiedThisTurn++; } } } @@ -113,17 +111,17 @@ class FloatingDreamZuberaWatcher extends WatcherImpl } -class FloatingDreamZuberaDynamicValue implements DynamicValue { +class ZuberasDiedDynamicValue implements DynamicValue { @Override public int calculate(Game game, Ability sourceAbility) { - Watcher watcher = game.getState().getWatchers().get(sourceAbility.getControllerId(), "ZuberasDiedFloatingDreamZubera"); - return ((FloatingDreamZuberaWatcher) watcher).zuberasDiedThisTurn; + ZuberasDiedWatcher watcher = (ZuberasDiedWatcher) game.getState().getWatchers().get("ZuberasDied"); + return watcher.zuberasDiedThisTurn; } @Override - public DynamicValue clone() { - return new FloatingDreamZuberaDynamicValue(); + public ZuberasDiedDynamicValue clone() { + return new ZuberasDiedDynamicValue(); } @Override @@ -133,6 +131,6 @@ class FloatingDreamZuberaDynamicValue implements DynamicValue { @Override public String getMessage() { - return "for each Zubera put into a graveyard from play this turn"; + return "for each Zubera that died this turn"; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java index 82de09e3ba..d988000541 100644 --- a/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java +++ b/Mage.Sets/src/mage/sets/championsofkamigawa/MyojinOfCleansingFire.java @@ -44,6 +44,7 @@ import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.common.DestroyAllEffect; import mage.abilities.effects.common.continious.GainAbilitySourceEffect; import mage.abilities.keyword.IndestructibleAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.counters.CounterType; import mage.filter.common.FilterCreaturePermanent; @@ -105,10 +106,10 @@ class MyojinOfCleansingFireEntersBattlefieldEffect extends OneShotEffect { this.toughness = new MageInt(2); Ability ability = new DiesTriggeredAbility(new GainLifeEffect(new SilentChantZuberaDynamicValue())); this.addAbility(ability); - this.addWatcher(new AshenSkinZuberaWatcher()); + this.addWatcher(new ZuberasDiedWatcher()); } public SilentChantZubera (final SilentChantZubera card) { @@ -76,54 +76,16 @@ public class SilentChantZubera extends CardImpl { } -class SilentChantZuberaWatcher extends WatcherImpl { - - public int zuberasDiedThisTurn = 0; - - public SilentChantZuberaWatcher() { - super("ZuberasDiedSilentChantZubera"); - } - - public SilentChantZuberaWatcher(final SilentChantZuberaWatcher watcher) { - super(watcher); - } - - @Override - public SilentChantZuberaWatcher copy() { - return new SilentChantZuberaWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent) event).getFromZone() == Constants.Zone.BATTLEFIELD && - ((ZoneChangeEvent) event).getToZone() == Constants.Zone.GRAVEYARD) { - Card card = game.getLastKnownInformation(event.getTargetId(), Constants.Zone.BATTLEFIELD); - if (card != null && card.hasSubtype("Zubera")) { - zuberasDiedThisTurn++; - } - } - } - } - - @Override - public void reset() { - super.reset(); - zuberasDiedThisTurn = 0; - } - -} - class SilentChantZuberaDynamicValue implements DynamicValue { @Override public int calculate(Game game, Ability sourceAbility) { - Watcher watcher = game.getState().getWatchers().get(sourceAbility.getControllerId(), "ZuberasDiedSilentChantZubera"); - return ((SilentChantZuberaWatcher) watcher).zuberasDiedThisTurn; + ZuberasDiedWatcher watcher = (ZuberasDiedWatcher) game.getState().getWatchers().get("ZuberasDied"); + return watcher.zuberasDiedThisTurn * 2; } @Override - public DynamicValue clone() { + public SilentChantZuberaDynamicValue clone() { return new SilentChantZuberaDynamicValue(); } @@ -134,6 +96,6 @@ class SilentChantZuberaDynamicValue implements DynamicValue { @Override public String getMessage() { - return "Zubera put into a graveyard from play this turn"; + return "for each Zubera that died this turn"; } } \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/innistrad/AbattoirGhoul.java b/Mage.Sets/src/mage/sets/innistrad/AbattoirGhoul.java index fa8413adf2..a3c5430d37 100644 --- a/Mage.Sets/src/mage/sets/innistrad/AbattoirGhoul.java +++ b/Mage.Sets/src/mage/sets/innistrad/AbattoirGhoul.java @@ -39,7 +39,6 @@ import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.FirstStrikeAbility; -import mage.cards.Card; import mage.cards.CardImpl; import mage.game.Game; import mage.game.events.GameEvent; @@ -47,8 +46,7 @@ import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.players.Player; -import mage.watchers.Watcher; -import mage.watchers.WatcherImpl; +import mage.watchers.common.DamagedByWatcher; /** * @@ -70,7 +68,7 @@ public class AbattoirGhoul extends CardImpl { AbattoirGhoulEffect effect = new AbattoirGhoulEffect(); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); - this.addWatcher(new AbattoirGhoulWatcher()); + this.addWatcher(new DamagedByWatcher()); } public AbattoirGhoul(final AbattoirGhoul card) { @@ -118,47 +116,15 @@ class AbattoirGhoulEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == EventType.ZONE_CHANGE && - ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD && - ((ZoneChangeEvent)event).getFromZone() == Zone.BATTLEFIELD) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "AbattoirGhoulDamagedCreature"); - if (watcher != null) - return watcher.conditionMet(); + if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).isDiesEvent()) { + Permanent p = game.getPermanent(source.getSourceId()); + if (p != null) { + DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get("DamagedByWatcher", source.getSourceId()); + if (watcher != null) + return watcher.damagedCreatures.contains(event.getTargetId()); + } } return false; } } - -class AbattoirGhoulWatcher extends WatcherImpl { - - public AbattoirGhoulWatcher() { - super("AbattoirGhoulDamagedCreature"); - } - - public AbattoirGhoulWatcher(final AbattoirGhoulWatcher watcher) { - super(watcher); - } - - @Override - public AbattoirGhoulWatcher copy() { - return new AbattoirGhoulWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - if (condition == true) //no need to check - condition has already occured - return; - if (event.getType() == EventType.DAMAGED_CREATURE) { - Card card = game.getCard(sourceId); - - if (card != null && card.getId().equals(event.getSourceId())) { - condition = true; - AbattoirGhoulEffect effect = (AbattoirGhoulEffect)card.getAbilities().get(2).getEffects().get(0); - effect.setValue("player", game.getPlayer(card.getOwnerId())); - } - } - - } - -} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/innistrad/BrimstoneVolley.java b/Mage.Sets/src/mage/sets/innistrad/BrimstoneVolley.java index cf0d804210..ff96788c2b 100644 --- a/Mage.Sets/src/mage/sets/innistrad/BrimstoneVolley.java +++ b/Mage.Sets/src/mage/sets/innistrad/BrimstoneVolley.java @@ -84,7 +84,7 @@ class BrimstoneVolleyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { int damage = 3; - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "Morbid"); + Watcher watcher = game.getState().getWatchers().get("Morbid"); if (watcher.conditionMet()) { damage = 5; } diff --git a/Mage.Sets/src/mage/sets/innistrad/CivilizedScholar.java b/Mage.Sets/src/mage/sets/innistrad/CivilizedScholar.java index 72abff2281..96e03c4944 100644 --- a/Mage.Sets/src/mage/sets/innistrad/CivilizedScholar.java +++ b/Mage.Sets/src/mage/sets/innistrad/CivilizedScholar.java @@ -67,7 +67,7 @@ public class CivilizedScholar extends CardImpl { this.addAbility(new SimpleActivatedAbility(Constants.Zone.BATTLEFIELD, new CivilizedScholarEffect(), new TapSourceCost())); this.addAbility(new TransformAbility()); - this.addWatcher(new HomicidalBrute.HomicidalBruteWatcher()); +// this.addWatcher(new HomicidalBrute.HomicidalBruteWatcher()); } public CivilizedScholar(final CivilizedScholar card) { diff --git a/Mage.Sets/src/mage/sets/innistrad/HomicidalBrute.java b/Mage.Sets/src/mage/sets/innistrad/HomicidalBrute.java index 60863be228..c98c80d526 100644 --- a/Mage.Sets/src/mage/sets/innistrad/HomicidalBrute.java +++ b/Mage.Sets/src/mage/sets/innistrad/HomicidalBrute.java @@ -39,10 +39,10 @@ import mage.game.Game; import mage.game.events.GameEvent; import mage.watchers.WatcherImpl; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; import java.util.UUID; +import mage.Constants.WatcherScope; +import mage.cards.Card; +import mage.watchers.Watcher; /** * @author nantuko @@ -65,6 +65,7 @@ public class HomicidalBrute extends CardImpl { // At the beginning of your end step, if Homicidal Brute didn't attack this turn, tap Homicidal Brute, then transform it. this.addAbility(new HomicidalBruteTriggeredAbility()); + this.addWatcher(new HomicidalBruteWatcher()); } public HomicidalBrute(final HomicidalBrute card) { @@ -76,28 +77,29 @@ public class HomicidalBrute extends CardImpl { return new HomicidalBrute(this); } - public static class HomicidalBruteWatcher extends WatcherImpl { +} - public Map> blockedCreatures = new HashMap>(); +class HomicidalBruteWatcher extends WatcherImpl { - public HomicidalBruteWatcher() { - super("HomicidalBruteWatcher"); - } + public HomicidalBruteWatcher() { + super("HomicidalBruteAttacked", WatcherScope.CARD); + } - public HomicidalBruteWatcher(final HomicidalBruteWatcher watcher) { - super(watcher); - } + public HomicidalBruteWatcher(final HomicidalBruteWatcher watcher) { + super(watcher); + } - @Override - public HomicidalBruteWatcher copy() { - return new HomicidalBruteWatcher(this); - } + @Override + public HomicidalBruteWatcher copy() { + return new HomicidalBruteWatcher(this); + } - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED && event.getSourceId().equals(sourceId)) { - condition = true; - } + @Override + public void watch(GameEvent event, Game game) { + if (condition == true) + return; + if (event.getType() == GameEvent.EventType.ATTACKER_DECLARED && event.getSourceId().equals(sourceId)) { + condition = true; } } } @@ -121,7 +123,7 @@ class HomicidalBruteTriggeredAbility extends TriggeredAbilityImpl { @Override public boolean canPay(UUID sourceId, UUID controllerId, Game game) { - return game.getState().getWatchers().get(controllerId, "Morbid").conditionMet(); + return game.getState().getWatchers().get("Morbid").conditionMet(); } @Override diff --git a/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java b/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java index 452e997e24..d1bd5030bd 100644 --- a/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java +++ b/Mage.Sets/src/mage/sets/magic2011/AngelicArbiter.java @@ -33,12 +33,14 @@ import mage.Constants.CardType; import mage.Constants.Duration; import mage.Constants.Outcome; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.Constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.keyword.FlyingAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.game.Game; import mage.game.events.GameEvent; @@ -81,7 +83,7 @@ public class AngelicArbiter extends CardImpl { class AngelicArbiterWatcher1 extends WatcherImpl { public AngelicArbiterWatcher1() { - super("CastSpell"); + super("OpponentCastSpell", WatcherScope.PLAYER); } public AngelicArbiterWatcher1(final AngelicArbiterWatcher1 watcher) { @@ -106,7 +108,7 @@ class AngelicArbiterWatcher1 extends WatcherImpl { class AngelicArbiterWatcher2 extends WatcherImpl { public AngelicArbiterWatcher2() { - super("Attacked"); + super("OpponentAttacked", WatcherScope.PLAYER); } public AngelicArbiterWatcher2(final AngelicArbiterWatcher2 watcher) { @@ -155,9 +157,9 @@ class AngelicArbiterEffect1 extends ReplacementEffectImpl @Override public boolean applies(GameEvent event, Ability source, Game game) { if (event.getType() == EventType.DECLARE_ATTACKER && game.getActivePlayerId().equals(event.getPlayerId()) && game.getOpponents(source.getControllerId()).contains(event.getPlayerId())) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "CastSpell"); - if (watcher != null && watcher.conditionMet()) - return true; + Watcher watcher = game.getState().getWatchers().get("OpponentCastSpell", source.getControllerId()); + if (watcher != null && watcher.conditionMet()) + return true; } return false; } @@ -193,9 +195,9 @@ class AngelicArbiterEffect2 extends ReplacementEffectImpl @Override 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(source.getControllerId(), "Attacked"); - if (watcher != null && watcher.conditionMet()) - return true; + Watcher watcher = game.getState().getWatchers().get("OpponentAttacked", source.getControllerId()); + if (watcher != null && watcher.conditionMet()) + return true; } return false; } diff --git a/Mage.Sets/src/mage/sets/magic2011/BloodcrazedGoblin.java b/Mage.Sets/src/mage/sets/magic2011/BloodcrazedGoblin.java index 07d6d6d234..da5f19d614 100644 --- a/Mage.Sets/src/mage/sets/magic2011/BloodcrazedGoblin.java +++ b/Mage.Sets/src/mage/sets/magic2011/BloodcrazedGoblin.java @@ -40,7 +40,9 @@ import mage.abilities.effects.RestrictionEffect; import mage.cards.CardImpl; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; import mage.watchers.Watcher; +import mage.watchers.common.BloodthirstWatcher; /** * @@ -95,10 +97,7 @@ class BloodcrazedGoblinEffect extends RestrictionEffect @Override public boolean applies(Permanent permanent, Ability source, Game game) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "DamagedOpponents"); - if (watcher != null) { - return !watcher.conditionMet(); - } - return false; + BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get("DamagedOpponents", source.getControllerId()); + return !watcher.conditionMet(); } } diff --git a/Mage.Sets/src/mage/sets/mirrodinbesieged/RedSunsZenith.java b/Mage.Sets/src/mage/sets/mirrodinbesieged/RedSunsZenith.java index bce9492efe..07a3e104f0 100644 --- a/Mage.Sets/src/mage/sets/mirrodinbesieged/RedSunsZenith.java +++ b/Mage.Sets/src/mage/sets/mirrodinbesieged/RedSunsZenith.java @@ -32,13 +32,11 @@ import mage.Constants.CardType; import mage.Constants.Duration; import mage.Constants.Outcome; import mage.Constants.Rarity; -import mage.Constants.Zone; -import mage.MageObject; import mage.abilities.Ability; +import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.effects.ReplacementEffectImpl; -import mage.abilities.effects.common.DamageXTargetEffect; +import mage.abilities.effects.common.DamageTargetEffect; import mage.abilities.effects.common.ShuffleSpellEffect; -import mage.cards.Card; import mage.cards.CardImpl; import mage.game.Game; import mage.game.events.GameEvent; @@ -46,8 +44,7 @@ import mage.game.events.GameEvent.EventType; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.target.common.TargetCreatureOrPlayer; -import mage.watchers.Watcher; -import mage.watchers.WatcherImpl; +import mage.watchers.common.DamagedByWatcher; /** * @@ -60,10 +57,10 @@ public class RedSunsZenith extends CardImpl { this.expansionSetCode = "MBS"; this.color.setRed(true); this.getSpellAbility().addTarget(new TargetCreatureOrPlayer()); - this.getSpellAbility().addEffect(new DamageXTargetEffect()); + this.getSpellAbility().addEffect(new DamageTargetEffect(new ManacostVariableValue())); this.getSpellAbility().addEffect(new RedSunsZenithEffect()); this.getSpellAbility().addEffect(ShuffleSpellEffect.getInstance()); - this.addWatcher(new RedSunsZenithWatcher()); + this.addWatcher(new DamagedByWatcher()); } public RedSunsZenith(final RedSunsZenith card) { @@ -109,42 +106,12 @@ class RedSunsZenithEffect extends ReplacementEffectImpl { @Override public boolean applies(GameEvent event, Ability source, Game game) { - if (event.getType() == EventType.ZONE_CHANGE && - ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD && - ((ZoneChangeEvent)event).getFromZone() == Zone.BATTLEFIELD) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "RedSunsZenithDamagedCreature"); - if (watcher != null) - return watcher.conditionMet(); + if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).isDiesEvent()) { + DamagedByWatcher watcher = (DamagedByWatcher) game.getState().getWatchers().get("DamagedByWatcher", source.getSourceId()); + if (watcher != null) + return watcher.damagedCreatures.contains(event.getTargetId()); } return false; } } - -class RedSunsZenithWatcher extends WatcherImpl { - - public RedSunsZenithWatcher() { - super("RedSunsZenithDamagedCreature"); - } - - public RedSunsZenithWatcher(final RedSunsZenithWatcher watcher) { - super(watcher); - } - - @Override - public RedSunsZenithWatcher copy() { - return new RedSunsZenithWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - if (condition == true) //no need to check - condition has already occured - return; - if (event.getType() == EventType.DAMAGED_CREATURE) { - Card card = game.getCard(sourceId); - if (card != null && card.getSpellAbility().getId().equals(event.getSourceId())) - condition = true; - } - } - -} diff --git a/Mage.Sets/src/mage/sets/newphyrexia/CathedralMembrane.java b/Mage.Sets/src/mage/sets/newphyrexia/CathedralMembrane.java index a964d02e10..5eb97f8738 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/CathedralMembrane.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/CathedralMembrane.java @@ -27,8 +27,10 @@ */ package mage.sets.newphyrexia; +import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; @@ -36,12 +38,14 @@ import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; import mage.Constants.TurnPhase; +import mage.Constants.WatcherScope; import mage.Constants.Zone; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.ZoneChangeTriggeredAbility; import mage.abilities.effects.OneShotEffect; import mage.abilities.keyword.DefenderAbility; +import mage.cards.Card; import mage.cards.CardImpl; import mage.game.Game; import mage.game.events.GameEvent; @@ -127,10 +131,9 @@ class CathedralMembraneEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - CathedralMembraneWatcher watcher = (CathedralMembraneWatcher) game.getState().getWatchers().get(source.getControllerId(), "CathedralMembraneWatcher"); - if (watcher != null && watcher.blockedCreatures.containsKey(source.getSourceId())) { - Set creatures = watcher.blockedCreatures.get(source.getSourceId()); - for (UUID uuid : creatures) { + CathedralMembraneWatcher watcher = (CathedralMembraneWatcher) game.getState().getWatchers().get("CathedralMembraneWatcher", source.getSourceId()); + if (watcher != null) { + for (UUID uuid : watcher.blockedCreatures) { Permanent permanent = game.getPermanent(uuid); if (permanent != null) { permanent.damage(6, source.getSourceId(), game, true, false); @@ -143,14 +146,15 @@ class CathedralMembraneEffect extends OneShotEffect { class CathedralMembraneWatcher extends WatcherImpl { - public Map> blockedCreatures = new HashMap>(); + public List blockedCreatures = new ArrayList(); public CathedralMembraneWatcher() { - super("CathedralMembraneWatcher"); + super("CathedralMembraneWatcher", WatcherScope.CARD); } public CathedralMembraneWatcher(final CathedralMembraneWatcher watcher) { super(watcher); + this.blockedCreatures = watcher.blockedCreatures; } @Override @@ -161,13 +165,8 @@ class CathedralMembraneWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { if (event.getType() == GameEvent.EventType.BLOCKER_DECLARED && event.getSourceId().equals(sourceId)) { - Set creatures = blockedCreatures.get(sourceId); - if (creatures != null) { - creatures.add(event.getTargetId()); - } else { - creatures = new HashSet(); - creatures.add(event.getTargetId()); - blockedCreatures.put(sourceId, creatures); + if (!blockedCreatures.contains(event.getTargetId())) { + blockedCreatures.add(event.getTargetId()); } } } diff --git a/Mage.Sets/src/mage/sets/newphyrexia/FreshMeat.java b/Mage.Sets/src/mage/sets/newphyrexia/FreshMeat.java index e87e60bcd2..0c7326d0ea 100644 --- a/Mage.Sets/src/mage/sets/newphyrexia/FreshMeat.java +++ b/Mage.Sets/src/mage/sets/newphyrexia/FreshMeat.java @@ -29,11 +29,12 @@ package mage.sets.newphyrexia; import java.util.UUID; import mage.Constants.CardType; -import mage.Constants.Outcome; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.Constants.Zone; import mage.abilities.Ability; -import mage.abilities.effects.OneShotEffect; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.effects.common.CreateTokenEffect; import mage.cards.Card; import mage.cards.CardImpl; import mage.game.Game; @@ -56,7 +57,7 @@ public class FreshMeat extends CardImpl { this.color.setGreen(true); this.addWatcher(new FreshMeatWatcher()); - this.getSpellAbility().addEffect(new FreshMeatEffect()); + this.getSpellAbility().addEffect(new CreateTokenEffect(new BeastToken(), new FreshMeatDynamicValue())); } public FreshMeat(final FreshMeat card) { @@ -74,7 +75,7 @@ class FreshMeatWatcher extends WatcherImpl { private int creaturesCount = 0; public FreshMeatWatcher() { - super("CreaturesDiedFreshMeat"); + super("YourCreaturesDied", WatcherScope.PLAYER); condition = true; } @@ -94,9 +95,7 @@ class FreshMeatWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.ZONE_CHANGE - && ((ZoneChangeEvent) event).getFromZone() == Zone.BATTLEFIELD - && ((ZoneChangeEvent) event).getToZone() == Zone.GRAVEYARD) { + if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).isDiesEvent()) { Card card = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); if (card != null && card.getOwnerId().equals(this.controllerId) && card.getCardType().contains(CardType.CREATURE)) { creaturesCount++; @@ -111,28 +110,28 @@ class FreshMeatWatcher extends WatcherImpl { } } -class FreshMeatEffect extends OneShotEffect { +class FreshMeatDynamicValue implements DynamicValue { - public FreshMeatEffect() { - super(Outcome.PutCreatureInPlay); - this.staticText = "Put a 3/3 green Beast creature token onto the battlefield for each creature put into your graveyard from the battlefield this turn"; - } - - public FreshMeatEffect(final FreshMeatEffect effect) { - super(effect); + @Override + public int calculate(Game game, Ability sourceAbility) { + FreshMeatWatcher watcher = (FreshMeatWatcher) game.getState().getWatchers().get("YourCreaturesDied", sourceAbility.getControllerId()); + if (watcher != null) + return watcher.getCreaturesCount(); + return 0; } @Override - public FreshMeatEffect copy() { - return new FreshMeatEffect(this); + public FreshMeatDynamicValue clone() { + return new FreshMeatDynamicValue(); } @Override - public boolean apply(Game game, Ability source) { - FreshMeatWatcher watcher = (FreshMeatWatcher) game.getState().getWatchers().get(source.getControllerId(), "CreaturesDiedFreshMeat"); - int count = watcher.getCreaturesCount(); - BeastToken token = new BeastToken(); - token.putOntoBattlefield(count, game, source.getSourceId(), source.getControllerId()); - return true; + public String toString() { + return "1"; + } + + @Override + public String getMessage() { + return "for each creature put into your graveyard from the battlefield this turn"; } } diff --git a/Mage.Sets/src/mage/sets/riseoftheeldrazi/Vengevine.java b/Mage.Sets/src/mage/sets/riseoftheeldrazi/Vengevine.java index cd8b22eea2..a2a0d1e968 100644 --- a/Mage.Sets/src/mage/sets/riseoftheeldrazi/Vengevine.java +++ b/Mage.Sets/src/mage/sets/riseoftheeldrazi/Vengevine.java @@ -31,6 +31,7 @@ package mage.sets.riseoftheeldrazi; import java.util.UUID; import mage.Constants.CardType; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.Constants.Zone; import mage.MageInt; import mage.abilities.TriggeredAbilityImpl; @@ -92,10 +93,10 @@ class VengevineAbility extends TriggeredAbilityImpl { @Override public boolean checkTrigger(GameEvent event, Game game) { if (event.getType() == EventType.SPELL_CAST && event.getPlayerId().equals(controllerId)) { - Watcher watcher = game.getState().getWatchers().get(controllerId, "CreatureCast"); - if (watcher != null && watcher.conditionMet()) { - return true; - } + Watcher watcher = game.getState().getWatchers().get("CreatureCast", controllerId); + if (watcher != null && watcher.conditionMet()) { + return true; + } } return false; } @@ -113,11 +114,12 @@ class VengevineWatcher extends WatcherImpl { int creatureSpellCount = 0; public VengevineWatcher() { - super("CreatureCast"); + super("CreatureCast", WatcherScope.PLAYER); } public VengevineWatcher(final VengevineWatcher watcher) { super(watcher); + this.creatureSpellCount = watcher.creatureSpellCount; } @Override diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/FleshAllergy.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/FleshAllergy.java index 8afdc83e9d..0a2581ae55 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/FleshAllergy.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/FleshAllergy.java @@ -33,6 +33,7 @@ import java.util.UUID; import mage.Constants.CardType; import mage.Constants.Outcome; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.costs.common.SacrificeTargetCost; @@ -83,7 +84,7 @@ class FleshAllergyWatcher extends WatcherImpl { public int creaturesDiedThisTurn = 0; public FleshAllergyWatcher() { - super("CreaturesDiedFleshAllergy"); + super("CreaturesDied", WatcherScope.GAME); } public FleshAllergyWatcher(final FleshAllergyWatcher watcher) { @@ -97,14 +98,11 @@ class FleshAllergyWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.ZONE_CHANGE) { - if (((ZoneChangeEvent)event).getFromZone() == Zone.BATTLEFIELD && - ((ZoneChangeEvent)event).getToZone() == Zone.GRAVEYARD) { - Card card = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); - if (card != null && card.getCardType().contains(CardType.CREATURE)) { - creaturesDiedThisTurn++; - } - } + if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).isDiesEvent()) { + Card card = game.getLastKnownInformation(event.getTargetId(), Zone.BATTLEFIELD); + if (card != null && card.getCardType().contains(CardType.CREATURE)) { + creaturesDiedThisTurn++; + } } } @@ -120,7 +118,7 @@ class FleshAllergyEffect extends OneShotEffect { public FleshAllergyEffect() { super(Outcome.DestroyPermanent); - staticText = "Destroy target creature. Its controller loses life equal to the number of creatures that died this turn"; + staticText = "Its controller loses life equal to the number of creatures that died this turn"; } public FleshAllergyEffect(final FleshAllergyEffect effect) { @@ -134,18 +132,18 @@ class FleshAllergyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "CreaturesDiedFleshAllergy"); - Card card = game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD); - if (card != null && watcher != null) { - Player player = game.getPlayer(((Permanent)card).getControllerId()); - if (player != null) { - int amount = ((FleshAllergyWatcher)watcher).creaturesDiedThisTurn; - if (amount > 0) { - player.loseLife(amount, game); - return true; - } - } - } + FleshAllergyWatcher watcher = (FleshAllergyWatcher) game.getState().getWatchers().get("CreaturesDied"); + Card card = game.getLastKnownInformation(source.getFirstTarget(), Zone.BATTLEFIELD); + if (card != null && watcher != null) { + Player player = game.getPlayer(((Permanent)card).getControllerId()); + if (player != null) { + int amount = watcher.creaturesDiedThisTurn; + if (amount > 0) { + player.loseLife(amount, game); + return true; + } + } + } return false; } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/MoltenPsyche.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/MoltenPsyche.java index 8125e0063a..9250f945f9 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/MoltenPsyche.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/MoltenPsyche.java @@ -29,10 +29,12 @@ package mage.sets.scarsofmirrodin; import java.util.HashMap; import java.util.Map; +import java.util.Map.Entry; import java.util.UUID; import mage.Constants.CardType; import mage.Constants.Outcome; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.abilities.Ability; import mage.abilities.condition.common.MetalcraftCondition; import mage.abilities.effects.OneShotEffect; @@ -91,9 +93,9 @@ class MoltenPsycheEffect extends OneShotEffect { player.getHand().clear(); player.drawCards(count, game); if (MetalcraftCondition.getInstance().apply(game, source) && !playerId.equals(source.getControllerId())) { - MoltenPsycheWatcher watcher = (MoltenPsycheWatcher) game.getState().getWatchers().get(source.getControllerId(), "CardsDrawnMoltenPsyche"); - player.damage(watcher.getDraws(playerId), source.getId(), game, false, true); - } + MoltenPsycheWatcher watcher = (MoltenPsycheWatcher) game.getState().getWatchers().get("CardsDrawn"); + player.damage(watcher.getDraws(playerId), source.getId(), game, false, true); + } } } return true; @@ -111,11 +113,14 @@ class MoltenPsycheWatcher extends WatcherImpl { private Map draws = new HashMap(); public MoltenPsycheWatcher() { - super("CardsDrawnMoltenPsyche"); + super("CardsDrawn", WatcherScope.GAME); } public MoltenPsycheWatcher(final MoltenPsycheWatcher watcher) { super(watcher); + for (Entry entry: watcher.draws.entrySet()) { + draws.put(entry.getKey(), entry.getValue()); + } } @Override diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/SteelHellkite.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/SteelHellkite.java index 19dd4a51ab..e15227f12c 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/SteelHellkite.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/SteelHellkite.java @@ -47,6 +47,7 @@ import mage.game.permanent.Permanent; import mage.watchers.WatcherImpl; import java.util.*; +import mage.Constants.WatcherScope; /** * @author nantuko @@ -98,32 +99,34 @@ class SteelHellkiteDestroyEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - SteelHellkiteWatcher watcher = (SteelHellkiteWatcher) game.getState().getWatchers().get(source.getControllerId(), "SteelHellkiteWatcher"); - if (watcher != null && watcher.damagedPlayers.containsKey(source.getSourceId())) { - Set players = watcher.damagedPlayers.get(source.getSourceId()); - int xValue = source.getManaCostsToPay().getX(); - for (UUID uuid : players) { - for (Permanent permanent: game.getBattlefield().getAllActivePermanents()) { - if (permanent.getControllerId().equals(uuid) && permanent.getManaCost().convertedManaCost() == xValue) { - permanent.destroy(source.getId(), game, false); - } - } - } - } - return true; + SteelHellkiteWatcher watcher = (SteelHellkiteWatcher) game.getState().getWatchers().get("SteelHellkiteWatcher", source.getSourceId()); + if (watcher != null) { + int xValue = source.getManaCostsToPay().getX(); + for (UUID uuid : watcher.damagedPlayers) { + for (Permanent permanent: game.getBattlefield().getAllActivePermanents()) { + if (permanent.getControllerId().equals(uuid) && permanent.getManaCost().convertedManaCost() == xValue) { + permanent.destroy(source.getId(), game, false); + } + } + } + } + return true; } } class SteelHellkiteWatcher extends WatcherImpl { - public Map> damagedPlayers = new HashMap>(); + public List damagedPlayers = new ArrayList(); public SteelHellkiteWatcher() { - super("SteelHellkiteWatcher"); + super("SteelHellkiteWatcher", WatcherScope.CARD); } public SteelHellkiteWatcher(final SteelHellkiteWatcher watcher) { super(watcher); + for (UUID playerId: watcher.damagedPlayers) { + damagedPlayers.add(playerId); + } } @Override @@ -138,14 +141,9 @@ class SteelHellkiteWatcher extends WatcherImpl { UUID sourceId = damageEvent.getSourceId(); Permanent permanent = game.getPermanent(sourceId); if (sourceId != null && permanent != null && permanent.getName().equals("Steel Hellkite")) { - Set players = damagedPlayers.get(sourceId); - if (players != null) { - players.add(damageEvent.getPlayerId()); - } else { - players = new HashSet(); - players.add(damageEvent.getPlayerId()); - damagedPlayers.put(sourceId, players); - } + if (!damagedPlayers.contains(event.getTargetId())) { + damagedPlayers.add(event.getTargetId()); + } } } } diff --git a/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.java b/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.java index 52df2e7332..e2d16a5640 100644 --- a/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.java +++ b/Mage.Sets/src/mage/sets/scarsofmirrodin/TunnelIgnus.java @@ -28,6 +28,9 @@ package mage.sets.scarsofmirrodin; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; import mage.Constants; import mage.Constants.CardType; import mage.Constants.Rarity; @@ -41,10 +44,10 @@ import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; import mage.target.targetpointer.FixedTarget; -import mage.watchers.Watcher; import mage.watchers.WatcherImpl; import java.util.UUID; +import mage.Constants.WatcherScope; /** * @author Loki @@ -74,15 +77,17 @@ public class TunnelIgnus extends CardImpl { } class TunnelIgnusWatcher extends WatcherImpl { - int count = 0; + protected Map counts = new HashMap(); public TunnelIgnusWatcher() { - super("LandPlayedCount"); + super("LandPlayedCount", WatcherScope.PLAYER); } public TunnelIgnusWatcher(final TunnelIgnusWatcher watcher) { super(watcher); - this.count = watcher.count; + for (Entry entry: watcher.counts.entrySet()) { + counts.put(entry.getKey(), entry.getValue()); + } } @Override @@ -92,15 +97,14 @@ class TunnelIgnusWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (condition == true) //no need to check - condition has already occured - return; if (event.getType() == GameEvent.EventType.ZONE_CHANGE && ((ZoneChangeEvent) event).getToZone() == Constants.Zone.BATTLEFIELD) { Permanent permanent = game.getPermanent(event.getTargetId()); if (permanent.getCardType().contains(CardType.LAND) && game.getOpponents(this.controllerId).contains(permanent.getControllerId())) { - count++; - if (count > 1) { - condition = true; + int count = 1; + if (counts.containsKey(permanent.getControllerId())) { + count += counts.get(permanent.getControllerId()); } + counts.put(permanent.getControllerId(), count); } } } @@ -108,7 +112,7 @@ class TunnelIgnusWatcher extends WatcherImpl { @Override public void reset() { super.reset(); - count = 0; + counts.clear(); } } @@ -128,18 +132,18 @@ class TunnelIgnusTriggeredAbility extends TriggeredAbilityImpl 1) { for (Effect effect : this.getEffects()) { effect.setTargetPointer(new FixedTarget(permanent.getControllerId())); } return true; } + return false; } - return false; } return false; } diff --git a/Mage.Sets/src/mage/sets/worldwake/Groundswell.java b/Mage.Sets/src/mage/sets/worldwake/Groundswell.java index 194e65e358..020e411a74 100644 --- a/Mage.Sets/src/mage/sets/worldwake/Groundswell.java +++ b/Mage.Sets/src/mage/sets/worldwake/Groundswell.java @@ -39,6 +39,7 @@ import mage.Constants.SubLayer; import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.effects.ContinuousEffectImpl; +import mage.cards.Card; import mage.cards.CardImpl; import mage.game.Game; import mage.game.events.GameEvent; @@ -63,7 +64,7 @@ public class Groundswell extends CardImpl { this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addEffect(new GroundswellEffect(Duration.EndOfTurn)); - this.addWatcher(new GroundswellWatcher()); + this.addWatcher(new LandfallWatcher()); } public Groundswell(final Groundswell card) { @@ -76,34 +77,6 @@ public class Groundswell extends CardImpl { } } -class GroundswellWatcher extends WatcherImpl { - - public GroundswellWatcher() { - super("LandPlayed"); - } - - public GroundswellWatcher(final GroundswellWatcher watcher) { - super(watcher); - } - - @Override - public GroundswellWatcher copy() { - return new GroundswellWatcher(this); - } - - @Override - public void watch(GameEvent event, Game game) { - if (condition == true) //no need to check - condition has already occured - return; - if (event.getType() == EventType.ZONE_CHANGE && ((ZoneChangeEvent)event).getToZone() == Zone.BATTLEFIELD) { - Permanent permanent = game.getPermanent(event.getTargetId()); - if (permanent.getCardType().contains(CardType.LAND) && permanent.getControllerId().equals(this.controllerId)) { - condition = true; - } - } - } -} - class GroundswellEffect extends ContinuousEffectImpl { public GroundswellEffect(Duration duration) { @@ -122,19 +95,19 @@ class GroundswellEffect extends ContinuousEffectImpl { @Override public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "LandPlayed"); - Permanent target = (Permanent) game.getPermanent(source.getFirstTarget()); - if (target != null) { - if (watcher != null && watcher.conditionMet()) { - target.addPower(4); - target.addToughness(4); - } - else{ - target.addPower(2); - target.addToughness(2); - } - return true; - } + Watcher watcher = game.getState().getWatchers().get("LandPlayed", source.getControllerId()); + Permanent target = (Permanent) game.getPermanent(source.getFirstTarget()); + if (target != null) { + if (watcher != null && watcher.conditionMet()) { + target.addPower(4); + target.addToughness(4); + } + else{ + target.addPower(2); + target.addToughness(2); + } + return true; + } return false; } diff --git a/Mage.Sets/src/mage/sets/worldwake/SearingBlaze.java b/Mage.Sets/src/mage/sets/worldwake/SearingBlaze.java index 30362d5153..bea3b4e507 100644 --- a/Mage.Sets/src/mage/sets/worldwake/SearingBlaze.java +++ b/Mage.Sets/src/mage/sets/worldwake/SearingBlaze.java @@ -34,6 +34,7 @@ import java.util.UUID; import mage.Constants.CardType; import mage.Constants.Outcome; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.Constants.Zone; import mage.MageObject; import mage.abilities.Ability; @@ -70,7 +71,7 @@ public class SearingBlaze extends CardImpl { this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new SearingBlazeTarget()); this.getSpellAbility().addEffect(new SearingBlazeEffect()); - this.addWatcher(new SearingBlazeWatcher()); + this.addWatcher(new LandfallWatcher()); } public SearingBlaze(final SearingBlaze card) { @@ -84,19 +85,19 @@ public class SearingBlaze extends CardImpl { } -class SearingBlazeWatcher extends WatcherImpl { +class LandfallWatcher extends WatcherImpl { - public SearingBlazeWatcher() { - super("LandPlayed"); + public LandfallWatcher() { + super("LandPlayed", WatcherScope.PLAYER); } - public SearingBlazeWatcher(final SearingBlazeWatcher watcher) { + public LandfallWatcher(final LandfallWatcher watcher) { super(watcher); } @Override - public SearingBlazeWatcher copy() { - return new SearingBlazeWatcher(this); + public LandfallWatcher copy() { + return new LandfallWatcher(this); } @Override @@ -131,26 +132,26 @@ class SearingBlazeEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "LandPlayed"); - Player player = game.getPlayer(source.getTargets().get(0).getFirstTarget()); - Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget()); - if (watcher != null && watcher.conditionMet()) { - if (player != null) { - player.damage(3, source.getSourceId(), game, false, true); - } - if (creature != null) { - creature.damage(3, source.getSourceId(), game, true, false); - } - } - else { - if (player != null) { - player.damage(1, source.getSourceId(), game, false, true); - } - if (creature != null) { - creature.damage(1, source.getSourceId(), game, true, false); - } - } - return true; + Watcher watcher = game.getState().getWatchers().get("LandPlayed", source.getControllerId()); + Player player = game.getPlayer(source.getTargets().get(0).getFirstTarget()); + Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget()); + if (watcher != null && watcher.conditionMet()) { + if (player != null) { + player.damage(3, source.getSourceId(), game, false, true); + } + if (creature != null) { + creature.damage(3, source.getSourceId(), game, true, false); + } + } + else { + if (player != null) { + player.damage(1, source.getSourceId(), game, false, true); + } + if (creature != null) { + creature.damage(1, source.getSourceId(), game, true, false); + } + } + return true; } } diff --git a/Mage.Sets/src/mage/sets/zendikar/ArchiveTrap.java b/Mage.Sets/src/mage/sets/zendikar/ArchiveTrap.java index 6daae91fb5..6f873b1dfb 100644 --- a/Mage.Sets/src/mage/sets/zendikar/ArchiveTrap.java +++ b/Mage.Sets/src/mage/sets/zendikar/ArchiveTrap.java @@ -43,6 +43,7 @@ import mage.watchers.Watcher; import mage.watchers.WatcherImpl; import java.util.UUID; +import mage.Constants.WatcherScope; /** * @author BetaSteward_at_googlemail.com @@ -73,7 +74,7 @@ public class ArchiveTrap extends CardImpl { class ArchiveTrapWatcher extends WatcherImpl { public ArchiveTrapWatcher() { - super("LibrarySearched"); + super("LibrarySearched", WatcherScope.PLAYER); } public ArchiveTrapWatcher(final ArchiveTrapWatcher watcher) { @@ -113,7 +114,7 @@ class ArchiveTrapAlternativeCost extends AlternativeCostImpl { class CobraTrapWatcher extends WatcherImpl { public CobraTrapWatcher() { - super("noncreature permanent destroyed"); + super("noncreature permanent destroyed", WatcherScope.PLAYER); } public CobraTrapWatcher(final CobraTrapWatcher watcher) { @@ -91,11 +93,7 @@ class CobraTrapWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.END_TURN_STEP_POST) { - condition = false; - } - if (condition == true) // no need to check - condition has already occured - { + if (condition == true) { // no need to check - condition has already occured return; } if (event.getType() == EventType.DESTROYED_PERMANENT @@ -110,8 +108,8 @@ class CobraTrapWatcher extends WatcherImpl { class CobraTrapAlternativeCost extends AlternativeCostImpl { public CobraTrapAlternativeCost() { - super("you may pay {0} rather than pay Cobra Trap's mana cost"); - this.add(new GenericManaCost(0)); + super("you may pay {G} rather than pay Cobra Trap's mana cost"); + this.add(new ColoredManaCost(ColoredManaSymbol.G)); } public CobraTrapAlternativeCost(final CobraTrapAlternativeCost cost) { @@ -125,7 +123,7 @@ class CobraTrapAlternativeCost extends AlternativeCostImpl { class MindbreakTrapWatcher extends WatcherImpl { - protected int spellCast; + private Map counts = new HashMap(); public MindbreakTrapWatcher() { - super("opponent cast three or more spells"); - spellCast = 0; + super("opponent cast three or more spells", WatcherScope.PLAYER); } public MindbreakTrapWatcher(final MindbreakTrapWatcher watcher) { super(watcher); - this.spellCast = watcher.spellCast; + for (Entry entry: watcher.counts.entrySet()) { + counts.put(entry.getKey(), entry.getValue()); + } } @Override @@ -97,24 +103,27 @@ class MindbreakTrapWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.END_TURN_STEP_POST) { - condition = false; - spellCast = 0; + if (condition == true) { // no need to check - condition has already occured return; } - if (condition == true) // no need to check - condition has already occured - { - return; - } - Logger.getAnonymousLogger().info(((Integer) spellCast).toString()); if (event.getType() == EventType.SPELL_CAST && game.getOpponents(controllerId).contains(event.getPlayerId())) { - spellCast++; - if (spellCast >= 3) { - condition = true; + int count = 1; + if (counts.containsKey(event.getPlayerId())) { + count += counts.get(event.getPlayerId()); + if (count >= 3) + condition = true; } + counts.put(event.getPlayerId(), count); } } + + @Override + public void reset() { + super.reset(); + counts.clear(); + } + } class MindbreakTrapAlternativeCost extends AlternativeCostImpl { @@ -135,7 +144,7 @@ class MindbreakTrapAlternativeCost extends AlternativeCostImpl{ MindbreakEffect(MindbreakEffect effect) { diff --git a/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java b/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java index 6417e451d9..08cd2c738a 100644 --- a/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java +++ b/Mage.Sets/src/mage/sets/zendikar/SummoningTrap.java @@ -34,6 +34,7 @@ import mage.Constants; import mage.Constants.CardType; import mage.Constants.Outcome; import mage.Constants.Rarity; +import mage.Constants.WatcherScope; import mage.Constants.Zone; import mage.abilities.Ability; import mage.abilities.costs.AlternativeCostImpl; @@ -93,7 +94,7 @@ public class SummoningTrap extends CardImpl { class SummoningTrapWatcher extends WatcherImpl { public SummoningTrapWatcher() { - super("CreatureSpellCountered"); + super("CreatureSpellCountered", WatcherScope.PLAYER); } public SummoningTrapWatcher(final SummoningTrapWatcher watcher) { @@ -107,11 +108,7 @@ class SummoningTrapWatcher extends WatcherImpl { @Override public void watch(GameEvent event, Game game) { - if (event.getType() == EventType.END_TURN_STEP_POST) { - condition = false; - } - if (condition == true) // no need to check - condition has already occured - { + if (condition == true) {// no need to check - condition has already occured return; } if (event.getType() == EventType.COUNTERED @@ -140,7 +137,7 @@ class SummoningTrapAlternativeCost extends AlternativeCostImpl PlaneswalkerTypes = new ArrayList() {{add("Ajani"); add("Bolas"); add("Chandra"); add("Elspeth");add("Garruk"); add("Jace"); add("Liliana"); add("Nissa"); add("Sarkhan"); add("Sorin"); add("Tezzeret");}}; diff --git a/Mage/src/mage/abilities/condition/common/MorbidCondition.java b/Mage/src/mage/abilities/condition/common/MorbidCondition.java index f6ccc9817b..e3f54f5fc7 100644 --- a/Mage/src/mage/abilities/condition/common/MorbidCondition.java +++ b/Mage/src/mage/abilities/condition/common/MorbidCondition.java @@ -45,7 +45,7 @@ public class MorbidCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "Morbid"); + Watcher watcher = game.getState().getWatchers().get("Morbid"); return watcher.conditionMet(); } } diff --git a/Mage/src/mage/abilities/condition/common/NoSpellsWereCastLastTurnCondition.java b/Mage/src/mage/abilities/condition/common/NoSpellsWereCastLastTurnCondition.java index efd7774e41..102f1ab9b1 100644 --- a/Mage/src/mage/abilities/condition/common/NoSpellsWereCastLastTurnCondition.java +++ b/Mage/src/mage/abilities/condition/common/NoSpellsWereCastLastTurnCondition.java @@ -45,7 +45,7 @@ public class NoSpellsWereCastLastTurnCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(source.getControllerId(), "CastSpellLastTurnWatcher"); + CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get("CastSpellLastTurnWatcher"); return watcher.getAmountOfSpellsCastOnPrevTurn() == 0; } } diff --git a/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java b/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java index 54316d37ab..f38e7ea6de 100644 --- a/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java +++ b/Mage/src/mage/abilities/condition/common/TwoOrMoreSpellsWereCastLastTurnCondition.java @@ -45,7 +45,7 @@ public class TwoOrMoreSpellsWereCastLastTurnCondition implements Condition { @Override public boolean apply(Game game, Ability source) { - CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get(source.getControllerId(), "CastSpellLastTurnWatcher"); + CastSpellLastTurnWatcher watcher = (CastSpellLastTurnWatcher) game.getState().getWatchers().get("CastSpellLastTurnWatcher"); return watcher.getAmountOfSpellsCastOnPrevTurn() >= 2; } } diff --git a/Mage/src/mage/abilities/keyword/BloodthirstAbility.java b/Mage/src/mage/abilities/keyword/BloodthirstAbility.java index 8fde2fb54e..4a4d98ebe4 100644 --- a/Mage/src/mage/abilities/keyword/BloodthirstAbility.java +++ b/Mage/src/mage/abilities/keyword/BloodthirstAbility.java @@ -7,7 +7,9 @@ import mage.abilities.effects.OneShotEffect; import mage.counters.CounterType; import mage.game.Game; import mage.game.permanent.Permanent; +import mage.players.Player; import mage.watchers.Watcher; +import mage.watchers.common.BloodthirstWatcher; /** * @@ -53,11 +55,14 @@ class BloodthirstEffect extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - Watcher watcher = game.getState().getWatchers().get(source.getControllerId(), "DamagedOpponents"); - if (watcher.conditionMet()) { - Permanent p = game.getPermanent(source.getSourceId()); - if (p != null) { - p.addCounters(CounterType.P1P1.createInstance(amount), game); + Player player = game.getPlayer(source.getControllerId()); + if (player != null) { + BloodthirstWatcher watcher = (BloodthirstWatcher) game.getState().getWatchers().get("DamagedOpponents", source.getControllerId()); + if (watcher.conditionMet()) { + Permanent p = game.getPermanent(source.getSourceId()); + if (p != null) { + p.addCounters(CounterType.P1P1.createInstance(amount), game); + } } } return false; diff --git a/Mage/src/mage/cards/Card.java b/Mage/src/mage/cards/Card.java index 36a8e72255..fe4bdf3aa5 100644 --- a/Mage/src/mage/cards/Card.java +++ b/Mage/src/mage/cards/Card.java @@ -54,7 +54,7 @@ public interface Card extends MageObject { public void addWatcher(Watcher watcher); public SpellAbility getSpellAbility(); public List getRules(); - public Watchers getWatchers(); + public List getWatchers(); public String getExpansionSetCode(); public void setExpansionSetCode(String expansionSetCode); public void setFaceDown(boolean value); diff --git a/Mage/src/mage/cards/CardImpl.java b/Mage/src/mage/cards/CardImpl.java index 1fa0a486af..812ad72584 100644 --- a/Mage/src/mage/cards/CardImpl.java +++ b/Mage/src/mage/cards/CardImpl.java @@ -35,6 +35,7 @@ import java.util.List; import java.util.UUID; import mage.Constants.CardType; +import mage.Constants.Outcome; import mage.Constants.Rarity; import mage.Constants.Zone; import mage.MageObjectImpl; @@ -50,7 +51,7 @@ import mage.game.events.ZoneChangeEvent; import mage.game.permanent.PermanentCard; import mage.game.stack.Spell; import mage.watchers.Watcher; -import mage.watchers.Watchers; +import mage.watchers.WatcherImpl; import org.apache.log4j.Logger; public abstract class CardImpl> extends MageObjectImpl implements Card { @@ -60,7 +61,7 @@ public abstract class CardImpl> extends MageObjectImpl protected UUID ownerId; protected int cardNumber; - protected Watchers watchers = new Watchers(); + protected List watchers = new ArrayList(); protected String expansionSetCode; protected Rarity rarity; protected boolean faceDown; @@ -97,7 +98,9 @@ public abstract class CardImpl> extends MageObjectImpl cardNumber = card.cardNumber; expansionSetCode = card.expansionSetCode; rarity = card.rarity; - watchers = card.watchers.copy(); + for (Watcher watcher: (List)card.watchers) { + this.watchers.add(watcher.copy()); + } faceDown = card.faceDown; canTransform = card.canTransform; @@ -112,7 +115,6 @@ public abstract class CardImpl> extends MageObjectImpl this.objectId = UUID.randomUUID(); this.abilities.newOriginalId(); this.abilities.setSourceId(objectId); - this.watchers.setSourceId(objectId); } public static Card createCard(String name) { @@ -190,10 +192,10 @@ public abstract class CardImpl> extends MageObjectImpl } @Override - public Watchers getWatchers() { + public List getWatchers() { return watchers; } - + @Override public void checkTriggers(Zone zone, GameEvent event, Game game) { for (TriggeredAbility ability : abilities.getTriggeredAbilities(zone)) { diff --git a/Mage/src/mage/game/GameImpl.java b/Mage/src/mage/game/GameImpl.java index 74277b6b5e..51ba6a0dbf 100644 --- a/Mage/src/mage/game/GameImpl.java +++ b/Mage/src/mage/game/GameImpl.java @@ -60,6 +60,7 @@ import mage.watchers.Watcher; import java.io.IOException; import java.io.Serializable; import java.util.*; +import java.util.Map.Entry; import mage.abilities.common.ChancellorAbility; import mage.abilities.mana.TriggeredManaAbility; @@ -159,7 +160,8 @@ public abstract class GameImpl> implements Game, Serializa gameCards.put(card.getId(), card); state.setZone(card.getId(), Zone.OUTSIDE); for (Watcher watcher: card.getWatchers()) { - watcher.setControllerId(ownerId); + watcher.setControllerId(ownerId); + watcher.setSourceId(card.getId()); state.getWatchers().add(watcher); } } diff --git a/Mage/src/mage/game/events/ZoneChangeEvent.java b/Mage/src/mage/game/events/ZoneChangeEvent.java index 51e4426292..f89530a461 100644 --- a/Mage/src/mage/game/events/ZoneChangeEvent.java +++ b/Mage/src/mage/game/events/ZoneChangeEvent.java @@ -78,4 +78,8 @@ public class ZoneChangeEvent extends GameEvent { public Permanent getTarget() { return target; } + + public boolean isDiesEvent() { + return (toZone == Zone.GRAVEYARD && fromZone == Zone.BATTLEFIELD); + } } diff --git a/Mage/src/mage/game/stack/Spell.java b/Mage/src/mage/game/stack/Spell.java index 33d3267961..331c21c15e 100644 --- a/Mage/src/mage/game/stack/Spell.java +++ b/Mage/src/mage/game/stack/Spell.java @@ -323,8 +323,8 @@ public class Spell> implements StackObject, Card { return card.getRules(); } - @Override - public Watchers getWatchers() { + @Override + public List getWatchers() { return card.getWatchers(); } diff --git a/Mage/src/mage/players/PlayerImpl.java b/Mage/src/mage/players/PlayerImpl.java index 8fe09176d9..76afaca509 100644 --- a/Mage/src/mage/players/PlayerImpl.java +++ b/Mage/src/mage/players/PlayerImpl.java @@ -73,7 +73,6 @@ import mage.game.stack.StackAbility; import mage.players.net.UserData; import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetDiscard; -import mage.watchers.Watcher; import mage.watchers.common.BloodthirstWatcher; public abstract class PlayerImpl> implements Player, Serializable { @@ -188,9 +187,7 @@ public abstract class PlayerImpl> implements Player, Ser this.passedTurn = false; this.canGainLife = true; this.canLoseLife = true; - Watcher bloodthirst = new BloodthirstWatcher(); - bloodthirst.setControllerId(playerId); - game.getState().getWatchers().add(bloodthirst); + game.getState().getWatchers().add(new BloodthirstWatcher(playerId)); } @Override diff --git a/Mage/src/mage/watchers/WatcherImpl.java b/Mage/src/mage/watchers/WatcherImpl.java index 91588736d3..814a7ac840 100644 --- a/Mage/src/mage/watchers/WatcherImpl.java +++ b/Mage/src/mage/watchers/WatcherImpl.java @@ -29,6 +29,7 @@ package mage.watchers; import java.util.UUID; +import mage.Constants.WatcherScope; /** * @@ -42,9 +43,11 @@ public abstract class WatcherImpl> implements Watcher> implements Watcher> implements Watcher { - - public Watchers copy() { - Watchers newCopy = new Watchers(); - for (Watcher watcher: this) { - newCopy.add(watcher.copy()); +public class Watchers extends HashMap { + + public Watchers() {} + + public Watchers(final Watchers watchers) { + for (Map.Entry entry: watchers.entrySet()) { + this.put(entry.getKey(), entry.getValue().copy()); } - return newCopy; + } + + public Watchers copy() { + return new Watchers(this); } - + + public void add(Watcher watcher) { + if (!this.containsKey(watcher.getKey())) + this.put(watcher.getKey(), watcher); + } + public void watch(GameEvent event, Game game) { - for (Watcher watcher: this) { + for (Watcher watcher: this.values()) { watcher.watch(event, game); } } public void reset() { - for (Watcher watcher: this) { + for (Watcher watcher: this.values()) { watcher.reset(); } } - public void setSourceId(UUID sourceId) { - for (Watcher watcher: this) { - watcher.setSourceId(sourceId); - } +// public void setSourceId(UUID sourceId) { +// for (Watcher watcher: this.values()) { +// watcher.setSourceId(sourceId); +// } +// } +// +// public void setControllerId(UUID controllerId) { +// for (Watcher watcher: this.values()) { +// watcher.setControllerId(controllerId); +// } +// } + + public Watcher get(String key, UUID id) { + return this.get(id + key); } - public void setControllerId(UUID controllerId) { - for (Watcher watcher: this) { - watcher.setControllerId(controllerId); - } - } - - public Watcher get(UUID controllerId, String key) { - for (Watcher watcher: this) { - if ((watcher.getControllerId() == null || watcher.getControllerId().equals(controllerId)) && watcher.getKey().equals(key)) - return watcher; - } - return null; - } +// public Watcher get(UUID controllerId, UUID sourceId, String key) { +// for (Watcher watcher: this) { +// if ((watcher.getControllerId() == null || watcher.getControllerId().equals(controllerId)) && watcher.getKey().equals(key) && watcher.getSourceId().equals(sourceId)) +// return watcher; +// } +// return null; +// } } diff --git a/Mage/src/mage/watchers/common/BloodthirstWatcher.java b/Mage/src/mage/watchers/common/BloodthirstWatcher.java index acf73d5073..080f9b7d38 100644 --- a/Mage/src/mage/watchers/common/BloodthirstWatcher.java +++ b/Mage/src/mage/watchers/common/BloodthirstWatcher.java @@ -1,5 +1,7 @@ package mage.watchers.common; +import java.util.UUID; +import mage.Constants.WatcherScope; import mage.game.Game; import mage.game.events.DamagedPlayerEvent; import mage.game.events.GameEvent; @@ -10,8 +12,9 @@ import mage.watchers.WatcherImpl; * @author Loki */ public class BloodthirstWatcher extends WatcherImpl { - public BloodthirstWatcher() { - super("DamagedOpponents"); + public BloodthirstWatcher(UUID controllerId) { + super("DamagedOpponents", WatcherScope.PLAYER); + this.controllerId = controllerId; } public BloodthirstWatcher(final BloodthirstWatcher watcher) { diff --git a/Mage/src/mage/watchers/common/CastFromHandWatcher.java b/Mage/src/mage/watchers/common/CastFromHandWatcher.java index f3578b8e2c..c93c4e59c4 100644 --- a/Mage/src/mage/watchers/common/CastFromHandWatcher.java +++ b/Mage/src/mage/watchers/common/CastFromHandWatcher.java @@ -1,6 +1,7 @@ package mage.watchers.common; import mage.Constants; +import mage.Constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.stack.Spell; @@ -8,7 +9,7 @@ import mage.watchers.WatcherImpl; public class CastFromHandWatcher extends WatcherImpl { public CastFromHandWatcher() { - super("CastFromHand"); + super("CastFromHand", WatcherScope.CARD); } public CastFromHandWatcher(final CastFromHandWatcher watcher) { diff --git a/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java b/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java index 06720ca1ea..3f98608d26 100644 --- a/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java +++ b/Mage/src/mage/watchers/common/CastSpellLastTurnWatcher.java @@ -28,6 +28,7 @@ package mage.watchers.common; +import mage.Constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; import mage.watchers.WatcherImpl; @@ -42,7 +43,7 @@ public class CastSpellLastTurnWatcher extends WatcherImpl { + + public List damagedCreatures = new ArrayList(); + + public DamagedByWatcher() { + super("DamagedByWatcher", WatcherScope.CARD); + } + + public DamagedByWatcher(final DamagedByWatcher watcher) { + super(watcher); + this.damagedCreatures = watcher.damagedCreatures; + } + + @Override + public DamagedByWatcher copy() { + return new DamagedByWatcher(this); + } + + @Override + public void watch(GameEvent event, Game game) { + if (event.getType() == EventType.DAMAGED_CREATURE) { + if (sourceId.equals(event.getSourceId()) && !damagedCreatures.contains(event.getTargetId())) { + damagedCreatures.add(event.getTargetId()); + } + } + } + + @Override + public void reset() { + super.reset(); + damagedCreatures.clear(); + } + +} diff --git a/Mage/src/mage/watchers/common/MorbidWatcher.java b/Mage/src/mage/watchers/common/MorbidWatcher.java index dedde9ec77..fc53c6d84f 100644 --- a/Mage/src/mage/watchers/common/MorbidWatcher.java +++ b/Mage/src/mage/watchers/common/MorbidWatcher.java @@ -30,6 +30,7 @@ package mage.watchers.common; import mage.Constants; import mage.Constants.CardType; +import mage.Constants.WatcherScope; import mage.game.Game; import mage.game.events.GameEvent; import mage.game.events.ZoneChangeEvent; @@ -43,7 +44,7 @@ import mage.watchers.WatcherImpl; public class MorbidWatcher extends WatcherImpl { public MorbidWatcher() { - super("Morbid"); + super("Morbid", WatcherScope.GAME); } public MorbidWatcher(final MorbidWatcher watcher) {