diff --git a/Mage.Sets/src/mage/cards/b/BergStrider.java b/Mage.Sets/src/mage/cards/b/BergStrider.java index b6cdb6361bf..69d499481a4 100644 --- a/Mage.Sets/src/mage/cards/b/BergStrider.java +++ b/Mage.Sets/src/mage/cards/b/BergStrider.java @@ -46,7 +46,7 @@ public final class BergStrider extends CardImpl { Ability ability = new EntersBattlefieldTriggeredAbility(new TapTargetEffect()); ability.addEffect(new BergStriderEffect()); ability.addTarget(new TargetPermanent(filter)); - this.addAbility(ability, new ManaPaidSourceWatcher()); + this.addAbility(ability); } private BergStrider(final BergStrider card) { diff --git a/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java b/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java index 37530182fe6..204ccb62308 100644 --- a/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java +++ b/Mage.Sets/src/mage/cards/b/BlessingOfFrost.java @@ -34,7 +34,6 @@ public final class BlessingOfFrost extends CardImpl { // Distribute X +1/+1 counters among any number of creatures you control, where X is the amount of {S} spent to cast this spell. Then draw a card for each creature you control with power 4 or greater. this.getSpellAbility().addEffect(new BlessingOfFrostEffect()); - this.getSpellAbility().addWatcher(new ManaPaidSourceWatcher()); } private BlessingOfFrost(final BlessingOfFrost card) { diff --git a/Mage.Sets/src/mage/cards/b/BloodOnTheSnow.java b/Mage.Sets/src/mage/cards/b/BloodOnTheSnow.java index 878200fb34f..6b95b374b25 100644 --- a/Mage.Sets/src/mage/cards/b/BloodOnTheSnow.java +++ b/Mage.Sets/src/mage/cards/b/BloodOnTheSnow.java @@ -45,7 +45,6 @@ public final class BloodOnTheSnow extends CardImpl { "Then return a creature or planeswalker card with mana value X or less" + " from your graveyard to the battlefield, where X is the amount of {S} spent to cast this spell." ); - this.getSpellAbility().addWatcher(new ManaPaidSourceWatcher()); } private BloodOnTheSnow(final BloodOnTheSnow card) { diff --git a/Mage.Sets/src/mage/cards/b/BorealOutrider.java b/Mage.Sets/src/mage/cards/b/BorealOutrider.java index f639e2aad9d..daa40fa08a5 100644 --- a/Mage.Sets/src/mage/cards/b/BorealOutrider.java +++ b/Mage.Sets/src/mage/cards/b/BorealOutrider.java @@ -41,7 +41,7 @@ public final class BorealOutrider extends CardImpl { ), BorealOutriderCondition.instance, "Whenever you cast a creature spell, " + "if {S} of any of that spell's colors was spent to cast it, that creature " + "enters the battlefield with an additional +1/+1 counter on it." - ), new ManaPaidSourceWatcher()); + )); } private BorealOutrider(final BorealOutrider card) { diff --git a/Mage.Sets/src/mage/cards/d/DevourIntellect.java b/Mage.Sets/src/mage/cards/d/DevourIntellect.java index 52249ff28b2..6a40c895f93 100644 --- a/Mage.Sets/src/mage/cards/d/DevourIntellect.java +++ b/Mage.Sets/src/mage/cards/d/DevourIntellect.java @@ -30,7 +30,6 @@ public final class DevourIntellect extends CardImpl { TreasureSpentToCastCondition.instance, "Target opponent discards a card. If mana from a Treasure was spent to cast this spell, instead that player reveals their hand, you choose a nonland card from it, then that player discards a card" )); - this.getSpellAbility().addWatcher(new ManaPaidSourceWatcher()); } private DevourIntellect(final DevourIntellect card) { diff --git a/Mage.Sets/src/mage/cards/f/ForswornPaladin.java b/Mage.Sets/src/mage/cards/f/ForswornPaladin.java index 517f4fb6f39..16ed68fd800 100644 --- a/Mage.Sets/src/mage/cards/f/ForswornPaladin.java +++ b/Mage.Sets/src/mage/cards/f/ForswornPaladin.java @@ -53,7 +53,7 @@ public final class ForswornPaladin extends CardImpl { ); ability.addEffect(new ForswornPaladinEffect()); ability.addTarget(new TargetCreaturePermanent()); - this.addAbility(ability, new ManaPaidSourceWatcher()); + this.addAbility(ability); } private ForswornPaladin(final ForswornPaladin card) { diff --git a/Mage.Sets/src/mage/cards/g/GravenLore.java b/Mage.Sets/src/mage/cards/g/GravenLore.java index daf9e0852ab..17cc7ff8ce3 100644 --- a/Mage.Sets/src/mage/cards/g/GravenLore.java +++ b/Mage.Sets/src/mage/cards/g/GravenLore.java @@ -25,7 +25,6 @@ public final class GravenLore extends CardImpl { // Scry X, where is the amount of {S} spent to cast this spell, then draw three cards. this.getSpellAbility().addEffect(new GravenLoreEffect()); - this.getSpellAbility().addWatcher(new ManaPaidSourceWatcher()); } private GravenLore(final GravenLore card) { diff --git a/Mage.Sets/src/mage/cards/h/HiredHexblade.java b/Mage.Sets/src/mage/cards/h/HiredHexblade.java index 0ce856116e3..a6b93fb81e3 100644 --- a/Mage.Sets/src/mage/cards/h/HiredHexblade.java +++ b/Mage.Sets/src/mage/cards/h/HiredHexblade.java @@ -35,7 +35,7 @@ public final class HiredHexblade extends CardImpl { "if mana from a Treasure was spent to cast it, you draw a card and you lose 1 life." ); ability.addEffect(new LoseLifeSourceControllerEffect(1)); - this.addAbility(ability, new ManaPaidSourceWatcher()); + this.addAbility(ability); } private HiredHexblade(final HiredHexblade card) { diff --git a/Mage.Sets/src/mage/cards/j/JadedSellSword.java b/Mage.Sets/src/mage/cards/j/JadedSellSword.java index a66afed466e..ab9ee5432da 100644 --- a/Mage.Sets/src/mage/cards/j/JadedSellSword.java +++ b/Mage.Sets/src/mage/cards/j/JadedSellSword.java @@ -40,7 +40,7 @@ public final class JadedSellSword extends CardImpl { ability.addEffect(new GainAbilitySourceEffect( HasteAbility.getInstance(), Duration.EndOfTurn )); - this.addAbility(ability, new ManaPaidSourceWatcher()); + this.addAbility(ability); } private JadedSellSword(final JadedSellSword card) { diff --git a/Mage.Sets/src/mage/cards/k/KalainReclusivePainter.java b/Mage.Sets/src/mage/cards/k/KalainReclusivePainter.java index 69ee7b4fc0f..28db8d60339 100644 --- a/Mage.Sets/src/mage/cards/k/KalainReclusivePainter.java +++ b/Mage.Sets/src/mage/cards/k/KalainReclusivePainter.java @@ -38,7 +38,7 @@ public final class KalainReclusivePainter extends CardImpl { this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new TreasureToken()))); // Other creatures you control enter the battlefield with an additional +1/+1 counter on them for each mana from a Treasure spent to cast them. - this.addAbility(new SimpleStaticAbility(new KalainReclusivePainterEffect()), new ManaPaidSourceWatcher()); + this.addAbility(new SimpleStaticAbility(new KalainReclusivePainterEffect())); } private KalainReclusivePainter(final KalainReclusivePainter card) { diff --git a/Mage.Sets/src/mage/cards/p/PriceOfLoyalty.java b/Mage.Sets/src/mage/cards/p/PriceOfLoyalty.java index 0b9616af8fb..1ffebefc744 100644 --- a/Mage.Sets/src/mage/cards/p/PriceOfLoyalty.java +++ b/Mage.Sets/src/mage/cards/p/PriceOfLoyalty.java @@ -34,7 +34,6 @@ public final class PriceOfLoyalty extends CardImpl { ).setText("It gains haste until end of turn.")); this.getSpellAbility().addEffect(new PriceOfLoyaltyEffect()); this.getSpellAbility().addTarget(new TargetCreaturePermanent()); - this.getSpellAbility().addWatcher(new ManaPaidSourceWatcher()); } private PriceOfLoyalty(final PriceOfLoyalty card) { diff --git a/Mage.Sets/src/mage/cards/s/SearchForGlory.java b/Mage.Sets/src/mage/cards/s/SearchForGlory.java index 3d83b60d91f..7fafe894890 100644 --- a/Mage.Sets/src/mage/cards/s/SearchForGlory.java +++ b/Mage.Sets/src/mage/cards/s/SearchForGlory.java @@ -42,7 +42,6 @@ public final class SearchForGlory extends CardImpl { this.getSpellAbility().addEffect(new GainLifeEffect( SnowManaSpentValue.instance ).setText("You gain 1 life for each {S} spent to cast this spell")); - this.getSpellAbility().addWatcher(new ManaPaidSourceWatcher()); } private SearchForGlory(final SearchForGlory card) { diff --git a/Mage.Sets/src/mage/cards/s/SpoilsOfTheHunt.java b/Mage.Sets/src/mage/cards/s/SpoilsOfTheHunt.java index 7eb20251d30..9892cbd7d16 100644 --- a/Mage.Sets/src/mage/cards/s/SpoilsOfTheHunt.java +++ b/Mage.Sets/src/mage/cards/s/SpoilsOfTheHunt.java @@ -32,7 +32,6 @@ public final class SpoilsOfTheHunt extends CardImpl { )); this.getSpellAbility().addTarget(new TargetControlledCreaturePermanent()); this.getSpellAbility().addTarget(new TargetOpponentsCreaturePermanent()); - this.getSpellAbility().addWatcher(new ManaPaidSourceWatcher()); } private SpoilsOfTheHunt(final SpoilsOfTheHunt card) { diff --git a/Mage/src/main/java/mage/game/GameImpl.java b/Mage/src/main/java/mage/game/GameImpl.java index e6b60b5d74c..79d0d573c27 100644 --- a/Mage/src/main/java/mage/game/GameImpl.java +++ b/Mage/src/main/java/mage/game/GameImpl.java @@ -64,6 +64,8 @@ import mage.util.GameLog; import mage.util.MessageToClient; import mage.util.RandomUtil; import mage.util.functions.CopyApplier; +import mage.watchers.Watcher; +import mage.watchers.Watchers; import mage.watchers.common.*; import org.apache.log4j.Logger; @@ -1185,18 +1187,29 @@ public abstract class GameImpl implements Game, Serializable { } public void initGameDefaultWatchers() { - getState().addWatcher(new MorbidWatcher()); - getState().addWatcher(new CastSpellLastTurnWatcher()); - getState().addWatcher(new CastSpellYourLastTurnWatcher()); - getState().addWatcher(new PlayerLostLifeWatcher()); - getState().addWatcher(new PlayerLostLifeNonCombatWatcher()); - getState().addWatcher(new BlockedAttackerWatcher()); - getState().addWatcher(new DamageDoneWatcher()); - getState().addWatcher(new PlanarRollWatcher()); - getState().addWatcher(new AttackedThisTurnWatcher()); - getState().addWatcher(new PlayersAttackedThisTurnWatcher()); - getState().addWatcher(new CardsDrawnThisTurnWatcher()); - getState().addWatcher(new ManaSpentToCastWatcher()); + List newWatchers = new ArrayList<>(); + newWatchers.add(new MorbidWatcher()); + newWatchers.add(new CastSpellLastTurnWatcher()); + newWatchers.add(new CastSpellYourLastTurnWatcher()); + newWatchers.add(new PlayerLostLifeWatcher()); + newWatchers.add(new PlayerLostLifeNonCombatWatcher()); + newWatchers.add(new BlockedAttackerWatcher()); + newWatchers.add(new DamageDoneWatcher()); + newWatchers.add(new PlanarRollWatcher()); + newWatchers.add(new AttackedThisTurnWatcher()); + newWatchers.add(new PlayersAttackedThisTurnWatcher()); + newWatchers.add(new CardsDrawnThisTurnWatcher()); + newWatchers.add(new ManaSpentToCastWatcher()); + newWatchers.add(new ManaPaidSourceWatcher()); + + // runtime check - allows only GAME scope (one watcher per game) + newWatchers.forEach(watcher -> { + if (watcher.getScope().equals(WatcherScope.GAME)) { + throw new IllegalStateException("Game default watchers must have GAME scope: " + watcher.getClass().getCanonicalName()); + } + }); + + newWatchers.forEach(getState()::addWatcher); } public void initPlayerDefaultWatchers(UUID playerId) { diff --git a/Mage/src/main/java/mage/watchers/Watcher.java b/Mage/src/main/java/mage/watchers/Watcher.java index 96743ceeb5a..d12f796f806 100644 --- a/Mage/src/main/java/mage/watchers/Watcher.java +++ b/Mage/src/main/java/mage/watchers/Watcher.java @@ -169,4 +169,7 @@ public abstract class Watcher implements Serializable { return null; } + public WatcherScope getScope() { + return scope; + } } diff --git a/Mage/src/main/java/mage/watchers/common/ManaPaidSourceWatcher.java b/Mage/src/main/java/mage/watchers/common/ManaPaidSourceWatcher.java index 9305ebfaf22..f08c20e10eb 100644 --- a/Mage/src/main/java/mage/watchers/common/ManaPaidSourceWatcher.java +++ b/Mage/src/main/java/mage/watchers/common/ManaPaidSourceWatcher.java @@ -19,6 +19,8 @@ import java.util.Map; import java.util.UUID; /** + * Default watcher, no needs to add it to ability + * * @author TheElk801 */ public class ManaPaidSourceWatcher extends Watcher {