Fixed some transformed triggered abilities after the recent change of transform handling.

This commit is contained in:
LevelX2 2016-04-06 00:37:29 +02:00
parent 6e5a1fa826
commit ae932f9dd7
12 changed files with 363 additions and 374 deletions

View file

@ -28,11 +28,7 @@
package mage.sets.darkascension;
import java.util.UUID;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition;
@ -40,6 +36,8 @@ import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.TargetController;
/**
@ -60,11 +58,6 @@ public class AfflictedDeserter extends CardImpl {
this.power = new MageInt(3);
this.toughness = new MageInt(2);
// Whenever this creature transforms into Werewolf Ransacker, you may destroy target artifact. If that artifact is put into a graveyard this way, Werewolf Ransacker deals 3 damage to that artifact's controller.
Ability ability1 = new WerewolfRansackerAbility();
ability1.setRuleVisible(false); // rule will be shown only on the other face of the card but triggers only on this side
this.addAbility(ability1);
// At the beginning of each upkeep, if no spells were cast last turn, transform Afflicted Deserter.
this.addAbility(new TransformAbility());
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false);
@ -80,5 +73,3 @@ public class AfflictedDeserter extends CardImpl {
return new AfflictedDeserter(this);
}
}

View file

@ -27,36 +27,24 @@
*/
package mage.sets.darkascension;
import mage.constants.*;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.condition.common.NoSpellsWereCastLastTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.filter.common.FilterCreaturePermanent;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.Token;
import mage.game.permanent.token.WolfToken;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.common.TargetOpponent;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
@ -79,9 +67,6 @@ public class HuntmasterOfTheFells extends CardImpl {
// Whenever this creature enters the battlefield or transforms into Huntmaster of the Fells, put a 2/2 green Wolf creature token onto the battlefield and you gain 2 life.
this.addAbility(new HuntmasterOfTheFellsAbility());
// Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls.
this.addAbility(new RavagerOfTheFellsAbility());
// At the beginning of each upkeep, if no spells were cast last turn, transform Huntmaster of the Fells.
this.addAbility(new TransformAbility());
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(true), TargetController.ANY, false);
@ -113,8 +98,6 @@ class HuntmasterOfTheFellsAbility extends TriggeredAbilityImpl {
public HuntmasterOfTheFellsAbility copy() {
return new HuntmasterOfTheFellsAbility(this);
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
@ -126,12 +109,12 @@ class HuntmasterOfTheFellsAbility extends TriggeredAbilityImpl {
}
return super.isInUseableZone(game, source, event);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED || event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getType() == GameEvent.EventType.TRANSFORMED && event.getTargetId().equals(this.getSourceId())) {
@ -150,141 +133,4 @@ class HuntmasterOfTheFellsAbility extends TriggeredAbilityImpl {
public String getRule() {
return "Whenever this creature enters the battlefield or transforms into {this}, put a 2/2 green Wolf creature token onto the battlefield and you gain 2 life.";
}
}
class RavagerOfTheFellsAbility extends TriggeredAbilityImpl {
public RavagerOfTheFellsAbility() {
super(Zone.BATTLEFIELD, new RavagerOfTheFellsEffect(), false);
Target target1 = new TargetOpponent();
this.addTarget(target1);
this.addTarget(new RavagerOfTheFellsTarget());
// Rule only shown on the night side
this.setRuleVisible(false);
}
public RavagerOfTheFellsAbility(final RavagerOfTheFellsAbility ability) {
super(ability);
}
@Override
public RavagerOfTheFellsAbility copy() {
return new RavagerOfTheFellsAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED;
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
Permanent currentSourceObject = (Permanent) getSourceObjectIfItStillExists(game);
if (currentSourceObject != null && currentSourceObject.isNightCard()) {
return true;
}
return super.isInUseableZone(game, source, event);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(sourceId)) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.isTransformed()) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls.";
}
}
class RavagerOfTheFellsEffect extends OneShotEffect {
public RavagerOfTheFellsEffect() {
super(Outcome.Damage);
}
public RavagerOfTheFellsEffect(final RavagerOfTheFellsEffect effect) {
super(effect);
}
@Override
public RavagerOfTheFellsEffect copy() {
return new RavagerOfTheFellsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getTargets().get(0).getFirstTarget());
if (player != null) {
player.damage(2, source.getSourceId(), game, false, true);
}
Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (creature != null) {
creature.damage(2, source.getSourceId(), game, false, true);
}
return true;
}
}
class RavagerOfTheFellsTarget extends TargetPermanent {
public RavagerOfTheFellsTarget() {
super(0, 1, new FilterCreaturePermanent(), false);
}
public RavagerOfTheFellsTarget(final RavagerOfTheFellsTarget target) {
super(target);
}
@Override
public boolean canTarget(UUID id, Ability source, Game game) {
UUID firstTarget = source.getFirstTarget();
Permanent permanent = game.getPermanent(id);
if (firstTarget != null && permanent != null && permanent.getControllerId().equals(firstTarget)) {
return super.canTarget(id, source, game);
}
return false;
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
Set<UUID> possibleTargets = new HashSet<>();
MageObject object = game.getObject(sourceId);
for (StackObject item: game.getState().getStack()) {
if (item.getId().equals(sourceId)) {
object = item;
}
if (item.getSourceId().equals(sourceId)) {
object = item;
}
}
if (object instanceof StackObject) {
UUID playerId = ((StackObject)object).getStackAbility().getFirstTarget();
for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId);
if(permanent != null && permanent.getControllerId().equals(playerId)){
possibleTargets.add(targetId);
}
}
}
return possibleTargets;
}
@Override
public RavagerOfTheFellsTarget copy() {
return new RavagerOfTheFellsTarget(this);
}
}

View file

@ -27,24 +27,36 @@
*/
package mage.sets.darkascension;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.StackObject;
import mage.players.Player;
import mage.target.Target;
import mage.target.TargetPermanent;
import mage.target.common.TargetOpponent;
/**
*
@ -52,8 +64,6 @@ import mage.constants.Zone;
*/
public class RavagerOfTheFells extends CardImpl {
private static final String rule = "Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls";
public RavagerOfTheFells(UUID ownerId) {
super(ownerId, 140, "Ravager of the Fells", Rarity.MYTHIC, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "DKA";
@ -71,7 +81,7 @@ public class RavagerOfTheFells extends CardImpl {
this.addAbility(TrampleAbility.getInstance());
// Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect(rule)));
this.addAbility(new RavagerOfTheFellsAbility());
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Ravager of the Fells.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false);
@ -87,3 +97,136 @@ public class RavagerOfTheFells extends CardImpl {
return new RavagerOfTheFells(this);
}
}
class RavagerOfTheFellsAbility extends TriggeredAbilityImpl {
public RavagerOfTheFellsAbility() {
super(Zone.BATTLEFIELD, new RavagerOfTheFellsEffect(), false);
Target target1 = new TargetOpponent();
this.addTarget(target1);
this.addTarget(new RavagerOfTheFellsTarget());
}
public RavagerOfTheFellsAbility(final RavagerOfTheFellsAbility ability) {
super(ability);
}
@Override
public RavagerOfTheFellsAbility copy() {
return new RavagerOfTheFellsAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED;
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
Permanent currentSourceObject = (Permanent) getSourceObjectIfItStillExists(game);
if (currentSourceObject != null && currentSourceObject.isNightCard()) {
return true;
}
return super.isInUseableZone(game, source, event);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(sourceId)) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.isTransformed()) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature transforms into Ravager of the Fells, it deals 2 damage to target opponent and 2 damage to up to one target creature that player controls.";
}
}
class RavagerOfTheFellsEffect extends OneShotEffect {
public RavagerOfTheFellsEffect() {
super(Outcome.Damage);
}
public RavagerOfTheFellsEffect(final RavagerOfTheFellsEffect effect) {
super(effect);
}
@Override
public RavagerOfTheFellsEffect copy() {
return new RavagerOfTheFellsEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getTargets().get(0).getFirstTarget());
if (player != null) {
player.damage(2, source.getSourceId(), game, false, true);
}
Permanent creature = game.getPermanent(source.getTargets().get(1).getFirstTarget());
if (creature != null) {
creature.damage(2, source.getSourceId(), game, false, true);
}
return true;
}
}
class RavagerOfTheFellsTarget extends TargetPermanent {
public RavagerOfTheFellsTarget() {
super(0, 1, new FilterCreaturePermanent(), false);
}
public RavagerOfTheFellsTarget(final RavagerOfTheFellsTarget target) {
super(target);
}
@Override
public boolean canTarget(UUID id, Ability source, Game game) {
UUID firstTarget = source.getFirstTarget();
Permanent permanent = game.getPermanent(id);
if (firstTarget != null && permanent != null && permanent.getControllerId().equals(firstTarget)) {
return super.canTarget(id, source, game);
}
return false;
}
@Override
public Set<UUID> possibleTargets(UUID sourceId, UUID sourceControllerId, Game game) {
Set<UUID> availablePossibleTargets = super.possibleTargets(sourceId, sourceControllerId, game);
Set<UUID> possibleTargets = new HashSet<>();
MageObject object = game.getObject(sourceId);
for (StackObject item : game.getState().getStack()) {
if (item.getId().equals(sourceId)) {
object = item;
}
if (item.getSourceId().equals(sourceId)) {
object = item;
}
}
if (object instanceof StackObject) {
UUID playerId = ((StackObject) object).getStackAbility().getFirstTarget();
for (UUID targetId : availablePossibleTargets) {
Permanent permanent = game.getPermanent(targetId);
if (permanent != null && permanent.getControllerId().equals(playerId)) {
possibleTargets.add(targetId);
}
}
}
return possibleTargets;
}
@Override
public RavagerOfTheFellsTarget copy() {
return new RavagerOfTheFellsTarget(this);
}
}

View file

@ -33,11 +33,9 @@ import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.TwoOrMoreSpellsWereCastLastTurnCondition;
import mage.abilities.decorator.ConditionalTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
@ -75,7 +73,7 @@ public class WerewolfRansacker extends CardImpl {
this.toughness = new MageInt(4);
// Whenever this creature transforms into Werewolf Ransacker, you may destroy target artifact. If that artifact is put into a graveyard this way, Werewolf Ransacker deals 3 damage to that artifact's controller.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect(WerewolfRansackerAbility.RULE_TEXT)));
this.addAbility(new WerewolfRansackerAbility());
// At the beginning of each upkeep, if a player cast two or more spells last turn, transform Werewolf Ransacker.
TriggeredAbility ability = new BeginningOfUpkeepTriggeredAbility(new TransformSourceEffect(false), TargetController.ANY, false);
@ -93,9 +91,9 @@ public class WerewolfRansacker extends CardImpl {
}
class WerewolfRansackerAbility extends TriggeredAbilityImpl {
public static final String RULE_TEXT = "Whenever this creature transforms into Werewolf Ransacker, you may destroy target artifact. If that artifact is put into a graveyard this way, Werewolf Ransacker deals 3 damage to that artifact's controller";
public WerewolfRansackerAbility() {
super(Zone.BATTLEFIELD, new WerewolfRansackerEffect(), true);
Target target = new TargetPermanent(new FilterArtifactPermanent());
@ -159,8 +157,9 @@ class WerewolfRansackerEffect extends OneShotEffect {
affectedTargets++;
if (game.getState().getZone(permanent.getId()) == Zone.GRAVEYARD) {
Player player = game.getPlayer(permanent.getControllerId());
if (player != null)
if (player != null) {
player.damage(3, source.getSourceId(), game, false, true);
}
}
}
}

View file

@ -29,28 +29,15 @@ package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.condition.common.EquippedSourceCondition;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.TargetController;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/**
*
@ -73,11 +60,6 @@ public class AvacynianMissionaries extends CardImpl {
this.addAbility(new TransformAbility());
this.addAbility(new BeginningOfEndStepTriggeredAbility(Zone.BATTLEFIELD, new TransformSourceEffect(true), TargetController.YOU, new EquippedSourceCondition(), false));
// When this creature transforms into Lunarch Inquisitors, you may exile another target creature until Lunarch Inquisitors leaves the battlefield.
Ability ability = new LunarchInquisitorsAbility();
ability.addTarget(new TargetCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability);
}
public AvacynianMissionaries(final AvacynianMissionaries card) {
@ -89,80 +71,3 @@ public class AvacynianMissionaries extends CardImpl {
return new AvacynianMissionaries(this);
}
}
class LunarchInquisitorsAbility extends TriggeredAbilityImpl {
public LunarchInquisitorsAbility() {
super(Zone.BATTLEFIELD, new LunarchInquisitorsExileEffect(), true);
// Rule only shown on the night side
this.setRuleVisible(false);
}
public LunarchInquisitorsAbility(final LunarchInquisitorsAbility ability) {
super(ability);
}
@Override
public LunarchInquisitorsAbility copy() {
return new LunarchInquisitorsAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED;
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
Permanent currentSourceObject = (Permanent) getSourceObjectIfItStillExists(game);
if (currentSourceObject != null && currentSourceObject.isNightCard()) {
return true;
}
return super.isInUseableZone(game, source, event);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(sourceId)) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.isTransformed()) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature transforms into Lunarch Inquisitors, you may exile another target creature until Lunarch Inquisitors leaves the battlefield.";
}
}
class LunarchInquisitorsExileEffect extends OneShotEffect {
public LunarchInquisitorsExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile target creature until {this} leaves the battlefield";
}
public LunarchInquisitorsExileEffect(final LunarchInquisitorsExileEffect effect) {
super(effect);
}
@Override
public LunarchInquisitorsExileEffect copy() {
return new LunarchInquisitorsExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If Lunarch Inquisitors leaves the battlefield before its triggered ability resolves,
// the target won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -29,12 +29,18 @@ package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
@ -42,8 +48,6 @@ import mage.constants.Zone;
*/
public class AwokenHorror extends CardImpl {
private static final String rule = "Whenever this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands";
public AwokenHorror(UUID ownerId) {
super(ownerId, 92, "Awoken Horror", Rarity.RARE, new CardType[]{CardType.CREATURE}, "");
this.expansionSetCode = "SOI";
@ -56,7 +60,7 @@ public class AwokenHorror extends CardImpl {
this.nightCard = true;
// When this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect(rule)));
this.addAbility(new AwokenHorrorAbility());
}
public AwokenHorror(final AwokenHorror card) {
@ -68,3 +72,55 @@ public class AwokenHorror extends CardImpl {
return new AwokenHorror(this);
}
}
class AwokenHorrorAbility extends TriggeredAbilityImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Horror creatures");
static {
filter.add(Predicates.not(new SubtypePredicate("Horror")));
}
public AwokenHorrorAbility() {
super(Zone.BATTLEFIELD, new ReturnToHandFromBattlefieldAllEffect(filter), false);
}
public AwokenHorrorAbility(final AwokenHorrorAbility ability) {
super(ability);
}
@Override
public AwokenHorrorAbility copy() {
return new AwokenHorrorAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED;
}
// @Override
// public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
// Permanent currentSourceObject = (Permanent) getSourceObjectIfItStillExists(game);
// if (currentSourceObject != null && currentSourceObject.isTransformed()) {
// // hard to check if the not transformed source hat the ability. But if it was transformed it probably had it, but maybe no perfect solution
// return true;
// }
// return false;
// }
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(sourceId)) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.isTransformed()) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands.";
}
}

View file

@ -29,12 +29,23 @@ package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.delayed.OnLeaveReturnExiledToBattlefieldAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.ExileTargetEffect;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil;
/**
*
@ -57,7 +68,10 @@ public class LunarchInquisitors extends CardImpl {
this.nightCard = true;
// When this creature transforms into Lunarch Inquisitors, you may exile another target creature until Lunarch Inquisitors leaves the battlefield.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new InfoEffect(rule)));
Ability ability = new LunarchInquisitorsAbility();
ability.addTarget(new TargetCreaturePermanent());
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new OnLeaveReturnExiledToBattlefieldAbility()));
this.addAbility(ability);
}
public LunarchInquisitors(final LunarchInquisitors card) {
@ -69,3 +83,79 @@ public class LunarchInquisitors extends CardImpl {
return new LunarchInquisitors(this);
}
}
class LunarchInquisitorsAbility extends TriggeredAbilityImpl {
public LunarchInquisitorsAbility() {
super(Zone.BATTLEFIELD, new LunarchInquisitorsExileEffect(), true);
// Rule only shown on the night side
this.setRuleVisible(false);
}
public LunarchInquisitorsAbility(final LunarchInquisitorsAbility ability) {
super(ability);
}
@Override
public LunarchInquisitorsAbility copy() {
return new LunarchInquisitorsAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED;
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
Permanent currentSourceObject = (Permanent) getSourceObjectIfItStillExists(game);
if (currentSourceObject != null && currentSourceObject.isNightCard()) {
return true;
}
return super.isInUseableZone(game, source, event);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(sourceId)) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.isTransformed()) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature transforms into Lunarch Inquisitors, you may exile another target creature until Lunarch Inquisitors leaves the battlefield.";
}
}
class LunarchInquisitorsExileEffect extends OneShotEffect {
public LunarchInquisitorsExileEffect() {
super(Outcome.Benefit);
this.staticText = "exile target creature until {this} leaves the battlefield";
}
public LunarchInquisitorsExileEffect(final LunarchInquisitorsExileEffect effect) {
super(effect);
}
@Override
public LunarchInquisitorsExileEffect copy() {
return new LunarchInquisitorsExileEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
// If Lunarch Inquisitors leaves the battlefield before its triggered ability resolves,
// the target won't be exiled.
if (permanent != null) {
return new ExileTargetEffect(CardUtil.getCardExileZoneId(game, source), permanent.getIdName()).apply(game, source);
}
return false;
}
}

View file

@ -29,15 +29,12 @@ package mage.sets.shadowsoverinnistrad;
import java.util.UUID;
import mage.MageInt;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.decorator.ConditionalOneShotEffect;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.ReturnToHandFromBattlefieldAllEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
@ -46,16 +43,10 @@ import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.constants.CardType;
import mage.constants.Rarity;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.FilterSpell;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.CardTypePredicate;
import mage.filter.predicate.mageobject.SubtypePredicate;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
/**
*
@ -99,8 +90,6 @@ public class ThingInTheIce extends CardImpl {
ability.addEffect(effect);
this.addAbility(ability);
// When this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands.
this.addAbility(new AwokenHorrorAbility());
}
public ThingInTheIce(final ThingInTheIce card) {
@ -112,58 +101,3 @@ public class ThingInTheIce extends CardImpl {
return new ThingInTheIce(this);
}
}
class AwokenHorrorAbility extends TriggeredAbilityImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("non-Horror creatures");
static {
filter.add(Predicates.not(new SubtypePredicate("Horror")));
}
public AwokenHorrorAbility() {
super(Zone.BATTLEFIELD, new ReturnToHandFromBattlefieldAllEffect(filter), false);
// Rule only shown on the night side
this.setRuleVisible(false);
}
public AwokenHorrorAbility(final AwokenHorrorAbility ability) {
super(ability);
}
@Override
public AwokenHorrorAbility copy() {
return new AwokenHorrorAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.TRANSFORMED;
}
@Override
public boolean isInUseableZone(Game game, MageObject source, GameEvent event) {
Permanent currentSourceObject = (Permanent) getSourceObjectIfItStillExists(game);
if (currentSourceObject != null && currentSourceObject.isNightCard()) {
return true;
}
return super.isInUseableZone(game, source, event);
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getTargetId().equals(sourceId)) {
Permanent permanent = game.getPermanent(sourceId);
if (permanent != null && permanent.isTransformed()) {
return true;
}
}
return false;
}
@Override
public String getRule() {
return "Whenever this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands.";
}
}

View file

@ -19,11 +19,11 @@ public class WerewolfRansackerTest extends CardTestPlayerBase {
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertLife(playerA, 20);
assertLife(playerB, 17);
assertPermanentCount(playerB, "Ornithopter", 0);
assertPermanentCount(playerA, "Afflicted Deserter", 0);
assertPermanentCount(playerA, "Werewolf Ransacker", 1);
assertLife(playerA, 20);
assertLife(playerB, 17);
}
@Test
@ -69,5 +69,5 @@ public class WerewolfRansackerTest extends CardTestPlayerBase {
assertPermanentCount(playerB, "Ornithopter", 0);
assertPermanentCount(playerA, "Afflicted Deserter", 1);
assertPermanentCount(playerA, "Werewolf Ransacker", 0);
}
}
}

View file

@ -6,30 +6,41 @@ import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
*Defender
Thing in the Ice enters the battlefield with four ice counters on it.
Whenever you cast an instant or sorcery spell, remove an ice counter from Thing in the Ice. Then if it has no ice counters on it, transform it.
When this creature transforms into Awoken Horror, return all non-Horror creatures to their owners' hands.
* Defender
*
* Thing in the Ice enters the battlefield with four ice counters on it.
*
* Whenever you cast an instant or sorcery spell, remove an ice counter from
* Thing in the Ice. Then if it has no ice counters on it, transform it. When
* this creature transforms into Awoken Horror, return all non-Horror creatures
* to their owners' hands.
*
* @author escplan9 (Derek Monturo - dmontur1 at gmail dot com)
*/
public class ThingInTheIceTest extends CardTestPlayerBase {
/**
* Reported bug: When Thing in the Ice transforms, it bounces Clue tokens.
**/
*
*/
@Test
public void testClueTokens() {
addCard(Zone.BATTLEFIELD, playerA, "Tireless Tracker", 1);
// Whenever a land enters the battlefield under your control, investigate. <i>(Put a colorless Clue artifact token onto the battlefield with "{2}, Sacrifice this artifact: Draw a card.")</i>
// Whenever you sacrifice a Clue, put a +1/+1 counter on Tireless Tracker.
addCard(Zone.BATTLEFIELD, playerA, "Tireless Tracker", 1); // Human, Scout 3/2
addCard(Zone.HAND, playerA, "Forest", 1);
// Defender
// Thing in the Ice enters the battlefield with four ice counters on it.
// Whenever you cast an instant or sorcery spell, remove an ice counter from Thing in the Ice. Then if it has no ice counters on it, transform it.
// When this creature transforms into Awoken Horrow, return all non-Horror creatures to their owners' hands.
addCard(Zone.BATTLEFIELD, playerB, "Thing in the Ice", 1);
// Target creature gains haste until end of turn.
// Draw a card.
addCard(Zone.HAND, playerB, "Expedite", 4);
addCard(Zone.BATTLEFIELD, playerB, "Mountain", 4);
playLand(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Forest"); // creates a clue
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Expedite");
addTarget(playerB, "Thing in the Ice");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Expedite");
@ -38,10 +49,10 @@ public class ThingInTheIceTest extends CardTestPlayerBase {
addTarget(playerB, "Thing in the Ice");
castSpell(2, PhaseStep.PRECOMBAT_MAIN, playerB, "Expedite");
addTarget(playerB, "Thing in the Ice"); // remove all 4 ice counters to transform it
setStopAt(2, PhaseStep.BEGIN_COMBAT);
execute();
assertPermanentCount(playerA, "Clue", 1);
assertHandCount(playerA, "Tireless Tracker", 1); // returned to hand
assertPermanentCount(playerA, "Tireless Tracker", 0);

View file

@ -1167,6 +1167,9 @@ public abstract class AbilityImpl implements Ability {
public MageObject getSourceObjectIfItStillExists(Game game) {
MageObject currentObject = game.getObject(getSourceId());
if (currentObject != null) {
if (sourceObject == null) {
setSourceObject(currentObject, game);
}
MageObjectReference mor = new MageObjectReference(currentObject, game);
if (mor.getZoneChangeCounter() == getSourceObjectZoneChangeCounter()) {
// source object has meanwhile not changed zone

View file

@ -31,6 +31,7 @@ import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
import mage.constants.Zone;
@ -78,20 +79,30 @@ public class ReturnToBattlefieldUnderOwnerControlTargetEffect extends OneShotEff
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = null;
Cards cardsToMove = new CardsImpl();
if (fromExileZone) {
UUID exilZoneId = CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter());
if (exilZoneId != null) {
ExileZone exileZone = game.getExile().getExileZone(exilZoneId);
if (exileZone != null && getTargetPointer().getFirst(game, source) != null) {
card = exileZone.get(getTargetPointer().getFirst(game, source), game);
if (exileZone != null) {
for (UUID cardId : getTargetPointer().getTargets(game, source)) {
Card card = exileZone.get(cardId, game);
if (card != null) {
cardsToMove.add(card);
}
}
}
}
} else {
card = game.getCard(getTargetPointer().getFirst(game, source));
for (UUID cardId : getTargetPointer().getTargets(game, source)) {
Card card = game.getCard(cardId);
if (card != null) {
cardsToMove.add(card);
}
}
}
if (card != null) {
controller.moveCards(new CardsImpl(card).getCards(game),
if (!cardsToMove.isEmpty()) {
controller.moveCards(cardsToMove.getCards(game),
Zone.BATTLEFIELD, source, game, tapped, false, true, null);
return true;
}