diff --git a/Mage.Sets/src/mage/cards/w/WookieeMystic.java b/Mage.Sets/src/mage/cards/w/WookieeMystic.java index 1d8f1d879d9..655ffc900a7 100644 --- a/Mage.Sets/src/mage/cards/w/WookieeMystic.java +++ b/Mage.Sets/src/mage/cards/w/WookieeMystic.java @@ -1,16 +1,12 @@ - package mage.cards.w; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; import mage.MageInt; import mage.MageObject; import mage.Mana; import mage.abilities.Ability; import mage.abilities.costs.common.TapSourceCost; -import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.effects.common.ManaEffect; +import mage.abilities.effects.mana.BasicManaEffect; import mage.abilities.mana.SimpleManaAbility; import mage.cards.CardImpl; import mage.cards.CardSetInfo; @@ -26,14 +22,17 @@ import mage.game.permanent.Permanent; import mage.game.stack.Spell; import mage.watchers.Watcher; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + /** - * * @author Styxo */ public final class WookieeMystic extends CardImpl { public WookieeMystic(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{R}{G}{W}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{R}{G}{W}"); this.subtype.add(SubType.WOOKIEE); this.subtype.add(SubType.SHAMAN); this.power = new MageInt(2); @@ -45,21 +44,21 @@ public final class WookieeMystic extends CardImpl { ManaEffect effect = new BasicManaEffect(mana); effect.setText("Add {R}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it"); Ability ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); - this.addAbility(ability, new WookieeMysticWatcher(ability)); + this.addAbility(ability, new WookieeMysticWatcher().withParams(ability)); mana = Mana.GreenMana(1); mana.setFlag(true); effect = new BasicManaEffect(mana); effect.setText("Add {G}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it"); ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); - this.addAbility(ability, new WookieeMysticWatcher(ability)); + this.addAbility(ability, new WookieeMysticWatcher().withParams(ability)); mana = Mana.WhiteMana(1); mana.setFlag(true); effect = new BasicManaEffect(mana); effect.setText("Add {W}. If that mana is spent on a creature spell, it enters the battlefield with a +1/+1 counter on it"); ability = new SimpleManaAbility(Zone.BATTLEFIELD, effect, new TapSourceCost()); - this.addAbility(ability, new WookieeMysticWatcher(ability)); + this.addAbility(ability, new WookieeMysticWatcher().withParams(ability)); } public WookieeMystic(final WookieeMystic card) { @@ -74,23 +73,16 @@ public final class WookieeMystic extends CardImpl { class WookieeMysticWatcher extends Watcher { - private final Ability source; - private final List creatures = new ArrayList<>(); + private Ability source; + private List creatures = new ArrayList<>(); - WookieeMysticWatcher(Ability source) { + WookieeMysticWatcher() { super(WatcherScope.CARD); + } + + Watcher withParams(Ability source) { this.source = source; - } - - WookieeMysticWatcher(final WookieeMysticWatcher watcher) { - super(watcher); - this.creatures.addAll(watcher.creatures); - this.source = watcher.source; - } - - @Override - public WookieeMysticWatcher copy() { - return new WookieeMysticWatcher(this); + return this; } @Override diff --git a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java index 4ea8fb15cb9..b3fcd37e40d 100644 --- a/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java +++ b/Mage.Verify/src/test/java/mage/verify/VerifyCardDataTest.java @@ -414,7 +414,7 @@ public class VerifyCardDataTest { } @Test - @Ignore // TODO: enable it on copy() methods removing + //@Ignore // TODO: enable it on copy() methods removing public void checkWatcherCopyMethods() { Collection errorsList = new ArrayList<>(); @@ -424,6 +424,13 @@ public class VerifyCardDataTest { Set> watcherClassesList = reflections.getSubTypesOf(Watcher.class); for (Class watcherClass : watcherClassesList) { + + // only watcher class can be extended (e.g. final) + if (!watcherClass.getSuperclass().equals(Watcher.class)) { + errorsList.add("error, only Watcher class can be extended: " + watcherClass.getName()); + } + + // no copy methods try { Method m = watcherClass.getMethod("copy"); if (!m.getGenericReturnType().getTypeName().equals("T")) { @@ -432,6 +439,34 @@ public class VerifyCardDataTest { } catch (NoSuchMethodException e) { errorsList.add("error, can't find copy() method in watcher class: " + watcherClass.getName()); } + + // no constructor for copy + try { + Constructor constructor = watcherClass.getDeclaredConstructor(watcherClass); + errorsList.add("error, copy constructor is not allowed in watcher class: " + watcherClass.getName()); + } catch (NoSuchMethodException e) { + // all fine, no needs in copy constructors + } + + // errors on create + try { + Constructor constructor = watcherClass.getDeclaredConstructor(); + constructor.setAccessible(true); + Watcher w1 = constructor.newInstance(); + + // errors on copy + try { + Watcher w2 = w1.copy(); + if (w2 == null) { + errorsList.add("error, can't copy watcher with unknown error, look at error logs above: " + watcherClass.getName()); + } + } catch (Exception e) { + errorsList.add("error, can't copy watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")"); + } + } catch (Exception e) { + errorsList.add("error, can't create watcher: " + watcherClass.getName() + " (" + e.getMessage() + ")"); + } + } printMessages(warningsList); diff --git a/Mage/src/main/java/mage/watchers/Watcher.java b/Mage/src/main/java/mage/watchers/Watcher.java index 05efdc76f39..1beb4e73930 100644 --- a/Mage/src/main/java/mage/watchers/Watcher.java +++ b/Mage/src/main/java/mage/watchers/Watcher.java @@ -1,10 +1,7 @@ - package mage.watchers; -import mage.Mana; import mage.constants.WatcherScope; import mage.game.Game; -import mage.game.turn.Step; import mage.game.events.GameEvent; import org.apache.log4j.Logger; @@ -26,8 +23,7 @@ public abstract class Watcher implements Serializable { protected UUID controllerId; protected UUID sourceId; protected boolean condition; - protected final WatcherScope scope; - + protected WatcherScope scope; public Watcher(WatcherScope scope) { this.scope = scope; @@ -81,11 +77,15 @@ public abstract class Watcher implements Serializable { return getClass().getSimpleName(); } + public void setScope(WatcherScope scope) { + this.scope = scope; + } + public abstract void watch(GameEvent event, Game game); public T copy() { try { - List constructors = Arrays.asList(this.getClass().getConstructors()); + List constructors = Arrays.asList(this.getClass().getDeclaredConstructors()); // needs private constructor if (constructors.size() > 1) { logger.error(getClass().getSimpleName() + " has multiple constructors"); return null; @@ -103,7 +103,7 @@ public abstract class Watcher implements Serializable { allFields.addAll(Arrays.asList(getClass().getSuperclass().getDeclaredFields())); for (Field field : allFields) { field.setAccessible(true); - if (field.getType() == Set.class) { + if (field.getType() == Set.class) { ((Set) field.get(watcher)).clear(); ((Set) field.get(watcher)).addAll((Set) field.get(this)); } else if (field.getType() == Map.class) {