From 9410434f050149bd8a9cc478e57391237fc15448 Mon Sep 17 00:00:00 2001 From: Daniel Bomar Date: Sun, 30 Oct 2022 21:28:56 -0500 Subject: [PATCH] [BRO] Implemented In the Trenches (#9704) --- Mage.Sets/src/mage/cards/i/InTheTrenches.java | 52 +++++++++++++++++++ Mage.Sets/src/mage/cards/s/SurgeEngine.java | 20 +------ Mage.Sets/src/mage/sets/TheBrothersWar.java | 1 + .../mage/abilities/ActivatedAbilityImpl.java | 29 ++++++++--- .../ActivateOncePerGameActivatedAbility.java | 40 ++++++++++++++ 5 files changed, 115 insertions(+), 27 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/i/InTheTrenches.java create mode 100644 Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java diff --git a/Mage.Sets/src/mage/cards/i/InTheTrenches.java b/Mage.Sets/src/mage/cards/i/InTheTrenches.java new file mode 100644 index 0000000000..a0d431020d --- /dev/null +++ b/Mage.Sets/src/mage/cards/i/InTheTrenches.java @@ -0,0 +1,52 @@ +package mage.cards.i; + +import java.util.UUID; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateOncePerGameActivatedAbility; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; +import mage.abilities.effects.common.ExileUntilSourceLeavesEffect; +import mage.abilities.effects.common.continuous.BoostControlledEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.common.FilterNonlandPermanent; +import mage.target.TargetPermanent; + +/** + * + * @author weirddan455 + */ +public final class InTheTrenches extends CardImpl { + + private static final FilterNonlandPermanent filter = new FilterNonlandPermanent("nonland permanent you don't control"); + + static { + filter.add(TargetController.NOT_YOU.getControllerPredicate()); + } + + public InTheTrenches(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{W}{W}"); + + // Creatures you control get +1/+1. + this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield))); + + // {5}{W}: Exile target nonland permanent you don't control until In the Trenches leaves the battlefield. Activate only as a sorcery and only once. + Ability ability = new ActivateOncePerGameActivatedAbility(Zone.BATTLEFIELD, new ExileUntilSourceLeavesEffect(), new ManaCostsImpl<>("{5}{W}"), TimingRule.SORCERY); + ability.addTarget(new TargetPermanent(filter)); + ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility())); + this.addAbility(ability); + } + + private InTheTrenches(final InTheTrenches card) { + super(card); + } + + @Override + public InTheTrenches copy() { + return new InTheTrenches(this); + } +} diff --git a/Mage.Sets/src/mage/cards/s/SurgeEngine.java b/Mage.Sets/src/mage/cards/s/SurgeEngine.java index ee1671266a..d8cf49a5df 100644 --- a/Mage.Sets/src/mage/cards/s/SurgeEngine.java +++ b/Mage.Sets/src/mage/cards/s/SurgeEngine.java @@ -19,7 +19,6 @@ import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.*; import mage.game.Game; -import mage.util.CardUtil; import java.util.Objects; import java.util.Optional; @@ -103,6 +102,7 @@ class SurgeEngineAbility extends ActivatedAbilityImpl { SurgeEngineAbility() { super(Zone.BATTLEFIELD, new DrawCardSourceControllerEffect(3), new ManaCostsImpl<>("{4}{U}{U}")); this.condition = staticCondition; + this.maxActivationsPerGame = 1; } private SurgeEngineAbility(final SurgeEngineAbility ability) { @@ -114,24 +114,6 @@ class SurgeEngineAbility extends ActivatedAbilityImpl { return new SurgeEngineAbility(this); } - @Override - public boolean activate(Game game, boolean noMana) { - if (!super.activate(game, noMana)) { - return false; - } - game.getState().setValue(CardUtil.getCardZoneString("activationsAny" + originalId, sourceId, game), true); - return true; - } - - @Override - protected boolean hasMoreActivationsThisTurn(Game game) { - if (!super.hasMoreActivationsThisTurn(game)) { - return false; - } - Object value = game.getState().getValue(CardUtil.getCardZoneString("activationsAny" + originalId, sourceId, game)); - return value == null || ((Boolean) value) == false; - } - @Override public String getRule() { return "{4}{U}{U}: Draw three cards. Activate only if {this} is blue and only once."; diff --git a/Mage.Sets/src/mage/sets/TheBrothersWar.java b/Mage.Sets/src/mage/sets/TheBrothersWar.java index f0833268a4..4e9772da8f 100644 --- a/Mage.Sets/src/mage/sets/TheBrothersWar.java +++ b/Mage.Sets/src/mage/sets/TheBrothersWar.java @@ -44,6 +44,7 @@ public final class TheBrothersWar extends ExpansionSet { cards.add(new SetCardInfo("Harbin, Vanguard Aviator", 212, Rarity.RARE, mage.cards.h.HarbinVanguardAviator.class)); cards.add(new SetCardInfo("Hurkyl's Final Meditation", 52, Rarity.RARE, mage.cards.h.HurkylsFinalMeditation.class)); cards.add(new SetCardInfo("Hurkyl, Master Wizard", 51, Rarity.RARE, mage.cards.h.HurkylMasterWizard.class)); + cards.add(new SetCardInfo("In the Trenches", 8, Rarity.MYTHIC, mage.cards.i.InTheTrenches.class)); cards.add(new SetCardInfo("Island", 280, Rarity.LAND, mage.cards.basiclands.Island.class, FULL_ART_BFZ_VARIOUS)); cards.add(new SetCardInfo("Llanowar Wastes", 264, Rarity.RARE, mage.cards.l.LlanowarWastes.class)); cards.add(new SetCardInfo("Mishra's Command", 141, Rarity.RARE, mage.cards.m.MishrasCommand.class)); diff --git a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java index 81dadb57b6..d92974b3e8 100644 --- a/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java +++ b/Mage/src/main/java/mage/abilities/ActivatedAbilityImpl.java @@ -8,7 +8,6 @@ import mage.abilities.costs.Costs; import mage.abilities.costs.mana.ManaCosts; import mage.abilities.effects.Effect; import mage.abilities.effects.Effects; -import mage.abilities.mana.ManaAbility; import mage.abilities.mana.ManaOptions; import mage.cards.Card; import mage.constants.*; @@ -29,14 +28,17 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa public int turnNum; public int activationCounter; + public int totalActivations; - public ActivationInfo(int turnNum, int activationCounter) { + public ActivationInfo(int turnNum, int activationCounter, int totalActivations) { this.turnNum = turnNum; this.activationCounter = activationCounter; + this.totalActivations = totalActivations; } } protected int maxActivationsPerTurn = Integer.MAX_VALUE; + protected int maxActivationsPerGame = Integer.MAX_VALUE; protected Condition condition; protected TimingRule timing = TimingRule.INSTANT; protected TargetController mayActivate = TargetController.YOU; @@ -52,6 +54,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa mayActivate = ability.mayActivate; activatorId = ability.activatorId; maxActivationsPerTurn = ability.maxActivationsPerTurn; + maxActivationsPerGame = ability.maxActivationsPerGame; condition = ability.condition; } @@ -243,12 +246,17 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } protected boolean hasMoreActivationsThisTurn(Game game) { - if (getMaxActivationsPerTurn(game) == Integer.MAX_VALUE) { + if (getMaxActivationsPerTurn(game) == Integer.MAX_VALUE && maxActivationsPerGame == Integer.MAX_VALUE) { return true; } ActivationInfo activationInfo = getActivationInfo(game); - return activationInfo == null - || activationInfo.turnNum != game.getTurnNum() + if (activationInfo == null) { + return true; + } + if (activationInfo.totalActivations >= maxActivationsPerGame) { + return false; + } + return activationInfo.turnNum != game.getTurnNum() || activationInfo.activationCounter < getMaxActivationsPerTurn(game); } @@ -259,13 +267,14 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa } ActivationInfo activationInfo = getActivationInfo(game); if (activationInfo == null) { - activationInfo = new ActivationInfo(game.getTurnNum(), 1); + activationInfo = new ActivationInfo(game.getTurnNum(), 1, 0); } else if (activationInfo.turnNum != game.getTurnNum()) { activationInfo.turnNum = game.getTurnNum(); activationInfo.activationCounter = 1; } else { activationInfo.activationCounter++; } + activationInfo.totalActivations++; setActivationInfo(activationInfo, game); return true; } @@ -285,10 +294,12 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa .getValue(CardUtil.getCardZoneString("activationsTurn" + originalId, sourceId, game)); Integer activationCount = (Integer) game.getState() .getValue(CardUtil.getCardZoneString("activationsCount" + originalId, sourceId, game)); - if (turnNum == null || activationCount == null) { + Integer totalActivations = (Integer) game.getState() + .getValue(CardUtil.getCardZoneString("totalActivations" + originalId, sourceId, game)); + if (turnNum == null || activationCount == null || totalActivations == null) { return null; } - return new ActivationInfo(turnNum, activationCount); + return new ActivationInfo(turnNum, activationCount, totalActivations); } protected void setActivationInfo(ActivationInfo activationInfo, Game game) { @@ -296,5 +307,7 @@ public abstract class ActivatedAbilityImpl extends AbilityImpl implements Activa .getCardZoneString("activationsTurn" + originalId, sourceId, game), activationInfo.turnNum); game.getState().setValue(CardUtil .getCardZoneString("activationsCount" + originalId, sourceId, game), activationInfo.activationCounter); + game.getState().setValue(CardUtil + .getCardZoneString("totalActivations" + originalId, sourceId, game), activationInfo.totalActivations); } } diff --git a/Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java b/Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java new file mode 100644 index 0000000000..a1c9992a76 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/common/ActivateOncePerGameActivatedAbility.java @@ -0,0 +1,40 @@ +package mage.abilities.common; + +import mage.abilities.ActivatedAbilityImpl; +import mage.abilities.costs.Cost; +import mage.abilities.effects.Effect; +import mage.constants.TimingRule; +import mage.constants.Zone; + +/** + * + * @author weirddan455 + */ +public class ActivateOncePerGameActivatedAbility extends ActivatedAbilityImpl { + + public ActivateOncePerGameActivatedAbility(Zone zone, Effect effect, Cost cost, TimingRule timingRule) { + super(zone, effect, cost); + this.timing = timingRule; + this.maxActivationsPerGame = 1; + } + + private ActivateOncePerGameActivatedAbility(final ActivateOncePerGameActivatedAbility ability) { + super(ability); + } + + @Override + public ActivateOncePerGameActivatedAbility copy() { + return new ActivateOncePerGameActivatedAbility(this); + } + + @Override + public String getRule() { + StringBuilder sb = new StringBuilder(super.getRule()); + sb.append(" Activate "); + if (this.timing == TimingRule.SORCERY) { + sb.append("only as a sorcery and "); + } + sb.append("only once."); + return sb.toString(); + } +}