convert transforming "O" cards to single class file

part of #14099
This commit is contained in:
jmlundeen 2025-12-02 13:49:55 -06:00
parent 60e2d4d89f
commit 39f62a1c02
26 changed files with 413 additions and 770 deletions

View file

@ -1,48 +0,0 @@
package mage.cards.a;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.keyword.DisturbAbility;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ArchiveHaunt extends CardImpl {
public ArchiveHaunt(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
this.color.setBlue(true);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Archive Haunt attacks, draw a card, then discard a card.
this.addAbility(new AttacksTriggeredAbility(new DrawDiscardControllerEffect(1, 1)));
// If Archive Haunt would be put into a graveyard from anywhere, exile it instead.
this.addAbility(DisturbAbility.makeBackAbility());
}
private ArchiveHaunt(final ArchiveHaunt card) {
super(card);
}
@Override
public ArchiveHaunt copy() {
return new ArchiveHaunt(this);
}
}

View file

@ -1,67 +0,0 @@
package mage.cards.f;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.keyword.NightboundAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
import mage.filter.predicate.permanent.DefendingPlayerControlsSourceAttackingPredicate;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class FrenziedTrapbreaker extends CardImpl {
private static final FilterPermanent filter
= new FilterArtifactOrEnchantmentPermanent("artifact or enchantment defending player controls");
static {
filter.add(DefendingPlayerControlsSourceAttackingPredicate.instance);
}
public FrenziedTrapbreaker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.color.setGreen(true);
this.nightCard = true;
// {1}, Sacrifice Frenzied Trapbreaker: Destroy target artifact or enchantment.
Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(1));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
this.addAbility(ability);
// Whenever Frenzied Trapbreaker attacks, destroy target artifact or enchantment defending player controls.
ability = new AttacksTriggeredAbility(new DestroyTargetEffect());
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
// Nightbound
this.addAbility(new NightboundAbility());
}
private FrenziedTrapbreaker(final FrenziedTrapbreaker card) {
super(card);
}
@Override
public FrenziedTrapbreaker copy() {
return new FrenziedTrapbreaker(this);
}
}

View file

@ -1,38 +0,0 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.keyword.NightboundAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class MoonlitAmbusher extends CardImpl {
public MoonlitAmbusher(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(6);
this.toughness = new MageInt(3);
this.color.setGreen(true);
this.nightCard = true;
// Nightbound
this.addAbility(new NightboundAbility());
}
private MoonlitAmbusher(final MoonlitAmbusher card) {
super(card);
}
@Override
public MoonlitAmbusher copy() {
return new MoonlitAmbusher(this);
}
}

View file

@ -1,50 +0,0 @@
package mage.cards.n;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class NezumiRoadCaptain extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent(SubType.VEHICLE, "Vehicles");
public NezumiRoadCaptain(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, "");
this.subtype.add(SubType.RAT);
this.subtype.add(SubType.ROGUE);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.color.setBlack(true);
this.nightCard = true;
// Menace
this.addAbility(new MenaceAbility(false));
// Vehicles you control have menace.
this.addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
new MenaceAbility(true), Duration.WhileOnBattlefield, filter
)));
}
private NezumiRoadCaptain(final NezumiRoadCaptain card) {
super(card);
}
@Override
public NezumiRoadCaptain copy() {
return new NezumiRoadCaptain(this);
}
}

View file

@ -1,11 +1,11 @@
package mage.cards.o;
import mage.MageInt;
import mage.abilities.common.PayMoreToCastAsThoughtItHadFlashAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.keyword.DayboundAbility;
import mage.cards.CardImpl;
import mage.abilities.keyword.NightboundAbility;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.SubType;
@ -14,23 +14,28 @@ import java.util.UUID;
/**
* @author TheElk801
*/
public final class OakshadeStalker extends CardImpl {
public final class OakshadeStalker extends TransformingDoubleFacedCard {
public OakshadeStalker(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}");
super(ownerId, setInfo,
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.RANGER, SubType.WEREWOLF}, "{2}{G}",
"Moonlit Ambusher",
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.RANGER);
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.secondSideCardClazz = mage.cards.m.MoonlitAmbusher.class;
// Oakshade Stalker
this.getLeftHalfCard().setPT(3, 3);
// You may cast this spell as though it had flash if you pay {2} more to cast it.
this.addAbility(new PayMoreToCastAsThoughtItHadFlashAbility(this, new ManaCostsImpl<>("{2}")));
this.getLeftHalfCard().addAbility(new PayMoreToCastAsThoughtItHadFlashAbility(this.getLeftHalfCard(), new ManaCostsImpl<>("{2}")));
// Daybound
this.addAbility(new DayboundAbility());
this.getLeftHalfCard().addAbility(new DayboundAbility());
// Moonlit Ambusher
this.getRightHalfCard().setPT(6, 3);
// Nightbound
this.getRightHalfCard().addAbility(new NightboundAbility());
}
private OakshadeStalker(final OakshadeStalker card) {

View file

@ -1,50 +1,74 @@
package mage.cards.o;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.hint.Hint;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.mana.RedManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.*;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.command.CommandObject;
import mage.game.events.DamageEvent;
import mage.game.events.DamagedEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author Susucr
*/
public final class OjerAxonilDeepestMight extends CardImpl {
public final class OjerAxonilDeepestMight extends TransformingDoubleFacedCard {
public OjerAxonilDeepestMight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}{R}");
this.secondSideCardClazz = mage.cards.t.TempleOfPower.class;
super(ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{2}{R}{R}",
"Temple of Power",
new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
this.power = new MageInt(4);
this.toughness = new MageInt(4);
// Ojer Axonil, Deepest Might
this.getLeftHalfCard().setPT(4, 4);
// Trample
this.addAbility(TrampleAbility.getInstance());
this.getLeftHalfCard().addAbility(TrampleAbility.getInstance());
// If a red source you control would deal an amount of noncombat damage less than Ojer Axonil's power to an opponent, that source deals damage equal to Ojer Axonil's power instead.
this.addAbility(new SimpleStaticAbility(new OjerAxonilDeepestMightReplacementEffect()));
this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new OjerAxonilDeepestMightReplacementEffect()));
// When Ojer Axonil dies, return it to the battlefield tapped and transformed under its owner's control.
this.addAbility(new TransformAbility());
this.addAbility(new DiesSourceTriggeredAbility(new OjerAxonilDeepestMightTransformEffect()));
this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerAxonilDeepestMightTransformEffect()));
// Temple of Power
// {T}: Add {R}.
this.getRightHalfCard().addAbility(new RedManaAbility());
// {2}{R}, {T}: Transform Temple of Power. Activate only if red sources you controlled dealt 4 or more noncombat damage this turn and only as a sorcery.
Ability ability = new ActivateIfConditionActivatedAbility(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{R}"), TempleOfPowerCondition.instance
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
ability.addWatcher(new TempleOfPowerWatcher());
this.getRightHalfCard().addAbility(ability.addHint(TempleOfPowerHint.instance));
}
private OjerAxonilDeepestMight(final OjerAxonilDeepestMight card) {
@ -155,3 +179,100 @@ class OjerAxonilDeepestMightReplacementEffect extends ReplacementEffectImpl {
&& event.getAmount() < ojer.getPower().getValue();
}
}
enum TempleOfPowerCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class);
return watcher != null
&& 4 <= watcher.damageForPlayer(source.getControllerId());
}
@Override
public String toString() {
return "red sources you controlled dealt 4 or more noncombat damage this turn";
}
}
enum TempleOfPowerHint implements Hint {
instance;
@Override
public String getText(Game game, Ability ability) {
TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class);
if (watcher == null) {
return "";
}
return "Non-combat damage from red source: "
+ watcher.damageForPlayer(ability.getControllerId());
}
@Override
public TempleOfPowerHint copy() {
return instance;
}
}
class TempleOfPowerWatcher extends Watcher {
// player -> total non combat damage from red source controlled by that player dealt this turn.
private final Map<UUID, Integer> damageMap = new HashMap<>();
public TempleOfPowerWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER
|| event.getType() == GameEvent.EventType.DAMAGED_PERMANENT) {
DamagedEvent dmgEvent = (DamagedEvent) event;
// watch only non combat damage events.
if (dmgEvent == null || dmgEvent.isCombatDamage()) {
return;
}
MageObject sourceObject;
UUID sourceControllerId = null;
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (sourcePermanent != null) {
// source is a permanent.
sourceObject = sourcePermanent;
sourceControllerId = sourcePermanent.getControllerId();
} else {
sourceObject = game.getSpellOrLKIStack(event.getSourceId());
if (sourceObject != null) {
// source is a spell.
sourceControllerId = ((StackObject) sourceObject).getControllerId();
} else {
sourceObject = game.getObject(event.getSourceId());
if (sourceObject instanceof CommandObject) {
// source is a Command Object. For instance Emblem
sourceControllerId = ((CommandObject) sourceObject).getControllerId();
}
}
}
// watch only red sources dealing damage
if (sourceObject == null || sourceControllerId == null || !sourceObject.getColor().isRed()) {
return;
}
damageMap.compute(sourceControllerId, (k, i) -> (i == null ? 0 : i) + event.getAmount());
}
}
@Override
public void reset() {
damageMap.clear();
super.reset();
}
int damageForPlayer(UUID playerId) {
return damageMap.getOrDefault(playerId, 0);
}
}

View file

@ -1,15 +1,23 @@
package mage.cards.o;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.hint.common.PermanentsYouControlHint;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.*;
import mage.cards.g.GishathSunsAvatar;
import mage.constants.*;
import mage.filter.common.FilterControlledPermanent;
import mage.game.Game;
import mage.players.Player;
import mage.target.TargetCard;
@ -20,26 +28,39 @@ import java.util.UUID;
/**
* @author Susucr
*/
public final class OjerKaslemDeepestGrowth extends CardImpl {
public final class OjerKaslemDeepestGrowth extends TransformingDoubleFacedCard {
public OjerKaslemDeepestGrowth(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{G}{G}");
this.secondSideCardClazz = mage.cards.t.TempleOfCultivation.class;
super(ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{3}{G}{G}",
"Temple of Cultivation",
new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
this.power = new MageInt(6);
this.toughness = new MageInt(5);
// Ojer Kaslem, Deepest Growth
this.getLeftHalfCard().setPT(6, 5);
// Trample
this.addAbility(TrampleAbility.getInstance());
this.getLeftHalfCard().addAbility(TrampleAbility.getInstance());
// Whenever Ojer Kaslem deals combat damage to a player, reveal that many cards from the top of your library. You may put a creature card and/or a land card from among them onto the battlefield. Put the rest on the bottom in a random order.
this.addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new OjerKaslemDeepestGrowthEffect(), false, true));
this.getLeftHalfCard().addAbility(new DealsCombatDamageToAPlayerTriggeredAbility(new OjerKaslemDeepestGrowthEffect(), false, true));
// When Ojer Kaslem dies, return it to the battlefield tapped and transformed under its owner's control.
this.addAbility(new TransformAbility());
this.addAbility(new DiesSourceTriggeredAbility(new OjerKaslemDeepestGrowthTransformEffect()));
this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerKaslemDeepestGrowthTransformEffect()));
// Temple of Cultivation
// {T}: Add {G}.
this.getRightHalfCard().addAbility(new GreenManaAbility());
// {2}{G}, {T}: Transform Temple of Cultivation. Activate only if you control ten or more permanents and only as a sorcery.
Condition condition = new PermanentsOnTheBattlefieldCondition(
new FilterControlledPermanent("you control ten or more permanents"), ComparisonType.MORE_THAN, 9
);
Ability ability = new ActivateIfConditionActivatedAbility(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{G}"), condition
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
this.getRightHalfCard().addAbility(ability.addHint(PermanentsYouControlHint.instance));
}
private OjerKaslemDeepestGrowth(final OjerKaslemDeepestGrowth card) {
@ -82,7 +103,7 @@ class OjerKaslemDeepestGrowthTransformEffect extends OneShotEffect {
}
/**
* Inspired by {@link mage.cards.g.GishathSunsAvatar}
* Inspired by {@link GishathSunsAvatar}
*/
class OjerKaslemDeepestGrowthEffect extends OneShotEffect {
@ -116,7 +137,7 @@ class OjerKaslemDeepestGrowthEffect extends OneShotEffect {
controller.choose(Outcome.PutCardInPlay, cards, target, source, game);
Cards toBattlefield = new CardsImpl(target.getTargets());
cards.removeAll(toBattlefield);
controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game, false, false, false, null);
controller.moveCards(toBattlefield.getCards(game), Zone.BATTLEFIELD, source, game);
controller.putCardsOnBottomOfLibrary(cards, game, source, false);
}
return true;

View file

@ -1,18 +1,25 @@
package mage.cards.o;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.ReboundAbility;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.cards.n.NarsetTranscendent;
import mage.constants.*;
import mage.counters.CounterType;
import mage.counters.Counters;
@ -26,35 +33,48 @@ import java.util.UUID;
/**
* @author Susucr
*/
public final class OjerPakpatiqDeepestEpoch extends CardImpl {
public final class OjerPakpatiqDeepestEpoch extends TransformingDoubleFacedCard {
private static final FilterSpell filter = new FilterSpell("an instant spell");
private static final Condition condition = new SourceHasCounterCondition(CounterType.TIME, ComparisonType.EQUAL_TO, 0);
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;
super(ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{2}{U}{U}",
"Temple of Cyclical Time",
new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
this.power = new MageInt(4);
this.toughness = new MageInt(3);
// Ojer Pakpatiq, Deepest Epoch
this.getLeftHalfCard().setPT(4, 3);
// Flying
this.addAbility(FlyingAbility.getInstance());
this.getLeftHalfCard().addAbility(FlyingAbility.getInstance());
// Whenever you cast an instant spell from your hand, it gains rebound.
this.addAbility(new SpellCastControllerTriggeredAbility(
this.getLeftHalfCard().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()));
this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerPakpatiqDeepestEpochTrigger()));
// Temple of Cyclical Time
// {T}: Add {U}. Remove a time counter from Temple of Cyclical Time.
Ability ability = new BlueManaAbility();
ability.addEffect(new RemoveCounterSourceEffect(CounterType.TIME.createInstance()));
this.getRightHalfCard().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(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{U}"), condition
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
this.getRightHalfCard().addAbility(ability);
}
private OjerPakpatiqDeepestEpoch(final OjerPakpatiqDeepestEpoch card) {
@ -68,7 +88,7 @@ public final class OjerPakpatiqDeepestEpoch extends CardImpl {
}
/**
* Inspired by {@link mage.cards.n.NarsetTranscendent}
* Inspired by {@link NarsetTranscendent}
*/
class OjerPakpatiqDeepestEpochGainReboundEffect extends ContinuousEffectImpl {

View file

@ -1,48 +1,64 @@
package mage.cards.o;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.keyword.VigilanceAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.CreateTokenEvent;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.watchers.common.PlayerAttackedWatcher;
import java.util.UUID;
/**
* @author Susucr
*/
public final class OjerTaqDeepestFoundation extends CardImpl {
public final class OjerTaqDeepestFoundation extends TransformingDoubleFacedCard {
public OjerTaqDeepestFoundation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{W}{W}");
this.secondSideCardClazz = mage.cards.t.TempleOfCivilization.class;
super(ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.GOD}, "{4}{W}{W}",
"Temple of Civilization",
new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.GOD);
this.power = new MageInt(6);
this.toughness = new MageInt(6);
// Ojer Taq, Deepest Foundation
this.getLeftHalfCard().setPT(6, 6);
// Vigilance
this.addAbility(VigilanceAbility.getInstance());
this.getLeftHalfCard().addAbility(VigilanceAbility.getInstance());
// If one or more creature tokens would be created under your control, three times that many of those tokens are created instead.
this.addAbility(new SimpleStaticAbility(new OjerTaqDeepestFoundationTriplingEffect()));
this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new OjerTaqDeepestFoundationTriplingEffect()));
// When Ojer Taq dies, return it to the battlefield tapped and transformed under its owner's control.
this.addAbility(new TransformAbility());
this.addAbility(new DiesSourceTriggeredAbility(new OjerTaqDeepestFoundationTransformEffect()));
this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OjerTaqDeepestFoundationTransformEffect()));
// Temple of Civilization
// {T}: Add {W}.
this.getRightHalfCard().addAbility(new WhiteManaAbility());
// {2}{W}, {T}: Transform Temple of Civilization. Activate only if you attacked with three or more creatures this turn and only as a sorcery.
Ability ability = new ActivateIfConditionActivatedAbility(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{W}"), TempleOfCivilizationCondition.instance
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
ability.addWatcher(new PlayerAttackedWatcher());
this.getRightHalfCard().addAbility(ability);
}
private OjerTaqDeepestFoundation(final OjerTaqDeepestFoundation card) {
@ -124,3 +140,18 @@ class OjerTaqDeepestFoundationTriplingEffect extends ReplacementEffectImpl {
return false;
}
}
enum TempleOfCivilizationCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
PlayerAttackedWatcher watcher = game.getState().getWatcher(PlayerAttackedWatcher.class);
return watcher != null && watcher.getNumberOfAttackersCurrentTurn(source.getControllerId()) >= 3;
}
@Override
public String toString() {
return "you attacked with three or more creatures this turn";
}
}

View file

@ -1,36 +1,45 @@
package mage.cards.o;
import mage.abilities.common.SagaAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effects;
import mage.abilities.effects.common.ExileSagaAndReturnTransformedEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.LoseLifeOpponentsEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.abilities.effects.common.continuous.GainAbilityControlledEffect;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class OkibaReckonerRaid extends CardImpl {
public final class OkibaReckonerRaid extends TransformingDoubleFacedCard {
private static final FilterPermanent filter = new FilterPermanent(SubType.VEHICLE, "Vehicles");
public OkibaReckonerRaid(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{B}");
super(ownerId, setInfo,
new CardType[]{CardType.ENCHANTMENT}, new SubType[]{SubType.SAGA}, "{B}",
"Nezumi Road Captain",
new CardType[]{CardType.ENCHANTMENT, CardType.CREATURE}, new SubType[]{SubType.RAT, SubType.ROGUE}, "B");
this.subtype.add(SubType.SAGA);
this.secondSideCardClazz = mage.cards.n.NezumiRoadCaptain.class;
// Okiba Reckoner Raid
this.getRightHalfCard().setPT(2, 2);
// (As this Saga enters and after your draw step, add a lore counter.)
SagaAbility sagaAbility = new SagaAbility(this);
SagaAbility sagaAbility = new SagaAbility(this.getLeftHalfCard());
// I, II Each opponent loses 1 life and you gain 1 life.
sagaAbility.addChapterEffect(
this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II,
this.getLeftHalfCard(), SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_II,
new Effects(
new LoseLifeOpponentsEffect(1),
new GainLifeEffect(1).concatBy("and")
@ -38,10 +47,18 @@ public final class OkibaReckonerRaid extends CardImpl {
);
// III Exile this Saga, then return it to the battlefield transformed under your control.
this.addAbility(new TransformAbility());
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect());
sagaAbility.addChapterEffect(this.getLeftHalfCard(), SagaChapter.CHAPTER_III, new ExileSagaAndReturnTransformedEffect());
this.addAbility(sagaAbility);
this.getLeftHalfCard().addAbility(sagaAbility);
// Nezumi Road Captain
// Menace
this.getRightHalfCard().addAbility(new MenaceAbility(false));
// Vehicles you control have menace.
this.getRightHalfCard().addAbility(new SimpleStaticAbility(new GainAbilityControlledEffect(
new MenaceAbility(true), Duration.WhileOnBattlefield, filter)
));
}
private OkibaReckonerRaid(final OkibaReckonerRaid card) {

View file

@ -1,41 +0,0 @@
package mage.cards.o;
import mage.MageInt;
import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class OrderOfTheAlabasterHost extends CardImpl {
public OrderOfTheAlabasterHost(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.PHYREXIAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
this.color.setWhite(true);
this.color.setBlue(true);
this.nightCard = true;
// Whenever Order of the Alabaster Host becomes blocked by a creature, that creature gets -1/-1 until end of turn.
this.addAbility(new BecomesBlockedByCreatureTriggeredAbility(new BoostTargetEffect(-1, -1).setText("that creature gets -1/-1 until end of turn"), false));
}
private OrderOfTheAlabasterHost(final OrderOfTheAlabasterHost card) {
super(card);
}
@Override
public OrderOfTheAlabasterHost copy() {
return new OrderOfTheAlabasterHost(this);
}
}

View file

@ -1,12 +1,12 @@
package mage.cards.o;
import mage.MageInt;
import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.BecomesBlockedByCreatureTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.SubType;
@ -15,20 +15,25 @@ import java.util.UUID;
/**
* @author TheElk801
*/
public final class OrderOfTheMirror extends CardImpl {
public final class OrderOfTheMirror extends TransformingDoubleFacedCard {
public OrderOfTheMirror(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
super(ownerId, setInfo,
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.KNIGHT}, "{1}{U}",
"Order of the Alabaster Host",
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.PHYREXIAN, SubType.KNIGHT}, "WU");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
this.secondSideCardClazz = mage.cards.o.OrderOfTheAlabasterHost.class;
// Order of the Mirror
this.getLeftHalfCard().setPT(2, 1);
// {3}{W/P}: Transform Order of the Mirror. Activate only as a sorcery.
this.addAbility(new TransformAbility());
this.addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{W/P}")));
this.getLeftHalfCard().addAbility(new ActivateAsSorceryActivatedAbility(new TransformSourceEffect(), new ManaCostsImpl<>("{3}{W/P}")));
// Order of the Alabaster Host
this.getRightHalfCard().setPT(3, 3);
// Whenever Order of the Alabaster Host becomes blocked by a creature, that creature gets -1/-1 until end of turn.
this.getRightHalfCard().addAbility(new BecomesBlockedByCreatureTriggeredAbility(new BoostTargetEffect(-1, -1).setText("the blocking creature gets -1/-1 until end of turn"), false));
}
private OrderOfTheMirror(final OrderOfTheMirror card) {

View file

@ -1,28 +1,60 @@
package mage.cards.o;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.CraftAbility;
import mage.cards.CardImpl;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterAttackingCreature;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class OteclanLandmark extends CardImpl {
public final class OteclanLandmark extends TransformingDoubleFacedCard {
private static final FilterPermanent filter = new FilterAttackingCreature("attacking creature without flying");
static {
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
}
public OteclanLandmark(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{W}");
this.secondSideCardClazz = mage.cards.o.OteclanLevitator.class;
super(ownerId, setInfo,
new CardType[]{CardType.ARTIFACT}, new SubType[]{}, "{W}",
"Oteclan Levitator",
new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.GOLEM}, "W");
// Oteclan Landmark
this.getRightHalfCard().setPT(1, 4);
// When Oteclan Landmark enters the battlefield, scry 2.
this.addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2)));
this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new ScryEffect(2)));
// Craft with artifact {2}{W}
this.addAbility(new CraftAbility("{2}{W}"));
this.getLeftHalfCard().addAbility(new CraftAbility("{2}{W}"));
// Oteclan Levitator
this.getRightHalfCard().setPT(1, 4);
// Flying
this.getRightHalfCard().addAbility(FlyingAbility.getInstance());
// Whenever Oteclan Levitator attacks, target attacking creature without flying gains flying until end of turn.
Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance()));
ability.addTarget(new TargetPermanent(filter));
this.getRightHalfCard().addAbility(ability);
}
private OteclanLandmark(final OteclanLandmark card) {

View file

@ -1,57 +0,0 @@
package mage.cards.o;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterAttackingCreature;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class OteclanLevitator extends CardImpl {
private static final FilterPermanent filter = new FilterAttackingCreature("attacking creature without flying");
static {
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
}
public OteclanLevitator(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "");
this.subtype.add(SubType.GOLEM);
this.power = new MageInt(1);
this.toughness = new MageInt(4);
this.nightCard = true;
this.color.setWhite(true);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever Oteclan Levitator attacks, target attacking creature without flying gains flying until end of turn.
Ability ability = new AttacksTriggeredAbility(new GainAbilityTargetEffect(FlyingAbility.getInstance()));
ability.addTarget(new TargetPermanent(filter));
this.addAbility(ability);
}
private OteclanLevitator(final OteclanLevitator card) {
super(card);
}
@Override
public OteclanLevitator copy() {
return new OteclanLevitator(this);
}
}

View file

@ -1,17 +1,21 @@
package mage.cards.o;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.DestroyTargetEffect;
import mage.abilities.keyword.DayboundAbility;
import mage.cards.CardImpl;
import mage.abilities.keyword.NightboundAbility;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterArtifactOrEnchantmentPermanent;
import mage.filter.predicate.permanent.DefendingPlayerControlsSourceAttackingPredicate;
import mage.target.TargetPermanent;
import java.util.UUID;
@ -19,25 +23,49 @@ import java.util.UUID;
/**
* @author TheElk801
*/
public final class OutlandLiberator extends CardImpl {
public final class OutlandLiberator extends TransformingDoubleFacedCard {
private static final FilterPermanent filter
= new FilterArtifactOrEnchantmentPermanent("artifact or enchantment defending player controls");
static {
filter.add(DefendingPlayerControlsSourceAttackingPredicate.instance);
}
public OutlandLiberator(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
super(ownerId, setInfo,
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WEREWOLF}, "{1}{G}",
"Frenzied Trapbreaker",
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.WEREWOLF}, "G");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WEREWOLF);
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.secondSideCardClazz = mage.cards.f.FrenziedTrapbreaker.class;
// Outland Liberator
this.getLeftHalfCard().setPT(2, 2);
// {1}, Sacrifice Outland Liberator: Destroy target artifact or enchantment.
Ability ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(1));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
this.addAbility(ability);
this.getLeftHalfCard().addAbility(ability);
// Daybound
this.addAbility(new DayboundAbility());
this.getLeftHalfCard().addAbility(new DayboundAbility());
// Frenzied Trapbreaker
this.getRightHalfCard().setPT(3, 3);
// {1}, Sacrifice Frenzied Trapbreaker: Destroy target artifact or enchantment.
ability = new SimpleActivatedAbility(new DestroyTargetEffect(), new GenericManaCost(1));
ability.addCost(new SacrificeSourceCost());
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_PERMANENT_ARTIFACT_OR_ENCHANTMENT));
this.getRightHalfCard().addAbility(ability);
// Whenever Frenzied Trapbreaker attacks, destroy target artifact or enchantment defending player controls.
ability = new AttacksTriggeredAbility(new DestroyTargetEffect());
ability.addTarget(new TargetPermanent(filter));
this.getRightHalfCard().addAbility(ability);
// Nightbound
this.getRightHalfCard().addAbility(new NightboundAbility());
}
private OutlandLiberator(final OutlandLiberator card) {

View file

@ -1,12 +1,12 @@
package mage.cards.o;
import mage.MageInt;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.DrawDiscardControllerEffect;
import mage.abilities.keyword.DisturbAbility;
import mage.cards.CardImpl;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.SubType;
@ -15,22 +15,34 @@ import java.util.UUID;
/**
* @author TheElk801
*/
public final class OverwhelmedArchivist extends CardImpl {
public final class OverwhelmedArchivist extends TransformingDoubleFacedCard {
public OverwhelmedArchivist(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{U}");
super(ownerId, setInfo,
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.HUMAN, SubType.WIZARD}, "{2}{U}",
"Archive Haunt",
new CardType[]{CardType.CREATURE}, new SubType[]{SubType.SPIRIT, SubType.WIZARD}, "U");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(3);
this.toughness = new MageInt(2);
this.secondSideCardClazz = mage.cards.a.ArchiveHaunt.class;
// Overwhelmed Archivist
this.getLeftHalfCard().setPT(3, 2);
// When Overwhelmed Archivist enters the battlefield, draw a card, then discard a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1)));
this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new DrawDiscardControllerEffect(1, 1)));
// Disturb {3}{U}
this.addAbility(new DisturbAbility(this, "{3}{U}"));
this.getLeftHalfCard().addAbility(new DisturbAbility(this, "{3}{U}"));
// Archive Haunt
this.getRightHalfCard().setPT(2, 1);
// Flying
this.getRightHalfCard().addAbility(FlyingAbility.getInstance());
// Whenever Archive Haunt attacks, draw a card, then discard a card.
this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new DrawDiscardControllerEffect(1, 1)));
// If Archive Haunt would be put into a graveyard from anywhere, exile it instead.
this.getRightHalfCard().addAbility(DisturbAbility.makeBackAbility());
}
private OverwhelmedArchivist(final OverwhelmedArchivist card) {

View file

@ -1,64 +0,0 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TimingRule;
import mage.game.Game;
import mage.watchers.common.PlayerAttackedWatcher;
import java.util.UUID;
/**
* @author Susucr
*/
public final class TempleOfCivilization extends CardImpl {
public TempleOfCivilization(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.nightCard = true;
// (Transforms from Ojer Taq, Deepest Foundation.)
// {T}: Add {W}.
this.addAbility(new WhiteManaAbility());
// {2}{W}, {T}: Transform Temple of Civilization. Activate only if you attacked with three or more creatures this turn and only as a sorcery.
Ability ability = new ActivateIfConditionActivatedAbility(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{W}"), TempleOfCivilizationCondition.instance
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
this.addAbility(ability, new PlayerAttackedWatcher());
}
private TempleOfCivilization(final TempleOfCivilization card) {
super(card);
}
@Override
public TempleOfCivilization copy() {
return new TempleOfCivilization(this);
}
}
enum TempleOfCivilizationCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
PlayerAttackedWatcher watcher = game.getState().getWatcher(PlayerAttackedWatcher.class);
return watcher != null && watcher.getNumberOfAttackersCurrentTurn(source.getControllerId()) >= 3;
}
@Override
public String toString() {
return "you attacked with three or more creatures this turn";
}
}

View file

@ -1,55 +0,0 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.hint.common.PermanentsYouControlHint;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
import mage.constants.TimingRule;
import mage.filter.common.FilterControlledPermanent;
import java.util.UUID;
/**
* @author Susucr
*/
public final class TempleOfCultivation extends CardImpl {
private static final Condition condition = new PermanentsOnTheBattlefieldCondition(
new FilterControlledPermanent("you control ten or more permanents"), ComparisonType.MORE_THAN, 9
);
public TempleOfCultivation(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.nightCard = true;
// (Transforms from Ojer Kaslem, Deepest Growth.)
// {T}: Add {G}.
this.addAbility(new GreenManaAbility());
// {2}{G}, {T}: Transform Temple of Cultivation. Activate only if you control ten or more permanents and only as a sorcery.
Ability ability = new ActivateIfConditionActivatedAbility(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{G}"), condition
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
this.addAbility(ability.addHint(PermanentsYouControlHint.instance));
}
private TempleOfCultivation(final TempleOfCultivation card) {
super(card);
}
@Override
public TempleOfCultivation copy() {
return new TempleOfCultivation(this);
}
}

View file

@ -1,55 +0,0 @@
package mage.cards.t;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
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.ComparisonType;
import mage.constants.TimingRule;
import mage.counters.CounterType;
import java.util.UUID;
/**
* @author Susucr
*/
public final class TempleOfCyclicalTime extends CardImpl {
private static final Condition condition = new SourceHasCounterCondition(CounterType.TIME, ComparisonType.EQUAL_TO, 0);
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(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{U}"), condition
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
this.addAbility(ability);
}
private TempleOfCyclicalTime(final TempleOfCyclicalTime card) {
super(card);
}
@Override
public TempleOfCyclicalTime copy() {
return new TempleOfCyclicalTime(this);
}
}

View file

@ -1,156 +0,0 @@
package mage.cards.t;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.ActivateIfConditionActivatedAbility;
import mage.abilities.condition.Condition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.hint.Hint;
import mage.abilities.mana.RedManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.TimingRule;
import mage.constants.WatcherScope;
import mage.game.Game;
import mage.game.command.CommandObject;
import mage.game.events.DamagedEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* @author Susucr
*/
public final class TempleOfPower extends CardImpl {
public TempleOfPower(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
this.nightCard = true;
// <i>(Transforms from Ojer Axonil, Deepest Might.)</i>
// {T}: Add {R}.
this.addAbility(new RedManaAbility());
// {2}{R}, {T}: Transform Temple of Power. Activate only if red sources you controlled dealt 4 or more noncombat damage this turn and only as a sorcery.
Ability ability = new ActivateIfConditionActivatedAbility(
new TransformSourceEffect(), new ManaCostsImpl<>("{2}{R}"), TempleOfPowerCondition.instance
).setTiming(TimingRule.SORCERY);
ability.addCost(new TapSourceCost());
this.addAbility(ability.addHint(TempleOfPowerHint.instance), new TempleOfPowerWatcher());
}
private TempleOfPower(final TempleOfPower card) {
super(card);
}
@Override
public TempleOfPower copy() {
return new TempleOfPower(this);
}
}
enum TempleOfPowerCondition implements Condition {
instance;
@Override
public boolean apply(Game game, Ability source) {
TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class);
return watcher != null
&& 4 <= watcher.damageForPlayer(source.getControllerId());
}
@Override
public String toString() {
return "red sources you controlled dealt 4 or more noncombat damage this turn";
}
}
enum TempleOfPowerHint implements Hint {
instance;
@Override
public String getText(Game game, Ability ability) {
TempleOfPowerWatcher watcher = game.getState().getWatcher(TempleOfPowerWatcher.class);
if (watcher == null) {
return "";
}
return "Non-combat damage from red source: "
+ watcher.damageForPlayer(ability.getControllerId());
}
@Override
public TempleOfPowerHint copy() {
return instance;
}
}
class TempleOfPowerWatcher extends Watcher {
// player -> total non combat damage from red source controlled by that player dealt this turn.
private final Map<UUID, Integer> damageMap = new HashMap<>();
public TempleOfPowerWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.DAMAGED_PLAYER
|| event.getType() == GameEvent.EventType.DAMAGED_PERMANENT) {
DamagedEvent dmgEvent = (DamagedEvent) event;
// watch only non combat damage events.
if (dmgEvent == null || dmgEvent.isCombatDamage()) {
return;
}
MageObject sourceObject;
UUID sourceControllerId = null;
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(event.getSourceId());
if (sourcePermanent != null) {
// source is a permanent.
sourceObject = sourcePermanent;
sourceControllerId = sourcePermanent.getControllerId();
} else {
sourceObject = game.getSpellOrLKIStack(event.getSourceId());
if (sourceObject != null) {
// source is a spell.
sourceControllerId = ((StackObject) sourceObject).getControllerId();
} else {
sourceObject = game.getObject(event.getSourceId());
if (sourceObject instanceof CommandObject) {
// source is a Command Object. For instance Emblem
sourceControllerId = ((CommandObject) sourceObject).getControllerId();
}
}
}
// watch only red sources dealing damage
if (sourceObject == null || sourceControllerId == null || !sourceObject.getColor().isRed()) {
return;
}
damageMap.compute(sourceControllerId, (k, i) -> (i == null ? 0 : i) + event.getAmount());
}
}
@Override
public void reset() {
damageMap.clear();
super.reset();
}
int damageForPlayer(UUID playerId) {
return damageMap.getOrDefault(playerId, 0);
}
}

View file

@ -299,7 +299,6 @@ public final class InnistradCrimsonVow extends ExpansionSet {
cards.add(new SetCardInfo("Mirrorhall Mimic", 68, Rarity.RARE, mage.cards.m.MirrorhallMimic.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mischievous Catgeist", 69, Rarity.UNCOMMON, mage.cards.m.MischievousCatgeist.class));
cards.add(new SetCardInfo("Moldgraf Millipede", 209, Rarity.COMMON, mage.cards.m.MoldgrafMillipede.class));
cards.add(new SetCardInfo("Moonlit Ambusher", 212, Rarity.UNCOMMON, mage.cards.m.MoonlitAmbusher.class));
cards.add(new SetCardInfo("Mountain", 274, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Mountain", 275, Rarity.LAND, mage.cards.basiclands.Mountain.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Mountain", 401, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));

View file

@ -43,7 +43,6 @@ public final class InnistradDoubleFeature extends ExpansionSet {
cards.add(new SetCardInfo("Apprentice Sharpshooter", 452, Rarity.COMMON, mage.cards.a.ApprenticeSharpshooter.class));
cards.add(new SetCardInfo("Arcane Infusion", 210, Rarity.UNCOMMON, mage.cards.a.ArcaneInfusion.class));
cards.add(new SetCardInfo("Archghoul of Thraben", 360, Rarity.UNCOMMON, mage.cards.a.ArchghoulOfThraben.class));
cards.add(new SetCardInfo("Archive Haunt", 68, Rarity.UNCOMMON, mage.cards.a.ArchiveHaunt.class));
cards.add(new SetCardInfo("Ardent Elementalist", 128, Rarity.COMMON, mage.cards.a.ArdentElementalist.class));
cards.add(new SetCardInfo("Arlinn, the Pack's Hope", 211, Rarity.MYTHIC, mage.cards.a.ArlinnThePacksHope.class));
cards.add(new SetCardInfo("Arm the Cathars", 270, Rarity.UNCOMMON, mage.cards.a.ArmTheCathars.class));
@ -239,7 +238,6 @@ public final class InnistradDoubleFeature extends ExpansionSet {
cards.add(new SetCardInfo("Forsaken Thresher", 523, Rarity.UNCOMMON, mage.cards.f.ForsakenThresher.class));
cards.add(new SetCardInfo("Foul Play", 101, Rarity.UNCOMMON, mage.cards.f.FoulPlay.class));
cards.add(new SetCardInfo("Frenzied Devils", 426, Rarity.UNCOMMON, mage.cards.f.FrenziedDevils.class));
cards.add(new SetCardInfo("Frenzied Trapbreaker", 190, Rarity.UNCOMMON, mage.cards.f.FrenziedTrapbreaker.class));
cards.add(new SetCardInfo("Galedrifter", 55, Rarity.COMMON, mage.cards.g.Galedrifter.class));
cards.add(new SetCardInfo("Galvanic Iteration", 224, Rarity.RARE, mage.cards.g.GalvanicIteration.class));
cards.add(new SetCardInfo("Gavony Dawnguard", 20, Rarity.UNCOMMON, mage.cards.g.GavonyDawnguard.class));
@ -350,7 +348,6 @@ public final class InnistradDoubleFeature extends ExpansionSet {
cards.add(new SetCardInfo("Mirrorhall Mimic", 335, Rarity.RARE, mage.cards.m.MirrorhallMimic.class));
cards.add(new SetCardInfo("Mischievous Catgeist", 336, Rarity.UNCOMMON, mage.cards.m.MischievousCatgeist.class));
cards.add(new SetCardInfo("Moldgraf Millipede", 476, Rarity.COMMON, mage.cards.m.MoldgrafMillipede.class));
cards.add(new SetCardInfo("Moonlit Ambusher", 479, Rarity.UNCOMMON, mage.cards.m.MoonlitAmbusher.class));
cards.add(new SetCardInfo("Moonrager's Slash", 148, Rarity.COMMON, mage.cards.m.MoonragersSlash.class));
cards.add(new SetCardInfo("Moonsilver Key", 255, Rarity.UNCOMMON, mage.cards.m.MoonsilverKey.class));
cards.add(new SetCardInfo("Moonveil Regent", 149, Rarity.MYTHIC, mage.cards.m.MoonveilRegent.class));

View file

@ -46,7 +46,6 @@ public final class InnistradMidnightHunt extends ExpansionSet {
cards.add(new SetCardInfo("Angelfire Ignition", 209, Rarity.RARE, mage.cards.a.AngelfireIgnition.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Angelfire Ignition", 367, Rarity.RARE, mage.cards.a.AngelfireIgnition.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Arcane Infusion", 210, Rarity.UNCOMMON, mage.cards.a.ArcaneInfusion.class));
cards.add(new SetCardInfo("Archive Haunt", 68, Rarity.UNCOMMON, mage.cards.a.ArchiveHaunt.class));
cards.add(new SetCardInfo("Ardent Elementalist", 128, Rarity.COMMON, mage.cards.a.ArdentElementalist.class));
cards.add(new SetCardInfo("Arlinn, the Pack's Hope", 211, Rarity.MYTHIC, mage.cards.a.ArlinnThePacksHope.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Arlinn, the Pack's Hope", 279, Rarity.MYTHIC, mage.cards.a.ArlinnThePacksHope.class, NON_FULL_USE_VARIOUS));
@ -184,8 +183,6 @@ public final class InnistradMidnightHunt extends ExpansionSet {
cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
cards.add(new SetCardInfo("Forest", 384, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Foul Play", 101, Rarity.UNCOMMON, mage.cards.f.FoulPlay.class));
cards.add(new SetCardInfo("Frenzied Trapbreaker", 190, Rarity.UNCOMMON, mage.cards.f.FrenziedTrapbreaker.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Frenzied Trapbreaker", 303, Rarity.UNCOMMON, mage.cards.f.FrenziedTrapbreaker.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Galedrifter", 55, Rarity.COMMON, mage.cards.g.Galedrifter.class));
cards.add(new SetCardInfo("Galvanic Iteration", 224, Rarity.RARE, mage.cards.g.GalvanicIteration.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Galvanic Iteration", 371, Rarity.RARE, mage.cards.g.GalvanicIteration.class, NON_FULL_USE_VARIOUS));

View file

@ -374,7 +374,6 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
cards.add(new SetCardInfo("Nezumi Bladeblesser", 318, Rarity.COMMON, mage.cards.n.NezumiBladeblesser.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nezumi Prowler", 116, Rarity.UNCOMMON, mage.cards.n.NezumiProwler.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nezumi Prowler", 344, Rarity.UNCOMMON, mage.cards.n.NezumiProwler.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nezumi Road Captain", 117, Rarity.COMMON, mage.cards.n.NezumiRoadCaptain.class));
cards.add(new SetCardInfo("Ninja's Kunai", 252, Rarity.COMMON, mage.cards.n.NinjasKunai.class));
cards.add(new SetCardInfo("Norika Yamazaki, the Poet", 31, Rarity.UNCOMMON, mage.cards.n.NorikaYamazakiThePoet.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Norika Yamazaki, the Poet", 311, Rarity.UNCOMMON, mage.cards.n.NorikaYamazakiThePoet.class, NON_FULL_USE_VARIOUS));

View file

@ -284,7 +284,6 @@ public final class MarchOfTheMachine extends ExpansionSet {
cards.add(new SetCardInfo("Omnath, Locus of All", 387, Rarity.RARE, mage.cards.o.OmnathLocusOfAll.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Onakke Javelineer", 156, Rarity.COMMON, mage.cards.o.OnakkeJavelineer.class));
cards.add(new SetCardInfo("Oracle of Tragedy", 71, Rarity.UNCOMMON, mage.cards.o.OracleOfTragedy.class));
cards.add(new SetCardInfo("Order of the Alabaster Host", 72, Rarity.COMMON, mage.cards.o.OrderOfTheAlabasterHost.class));
cards.add(new SetCardInfo("Order of the Mirror", 72, Rarity.COMMON, mage.cards.o.OrderOfTheMirror.class));
cards.add(new SetCardInfo("Orthion, Hero of Lavabrink", 334, Rarity.RARE, mage.cards.o.OrthionHeroOfLavabrink.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Orthion, Hero of Lavabrink", 379, Rarity.RARE, mage.cards.o.OrthionHeroOfLavabrink.class, NON_FULL_USE_VARIOUS));

View file

@ -292,7 +292,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet {
cards.add(new SetCardInfo("Oltec Cloud Guard", 28, Rarity.COMMON, mage.cards.o.OltecCloudGuard.class));
cards.add(new SetCardInfo("Orazca Puzzle-Door", 68, Rarity.COMMON, mage.cards.o.OrazcaPuzzleDoor.class));
cards.add(new SetCardInfo("Oteclan Landmark", 29, Rarity.COMMON, mage.cards.o.OteclanLandmark.class));
cards.add(new SetCardInfo("Oteclan Levitator", 29, Rarity.COMMON, mage.cards.o.OteclanLevitator.class));
cards.add(new SetCardInfo("Out of Air", 69, Rarity.COMMON, mage.cards.o.OutOfAir.class));
cards.add(new SetCardInfo("Over the Edge", 205, Rarity.COMMON, mage.cards.o.OverTheEdge.class));
cards.add(new SetCardInfo("Palani's Hatcher", 237, Rarity.RARE, mage.cards.p.PalanisHatcher.class, NON_FULL_USE_VARIOUS));
@ -404,14 +403,6 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet {
cards.add(new SetCardInfo("Tarrian's Soulcleaver", 264, Rarity.RARE, mage.cards.t.TarriansSoulcleaver.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Tarrian's Soulcleaver", 389, Rarity.RARE, mage.cards.t.TarriansSoulcleaver.class, NON_FULL_USE_VARIOUS));
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, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of Civilization", 314, Rarity.MYTHIC, mage.cards.t.TempleOfCivilization.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of Cultivation", 204, Rarity.MYTHIC, mage.cards.t.TempleOfCultivation.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of Cultivation", 318, Rarity.MYTHIC, mage.cards.t.TempleOfCultivation.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of Cyclical Time", 315, Rarity.MYTHIC, mage.cards.t.TempleOfCyclicalTime.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of Cyclical Time", 67, Rarity.MYTHIC, mage.cards.t.TempleOfCyclicalTime.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of Power", 158, Rarity.MYTHIC, mage.cards.t.TempleOfPower.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Temple of Power", 317, Rarity.MYTHIC, mage.cards.t.TempleOfPower.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Tendril of the Mycotyrant", 215, Rarity.UNCOMMON, mage.cards.t.TendrilOfTheMycotyrant.class));
cards.add(new SetCardInfo("Terror Tide", 127, Rarity.RARE, mage.cards.t.TerrorTide.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Terror Tide", 372, Rarity.RARE, mage.cards.t.TerrorTide.class, NON_FULL_USE_VARIOUS));