From fd02d662274cde9f626bd8aeb2131b26e878883b Mon Sep 17 00:00:00 2001 From: Evan Kranzler Date: Tue, 14 Apr 2020 23:11:29 -0400 Subject: [PATCH] Implemented The Ozolith --- Mage.Sets/src/mage/cards/t/TheOzolith.java | 179 ++++++++++++++++++ .../src/mage/sets/IkoriaLairOfBehemoths.java | 1 + .../LeavesBattlefieldAllTriggeredAbility.java | 2 +- 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 Mage.Sets/src/mage/cards/t/TheOzolith.java diff --git a/Mage.Sets/src/mage/cards/t/TheOzolith.java b/Mage.Sets/src/mage/cards/t/TheOzolith.java new file mode 100644 index 00000000000..dc813c453ae --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TheOzolith.java @@ -0,0 +1,179 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.common.BeginningOfCombatTriggeredAbility; +import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility; +import mage.abilities.condition.Condition; +import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; +import mage.abilities.effects.OneShotEffect; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.Outcome; +import mage.constants.SuperType; +import mage.constants.TargetController; +import mage.counters.Counter; +import mage.counters.Counters; +import mage.filter.FilterPermanent; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.filter.predicate.permanent.CounterAnyPredicate; +import mage.game.Game; +import mage.game.events.GameEvent; +import mage.game.events.ZoneChangeEvent; +import mage.game.permanent.Permanent; +import mage.target.common.TargetCreaturePermanent; + +import java.util.UUID; + +/** + * @author TheElk801 + */ +public final class TheOzolith extends CardImpl { + + public TheOzolith(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); + + this.addSuperType(SuperType.LEGENDARY); + + // Whenever a creature you control leaves the battlefield, if it had counters on it, put those counters on The Ozolith. + this.addAbility(new TheOzolithTriggeredAbility()); + + // At the beginning of combat on your turn, if The Ozolith has counters on it, you may move all counters from The Ozolith onto target creature. + Ability ability = new ConditionalInterveningIfTriggeredAbility( + new BeginningOfCombatTriggeredAbility( + new TheOzolithMoveCountersEffect(), TargetController.YOU, true + ), TheOzolithCondition.instance, "At the beginning of combat on your turn, " + + "if {this} has counters on it, you may move all counters from {this} onto target creature." + ); + ability.addTarget(new TargetCreaturePermanent()); + this.addAbility(ability); + } + + private TheOzolith(final TheOzolith card) { + super(card); + } + + @Override + public TheOzolith copy() { + return new TheOzolith(this); + } +} + +class TheOzolithTriggeredAbility extends LeavesBattlefieldAllTriggeredAbility { + + private static final FilterPermanent filter = new FilterControlledCreaturePermanent(); + + static { + filter.add(CounterAnyPredicate.instance); + } + + TheOzolithTriggeredAbility() { + super(null, filter); + } + + private TheOzolithTriggeredAbility(final TheOzolithTriggeredAbility ability) { + super(ability); + } + + public TheOzolithTriggeredAbility copy() { + return new TheOzolithTriggeredAbility(this); + } + + @Override + public boolean checkTrigger(GameEvent event, Game game) { + if (!super.checkTrigger(event, game)) { + return false; + } + Permanent permanent = ((ZoneChangeEvent) event).getTarget(); + this.getEffects().clear(); + this.addEffect(new TheOzolithLeaveEffect(permanent.getCounters(game))); + return true; + } + + public String getRule() { + return "Whenever a creature you control leaves the battlefield, " + + "if it had counters on it, put those counters on {this}."; + } +} + +class TheOzolithLeaveEffect extends OneShotEffect { + + private final Counters counters; + + TheOzolithLeaveEffect(Counters counters) { + super(Outcome.Benefit); + this.counters = counters.copy(); + } + + private TheOzolithLeaveEffect(final TheOzolithLeaveEffect effect) { + super(effect); + this.counters = effect.counters.copy(); + } + + @Override + public TheOzolithLeaveEffect copy() { + return new TheOzolithLeaveEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + counters.values() + .stream() + .forEach(counter -> permanent.addCounters(counter, source, game)); + return true; + } +} + +enum TheOzolithCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent == null) { + return false; + } + return permanent != null + && permanent + .getCounters(game) + .values() + .stream() + .mapToInt(Counter::getCount) + .max() + .orElse(0) > 0; + } +} + +class TheOzolithMoveCountersEffect extends OneShotEffect { + + TheOzolithMoveCountersEffect() { + super(Outcome.Benefit); + } + + private TheOzolithMoveCountersEffect(final TheOzolithMoveCountersEffect effect) { + super(effect); + } + + @Override + public TheOzolithMoveCountersEffect copy() { + return new TheOzolithMoveCountersEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + Permanent creature = game.getPermanent(source.getFirstTarget()); + if (permanent == null || creature == null) { + return false; + } + permanent.getCounters(game) + .values() + .stream() + .forEach(counter -> creature.addCounters(counter, source, game)); + return true; + } +} \ No newline at end of file diff --git a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java index f6c35085bf4..e9aaadb486d 100644 --- a/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java +++ b/Mage.Sets/src/mage/sets/IkoriaLairOfBehemoths.java @@ -297,6 +297,7 @@ public final class IkoriaLairOfBehemoths extends ExpansionSet { cards.add(new SetCardInfo("Swamp", 268, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Swiftwater Cliffs", 255, Rarity.COMMON, mage.cards.s.SwiftwaterCliffs.class)); cards.add(new SetCardInfo("Tentative Connection", 138, Rarity.COMMON, mage.cards.t.TentativeConnection.class)); + cards.add(new SetCardInfo("The Ozolith", 237, Rarity.RARE, mage.cards.t.TheOzolith.class)); cards.add(new SetCardInfo("Thieving Otter", 69, Rarity.COMMON, mage.cards.t.ThievingOtter.class)); cards.add(new SetCardInfo("Thornwood Falls", 256, Rarity.COMMON, mage.cards.t.ThornwoodFalls.class)); cards.add(new SetCardInfo("Thwart the Enemy", 173, Rarity.COMMON, mage.cards.t.ThwartTheEnemy.class)); diff --git a/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java index 7ce2028a917..4d0099aae41 100644 --- a/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java +++ b/Mage/src/main/java/mage/abilities/common/LeavesBattlefieldAllTriggeredAbility.java @@ -40,7 +40,7 @@ public class LeavesBattlefieldAllTriggeredAbility extends TriggeredAbilityImpl { this.setTargetPointer = setTargetPointer; } - private LeavesBattlefieldAllTriggeredAbility(final LeavesBattlefieldAllTriggeredAbility ability) { + protected LeavesBattlefieldAllTriggeredAbility(final LeavesBattlefieldAllTriggeredAbility ability) { super(ability); filter = ability.filter; setTargetPointer = ability.setTargetPointer;