mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
convert a few more cards and add tests
This commit is contained in:
parent
0f25453898
commit
f46c84d41c
12 changed files with 241 additions and 215 deletions
|
|
@ -1,53 +1,80 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
|
||||
import mage.abilities.condition.Condition;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.costs.common.TapSourceCost;
|
||||
import mage.abilities.costs.mana.GenericManaCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.effects.keyword.InvestigateEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.abilities.mana.BlackManaAbility;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.TransformingDoubleFacedCard;
|
||||
import mage.constants.*;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
import mage.watchers.Watcher;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class HavengulLaboratory extends CardImpl {
|
||||
public final class HavengulLaboratory extends TransformingDoubleFacedCard {
|
||||
|
||||
public HavengulLaboratory(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
super(
|
||||
ownerId, setInfo,
|
||||
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, "",
|
||||
"Havengul Mystery",
|
||||
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.LAND}, new SubType[]{}, ""
|
||||
);
|
||||
|
||||
this.secondSideCardClazz = mage.cards.h.HavengulMystery.class;
|
||||
|
||||
// {T}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
this.getLeftHalfCard().addAbility(new ColorlessManaAbility());
|
||||
|
||||
// {4}, {T}: Investigate.
|
||||
Ability ability = new SimpleActivatedAbility(new InvestigateEffect(), new GenericManaCost(4));
|
||||
ability.addCost(new TapSourceCost());
|
||||
this.addAbility(ability);
|
||||
this.getLeftHalfCard().addAbility(ability);
|
||||
|
||||
// At the beginning of your end step, if you sacrificed three or more Clues this turn, transform Havengul Laboratory.
|
||||
this.addAbility(new TransformAbility());
|
||||
this.addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||
this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(
|
||||
TargetController.YOU, new TransformSourceEffect(),
|
||||
false, HavengulLaboratoryCondition.instance
|
||||
), new HavengulLaboratoryWatcher());
|
||||
|
||||
// When this land transforms into Havengul Mystery, return target creature card from your graveyard to the battlefield.
|
||||
ability = new TransformIntoSourceTriggeredAbility(new HavengulMysteryEffect())
|
||||
.setTriggerPhrase("When this land transforms into {this}, ");
|
||||
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
|
||||
this.getRightHalfCard().addAbility(ability);
|
||||
|
||||
// When the creature put onto the battlefield with Havengul Mystery leaves the battlefield, transform Havengul Mystery.
|
||||
this.getRightHalfCard().addAbility(new HavengulMysteryLeavesAbility());
|
||||
|
||||
// {T}, Pay 1 life: Add {B}.
|
||||
ability = new BlackManaAbility();
|
||||
ability.addCost(new PayLifeCost(1));
|
||||
this.getRightHalfCard().addAbility(ability);
|
||||
|
||||
this.finalizeDFC();
|
||||
}
|
||||
|
||||
private HavengulLaboratory(final HavengulLaboratory card) {
|
||||
|
|
@ -58,6 +85,10 @@ public final class HavengulLaboratory extends CardImpl {
|
|||
public HavengulLaboratory copy() {
|
||||
return new HavengulLaboratory(this);
|
||||
}
|
||||
|
||||
static String makeKey(Ability source, Game game) {
|
||||
return "HavengulMystery_" + source.getSourceId() + '_' + CardUtil.getActualSourceObjectZoneChangeCounter(game, source);
|
||||
}
|
||||
}
|
||||
|
||||
enum HavengulLaboratoryCondition implements Condition {
|
||||
|
|
@ -108,3 +139,85 @@ class HavengulLaboratoryWatcher extends Watcher {
|
|||
.getOrDefault(playerId, 0) >= 3;
|
||||
}
|
||||
}
|
||||
|
||||
class HavengulMysteryEffect extends OneShotEffect {
|
||||
|
||||
HavengulMysteryEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "return target creature card from your graveyard to the battlefield";
|
||||
}
|
||||
|
||||
private HavengulMysteryEffect(final HavengulMysteryEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HavengulMysteryEffect copy() {
|
||||
return new HavengulMysteryEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (player == null || card == null) {
|
||||
return false;
|
||||
}
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game);
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
String key = HavengulLaboratory.makeKey(source, game);
|
||||
Set<MageObjectReference> morSet;
|
||||
if (game.getState().getValue(key) != null) {
|
||||
morSet = (Set<MageObjectReference>) game.getState().getValue(key);
|
||||
} else {
|
||||
morSet = new HashSet<>();
|
||||
game.getState().setValue(key, morSet);
|
||||
}
|
||||
morSet.add(new MageObjectReference(permanent, game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class HavengulMysteryLeavesAbility extends TriggeredAbilityImpl {
|
||||
|
||||
HavengulMysteryLeavesAbility() {
|
||||
super(Zone.BATTLEFIELD, new TransformSourceEffect());
|
||||
setLeavesTheBattlefieldTrigger(true);
|
||||
}
|
||||
|
||||
private HavengulMysteryLeavesAbility(final HavengulMysteryLeavesAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HavengulMysteryLeavesAbility copy() {
|
||||
return new HavengulMysteryLeavesAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() != Zone.BATTLEFIELD) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String key = HavengulLaboratory.makeKey(this, game);
|
||||
Set<MageObjectReference> morSet = (Set<MageObjectReference>) game.getState().getValue(key);
|
||||
return morSet != null
|
||||
&& !morSet.isEmpty()
|
||||
&& morSet.stream().anyMatch(mor -> mor.refersTo(zEvent.getTarget(), game));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When the creature put onto the battlefield with {this} leaves the battlefield, transform {this}.";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,31 +1,10 @@
|
|||
package mage.cards.h;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.TriggeredAbilityImpl;
|
||||
import mage.abilities.common.TransformIntoSourceTriggeredAbility;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.mana.BlackManaAbility;
|
||||
import mage.cards.Card;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.TransformingDoubleFacedCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SuperType;
|
||||
import mage.constants.Zone;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.events.ZoneChangeEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCardInYourGraveyard;
|
||||
import mage.util.CardUtil;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
|
|
@ -34,23 +13,9 @@ import java.util.UUID;
|
|||
public final class HavengulMystery extends CardImpl {
|
||||
|
||||
public HavengulMystery(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
super(ownerId, setInfo, new CardType[]{}, "");
|
||||
this.nightCard = true;
|
||||
|
||||
// When this land transforms into Havengul Mystery, return target creature card from your graveyard to the battlefield.
|
||||
Ability ability = new TransformIntoSourceTriggeredAbility(new HavengulMysteryEffect())
|
||||
.setTriggerPhrase("When this land transforms into {this}, ");
|
||||
ability.addTarget(new TargetCardInYourGraveyard(StaticFilters.FILTER_CARD_CREATURE_YOUR_GRAVEYARD));
|
||||
this.addAbility(ability);
|
||||
|
||||
// When the creature put onto the battlefield with Havengul Mystery leaves the battlefield, transform Havengul Mystery.
|
||||
this.addAbility(new HavengulMysteryLeavesAbility());
|
||||
|
||||
// {T}, Pay 1 life: Add {B}.
|
||||
Ability ability2 = new BlackManaAbility();
|
||||
ability2.addCost(new PayLifeCost(1));
|
||||
this.addAbility(ability2);
|
||||
TransformingDoubleFacedCard.copyToBackFace(new HavengulLaboratory(ownerId, setInfo), this);
|
||||
}
|
||||
|
||||
private HavengulMystery(final HavengulMystery card) {
|
||||
|
|
@ -61,90 +26,4 @@ public final class HavengulMystery extends CardImpl {
|
|||
public HavengulMystery copy() {
|
||||
return new HavengulMystery(this);
|
||||
}
|
||||
|
||||
static String makeKey(Ability source, Game game) {
|
||||
return "HavengulMystery_" + source.getSourceId() + '_' + CardUtil.getActualSourceObjectZoneChangeCounter(game, source);
|
||||
}
|
||||
}
|
||||
|
||||
class HavengulMysteryEffect extends OneShotEffect {
|
||||
|
||||
HavengulMysteryEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "return target creature card from your graveyard to the battlefield";
|
||||
}
|
||||
|
||||
private HavengulMysteryEffect(final HavengulMysteryEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HavengulMysteryEffect copy() {
|
||||
return new HavengulMysteryEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player player = game.getPlayer(source.getControllerId());
|
||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||
if (player == null || card == null) {
|
||||
return false;
|
||||
}
|
||||
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||
Permanent permanent = CardUtil.getPermanentFromCardPutToBattlefield(card, game);
|
||||
if (permanent == null) {
|
||||
return false;
|
||||
}
|
||||
String key = HavengulMystery.makeKey(source, game);
|
||||
Set<MageObjectReference> morSet;
|
||||
if (game.getState().getValue(key) != null) {
|
||||
morSet = (Set<MageObjectReference>) game.getState().getValue(key);
|
||||
} else {
|
||||
morSet = new HashSet<>();
|
||||
game.getState().setValue(key, morSet);
|
||||
}
|
||||
morSet.add(new MageObjectReference(permanent, game));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class HavengulMysteryLeavesAbility extends TriggeredAbilityImpl {
|
||||
|
||||
HavengulMysteryLeavesAbility() {
|
||||
super(Zone.BATTLEFIELD, new TransformSourceEffect());
|
||||
setLeavesTheBattlefieldTrigger(true);
|
||||
}
|
||||
|
||||
private HavengulMysteryLeavesAbility(final HavengulMysteryLeavesAbility ability) {
|
||||
super(ability);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HavengulMysteryLeavesAbility copy() {
|
||||
return new HavengulMysteryLeavesAbility(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ZONE_CHANGE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkTrigger(GameEvent event, Game game) {
|
||||
ZoneChangeEvent zEvent = (ZoneChangeEvent) event;
|
||||
if (zEvent.getFromZone() != Zone.BATTLEFIELD) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String key = HavengulMystery.makeKey(this, game);
|
||||
Set<MageObjectReference> morSet = (Set<MageObjectReference>) game.getState().getValue(key);
|
||||
return morSet != null
|
||||
&& !morSet.isEmpty()
|
||||
&& morSet.stream().anyMatch(mor -> mor.refersTo(zEvent.getTarget(), game));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRule() {
|
||||
return "When the creature put onto the battlefield with {this} leaves the battlefield, transform {this}.";
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,14 +3,16 @@ package mage.cards.i;
|
|||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||
import mage.abilities.common.SiegeAbility;
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.continuous.BoostTargetEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.abilities.keyword.VigilanceAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.TransformingDoubleFacedCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.game.permanent.token.ValorsReachTagTeamToken;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
|
@ -18,17 +20,21 @@ import java.util.UUID;
|
|||
/**
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class InvasionOfKylem extends CardImpl {
|
||||
public final class InvasionOfKylem extends TransformingDoubleFacedCard {
|
||||
|
||||
public InvasionOfKylem(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.BATTLE}, "{2}{R}{W}");
|
||||
super(
|
||||
ownerId, setInfo,
|
||||
new CardType[]{CardType.BATTLE}, new SubType[]{SubType.SIEGE}, "{2}{R}{W}",
|
||||
"Valor's Reach Tag Team",
|
||||
new CardType[]{CardType.SORCERY}, new SubType[]{}, "RW"
|
||||
);
|
||||
this.getLeftHalfCard().setStartingDefense(5);
|
||||
|
||||
this.subtype.add(SubType.SIEGE);
|
||||
this.setStartingDefense(5);
|
||||
this.secondSideCardClazz = mage.cards.v.ValorsReachTagTeam.class;
|
||||
|
||||
// (As a Siege enters, choose an opponent to protect it. You and others can attack it. When it's defeated, exile it, then cast it transformed.)
|
||||
this.addAbility(new SiegeAbility());
|
||||
this.getLeftHalfCard().addAbility(new SiegeAbility());
|
||||
|
||||
// When Invasion of Kylem enters the battlefield, up to two target creatures each get +2/+0 and gain vigilance and haste until end of turn.
|
||||
Ability ability = new EntersBattlefieldTriggeredAbility(new BoostTargetEffect(2, 0)
|
||||
|
|
@ -38,7 +44,13 @@ public final class InvasionOfKylem extends CardImpl {
|
|||
ability.addEffect(new GainAbilityTargetEffect(HasteAbility.getInstance())
|
||||
.setText("and haste until end of turn"));
|
||||
ability.addTarget(new TargetCreaturePermanent(0, 2));
|
||||
this.addAbility(ability);
|
||||
this.getLeftHalfCard().addAbility(ability);
|
||||
|
||||
// Valor's Reach Tag Team
|
||||
// Create two 3/2 red and white Warrior creature tokens with "Whenever this creature and at least one other creature token attack, put a +1/+1 counter on this creature."
|
||||
this.getRightHalfCard().getSpellAbility().addEffect(new CreateTokenEffect(new ValorsReachTagTeamToken(), 2));
|
||||
|
||||
this.finalizeDFC();
|
||||
}
|
||||
|
||||
private InvasionOfKylem(final InvasionOfKylem card) {
|
||||
|
|
|
|||
|
|
@ -1,43 +1,22 @@
|
|||
|
||||
package mage.cards.o;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.MageInt;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.TransformingDoubleFacedCard;
|
||||
import mage.cards.w.WestvaleAbbey;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class OrmendahlProfanePrince extends CardImpl {
|
||||
|
||||
public OrmendahlProfanePrince(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"");
|
||||
this.supertype.add(SuperType.LEGENDARY);
|
||||
this.subtype.add(SubType.DEMON);
|
||||
this.power = new MageInt(9);
|
||||
this.toughness = new MageInt(7);
|
||||
this.color.setBlack(true);
|
||||
|
||||
// this card is the second face of double-faced card
|
||||
super(ownerId, setInfo, new CardType[]{}, "");
|
||||
this.nightCard = true;
|
||||
|
||||
// Flying
|
||||
this.addAbility(FlyingAbility.getInstance());
|
||||
// Lifelink
|
||||
this.addAbility(LifelinkAbility.getInstance());
|
||||
// Indestructible
|
||||
this.addAbility(IndestructibleAbility.getInstance());
|
||||
// Haste
|
||||
this.addAbility(HasteAbility.getInstance());
|
||||
TransformingDoubleFacedCard.copyToBackFace(new WestvaleAbbey(ownerId, setInfo), this);
|
||||
}
|
||||
|
||||
private OrmendahlProfanePrince(final OrmendahlProfanePrince card) {
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package mage.cards.v;
|
||||
|
||||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.TransformingDoubleFacedCard;
|
||||
import mage.cards.i.InvasionOfKylem;
|
||||
import mage.constants.CardType;
|
||||
import mage.game.permanent.token.ValorsReachTagTeamToken;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
|
|
@ -14,14 +14,9 @@ import java.util.UUID;
|
|||
public final class ValorsReachTagTeam extends CardImpl {
|
||||
|
||||
public ValorsReachTagTeam(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "");
|
||||
|
||||
this.color.setWhite(true);
|
||||
this.color.setRed(true);
|
||||
super(ownerId, setInfo, new CardType[]{}, "");
|
||||
this.nightCard = true;
|
||||
|
||||
// Create two 3/2 red and white Warrior creature tokens with "Whenever this creature and at least one other creature token attack, put a +1/+1 counter on this creature."
|
||||
this.getSpellAbility().addEffect(new CreateTokenEffect(new ValorsReachTagTeamToken(), 2));
|
||||
TransformingDoubleFacedCard.copyToBackFace(new InvasionOfKylem(ownerId, setInfo), this);
|
||||
}
|
||||
|
||||
private ValorsReachTagTeam(final ValorsReachTagTeam card) {
|
||||
|
|
|
|||
|
|
@ -1,8 +1,5 @@
|
|||
|
||||
package mage.cards.w;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.SimpleActivatedAbility;
|
||||
import mage.abilities.costs.common.PayLifeCost;
|
||||
|
|
@ -12,43 +9,67 @@ import mage.abilities.costs.mana.GenericManaCost;
|
|||
import mage.abilities.effects.common.CreateTokenEffect;
|
||||
import mage.abilities.effects.common.TransformSourceEffect;
|
||||
import mage.abilities.effects.common.UntapSourceEffect;
|
||||
import mage.abilities.keyword.TransformAbility;
|
||||
import mage.abilities.keyword.FlyingAbility;
|
||||
import mage.abilities.keyword.HasteAbility;
|
||||
import mage.abilities.keyword.IndestructibleAbility;
|
||||
import mage.abilities.keyword.LifelinkAbility;
|
||||
import mage.abilities.mana.ColorlessManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.cards.TransformingDoubleFacedCard;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Zone;
|
||||
import mage.constants.SubType;
|
||||
import mage.constants.SuperType;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.game.permanent.token.HumanClericToken;
|
||||
import mage.target.common.TargetControlledPermanent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author fireshoes
|
||||
*/
|
||||
public final class WestvaleAbbey extends CardImpl {
|
||||
public final class WestvaleAbbey extends TransformingDoubleFacedCard {
|
||||
|
||||
public WestvaleAbbey(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.LAND}, "");
|
||||
super(
|
||||
ownerId, setInfo,
|
||||
new SuperType[]{}, new CardType[]{CardType.LAND}, new SubType[]{}, "",
|
||||
"Ormendahl, Profane Prince",
|
||||
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.CREATURE}, new SubType[]{SubType.DEMON}, "B"
|
||||
);
|
||||
this.getRightHalfCard().setPT(9, 7);
|
||||
|
||||
this.secondSideCardClazz = mage.cards.o.OrmendahlProfanePrince.class;
|
||||
|
||||
// {T}: Add {C}.
|
||||
this.addAbility(new ColorlessManaAbility());
|
||||
this.getLeftHalfCard().addAbility(new ColorlessManaAbility());
|
||||
|
||||
// {5}, {T}, Pay 1 life: Create a 1/1 white and black Human Cleric creature token.
|
||||
Ability ability = new SimpleActivatedAbility(new CreateTokenEffect(new HumanClericToken()), new GenericManaCost(5));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new PayLifeCost(1));
|
||||
this.addAbility(ability);
|
||||
this.getLeftHalfCard().addAbility(ability);
|
||||
|
||||
// {5}, {T}, Sacrifice five creatures: Transform Westvale Abbey and untap it.
|
||||
this.addAbility(new TransformAbility());
|
||||
ability = new SimpleActivatedAbility(new TransformSourceEffect(), new GenericManaCost(5));
|
||||
ability.addCost(new TapSourceCost());
|
||||
ability.addCost(new SacrificeTargetCost(5, StaticFilters.FILTER_PERMANENT_CREATURES));
|
||||
ability.addEffect(new UntapSourceEffect().setText("untap it").concatBy(", then"));
|
||||
this.addAbility(ability);
|
||||
this.getLeftHalfCard().addAbility(ability);
|
||||
|
||||
// Ormendahl, Profane Prince
|
||||
// Flying
|
||||
this.getRightHalfCard().addAbility(FlyingAbility.getInstance());
|
||||
|
||||
// Lifelink
|
||||
this.getRightHalfCard().addAbility(LifelinkAbility.getInstance());
|
||||
|
||||
// Indestructible
|
||||
this.getRightHalfCard().addAbility(IndestructibleAbility.getInstance());
|
||||
|
||||
// Haste
|
||||
this.getRightHalfCard().addAbility(HasteAbility.getInstance());
|
||||
|
||||
this.finalizeDFC();
|
||||
}
|
||||
|
||||
private WestvaleAbbey(final WestvaleAbbey card) {
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ public class BattleBaseTest extends CardTestPlayerBaseWithAIHelps {
|
|||
protected static final String impact = "Explosive Impact";
|
||||
protected static final String stifle = "Stifle";
|
||||
protected static final String fayden = "Dack Fayden";
|
||||
protected static final String kylem = "Invasion of Kylem";
|
||||
|
||||
protected void assertBattle(Player controller, Player protector, String name) {
|
||||
assertPermanentCount(controller, name, 1);
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import mage.constants.PhaseStep;
|
|||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.player.TestPlayer;
|
||||
|
||||
/**
|
||||
* @author TheElk801, JayDi85
|
||||
|
|
@ -264,4 +265,24 @@ public class BattleDuelTest extends BattleBaseTest {
|
|||
assertCounterCount(belenon, CounterType.DEFENSE, 5);
|
||||
assertCounterCount(fayden, CounterType.LOYALTY, 3 - 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvasionOfKylem() {
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plateau", 4 + 6);
|
||||
addCard(Zone.HAND, playerA, kylem);
|
||||
addCard(Zone.HAND, playerA, impact);
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, kylem);
|
||||
addTarget(playerA, TestPlayer.TARGET_SKIP); // don't choose any targets for etb trigger
|
||||
|
||||
castSpell(1, PhaseStep.POSTCOMBAT_MAIN, playerA, impact, kylem);
|
||||
setChoice(playerA, true); // yes to cast it transformed
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_TURN);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, kylem, 0);
|
||||
assertPermanentCount(playerA, "Warrior Token", 2);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ import mage.game.GameState;
|
|||
import mage.game.Ownerable;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.util.ManaUtil;
|
||||
import mage.watchers.Watcher;
|
||||
import mage.watchers.common.CommanderPlaysCountWatcher;
|
||||
|
||||
import java.util.List;
|
||||
|
|
@ -155,6 +156,11 @@ public interface Card extends MageObject, Ownerable {
|
|||
|
||||
Counters getCounters(GameState state);
|
||||
|
||||
default void addAbility(Ability ability, Watcher watcher) {
|
||||
addAbility(ability);
|
||||
ability.addWatcher(watcher);
|
||||
}
|
||||
|
||||
void addAbility(Ability ability);
|
||||
|
||||
void looseAllAbilities(Game game);
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import mage.game.stack.StackObject;
|
|||
import mage.util.CardUtil;
|
||||
import mage.util.GameLog;
|
||||
import mage.util.ManaUtil;
|
||||
import mage.watchers.Watcher;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
|
|
@ -357,11 +356,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
|||
}
|
||||
}
|
||||
|
||||
protected void addAbility(Ability ability, Watcher watcher) {
|
||||
addAbility(ability);
|
||||
ability.addWatcher(watcher);
|
||||
}
|
||||
|
||||
public void replaceSpellAbility(SpellAbility newAbility) {
|
||||
SpellAbility oldAbility = this.getSpellAbility();
|
||||
while (oldAbility != null) {
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ public abstract class TransformingDoubleFacedCard extends CardImpl {
|
|||
SuperType[] superTypesRight, CardType[] typesRight, SubType[] subTypesRight, String colorRight
|
||||
) {
|
||||
super(ownerId, setInfo, typesLeft, costsLeft);
|
||||
this.leftHalfCard = new TransformingDoubleFacedCardHalfImpl(ownerId, setInfo, costsLeft);
|
||||
this.rightHalfCard = new TransformingDoubleFacedCardHalfImpl(ownerId, setInfo, "");
|
||||
this.leftHalfCard = new TransformingDoubleFacedCardHalfImpl(ownerId, setInfo, typesLeft, costsLeft);
|
||||
this.rightHalfCard = new TransformingDoubleFacedCardHalfImpl(ownerId, setInfo, typesRight, "");
|
||||
for (SuperType superType : superTypesLeft) {
|
||||
this.getLeftHalfCard().getSuperType().add(superType);
|
||||
}
|
||||
|
|
@ -50,7 +50,6 @@ public abstract class TransformingDoubleFacedCard extends CardImpl {
|
|||
for (SuperType superType : superTypesRight) {
|
||||
this.getRightHalfCard().getSuperType().add(superType);
|
||||
}
|
||||
this.getRightHalfCard().addCardType(typesRight);
|
||||
this.getRightHalfCard().setName(secondSideName);
|
||||
this.getRightHalfCard().addSubType(subTypesRight);
|
||||
this.getRightHalfCard().getColor().addColor(new ObjectColor(colorRight));
|
||||
|
|
@ -86,11 +85,14 @@ public abstract class TransformingDoubleFacedCard extends CardImpl {
|
|||
if (!this.getAbilities().containsClass(TransformAbility.class)) {
|
||||
this.addAbility(new TransformAbility());
|
||||
}
|
||||
for (Effect effect : this.getLeftHalfCard().getSpellAbility().getEffects()) {
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
}
|
||||
for (Target target : this.getLeftHalfCard().getSpellAbility().getTargets()) {
|
||||
this.getSpellAbility().addTarget(target);
|
||||
if (this.getLeftHalfCard().getSpellAbility() != null) {
|
||||
for (Effect effect : this.getLeftHalfCard().getSpellAbility().getEffects()) {
|
||||
this.getSpellAbility().addEffect(effect);
|
||||
}
|
||||
for (Target target : this.getLeftHalfCard().getSpellAbility().getTargets()) {
|
||||
this.getSpellAbility().addTarget(target);
|
||||
}
|
||||
this.getSpellAbility().setTargetAdjuster(this.getLeftHalfCard().getSpellAbility().getTargetAdjuster());
|
||||
}
|
||||
this.power = this.getLeftHalfCard().getPower().copy();
|
||||
this.toughness = this.getLeftHalfCard().getToughness().copy();
|
||||
|
|
@ -109,11 +111,14 @@ public abstract class TransformingDoubleFacedCard extends CardImpl {
|
|||
card.addAbility(ability);
|
||||
}
|
||||
}
|
||||
for (Effect effect : tdfc.getRightHalfCard().getSpellAbility().getEffects()) {
|
||||
card.getSpellAbility().addEffect(effect);
|
||||
}
|
||||
for (Target target : tdfc.getRightHalfCard().getSpellAbility().getTargets()) {
|
||||
card.getSpellAbility().addTarget(target);
|
||||
if (tdfc.getRightHalfCard().getSpellAbility() != null) {
|
||||
for (Effect effect : tdfc.getRightHalfCard().getSpellAbility().getEffects()) {
|
||||
card.getSpellAbility().addEffect(effect);
|
||||
}
|
||||
for (Target target : tdfc.getRightHalfCard().getSpellAbility().getTargets()) {
|
||||
card.getSpellAbility().addTarget(target);
|
||||
}
|
||||
card.getSpellAbility().setTargetAdjuster(tdfc.getRightHalfCard().getSpellAbility().getTargetAdjuster());
|
||||
}
|
||||
card.setPT(tdfc.getRightHalfCard().getPower().copy(), tdfc.getRightHalfCard().getToughness().copy());
|
||||
card.setStartingLoyalty(tdfc.getRightHalfCard().getStartingLoyalty());
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import java.util.UUID;
|
|||
*/
|
||||
public class TransformingDoubleFacedCardHalfImpl extends CardImpl {
|
||||
|
||||
TransformingDoubleFacedCardHalfImpl(UUID ownerId, CardSetInfo setInfo, String costs) {
|
||||
super(ownerId, setInfo, new CardType[]{}, costs);
|
||||
TransformingDoubleFacedCardHalfImpl(UUID ownerId, CardSetInfo setInfo, CardType[] cardTypes, String costs) {
|
||||
super(ownerId, setInfo, cardTypes, costs);
|
||||
}
|
||||
|
||||
private TransformingDoubleFacedCardHalfImpl(final TransformingDoubleFacedCardHalfImpl card) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue