diff --git a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java index 4e4b5cb0505..ca79b17b9d7 100644 --- a/Mage.Sets/src/mage/cards/m/MairsilThePretender.java +++ b/Mage.Sets/src/mage/cards/m/MairsilThePretender.java @@ -27,21 +27,14 @@ */ package mage.cards.m; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Optional; -import java.util.Set; import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.ActivatedAbility; +import mage.abilities.ActivatedAbilityImpl; import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.SimpleStaticAbility; import mage.abilities.effects.ContinuousEffectImpl; -import mage.abilities.effects.ContinuousRuleModifyingEffectImpl; -import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; import mage.cards.Card; import mage.cards.CardImpl; @@ -54,7 +47,6 @@ import mage.constants.Outcome; import mage.constants.SubLayer; import mage.constants.SuperType; import mage.constants.TargetController; -import mage.constants.WatcherScope; import mage.constants.Zone; import mage.counters.CounterType; import mage.filter.FilterCard; @@ -63,15 +55,11 @@ import mage.filter.predicate.mageobject.CardTypePredicate; import mage.filter.predicate.other.CounterCardPredicate; import mage.filter.predicate.other.OwnerPredicate; import mage.game.Game; -import mage.game.events.GameEvent; -import mage.game.events.ZoneChangeEvent; import mage.game.permanent.Permanent; -import mage.game.stack.StackAbility; import mage.players.Player; import mage.target.Target; import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInYourGraveyard; -import mage.watchers.Watcher; /** * @@ -93,8 +81,9 @@ public class MairsilThePretender extends CardImpl { // Mairsil, the Pretender has all activated abilities of all cards you own in exile with cage counters on them. You may activate each of those abilities only once each turn. Ability ability = new SimpleStaticAbility(Zone.BATTLEFIELD, new MairsilThePretenderGainAbilitiesEffect()); - ability.addEffect(new MairsilThePretenderRuleModifyingEffect()); - this.addAbility(ability, new MairsilThePretenderWatcher()); + this.addAbility(ability); +// ability.addEffect(new MairsilThePretenderRuleModifyingEffect()); +// this.addAbility(ability, new MairsilThePretenderWatcher()); } public MairsilThePretender(final MairsilThePretender card) { @@ -182,11 +171,8 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl { if (filter.match(card, game)) { for (Ability ability : card.getAbilities()) { if (ability instanceof ActivatedAbility) { - UUID originaId = ability.getId(); - ActivatedAbility copyAbility = (ActivatedAbility) ability.copy(); - Effect effect = new DoNothingEffect(); - effect.setValue("key", originaId); - copyAbility.addEffect(effect); + ActivatedAbilityImpl copyAbility = (ActivatedAbilityImpl) ability.copy(); + copyAbility.setMaxActivationsPerTurn(1); perm.addAbility(copyAbility, card.getId(), game); } } @@ -203,134 +189,134 @@ class MairsilThePretenderGainAbilitiesEffect extends ContinuousEffectImpl { } } -class MairsilThePretenderWatcher extends Watcher { - - public final Map> activatedThisTurnAbilities = new HashMap<>(); - - public MairsilThePretenderWatcher() { - super(MairsilThePretenderWatcher.class.getSimpleName(), WatcherScope.GAME); - } - - public MairsilThePretenderWatcher(final MairsilThePretenderWatcher watcher) { - super(watcher); - for (Entry> entry : watcher.activatedThisTurnAbilities.entrySet()) { - activatedThisTurnAbilities.put(entry.getKey(), entry.getValue()); - } - } - - @Override - public void watch(GameEvent event, Game game) { - if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event instanceof ZoneChangeEvent) { - ZoneChangeEvent zEvent = (ZoneChangeEvent) event; - if (zEvent.getFromZone() == Zone.BATTLEFIELD) { - Permanent permanent = zEvent.getTarget(); - if (permanent != null) { - this.activatedThisTurnAbilities.remove(permanent.getId()); - } - } - } - if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { - Set permAbilities; - if (activatedThisTurnAbilities.keySet().contains(event.getSourceId())) { - permAbilities = activatedThisTurnAbilities.get(event.getSourceId()); - } else { - permAbilities = new HashSet<>(); - } - StackAbility ability = (StackAbility) game.getStack().getStackObject(event.getSourceId()); - if (ability != null && ability.getStackAbility().isActivated()) { - for (Effect effect : ability.getAllEffects()) { - if (effect instanceof DoNothingEffect) { - permAbilities.add((UUID) effect.getValue("key")); - this.activatedThisTurnAbilities.put(event.getSourceId(), permAbilities); - } - } - } - } - } - - @Override - public void reset() { - activatedThisTurnAbilities.clear(); - } - - public Map> getActivatedThisTurnAbilities() { - return this.activatedThisTurnAbilities; - } - - @Override - public MairsilThePretenderWatcher copy() { - return new MairsilThePretenderWatcher(this); - } - -} - -class MairsilThePretenderRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { - - public MairsilThePretenderRuleModifyingEffect() { - super(Duration.WhileOnBattlefield, Outcome.Detriment); - } - - public MairsilThePretenderRuleModifyingEffect(final MairsilThePretenderRuleModifyingEffect effect) { - super(effect); - } - - @Override - public MairsilThePretenderRuleModifyingEffect copy() { - return new MairsilThePretenderRuleModifyingEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } - - @Override - public boolean checksEventType(GameEvent event, Game game) { - return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; - } - - @Override - public boolean applies(GameEvent event, Ability source, Game game) { - Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); - MairsilThePretenderWatcher watcher = (MairsilThePretenderWatcher) game.getState().getWatchers().get(MairsilThePretenderWatcher.class.getSimpleName()); - if (watcher != null && ability != null && ability.isPresent()) { - for (Effect effect : ability.get().getAllEffects()) { - if (effect instanceof DoNothingEffect) { - UUID originalID = (UUID) effect.getValue("key"); - if (watcher.getActivatedThisTurnAbilities().keySet().contains(event.getSourceId())) { - if (watcher.getActivatedThisTurnAbilities().get(event.getSourceId()).contains(originalID)) { - return true; - } - } - } - } - } - return false; - } - - @Override - public String getInfoMessage(Ability source, GameEvent event, Game game) { - return "This ability can only be activated once each turn."; - } -} - -class DoNothingEffect extends OneShotEffect { - - DoNothingEffect() { - super(Outcome.Neutral); - } - - DoNothingEffect(final DoNothingEffect effect) { - super(effect); - } - - @Override - public DoNothingEffect copy() { - return new DoNothingEffect(this); - } - - @Override - public boolean apply(Game game, Ability source) { - return true; - } -} +//class MairsilThePretenderWatcher extends Watcher { +// +// public final Map> activatedThisTurnAbilities = new HashMap<>(); +// +// public MairsilThePretenderWatcher() { +// super(MairsilThePretenderWatcher.class.getSimpleName(), WatcherScope.GAME); +// } +// +// public MairsilThePretenderWatcher(final MairsilThePretenderWatcher watcher) { +// super(watcher); +// for (Entry> entry : watcher.activatedThisTurnAbilities.entrySet()) { +// activatedThisTurnAbilities.put(entry.getKey(), entry.getValue()); +// } +// } +// +// @Override +// public void watch(GameEvent event, Game game) { +// if (event.getType() == GameEvent.EventType.ZONE_CHANGE && event instanceof ZoneChangeEvent) { +// ZoneChangeEvent zEvent = (ZoneChangeEvent) event; +// if (zEvent.getFromZone() == Zone.BATTLEFIELD) { +// Permanent permanent = zEvent.getTarget(); +// if (permanent != null) { +// this.activatedThisTurnAbilities.remove(permanent.getId()); +// } +// } +// } +// if (event.getType() == GameEvent.EventType.ACTIVATED_ABILITY) { +// Set permAbilities; +// if (activatedThisTurnAbilities.keySet().contains(event.getSourceId())) { +// permAbilities = activatedThisTurnAbilities.get(event.getSourceId()); +// } else { +// permAbilities = new HashSet<>(); +// } +// StackAbility ability = (StackAbility) game.getStack().getStackObject(event.getSourceId()); +// if (ability != null && ability.getStackAbility().isActivated()) { +// for (Effect effect : ability.getAllEffects()) { +// if (effect instanceof DoNothingEffect) { +// permAbilities.add((UUID) effect.getValue("key")); +// this.activatedThisTurnAbilities.put(event.getSourceId(), permAbilities); +// } +// } +// } +// } +// } +// +// @Override +// public void reset() { +// activatedThisTurnAbilities.clear(); +// } +// +// public Map> getActivatedThisTurnAbilities() { +// return this.activatedThisTurnAbilities; +// } +// +// @Override +// public MairsilThePretenderWatcher copy() { +// return new MairsilThePretenderWatcher(this); +// } +// +//} +// +//class MairsilThePretenderRuleModifyingEffect extends ContinuousRuleModifyingEffectImpl { +// +// public MairsilThePretenderRuleModifyingEffect() { +// super(Duration.WhileOnBattlefield, Outcome.Detriment); +// } +// +// public MairsilThePretenderRuleModifyingEffect(final MairsilThePretenderRuleModifyingEffect effect) { +// super(effect); +// } +// +// @Override +// public MairsilThePretenderRuleModifyingEffect copy() { +// return new MairsilThePretenderRuleModifyingEffect(this); +// } +// +// @Override +// public boolean apply(Game game, Ability source) { +// return true; +// } +// +// @Override +// public boolean checksEventType(GameEvent event, Game game) { +// return event.getType() == GameEvent.EventType.ACTIVATE_ABILITY; +// } +// +// @Override +// public boolean applies(GameEvent event, Ability source, Game game) { +// Optional ability = game.getAbility(event.getTargetId(), event.getSourceId()); +// MairsilThePretenderWatcher watcher = (MairsilThePretenderWatcher) game.getState().getWatchers().get(MairsilThePretenderWatcher.class.getSimpleName()); +// if (watcher != null && ability != null && ability.isPresent()) { +// for (Effect effect : ability.get().getAllEffects()) { +// if (effect instanceof DoNothingEffect) { +// UUID originalID = (UUID) effect.getValue("key"); +// if (watcher.getActivatedThisTurnAbilities().keySet().contains(event.getSourceId())) { +// if (watcher.getActivatedThisTurnAbilities().get(event.getSourceId()).contains(originalID)) { +// return true; +// } +// } +// } +// } +// } +// return false; +// } +// +// @Override +// public String getInfoMessage(Ability source, GameEvent event, Game game) { +// return "This ability can only be activated once each turn."; +// } +//} +// +//class DoNothingEffect extends OneShotEffect { +// +// DoNothingEffect() { +// super(Outcome.Neutral); +// } +// +// DoNothingEffect(final DoNothingEffect effect) { +// super(effect); +// } +// +// @Override +// public DoNothingEffect copy() { +// return new DoNothingEffect(this); +// } +// +// @Override +// public boolean apply(Game game, Ability source) { +// return true; +// } +//} diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 5021a83896f..0bbca8ccfd7 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -29,6 +29,7 @@ package mage.abilities; import java.util.UUID; import mage.MageObject; +import mage.abilities.condition.Condition; import mage.abilities.costs.Cost; import mage.abilities.costs.Costs; import mage.abilities.costs.mana.ManaCosts; @@ -45,6 +46,7 @@ import mage.constants.Zone; import mage.game.Game; import mage.game.command.Emblem; import mage.game.permanent.Permanent; +import mage.util.CardUtil; /** * @@ -52,6 +54,19 @@ import mage.game.permanent.Permanent; */ public abstract class ActivatedAbilityImpl extends AbilityImpl implements ActivatedAbility { + static class ActivationInfo { + + public int turnNum; + public int activationCounter; + + public ActivationInfo(int turnNum, int activationCounter) { + this.turnNum = turnNum; + this.activationCounter = activationCounter; + } + } + + protected int maxActivationsPerTurn = Integer.MAX_VALUE; + protected Condition condition; protected TimingRule timing = TimingRule.INSTANT; protected TargetController mayActivate = TargetController.YOU; protected UUID activatorId; @@ -68,6 +83,8 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa mayActivate = ability.mayActivate; activatorId = ability.activatorId; checkPlayableMode = ability.checkPlayableMode; + maxActivationsPerTurn = ability.maxActivationsPerTurn; + condition = ability.condition; } public ActivatedAbilityImpl(Zone zone) { @@ -161,6 +178,9 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa @Override public boolean canActivate(UUID playerId, Game game) { //20091005 - 602.2 + if (!(hasMoreActivationsThisTurn(game) && (condition == null || condition.apply(game, this)))) { + return false; + } switch (mayActivate) { case ANY: break; @@ -255,4 +275,46 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa return checkPlayableMode; } + private boolean hasMoreActivationsThisTurn(Game game) { + ActivationInfo activationInfo = getActivationInfo(game); + return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn; + } + + @Override + public boolean activate(Game game, boolean noMana) { + if (hasMoreActivationsThisTurn(game)) { + if (super.activate(game, noMana)) { + ActivationInfo activationInfo = getActivationInfo(game); + if (activationInfo == null) { + activationInfo = new ActivationInfo(game.getTurnNum(), 1); + } else if (activationInfo.turnNum != game.getTurnNum()) { + activationInfo.turnNum = game.getTurnNum(); + activationInfo.activationCounter = 1; + } else { + activationInfo.activationCounter++; + } + setActivationInfo(activationInfo, game); + return true; + } + } + return false; + } + + public void setMaxActivationsPerTurn(int maxActivationsPerTurn) { + this.maxActivationsPerTurn = maxActivationsPerTurn; + } + + private ActivationInfo getActivationInfo(Game game) { + Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game)); + Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game)); + if (turnNum == null || activationCount == null) { + return null; + } + return new ActivationInfo(turnNum, activationCount); + } + + private void setActivationInfo(ActivationInfo activationInfo, Game game) { + game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum); + game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter); + } } diff --git a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java index 1e0753ce927..c44fe6cb163 100644 --- a/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/common/ActivateIfConditionActivatedAbility.java @@ -25,10 +25,8 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.common; -import java.util.UUID; import mage.abilities.ActivatedAbilityImpl; import mage.abilities.condition.Condition; import mage.abilities.condition.InvertCondition; @@ -43,8 +41,6 @@ import mage.game.Game; */ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl { - private final Condition condition; - public ActivateIfConditionActivatedAbility(Zone zone, Effect effect, Cost cost, Condition condition) { super(zone, effect, cost); this.condition = condition; @@ -52,31 +48,11 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl { public ActivateIfConditionActivatedAbility(ActivateIfConditionActivatedAbility ability) { super(ability); - this.condition = ability.condition; - } - - @Override - public boolean canActivate(UUID playerId, Game game) { - if (condition.apply(game, this)) { - return super.canActivate(playerId, game); - } - return false; - } - - @Override - public boolean activate(Game game, boolean noMana) { - if (canActivate(this.controllerId, game)) { - return super.activate(game, noMana); - } - return false; } @Override public boolean resolve(Game game) { - if (super.resolve(game)) { - return true; - } - return false; + return super.resolve(game); } @Override @@ -88,15 +64,15 @@ public class ActivateIfConditionActivatedAbility extends ActivatedAbilityImpl { sb.append(" Activate this ability only "); } if (condition.toString() != null) { - if (!condition.toString().startsWith("during") && - !condition.toString().startsWith("before")) { + if (!condition.toString().startsWith("during") + && !condition.toString().startsWith("before")) { sb.append("if "); } sb.append(condition.toString()).append('.'); } else { sb.append(" [Condition toString() == null] "); } - return sb.toString() ; + return sb.toString(); } @Override diff --git a/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java index 4e42a1678c3..3358d9dd9f7 100644 --- a/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java +++ b/Mage/src/main/java/mage/abilities/common/LimitedTimesPerTurnActivatedAbility.java @@ -36,28 +36,12 @@ import mage.constants.Zone; import mage.game.Game; import mage.util.CardUtil; -import java.util.UUID; - /** * * @author BetaSteward_at_googlemail.com */ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl { - static class ActivationInfo { - - public int turnNum; - public int activationCounter; - - public ActivationInfo(int turnNum, int activationCounter) { - this.turnNum = turnNum; - this.activationCounter = activationCounter; - } - } - - private int maxActivationsPerTurn; - private Condition condition; - public LimitedTimesPerTurnActivatedAbility(Zone zone, Effect effect, Cost cost) { this(zone, effect, cost, 1); } @@ -78,38 +62,6 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl { this.condition = ability.condition; } - @Override - public boolean canActivate(UUID playerId, Game game) { - return super.canActivate(playerId, game) - && hasMoreActivationsThisTurn(game) - && (condition == null || condition.apply(game, this)); - } - - private boolean hasMoreActivationsThisTurn(Game game) { - ActivationInfo activationInfo = getActivationInfo(game); - return activationInfo == null || activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < maxActivationsPerTurn; - } - - @Override - public boolean activate(Game game, boolean noMana) { - if (hasMoreActivationsThisTurn(game)) { - if (super.activate(game, noMana)) { - ActivationInfo activationInfo = getActivationInfo(game); - if (activationInfo == null) { - activationInfo = new ActivationInfo(game.getTurnNum(), 1); - } else if (activationInfo.turnNum != game.getTurnNum()) { - activationInfo.turnNum = game.getTurnNum(); - activationInfo.activationCounter = 1; - } else { - activationInfo.activationCounter++; - } - setActivationInfo(activationInfo, game); - return true; - } - } - return false; - } - @Override public boolean resolve(Game game) { return super.resolve(game); @@ -142,18 +94,4 @@ public class LimitedTimesPerTurnActivatedAbility extends ActivatedAbilityImpl { public LimitedTimesPerTurnActivatedAbility copy() { return new LimitedTimesPerTurnActivatedAbility(this); } - - private ActivationInfo getActivationInfo(Game game) { - Integer turnNum = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game)); - Integer activationCount = (Integer) game.getState().getValue(CardUtil.getCardZoneString("activationsCount", sourceId, game)); - if (turnNum == null || activationCount == null) { - return null; - } - return new ActivationInfo(turnNum, activationCount); - } - - private void setActivationInfo(ActivationInfo activationInfo, Game game) { - game.getState().setValue(CardUtil.getCardZoneString("activationsTurn", sourceId, game), activationInfo.turnNum); - game.getState().setValue(CardUtil.getCardZoneString("activationsCount", sourceId, game), activationInfo.activationCounter); - } }