diff --git a/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java b/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java new file mode 100644 index 00000000000..a9d74386490 --- /dev/null +++ b/Mage.Sets/src/mage/cards/o/OjerPakpatiqDeepestEpoch.java @@ -0,0 +1,203 @@ +package mage.cards.o; + +import mage.MageInt; +import mage.MageObject; +import mage.abilities.Ability; +import mage.abilities.common.DiesSourceTriggeredAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.OneShotEffect; +import mage.abilities.effects.ReplacementEffectImpl; +import mage.abilities.keyword.FlyingAbility; +import mage.abilities.keyword.ReboundAbility; +import mage.abilities.keyword.TransformAbility; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.counters.CounterType; +import mage.filter.FilterSpell; +import mage.game.Game; +import mage.game.events.EntersTheBattlefieldEvent; +import mage.game.events.GameEvent; +import mage.game.permanent.Permanent; +import mage.game.stack.Spell; +import mage.players.Player; +import mage.target.targetpointer.FixedTarget; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class OjerPakpatiqDeepestEpoch extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("an instant spell"); + + static { + filter.add(CardType.INSTANT.getPredicate()); + } + + public OjerPakpatiqDeepestEpoch(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}{U}"); + this.secondSideCardClazz = mage.cards.t.TempleOfCyclicalTime.class; + + this.supertype.add(SuperType.LEGENDARY); + this.subtype.add(SubType.GOD); + this.power = new MageInt(4); + this.toughness = new MageInt(3); + + // Flying + this.addAbility(FlyingAbility.getInstance()); + + // Whenever you cast an instant spell from your hand, it gains rebound. + this.addAbility(new SpellCastControllerTriggeredAbility( + Zone.BATTLEFIELD, new OjerPakpatiqDeepestEpochGainReboundEffect(), filter, + false, SetTargetPointer.SPELL, Zone.HAND + )); + + // When Ojer Pakpatiq dies, return it to the battlefield tapped and transformed under its owner's control with three time counters on it. + this.addAbility(new TransformAbility()); + this.addAbility(new DiesSourceTriggeredAbility(new OjerPakpatiqDeepestEpochTrigger())); + } + + private OjerPakpatiqDeepestEpoch(final OjerPakpatiqDeepestEpoch card) { + super(card); + } + + @Override + public OjerPakpatiqDeepestEpoch copy() { + return new OjerPakpatiqDeepestEpoch(this); + } +} + +/** + * Inspired by {@link mage.cards.n.NarsetTranscendent} + */ +class OjerPakpatiqDeepestEpochGainReboundEffect extends ContinuousEffectImpl { + + public OjerPakpatiqDeepestEpochGainReboundEffect() { + super(Duration.Custom, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility); + staticText = "it gains rebound"; + } + + private OjerPakpatiqDeepestEpochGainReboundEffect(final OjerPakpatiqDeepestEpochGainReboundEffect effect) { + super(effect); + } + + @Override + public OjerPakpatiqDeepestEpochGainReboundEffect copy() { + return new OjerPakpatiqDeepestEpochGainReboundEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player player = game.getPlayer(source.getControllerId()); + if (player == null) { + return false; + } + + Spell spell = game.getStack().getSpell(getTargetPointer().getFirst(game, source)); + if (spell == null) { + discard(); + return false; + } + + Card card = spell.getCard(); + if (card == null) { + return false; + } + + addReboundAbility(card, game); + return true; + } + + private void addReboundAbility(Card card, Game game) { + boolean found = false; + for (Ability ability : card.getAbilities(game)) { + if (ability instanceof ReboundAbility) { + found = true; + break; + } + } + if (!found) { + Ability ability = new ReboundAbility(); + game.getState().addOtherAbility(card, ability); + } + } +} + +// Inspired by Edgar, Charmed Groom +class OjerPakpatiqDeepestEpochTrigger extends OneShotEffect { + + OjerPakpatiqDeepestEpochTrigger() { + super(Outcome.Benefit); + staticText = "return it to the battlefield tapped and transformed under its owner's control with three time counters on it"; + } + + private OjerPakpatiqDeepestEpochTrigger(final OjerPakpatiqDeepestEpochTrigger effect) { + super(effect); + } + + @Override + public OjerPakpatiqDeepestEpochTrigger copy() { + return new OjerPakpatiqDeepestEpochTrigger(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + MageObject sourceObject = source.getSourceObjectIfItStillExists(game); + if (!(sourceObject instanceof Card)) { + return false; + } + game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE); + + OjerPakpatiqDeepestEpochAddCounterReplacementEffect counterEffect = + new OjerPakpatiqDeepestEpochAddCounterReplacementEffect(); + counterEffect.setTargetPointer(new FixedTarget(sourceObject.getId(), game)); + game.addEffect(counterEffect, source); + controller.moveCards((Card) sourceObject, Zone.BATTLEFIELD, source, game, true, false, true, null); + return true; + } +} + +class OjerPakpatiqDeepestEpochAddCounterReplacementEffect extends ReplacementEffectImpl { + + public OjerPakpatiqDeepestEpochAddCounterReplacementEffect() { + super(Duration.EndOfStep, Outcome.BoostCreature); + } + + private OjerPakpatiqDeepestEpochAddCounterReplacementEffect(final OjerPakpatiqDeepestEpochAddCounterReplacementEffect effect) { + super(effect); + } + + @Override + public OjerPakpatiqDeepestEpochAddCounterReplacementEffect copy() { + return new OjerPakpatiqDeepestEpochAddCounterReplacementEffect(this); + } + + @Override + public boolean checksEventType(GameEvent event, Game game) { + return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD; + } + + @Override + public boolean applies(GameEvent event, Ability source, Game game) { + return getTargetPointer().getTargets(game, source).contains(event.getTargetId()); + } + + @Override + public boolean replaceEvent(GameEvent event, Ability source, Game game) { + Permanent permanent = ((EntersTheBattlefieldEvent) event).getTarget(); + if (permanent == null) { + return false; + } + permanent.addCounters(CounterType.TIME.createInstance(3), source.getControllerId(), source, game, event.getAppliedEffects()); + discard(); + return false; + } +} diff --git a/Mage.Sets/src/mage/cards/t/TempleOfCyclicalTime.java b/Mage.Sets/src/mage/cards/t/TempleOfCyclicalTime.java new file mode 100644 index 00000000000..e01c99d833d --- /dev/null +++ b/Mage.Sets/src/mage/cards/t/TempleOfCyclicalTime.java @@ -0,0 +1,56 @@ +package mage.cards.t; + +import mage.abilities.Ability; +import mage.abilities.common.ActivateIfConditionActivatedAbility; +import mage.abilities.condition.common.SourceHasCounterCondition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.costs.mana.ManaCostsImpl; +import mage.abilities.effects.common.TransformSourceEffect; +import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; +import mage.abilities.mana.BlueManaAbility; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.CardType; +import mage.constants.TimingRule; +import mage.constants.Zone; +import mage.counters.CounterType; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class TempleOfCyclicalTime extends CardImpl { + + public TempleOfCyclicalTime(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + this.nightCard = true; + + // (Transforms from Ojer Pakpatiq, Deepest Epoch.) + + // {T}: Add {U}. Remove a time counter from Temple of Cyclical Time. + Ability ability = new BlueManaAbility(); + ability.addEffect(new RemoveCounterSourceEffect(CounterType.TIME.createInstance())); + this.addAbility(ability); + + // {2}{U}, {T}: Transform Temple of Cyclical Time. Activate only if it has no time counters on it and only as a sorcery. + ability = new ActivateIfConditionActivatedAbility( + Zone.BATTLEFIELD, + new TransformSourceEffect(), + new ManaCostsImpl<>("{2}{U}"), + new SourceHasCounterCondition(CounterType.TIME, 0, 0), + TimingRule.SORCERY + ); + ability.addCost(new TapSourceCost()); + this.addAbility(ability); + } + + private TempleOfCyclicalTime(final TempleOfCyclicalTime card) { + super(card); + } + + @Override + public TempleOfCyclicalTime copy() { + return new TempleOfCyclicalTime(this); + } +} diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java index fc442838e86..84c6d8d6828 100644 --- a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java @@ -214,6 +214,7 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Oaken Siren", 66, Rarity.COMMON, mage.cards.o.OakenSiren.class)); cards.add(new SetCardInfo("Ojer Axonil, Deepest Might", 158, Rarity.MYTHIC, mage.cards.o.OjerAxonilDeepestMight.class)); cards.add(new SetCardInfo("Ojer Kaslem, Deepest Growth", 204, Rarity.MYTHIC, mage.cards.o.OjerKaslemDeepestGrowth.class)); + cards.add(new SetCardInfo("Ojer Pakpatiq, Deepest Epoch", 67, Rarity.MYTHIC, mage.cards.o.OjerPakpatiqDeepestEpoch.class)); cards.add(new SetCardInfo("Ojer Taq, Deepest Foundation", 26, Rarity.MYTHIC, mage.cards.o.OjerTaqDeepestFoundation.class)); cards.add(new SetCardInfo("Oltec Archaeologists", 27, Rarity.COMMON, mage.cards.o.OltecArchaeologists.class)); cards.add(new SetCardInfo("Oltec Cloud Guard", 28, Rarity.COMMON, mage.cards.o.OltecCloudGuard.class)); @@ -301,6 +302,7 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Tectonic Hazard", 169, Rarity.COMMON, mage.cards.t.TectonicHazard.class)); cards.add(new SetCardInfo("Temple of Civilization", 26, Rarity.MYTHIC, mage.cards.t.TempleOfCivilization.class)); cards.add(new SetCardInfo("Temple of Cultivation", 204, Rarity.MYTHIC, mage.cards.t.TempleOfCultivation.class)); + cards.add(new SetCardInfo("Temple of Cyclical Time", 67, Rarity.MYTHIC, mage.cards.t.TempleOfCyclicalTime.class)); cards.add(new SetCardInfo("Temple of Power", 158, Rarity.MYTHIC, mage.cards.t.TempleOfPower.class)); cards.add(new SetCardInfo("Temple of the Dead", 88, Rarity.MYTHIC, mage.cards.t.TempleOfTheDead.class)); cards.add(new SetCardInfo("Tendril of the Mycotyrant", 215, Rarity.UNCOMMON, mage.cards.t.TendrilOfTheMycotyrant.class));