mirror of
https://github.com/magefree/mage.git
synced 2025-12-20 02:30:08 -08:00
Merge d25edbce5b into 2a3b4aff7a
This commit is contained in:
commit
ff07e8cce7
54 changed files with 154 additions and 648 deletions
|
|
@ -4,7 +4,6 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
import mage.abilities.effects.common.continuous.BecomesFaceDownCreatureEffect;
|
||||||
import mage.abilities.icon.*;
|
import mage.abilities.icon.*;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.cards.decks.Deck;
|
import mage.cards.decks.Deck;
|
||||||
import mage.cards.repository.CardInfo;
|
import mage.cards.repository.CardInfo;
|
||||||
|
|
@ -13,34 +12,26 @@ import mage.cards.repository.ExpansionInfo;
|
||||||
import mage.cards.repository.ExpansionRepository;
|
import mage.cards.repository.ExpansionRepository;
|
||||||
import mage.client.MageFrame;
|
import mage.client.MageFrame;
|
||||||
import mage.client.cards.BigCard;
|
import mage.client.cards.BigCard;
|
||||||
import mage.client.game.PlayAreaPanel;
|
|
||||||
import mage.client.game.PlayerPanelExt;
|
import mage.client.game.PlayerPanelExt;
|
||||||
import mage.client.themes.ThemeType;
|
import mage.client.themes.ThemeType;
|
||||||
import mage.client.util.*;
|
import mage.client.util.*;
|
||||||
import mage.client.util.Event;
|
import mage.client.util.Event;
|
||||||
import mage.client.util.GUISizeHelper;
|
|
||||||
import mage.client.util.Listener;
|
|
||||||
import mage.constants.MultiplayerAttackOption;
|
|
||||||
import mage.constants.RangeOfInfluence;
|
import mage.constants.RangeOfInfluence;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
import mage.counters.Counter;
|
import mage.counters.Counter;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.designations.CitysBlessing;
|
import mage.designations.CitysBlessing;
|
||||||
import mage.designations.Monarch;
|
import mage.game.FakeGame;
|
||||||
import mage.game.*;
|
import mage.game.FakeMatch;
|
||||||
|
import mage.game.Game;
|
||||||
import mage.game.command.Dungeon;
|
import mage.game.command.Dungeon;
|
||||||
import mage.game.command.Emblem;
|
import mage.game.command.Emblem;
|
||||||
import mage.game.command.Plane;
|
import mage.game.command.Plane;
|
||||||
import mage.game.match.*;
|
import mage.game.match.Match;
|
||||||
import mage.game.mulligan.Mulligan;
|
|
||||||
import mage.game.mulligan.MulliganType;
|
|
||||||
import mage.game.permanent.PermanentCard;
|
import mage.game.permanent.PermanentCard;
|
||||||
import mage.game.permanent.PermanentMeld;
|
import mage.game.permanent.PermanentMeld;
|
||||||
import mage.game.permanent.PermanentToken;
|
import mage.game.permanent.PermanentToken;
|
||||||
import mage.game.permanent.token.IncubatorToken;
|
|
||||||
import mage.game.permanent.token.Phyrexian00Token;
|
|
||||||
import mage.game.permanent.token.Token;
|
import mage.game.permanent.token.Token;
|
||||||
import mage.game.permanent.token.ZombieToken;
|
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.players.StubPlayer;
|
import mage.players.StubPlayer;
|
||||||
import mage.util.CardUtil;
|
import mage.util.CardUtil;
|
||||||
|
|
@ -52,8 +43,8 @@ import org.mage.card.arcane.CardPanel;
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.util.List;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* App GUI: debug only, testing card renders and manipulations
|
* App GUI: debug only, testing card renders and manipulations
|
||||||
|
|
@ -150,8 +141,8 @@ public class TestCardRenderDialog extends MageDialog {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transform) {
|
if (transform) {
|
||||||
// need direct transform call to keep other side info (original)
|
permanent.setTransformed(true);
|
||||||
TransformAbility.transformPermanent(permanent, game, null);
|
permanent.reset(game);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (damage > 0) permanent.damage(damage, controllerId, null, game);
|
if (damage > 0) permanent.damage(damage, controllerId, null, game);
|
||||||
|
|
|
||||||
|
|
@ -538,17 +538,7 @@ public class CardView extends SimpleCardView {
|
||||||
|
|
||||||
this.extraDeckCard = card.isExtraDeckCard();
|
this.extraDeckCard = card.isExtraDeckCard();
|
||||||
|
|
||||||
// TODO: can probably remove this after tdfc rework
|
if (card instanceof PermanentCard && card.isTransformable()) {
|
||||||
// transformable, double faces cards
|
|
||||||
if (!(sourceCard.getMainCard() instanceof DoubleFacedCard)) {
|
|
||||||
this.transformable = card.isTransformable();
|
|
||||||
|
|
||||||
Card secondSideCard = card.getSecondCardFace();
|
|
||||||
if (secondSideCard != null) {
|
|
||||||
this.secondCardFace = new CardView(secondSideCard, game);
|
|
||||||
this.alternateName = secondCardFace.getName();
|
|
||||||
}
|
|
||||||
} else if (card instanceof PermanentCard && card.isTransformable()) {
|
|
||||||
this.transformable = card.isTransformable();
|
this.transformable = card.isTransformable();
|
||||||
Card secondSideCard = (Card) ((PermanentCard) card).getOtherFace();
|
Card secondSideCard = (Card) ((PermanentCard) card).getOtherFace();
|
||||||
this.secondCardFace = new CardView(secondSideCard, game);
|
this.secondCardFace = new CardView(secondSideCard, game);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import mage.abilities.effects.common.LoseLifeTargetEffect;
|
||||||
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
|
import mage.abilities.effects.common.cost.CostModificationEffectImpl;
|
||||||
import mage.abilities.effects.common.cost.SpellsCostModificationThatTargetSourceEffect;
|
import mage.abilities.effects.common.cost.SpellsCostModificationThatTargetSourceEffect;
|
||||||
import mage.abilities.keyword.EnchantAbility;
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.DoubleFacedCardHalf;
|
import mage.cards.DoubleFacedCardHalf;
|
||||||
|
|
@ -112,7 +111,7 @@ class AccursedWitchReturnTransformedEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
game.getState().setValue("attachTo:" + card.getOtherSide().getId(), attachTo.getId());
|
game.getState().setValue("attachTo:" + card.getOtherSide().getId(), attachTo.getId());
|
||||||
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
|
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
|
||||||
attachTo.addAttachment(card.getOtherSide().getId(), source, game);
|
attachTo.addAttachment(card.getOtherSide().getId(), source, game);
|
||||||
|
|
@ -120,6 +119,7 @@ class AccursedWitchReturnTransformedEffect extends OneShotEffect {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class InfectiousCurseCostReductionEffect extends CostModificationEffectImpl {
|
class InfectiousCurseCostReductionEffect extends CostModificationEffectImpl {
|
||||||
|
|
||||||
InfectiousCurseCostReductionEffect() {
|
InfectiousCurseCostReductionEffect() {
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,6 @@ import mage.abilities.hint.ConditionHint;
|
||||||
import mage.abilities.hint.Hint;
|
import mage.abilities.hint.Hint;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.keyword.LifelinkAbility;
|
import mage.abilities.keyword.LifelinkAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.mana.BlackManaAbility;
|
import mage.abilities.mana.BlackManaAbility;
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
|
|
@ -191,7 +190,7 @@ class AclazotzDeepestBetrayalTransformEffect extends OneShotEffect {
|
||||||
if (controller == null || card == null) {
|
if (controller == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||||
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
|
import mage.abilities.effects.common.combat.CantBeBlockedSourceEffect;
|
||||||
import mage.abilities.effects.keyword.ScryEffect;
|
import mage.abilities.effects.keyword.ScryEffect;
|
||||||
import mage.abilities.keyword.DefenderAbility;
|
import mage.abilities.keyword.DefenderAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
|
|
@ -94,7 +93,7 @@ class BiolumeEggEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
import mage.abilities.common.SimpleStaticAbility;
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
import mage.abilities.keyword.FlashAbility;
|
import mage.abilities.keyword.FlashAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
|
@ -86,7 +86,7 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl {
|
||||||
@Override
|
@Override
|
||||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||||
if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
|
if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
|
||||||
Object entersTransformed = game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId());
|
Object entersTransformed = game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId());
|
||||||
Card card = game.getCard(event.getTargetId());
|
Card card = game.getCard(event.getTargetId());
|
||||||
if (card != null && entersTransformed instanceof Boolean && (Boolean) entersTransformed && card.getSecondCardFace() != null) {
|
if (card != null && entersTransformed instanceof Boolean && (Boolean) entersTransformed && card.getSecondCardFace() != null) {
|
||||||
card = card.getSecondCardFace();
|
card = card.getSecondCardFace();
|
||||||
|
|
|
||||||
|
|
@ -1,56 +0,0 @@
|
||||||
package mage.cards.d;
|
|
||||||
|
|
||||||
import mage.MageInt;
|
|
||||||
import mage.abilities.common.PutCardIntoGraveFromAnywhereAllTriggeredAbility;
|
|
||||||
import mage.abilities.effects.keyword.InvestigateEffect;
|
|
||||||
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 mage.constants.SuperType;
|
|
||||||
import mage.constants.TargetController;
|
|
||||||
import mage.filter.StaticFilters;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author LePwnerer
|
|
||||||
*/
|
|
||||||
public final class DennickPiousApparition extends CardImpl {
|
|
||||||
|
|
||||||
public DennickPiousApparition(UUID ownerId, CardSetInfo setInfo) {
|
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
|
||||||
|
|
||||||
this.supertype.add(SuperType.LEGENDARY);
|
|
||||||
this.subtype.add(SubType.SPIRIT);
|
|
||||||
this.subtype.add(SubType.SOLDIER);
|
|
||||||
this.power = new MageInt(3);
|
|
||||||
this.toughness = new MageInt(2);
|
|
||||||
this.color.setWhite(true);
|
|
||||||
this.color.setBlue(true);
|
|
||||||
this.nightCard = true;
|
|
||||||
|
|
||||||
// Flying
|
|
||||||
this.addAbility(FlyingAbility.getInstance());
|
|
||||||
|
|
||||||
// Whenever one or more creature cards are put into graveyards from anywhere, investigate. This ability triggers only once each turn.
|
|
||||||
this.addAbility(new PutCardIntoGraveFromAnywhereAllTriggeredAbility(
|
|
||||||
new InvestigateEffect(1), false,
|
|
||||||
StaticFilters.FILTER_CARD_CREATURE, TargetController.ANY
|
|
||||||
).setTriggersLimitEachTurn(1).setTriggerPhrase("Whenever one or more creature cards are put into graveyards from anywhere, "));
|
|
||||||
|
|
||||||
// If Dennick, Pious Apparition would be put into a graveyard from anywhere, exile it instead.
|
|
||||||
this.addAbility(DisturbAbility.makeBackAbility());
|
|
||||||
}
|
|
||||||
|
|
||||||
private DennickPiousApparition(final DennickPiousApparition card) {
|
|
||||||
super(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public DennickPiousApparition copy() {
|
|
||||||
return new DennickPiousApparition(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -12,7 +12,6 @@ import mage.abilities.effects.common.RemoveAllCountersSourceEffect;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||||
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -97,7 +96,7 @@ class EdgarCharmedGroomEffect extends OneShotEffect {
|
||||||
if (controller == null || card == null) {
|
if (controller == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, true, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ import mage.abilities.effects.keyword.SurveilEffect;
|
||||||
import mage.abilities.effects.mana.BasicManaEffect;
|
import mage.abilities.effects.mana.BasicManaEffect;
|
||||||
import mage.abilities.keyword.FlashbackAbility;
|
import mage.abilities.keyword.FlashbackAbility;
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.CardsImpl;
|
import mage.cards.CardsImpl;
|
||||||
|
|
@ -115,7 +114,7 @@ class EsperOriginsEffect extends OneShotEffect {
|
||||||
Card card = spell.getMainCard();
|
Card card = spell.getMainCard();
|
||||||
player.moveCards(card, Zone.EXILED, source, game);
|
player.moveCards(card, Zone.EXILED, source, game);
|
||||||
game.setEnterWithCounters(card.getId(), new Counters(CounterType.FINALITY.createInstance()));
|
game.setEnterWithCounters(card.getId(), new Counters(CounterType.FINALITY.createInstance()));
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
||||||
player.moveCards(
|
player.moveCards(
|
||||||
card, Zone.BATTLEFIELD, source, game, false,
|
card, Zone.BATTLEFIELD, source, game, false,
|
||||||
false, true, null
|
false, true, null
|
||||||
|
|
|
||||||
|
|
@ -1,37 +0,0 @@
|
||||||
package mage.cards.f;
|
|
||||||
|
|
||||||
import mage.MageInt;
|
|
||||||
import mage.abilities.triggers.BeginningOfFirstMainTriggeredAbility;
|
|
||||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
|
||||||
import mage.cards.CardImpl;
|
|
||||||
import mage.cards.CardSetInfo;
|
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.SubType;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
public class ForsakenThresher extends CardImpl {
|
|
||||||
|
|
||||||
public ForsakenThresher(UUID ownerId, CardSetInfo setInfo) {
|
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "");
|
|
||||||
|
|
||||||
this.subtype.add(SubType.CONSTRUCT);
|
|
||||||
this.power = new MageInt(5);
|
|
||||||
this.toughness = new MageInt(5);
|
|
||||||
|
|
||||||
// Back half of Foreboding Statue
|
|
||||||
this.nightCard = true;
|
|
||||||
|
|
||||||
// At the beginning of your precombat main phase, add one mana of any color.
|
|
||||||
this.addAbility(new BeginningOfFirstMainTriggeredAbility(new AddManaOfAnyColorEffect()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private ForsakenThresher(final ForsakenThresher card) {
|
|
||||||
super(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForsakenThresher copy() {
|
|
||||||
return new ForsakenThresher(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -9,7 +9,6 @@ import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.PutOnLibrarySourceEffect;
|
import mage.abilities.effects.common.PutOnLibrarySourceEffect;
|
||||||
import mage.abilities.effects.keyword.SurveilEffect;
|
import mage.abilities.effects.keyword.SurveilEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
|
|
@ -95,7 +94,7 @@ class GarlandKnightOfCorneliaEffect extends OneShotEffect {
|
||||||
if (player == null || card == null) {
|
if (player == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
||||||
return player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
return player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import mage.abilities.effects.common.CreateTokenEffect;
|
||||||
import mage.abilities.effects.common.FightTargetSourceEffect;
|
import mage.abilities.effects.common.FightTargetSourceEffect;
|
||||||
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
import mage.abilities.effects.mana.AddManaOfAnyColorEffect;
|
||||||
import mage.abilities.keyword.DefenderAbility;
|
import mage.abilities.keyword.DefenderAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.mana.SimpleManaAbility;
|
import mage.abilities.mana.SimpleManaAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -120,7 +119,7 @@ class GoldenGuardianReturnTransformedEffect extends OneShotEffect {
|
||||||
if (controller == null || game.getState().getZone(source.getSourceId()) != Zone.GRAVEYARD) {
|
if (controller == null || game.getState().getZone(source.getSourceId()) != Zone.GRAVEYARD) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
Card card = game.getCard(source.getSourceId());
|
Card card = game.getCard(source.getSourceId());
|
||||||
return card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
return card != null && controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
import mage.abilities.effects.common.continuous.BoostControlledEffect;
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
|
|
@ -16,8 +15,7 @@ import mage.constants.SubType;
|
||||||
import mage.constants.SuperType;
|
import mage.constants.SuperType;
|
||||||
import mage.filter.common.FilterCreaturePermanent;
|
import mage.filter.common.FilterCreaturePermanent;
|
||||||
import mage.filter.predicate.Predicates;
|
import mage.filter.predicate.Predicates;
|
||||||
import mage.filter.predicate.mageobject.AbilityPredicate;
|
import mage.filter.predicate.permanent.TransformablePredicate;
|
||||||
import mage.filter.predicate.permanent.TransformedPredicate;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
|
|
@ -27,18 +25,13 @@ import java.util.UUID;
|
||||||
public final class GrimlockDinobotLeader extends TransformingDoubleFacedCard {
|
public final class GrimlockDinobotLeader extends TransformingDoubleFacedCard {
|
||||||
|
|
||||||
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaurs and Vehicles you control");
|
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Dinosaurs and Vehicles you control");
|
||||||
|
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Transformers creatures");
|
||||||
static {
|
static {
|
||||||
filter.add(Predicates.<MageObject>or(
|
filter.add(Predicates.<MageObject>or(
|
||||||
SubType.DINOSAUR.getPredicate(),
|
SubType.DINOSAUR.getPredicate(),
|
||||||
SubType.VEHICLE.getPredicate())
|
SubType.VEHICLE.getPredicate())
|
||||||
);
|
);
|
||||||
}
|
filter2.add(TransformablePredicate.instance);
|
||||||
|
|
||||||
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Transformers creatures");
|
|
||||||
static {
|
|
||||||
filter2.add(Predicates.not(SubType.DINOSAUR.getPredicate()));
|
|
||||||
filter2.add(Predicates.not(SubType.VEHICLE.getPredicate()));
|
|
||||||
filter2.add(Predicates.or(new AbilityPredicate(TransformAbility.class), TransformedPredicate.instance));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public GrimlockDinobotLeader(UUID ownerId, CardSetInfo setInfo) {
|
public GrimlockDinobotLeader(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ import mage.abilities.effects.common.continuous.BoostEquippedEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||||
import mage.abilities.keyword.EquipAbility;
|
import mage.abilities.keyword.EquipAbility;
|
||||||
import mage.abilities.keyword.MenaceAbility;
|
import mage.abilities.keyword.MenaceAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
|
|
@ -89,7 +88,7 @@ class HarvestHandReturnTransformedEffect extends OneShotEffect {
|
||||||
if (controller == null || card == null) {
|
if (controller == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,55 +0,0 @@
|
||||||
|
|
||||||
package mage.cards.h;
|
|
||||||
|
|
||||||
import mage.MageInt;
|
|
||||||
import mage.abilities.TriggeredAbility;
|
|
||||||
import mage.abilities.condition.Condition;
|
|
||||||
import mage.abilities.condition.InvertCondition;
|
|
||||||
import mage.abilities.condition.common.AttackedThisTurnSourceCondition;
|
|
||||||
import mage.abilities.effects.common.TapSourceEffect;
|
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.cards.CardImpl;
|
|
||||||
import mage.cards.CardSetInfo;
|
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.SubType;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nantuko
|
|
||||||
*/
|
|
||||||
public final class HomicidalBrute extends CardImpl {
|
|
||||||
|
|
||||||
private static final Condition condition = new InvertCondition(
|
|
||||||
AttackedThisTurnSourceCondition.instance, "{this} didn't attack this turn"
|
|
||||||
);
|
|
||||||
|
|
||||||
public HomicidalBrute(UUID ownerId, CardSetInfo setInfo) {
|
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
|
||||||
this.subtype.add(SubType.HUMAN);
|
|
||||||
this.subtype.add(SubType.MUTANT);
|
|
||||||
|
|
||||||
// this card is the second face of double-faced card
|
|
||||||
this.nightCard = true;
|
|
||||||
|
|
||||||
this.color.setRed(true);
|
|
||||||
this.power = new MageInt(5);
|
|
||||||
this.toughness = new MageInt(1);
|
|
||||||
|
|
||||||
// At the beginning of your end step, if Homicidal Brute didn't attack this turn, tap Homicidal Brute, then transform it.
|
|
||||||
TriggeredAbility ability = new BeginningOfEndStepTriggeredAbility(new TapSourceEffect());
|
|
||||||
ability.addEffect(new TransformSourceEffect().setText(", then transform it"));
|
|
||||||
this.addAbility(ability.withInterveningIf(condition));
|
|
||||||
}
|
|
||||||
|
|
||||||
private HomicidalBrute(final HomicidalBrute card) {
|
|
||||||
super(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public HomicidalBrute copy() {
|
|
||||||
return new HomicidalBrute(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
package mage.cards.j;
|
package mage.cards.j;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
|
@ -11,7 +10,6 @@ import mage.abilities.effects.common.AttachEffect;
|
||||||
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
|
import mage.abilities.effects.common.ReturnFromGraveyardToBattlefieldTargetEffect;
|
||||||
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlAttachedEffect;
|
import mage.abilities.effects.common.ReturnToBattlefieldUnderYourControlAttachedEffect;
|
||||||
import mage.abilities.keyword.EnchantAbility;
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.mana.AnyColorManaAbility;
|
import mage.abilities.mana.AnyColorManaAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -95,7 +93,7 @@ class JourneyToEternityReturnTransformedSourceEffect extends OneShotEffect {
|
||||||
if (zone == Zone.BATTLEFIELD || !zone.isPublicZone()) {
|
if (zone == Zone.BATTLEFIELD || !zone.isPublicZone()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, false, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, false, false, false, null);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||||
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
|
||||||
import mage.abilities.effects.Effect;
|
import mage.abilities.effects.Effect;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.keyword.VigilanceAbility;
|
import mage.abilities.keyword.VigilanceAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -111,7 +110,7 @@ class ReturnLoyalCatharEffect extends OneShotEffect {
|
||||||
}
|
}
|
||||||
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
Card card = game.getCard(getTargetPointer().getFirst(game, source));
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,10 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.common.SacrificeSourceCost;
|
import mage.abilities.costs.common.SacrificeSourceCost;
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardImpl;
|
import mage.cards.CardImpl;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
|
@ -88,7 +88,7 @@ class ContainmentPriestReplacementEffect extends ReplacementEffectImpl {
|
||||||
if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
|
if (((ZoneChangeEvent) event).getToZone() == Zone.BATTLEFIELD) {
|
||||||
Card card = game.getCard(event.getTargetId());
|
Card card = game.getCard(event.getTargetId());
|
||||||
if (card != null) {
|
if (card != null) {
|
||||||
Object entersTransformed = game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId());
|
Object entersTransformed = game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + event.getTargetId());
|
||||||
if (entersTransformed instanceof Boolean && (Boolean) entersTransformed && card.getSecondCardFace() != null) {
|
if (entersTransformed instanceof Boolean && (Boolean) entersTransformed && card.getSecondCardFace() != null) {
|
||||||
card = card.getSecondCardFace();
|
card = card.getSecondCardFace();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,12 +149,6 @@ class EverythingIsColorlessEffect extends ContinuousEffectImpl {
|
||||||
game.getState().getCreateMageObjectAttribute(leftHalfCard, game).getColor().setColor(colorless);
|
game.getState().getCreateMageObjectAttribute(leftHalfCard, game).getColor().setColor(colorless);
|
||||||
game.getState().getCreateMageObjectAttribute(rightHalfCard, game).getColor().setColor(colorless);
|
game.getState().getCreateMageObjectAttribute(rightHalfCard, game).getColor().setColor(colorless);
|
||||||
}
|
}
|
||||||
|
|
||||||
// double faces cards
|
|
||||||
// TODO: can remove after tdfc rework
|
|
||||||
if (card.getSecondCardFace() != null) {
|
|
||||||
game.getState().getCreateMageObjectAttribute(card, game).getColor().setColor(colorless);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.hint.Hint;
|
import mage.abilities.hint.Hint;
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.mana.RedManaAbility;
|
import mage.abilities.mana.RedManaAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -105,7 +104,7 @@ class OjerAxonilDeepestMightTransformEffect extends OneShotEffect {
|
||||||
if (controller == null || card == null) {
|
if (controller == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.hint.common.PermanentsYouControlHint;
|
import mage.abilities.hint.common.PermanentsYouControlHint;
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.mana.GreenManaAbility;
|
import mage.abilities.mana.GreenManaAbility;
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.cards.g.GishathSunsAvatar;
|
import mage.cards.g.GishathSunsAvatar;
|
||||||
|
|
@ -96,7 +95,7 @@ class OjerKaslemDeepestGrowthTransformEffect extends OneShotEffect {
|
||||||
if (controller == null || card == null) {
|
if (controller == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
|
||||||
import mage.abilities.keyword.FlyingAbility;
|
import mage.abilities.keyword.FlyingAbility;
|
||||||
import mage.abilities.keyword.ReboundAbility;
|
import mage.abilities.keyword.ReboundAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.mana.BlueManaAbility;
|
import mage.abilities.mana.BlueManaAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
|
|
@ -167,7 +166,7 @@ class OjerPakpatiqDeepestEpochTrigger extends OneShotEffect {
|
||||||
if (controller == null || card == null) {
|
if (controller == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
game.setEnterWithCounters(card.getId(), new Counters().addCounter(CounterType.TIME.createInstance(3)));
|
game.setEnterWithCounters(card.getId(), new Counters().addCounter(CounterType.TIME.createInstance(3)));
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.ReplacementEffectImpl;
|
import mage.abilities.effects.ReplacementEffectImpl;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.keyword.VigilanceAbility;
|
import mage.abilities.keyword.VigilanceAbility;
|
||||||
import mage.abilities.mana.WhiteManaAbility;
|
import mage.abilities.mana.WhiteManaAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
|
@ -94,7 +93,7 @@ class OjerTaqDeepestFoundationTransformEffect extends OneShotEffect {
|
||||||
if (controller == null || card == null) {
|
if (controller == null || card == null) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game, true, false, true, null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,16 +4,15 @@ import mage.MageObjectReference;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.DelayedTriggeredAbility;
|
import mage.abilities.DelayedTriggeredAbility;
|
||||||
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
|
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
|
||||||
import mage.abilities.keyword.LivingMetalAbility;
|
|
||||||
import mage.abilities.keyword.TrampleAbility;
|
|
||||||
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
|
||||||
import mage.abilities.common.DiesSourceTriggeredAbility;
|
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
|
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||||
import mage.abilities.effects.keyword.BolsterEffect;
|
import mage.abilities.effects.keyword.BolsterEffect;
|
||||||
|
import mage.abilities.keyword.LivingMetalAbility;
|
||||||
import mage.abilities.keyword.MoreThanMeetsTheEyeAbility;
|
import mage.abilities.keyword.MoreThanMeetsTheEyeAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
import mage.abilities.keyword.TrampleAbility;
|
||||||
|
import mage.abilities.triggers.BeginningOfEndStepTriggeredAbility;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
|
|
@ -106,7 +105,7 @@ class OptimusPrimeHeroEffect extends OneShotEffect {
|
||||||
if (backSide == null) {
|
if (backSide == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true);
|
||||||
controller.moveCards(backSide, Zone.BATTLEFIELD, source, game);
|
controller.moveCards(backSide, Zone.BATTLEFIELD, source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,12 +122,6 @@ class PaintersServantEffect extends ContinuousEffectImpl {
|
||||||
game.getState().getCreateMageObjectAttribute(leftHalfCard, game).getColor().addColor(color);
|
game.getState().getCreateMageObjectAttribute(leftHalfCard, game).getColor().addColor(color);
|
||||||
game.getState().getCreateMageObjectAttribute(rightHalfCard, game).getColor().addColor(color);
|
game.getState().getCreateMageObjectAttribute(rightHalfCard, game).getColor().addColor(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
// double faces cards
|
|
||||||
// TODO: can remove after tdfc rework
|
|
||||||
if (card.getSecondCardFace() != null) {
|
|
||||||
game.getState().getCreateMageObjectAttribute(card.getSecondCardFace(), game).getColor().addColor(color);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@ import mage.abilities.effects.common.PermanentsEnterBattlefieldTappedEffect;
|
||||||
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
import mage.abilities.effects.common.continuous.BoostEnchantedEffect;
|
||||||
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
|
||||||
import mage.abilities.keyword.EnchantAbility;
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.keyword.VigilanceAbility;
|
import mage.abilities.keyword.VigilanceAbility;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.DoubleFacedCardHalf;
|
import mage.cards.DoubleFacedCardHalf;
|
||||||
|
|
@ -116,7 +115,7 @@ class RadiantGraceEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
game.getState().setValue("attachTo:" + card.getOtherSide().getId(), player.getId());
|
game.getState().setValue("attachTo:" + card.getOtherSide().getId(), player.getId());
|
||||||
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
|
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
|
||||||
player.addAttachment(card.getId(), source, game);
|
player.addAttachment(card.getId(), source, game);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,6 @@ import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.AttachEffect;
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect;
|
import mage.abilities.effects.common.combat.AttacksIfAbleAttachedEffect;
|
||||||
import mage.abilities.keyword.EnchantAbility;
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
|
|
@ -82,7 +81,7 @@ class SkinInvasionEffect extends OneShotEffect {
|
||||||
Card card = game.getCard(source.getSourceId());
|
Card card = game.getCard(source.getSourceId());
|
||||||
Player controller = game.getPlayer(source.getControllerId());
|
Player controller = game.getPlayer(source.getControllerId());
|
||||||
if (card != null && controller != null) {
|
if (card != null && controller != null) {
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.MillCardsTargetEffect;
|
import mage.abilities.effects.common.MillCardsTargetEffect;
|
||||||
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
import mage.abilities.effects.common.ReturnToHandSourceEffect;
|
||||||
import mage.abilities.keyword.SkulkAbility;
|
import mage.abilities.keyword.SkulkAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
|
|
@ -96,7 +95,7 @@ class StartledAwakeReturnTransformedEffect extends OneShotEffect {
|
||||||
if (backSide == null) {
|
if (backSide == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + backSide.getId(), true);
|
||||||
controller.moveCards(backSide, Zone.BATTLEFIELD, source, game);
|
controller.moveCards(backSide, Zone.BATTLEFIELD, source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.effects.common.AttachEffect;
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
import mage.abilities.keyword.EnchantAbility;
|
import mage.abilities.keyword.EnchantAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
import mage.abilities.triggers.BeginningOfUpkeepTriggeredAbility;
|
||||||
import mage.cards.CardSetInfo;
|
import mage.cards.CardSetInfo;
|
||||||
import mage.cards.DoubleFacedCardHalf;
|
import mage.cards.DoubleFacedCardHalf;
|
||||||
|
|
@ -107,7 +106,7 @@ class VengefulStranglerEffect extends OneShotEffect {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
game.getState().setValue("attachTo:" + card.getOtherSide().getId(), permanent);
|
game.getState().setValue("attachTo:" + card.getOtherSide().getId(), permanent);
|
||||||
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
|
if (controller.moveCards(card, Zone.BATTLEFIELD, source, game)) {
|
||||||
permanent.addAttachment(card.getOtherSide().getId(), source, game);
|
permanent.addAttachment(card.getOtherSide().getId(), source, game);
|
||||||
|
|
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
|
|
||||||
package mage.cards.v;
|
|
||||||
|
|
||||||
import mage.MageInt;
|
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
|
||||||
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
|
|
||||||
import mage.abilities.keyword.ProwessAbility;
|
|
||||||
import mage.cards.CardImpl;
|
|
||||||
import mage.cards.CardSetInfo;
|
|
||||||
import mage.constants.CardType;
|
|
||||||
import mage.constants.SubType;
|
|
||||||
import mage.filter.FilterCard;
|
|
||||||
import mage.filter.common.FilterInstantOrSorceryCard;
|
|
||||||
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author fireshoes
|
|
||||||
*/
|
|
||||||
public final class VoraciousReader extends CardImpl {
|
|
||||||
|
|
||||||
private static final FilterCard filter = new FilterInstantOrSorceryCard("Instant and sorcery spells");
|
|
||||||
|
|
||||||
public VoraciousReader(UUID ownerId, CardSetInfo setInfo) {
|
|
||||||
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
|
|
||||||
this.subtype.add(SubType.ELDRAZI);
|
|
||||||
this.subtype.add(SubType.HOMUNCULUS);
|
|
||||||
this.power = new MageInt(3);
|
|
||||||
this.toughness = new MageInt(4);
|
|
||||||
|
|
||||||
// this card is the second face of double-faced card
|
|
||||||
this.nightCard = true;
|
|
||||||
|
|
||||||
// Prowess
|
|
||||||
this.addAbility(new ProwessAbility());
|
|
||||||
|
|
||||||
// Instant and sorcery spells you cast cost {1} less to cast.
|
|
||||||
this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private VoraciousReader(final VoraciousReader card) {
|
|
||||||
super(card);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public VoraciousReader copy() {
|
|
||||||
return new VoraciousReader(this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -239,7 +239,6 @@ public final class EldritchMoon extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Vexing Scuttler", 11, Rarity.UNCOMMON, mage.cards.v.VexingScuttler.class));
|
cards.add(new SetCardInfo("Vexing Scuttler", 11, Rarity.UNCOMMON, mage.cards.v.VexingScuttler.class));
|
||||||
cards.add(new SetCardInfo("Vildin-Pack Outcast", 148, Rarity.COMMON, mage.cards.v.VildinPackOutcast.class));
|
cards.add(new SetCardInfo("Vildin-Pack Outcast", 148, Rarity.COMMON, mage.cards.v.VildinPackOutcast.class));
|
||||||
cards.add(new SetCardInfo("Voldaren Pariah", 111, Rarity.RARE, mage.cards.v.VoldarenPariah.class));
|
cards.add(new SetCardInfo("Voldaren Pariah", 111, Rarity.RARE, mage.cards.v.VoldarenPariah.class));
|
||||||
cards.add(new SetCardInfo("Voracious Reader", 54, Rarity.UNCOMMON, mage.cards.v.VoraciousReader.class));
|
|
||||||
cards.add(new SetCardInfo("Wailing Ghoul", 112, Rarity.COMMON, mage.cards.w.WailingGhoul.class));
|
cards.add(new SetCardInfo("Wailing Ghoul", 112, Rarity.COMMON, mage.cards.w.WailingGhoul.class));
|
||||||
cards.add(new SetCardInfo("Waxing Moon", 177, Rarity.COMMON, mage.cards.w.WaxingMoon.class));
|
cards.add(new SetCardInfo("Waxing Moon", 177, Rarity.COMMON, mage.cards.w.WaxingMoon.class));
|
||||||
cards.add(new SetCardInfo("Weaver of Lightning", 149, Rarity.UNCOMMON, mage.cards.w.WeaverOfLightning.class));
|
cards.add(new SetCardInfo("Weaver of Lightning", 149, Rarity.UNCOMMON, mage.cards.w.WeaverOfLightning.class));
|
||||||
|
|
|
||||||
|
|
@ -187,7 +187,6 @@ public final class InnistradCrimsonVow extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Forest", 277, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Forest", 402, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Forest", 402, Rarity.LAND, mage.cards.basiclands.Forest.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Forest", 412, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
cards.add(new SetCardInfo("Forest", 412, Rarity.LAND, mage.cards.basiclands.Forest.class, FULL_ART_BFZ_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Forsaken Thresher", 256, Rarity.UNCOMMON, mage.cards.f.ForsakenThresher.class));
|
|
||||||
cards.add(new SetCardInfo("Frenzied Devils", 159, Rarity.UNCOMMON, mage.cards.f.FrenziedDevils.class));
|
cards.add(new SetCardInfo("Frenzied Devils", 159, Rarity.UNCOMMON, mage.cards.f.FrenziedDevils.class));
|
||||||
cards.add(new SetCardInfo("Geistlight Snare", 405, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Geistlight Snare", 405, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class, NON_FULL_USE_VARIOUS));
|
||||||
cards.add(new SetCardInfo("Geistlight Snare", 60, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class, NON_FULL_USE_VARIOUS));
|
cards.add(new SetCardInfo("Geistlight Snare", 60, Rarity.UNCOMMON, mage.cards.g.GeistlightSnare.class, NON_FULL_USE_VARIOUS));
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,6 @@ public final class InnistradDoubleFeature extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Florian, Voldaren Scion", 223, Rarity.RARE, mage.cards.f.FlorianVoldarenScion.class));
|
cards.add(new SetCardInfo("Florian, Voldaren Scion", 223, Rarity.RARE, mage.cards.f.FlorianVoldarenScion.class));
|
||||||
cards.add(new SetCardInfo("Flourishing Hunter", 466, Rarity.COMMON, mage.cards.f.FlourishingHunter.class));
|
cards.add(new SetCardInfo("Flourishing Hunter", 466, Rarity.COMMON, mage.cards.f.FlourishingHunter.class));
|
||||||
cards.add(new SetCardInfo("Foreboding Statue", 523, Rarity.UNCOMMON, mage.cards.f.ForebodingStatue.class));
|
cards.add(new SetCardInfo("Foreboding Statue", 523, Rarity.UNCOMMON, mage.cards.f.ForebodingStatue.class));
|
||||||
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("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 Devils", 426, Rarity.UNCOMMON, mage.cards.f.FrenziedDevils.class));
|
||||||
cards.add(new SetCardInfo("Galedrifter", 55, Rarity.COMMON, mage.cards.g.Galedrifter.class));
|
cards.add(new SetCardInfo("Galedrifter", 55, Rarity.COMMON, mage.cards.g.Galedrifter.class));
|
||||||
|
|
|
||||||
|
|
@ -311,7 +311,6 @@ public class ShadowsOverInnistradRemastered extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Veteran Cathar", 225, Rarity.UNCOMMON, mage.cards.v.VeteranCathar.class));
|
cards.add(new SetCardInfo("Veteran Cathar", 225, Rarity.UNCOMMON, mage.cards.v.VeteranCathar.class));
|
||||||
cards.add(new SetCardInfo("Village Messenger", 184, Rarity.UNCOMMON, mage.cards.v.VillageMessenger.class));
|
cards.add(new SetCardInfo("Village Messenger", 184, Rarity.UNCOMMON, mage.cards.v.VillageMessenger.class));
|
||||||
cards.add(new SetCardInfo("Voldaren Pariah", 138, Rarity.RARE, mage.cards.v.VoldarenPariah.class));
|
cards.add(new SetCardInfo("Voldaren Pariah", 138, Rarity.RARE, mage.cards.v.VoldarenPariah.class));
|
||||||
cards.add(new SetCardInfo("Voracious Reader", 58, Rarity.UNCOMMON, mage.cards.v.VoraciousReader.class));
|
|
||||||
cards.add(new SetCardInfo("Weirded Vampire", 139, Rarity.COMMON, mage.cards.w.WeirdedVampire.class));
|
cards.add(new SetCardInfo("Weirded Vampire", 139, Rarity.COMMON, mage.cards.w.WeirdedVampire.class));
|
||||||
cards.add(new SetCardInfo("Weirding Wood", 226, Rarity.COMMON, mage.cards.w.WeirdingWood.class));
|
cards.add(new SetCardInfo("Weirding Wood", 226, Rarity.COMMON, mage.cards.w.WeirdingWood.class));
|
||||||
cards.add(new SetCardInfo("Westvale Abbey", 275, Rarity.RARE, mage.cards.w.WestvaleAbbey.class));
|
cards.add(new SetCardInfo("Westvale Abbey", 275, Rarity.RARE, mage.cards.w.WestvaleAbbey.class));
|
||||||
|
|
|
||||||
|
|
@ -859,7 +859,7 @@ public class TransformTest extends CardTestPlayerBase {
|
||||||
assertLife(playerB, 20);
|
assertLife(playerB, 20);
|
||||||
assertGraveyardCount(playerA, dressDown, 1);
|
assertGraveyardCount(playerA, dressDown, 1);
|
||||||
assertPermanentCount(playerA, huntmasterOfTheFells, 1);
|
assertPermanentCount(playerA, huntmasterOfTheFells, 1);
|
||||||
assertPermanentCount(playerA, 6+1+1);
|
assertPermanentCount(playerA, 6 + 1 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -924,4 +924,32 @@ public class TransformTest extends CardTestPlayerBase {
|
||||||
assertPermanentCount(playerA, baithookAngler, 1);
|
assertPermanentCount(playerA, baithookAngler, 1);
|
||||||
assertTrue(getPermanent(baithookAngler, playerA).isTapped());
|
assertTrue(getPermanent(baithookAngler, playerA).isTapped());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test that copying a TDFC will not leave and return transformed
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
public void testCloneCantReturnTransformed() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, azusasManyJourneys);
|
||||||
|
addCard(Zone.HAND, playerA, "Clever Impersonator@impersonator");
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Island", 5);
|
||||||
|
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Clever Impersonator");
|
||||||
|
setChoice(playerA, true); // Choose to copy
|
||||||
|
setChoice(playerA, azusasManyJourneys);
|
||||||
|
waitStackResolved(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
|
||||||
|
addCounters(1, PhaseStep.PRECOMBAT_MAIN, playerA, "@impersonator", CounterType.LORE, 2);
|
||||||
|
setChoice(playerA, "II"); // order triggers
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, azusasManyJourneys, 1);
|
||||||
|
assertPermanentCount(playerA, likenessOfTheSeeker, 0);
|
||||||
|
assertPermanentCount(playerA, "Clever Impersonator", 0);
|
||||||
|
assertExileCount(playerA, "Clever Impersonator", 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ import mage.counters.CounterType;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class MycosynthLatticeTest extends CardTestPlayerBase {
|
public class MycosynthLatticeTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -57,4 +59,32 @@ public class MycosynthLatticeTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
assertCounterCount(playerA, crawler, CounterType.P1P1, 4);
|
assertCounterCount(playerA, crawler, CounterType.P1P1, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testColorsWithDifferentCardTypes() {
|
||||||
|
String azusasManyJourneys = "Azusa's Many Journeys"; // TDFC
|
||||||
|
String alrundGodOfTheCosmos = "Alrund, God of the Cosmos"; // MDFC
|
||||||
|
String carnivalCarnage = "Carnival // Carnage"; // Split Card
|
||||||
|
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Mycosynth Lattice");
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, azusasManyJourneys);
|
||||||
|
addCard(Zone.HAND, playerA, alrundGodOfTheCosmos);
|
||||||
|
addCard(Zone.LIBRARY, playerA, carnivalCarnage);
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.PRECOMBAT_MAIN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
currentGame.getCards().forEach(card -> {
|
||||||
|
if (card.getName().equals(azusasManyJourneys)
|
||||||
|
|| card.getName().equals("Likeness of the Seeker")
|
||||||
|
|| card.getName().equals(alrundGodOfTheCosmos)
|
||||||
|
|| card.getName().equals("Alrund's Epiphany")
|
||||||
|
|| card.getName().equals("Carnival")
|
||||||
|
|| card.getName().equals("Carnage")) {
|
||||||
|
assertTrue("Card " + card.getName() + " should be colorless", card.getColor(currentGame).isColorless());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1228,11 +1228,6 @@ public class VerifyCardDataTest {
|
||||||
cardInfo.getCardNumber(), cardInfo.getRarity(), cardInfo.getGraphicInfo()));
|
cardInfo.getCardNumber(), cardInfo.getRarity(), cardInfo.getGraphicInfo()));
|
||||||
Assert.assertNotNull(card);
|
Assert.assertNotNull(card);
|
||||||
|
|
||||||
//TODO: do we need this check after tdfc rework?
|
|
||||||
if (card.getSecondCardFace() != null && !(card instanceof DoubleFacedCard)) {
|
|
||||||
containsDoubleSideCards = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CHECK: all planeswalkers must be legendary
|
// CHECK: all planeswalkers must be legendary
|
||||||
if (card.isPlaneswalker() && !card.isLegendary()) {
|
if (card.isPlaneswalker() && !card.isLegendary()) {
|
||||||
errorsList.add("Error: planeswalker must have legendary type: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber());
|
errorsList.add("Error: planeswalker must have legendary type: " + set.getCode() + " - " + set.getName() + " - " + card.getName() + " - " + card.getCardNumber());
|
||||||
|
|
@ -2297,31 +2292,14 @@ public class VerifyCardDataTest {
|
||||||
fail(card, "abilities", "transforming double-faced card should not have abilities on the main card");
|
fail(card, "abilities", "transforming double-faced card should not have abilities on the main card");
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: remove after transform ability removed
|
|
||||||
// special check: new DFC implementation should not have transform ability
|
|
||||||
if (card instanceof DoubleFacedCardHalf && card.getAbilities().containsClass(TransformAbility.class)
|
|
||||||
&& !card.getAbilities().containsClass(DayboundAbility.class)
|
|
||||||
&& !card.getAbilities().containsClass(CraftAbility.class)
|
|
||||||
&& !card.getAbilities().containsClass(SiegeAbility.class)) {
|
|
||||||
fail(card, "abilities", "new transforming double-faced card should not have transform ability");
|
|
||||||
}
|
|
||||||
|
|
||||||
// special check: Werewolves front ability should only be on front and vice versa
|
// special check: Werewolves front ability should only be on front and vice versa
|
||||||
if (card.getAbilities().containsClass(WerewolfFrontTriggeredAbility.class) && (card.isNightCard() || (card instanceof DoubleFacedCardHalf && ((DoubleFacedCardHalf) card).isBackSide()))) {
|
if (card.getAbilities().containsClass(WerewolfFrontTriggeredAbility.class) && (card instanceof DoubleFacedCardHalf && ((DoubleFacedCardHalf) card).isBackSide())) {
|
||||||
fail(card, "abilities", "card is a back face werewolf with a front face ability");
|
fail(card, "abilities", "card is a back face werewolf with a front face ability");
|
||||||
}
|
}
|
||||||
if (card.getAbilities().containsClass(WerewolfBackTriggeredAbility.class) && (!card.isNightCard() && (card instanceof DoubleFacedCardHalf && !((DoubleFacedCardHalf) card).isBackSide()))) {
|
if (card.getAbilities().containsClass(WerewolfBackTriggeredAbility.class) && (card instanceof DoubleFacedCardHalf && !((DoubleFacedCardHalf) card).isBackSide())) {
|
||||||
fail(card, "abilities", "card is a front face werewolf with a back face ability");
|
fail(card, "abilities", "card is a front face werewolf with a back face ability");
|
||||||
}
|
}
|
||||||
|
|
||||||
// special check: transform ability in TDFC should only be on front and vice versa
|
|
||||||
if (card.getSecondCardFace() != null && !card.isNightCard() && !card.getAbilities().containsClass(TransformAbility.class)) {
|
|
||||||
fail(card, "abilities", "double-faced cards should have transform ability on the front");
|
|
||||||
}
|
|
||||||
if (card.getSecondCardFace() != null && card.isNightCard() && card.getAbilities().containsClass(TransformAbility.class)) {
|
|
||||||
fail(card, "abilities", "double-faced cards should not have transform ability on the back");
|
|
||||||
}
|
|
||||||
|
|
||||||
// special check: back side in TDFC must be only night card
|
// special check: back side in TDFC must be only night card
|
||||||
if (card.getSecondCardFace() != null && !card.getSecondCardFace().isNightCard()) {
|
if (card.getSecondCardFace() != null && !card.getSecondCardFace().isNightCard()) {
|
||||||
fail(card, "abilities", "the back face of a double-faced card should be nightCard = true");
|
fail(card, "abilities", "the back face of a double-faced card should be nightCard = true");
|
||||||
|
|
|
||||||
|
|
@ -5,9 +5,9 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.StaticAbility;
|
import mage.abilities.StaticAbility;
|
||||||
import mage.abilities.TriggeredAbilityImpl;
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.constants.*;
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.Zone;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
|
@ -21,7 +21,6 @@ public class SiegeAbility extends StaticAbility {
|
||||||
|
|
||||||
public SiegeAbility() {
|
public SiegeAbility() {
|
||||||
super(Zone.ALL, null);
|
super(Zone.ALL, null);
|
||||||
this.addSubAbility(new TransformAbility());
|
|
||||||
this.addSubAbility(new SiegeDefeatedTriggeredAbility());
|
this.addSubAbility(new SiegeDefeatedTriggeredAbility());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,13 @@
|
||||||
package mage.abilities.common;
|
package mage.abilities.common;
|
||||||
|
|
||||||
import mage.MageIdentifier;
|
import mage.MageIdentifier;
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.SpellAbility;
|
import mage.abilities.SpellAbility;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.effects.ContinuousEffectImpl;
|
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
import mage.cards.TransformingDoubleFacedCard;
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
import mage.constants.*;
|
import mage.constants.SpellAbilityCastMode;
|
||||||
|
import mage.constants.SpellAbilityType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.stack.Spell;
|
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
@ -21,7 +18,6 @@ import java.util.UUID;
|
||||||
public class SpellTransformedAbility extends SpellAbility {
|
public class SpellTransformedAbility extends SpellAbility {
|
||||||
|
|
||||||
protected final String manaCost; //This variable is only used for rules text
|
protected final String manaCost; //This variable is only used for rules text
|
||||||
private boolean ignoreTransformEffect; // TODO: temporary while converting tdfc
|
|
||||||
|
|
||||||
public SpellTransformedAbility(Card card, String manaCost) {
|
public SpellTransformedAbility(Card card, String manaCost) {
|
||||||
super(card.getSecondFaceSpellAbility());
|
super(card.getSecondFaceSpellAbility());
|
||||||
|
|
@ -37,11 +33,6 @@ public class SpellTransformedAbility extends SpellAbility {
|
||||||
this.clearManaCosts();
|
this.clearManaCosts();
|
||||||
this.clearManaCostsToPay();
|
this.clearManaCostsToPay();
|
||||||
this.addCost(new ManaCostsImpl<>(manaCost));
|
this.addCost(new ManaCostsImpl<>(manaCost));
|
||||||
if (!(card instanceof TransformingDoubleFacedCard)) {
|
|
||||||
this.addSubAbility(new TransformAbility());
|
|
||||||
} else {
|
|
||||||
ignoreTransformEffect = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SpellTransformedAbility(final SpellAbility ability) {
|
public SpellTransformedAbility(final SpellAbility ability) {
|
||||||
|
|
@ -54,13 +45,11 @@ public class SpellTransformedAbility extends SpellAbility {
|
||||||
|
|
||||||
this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
|
this.spellAbilityType = SpellAbilityType.BASE_ALTERNATE;
|
||||||
this.setSpellAbilityCastMode(SpellAbilityCastMode.TRANSFORMED);
|
this.setSpellAbilityCastMode(SpellAbilityCastMode.TRANSFORMED);
|
||||||
//when casting this way, the card must have the TransformAbility from elsewhere
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected SpellTransformedAbility(final SpellTransformedAbility ability) {
|
protected SpellTransformedAbility(final SpellTransformedAbility ability) {
|
||||||
super(ability);
|
super(ability);
|
||||||
this.manaCost = ability.manaCost;
|
this.manaCost = ability.manaCost;
|
||||||
this.ignoreTransformEffect = ability.ignoreTransformEffect;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -71,14 +60,7 @@ public class SpellTransformedAbility extends SpellAbility {
|
||||||
@Override
|
@Override
|
||||||
public boolean activate(Game game, Set<MageIdentifier> allowedIdentifiers, boolean noMana) {
|
public boolean activate(Game game, Set<MageIdentifier> allowedIdentifiers, boolean noMana) {
|
||||||
if (super.activate(game, allowedIdentifiers, noMana)) {
|
if (super.activate(game, allowedIdentifiers, noMana)) {
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + getSourceId(), Boolean.TRUE);
|
||||||
if (ignoreTransformEffect) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
// TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides)
|
|
||||||
TransformedEffect effect = new TransformedEffect();
|
|
||||||
game.addEffect(effect, this);
|
|
||||||
effect.apply(game, this); //Apply the effect immediately
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -95,31 +77,3 @@ public class SpellTransformedAbility extends SpellAbility {
|
||||||
return ActivationStatus.getFalse();
|
return ActivationStatus.getFalse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class TransformedEffect extends ContinuousEffectImpl {
|
|
||||||
|
|
||||||
public TransformedEffect() {
|
|
||||||
super(Duration.WhileOnStack, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.BecomeCreature);
|
|
||||||
staticText = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private TransformedEffect(final TransformedEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TransformedEffect copy() {
|
|
||||||
return new TransformedEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Spell spell = game.getSpell(source.getSourceId());
|
|
||||||
if (spell == null || spell.getCard().getSecondCardFace() == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// simulate another side as new card (another code part in spell constructor)
|
|
||||||
TransformAbility.transformCardSpellDynamic(spell, spell.getCard().getSecondCardFace(), game);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
package mage.abilities.effects;
|
package mage.abilities.effects;
|
||||||
|
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.SpellAbility;
|
import mage.abilities.SpellAbility;
|
||||||
import mage.abilities.effects.common.AttachEffect;
|
import mage.abilities.effects.common.AttachEffect;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.events.GameEvent;
|
import mage.game.events.GameEvent;
|
||||||
|
|
@ -18,6 +15,9 @@ import mage.players.Player;
|
||||||
import mage.target.Target;
|
import mage.target.Target;
|
||||||
import mage.target.common.TargetCardInGraveyard;
|
import mage.target.common.TargetCardInGraveyard;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cards with the Aura subtype don't change the zone they are in, if there is no
|
* Cards with the Aura subtype don't change the zone they are in, if there is no
|
||||||
* valid target on the battlefield. Also, when entering the battlefield and it
|
* valid target on the battlefield. Also, when entering the battlefield and it
|
||||||
|
|
@ -184,7 +184,7 @@ public class AuraReplacementEffect extends ReplacementEffectImpl {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// in case of transformable enchantments
|
// in case of transformable enchantments
|
||||||
if (Boolean.TRUE.equals(game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()))
|
if (Boolean.TRUE.equals(game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId()))
|
||||||
&& card.getSecondCardFace() != null) {
|
&& card.getSecondCardFace() != null) {
|
||||||
card = card.getSecondCardFace();
|
card = card.getSecondCardFace();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import mage.abilities.costs.common.ExileSourceCost;
|
||||||
import mage.abilities.costs.mana.ManaCostsImpl;
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
import mage.abilities.effects.OneShotEffect;
|
import mage.abilities.effects.OneShotEffect;
|
||||||
import mage.cards.Card;
|
import mage.cards.Card;
|
||||||
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.filter.FilterCard;
|
import mage.filter.FilterCard;
|
||||||
import mage.filter.FilterPermanent;
|
import mage.filter.FilterPermanent;
|
||||||
|
|
@ -59,7 +60,6 @@ public class CraftAbility extends ActivatedAbilityImpl {
|
||||||
super(Zone.BATTLEFIELD, new CraftEffect(), new ManaCostsImpl<>(manaString));
|
super(Zone.BATTLEFIELD, new CraftEffect(), new ManaCostsImpl<>(manaString));
|
||||||
this.addCost(new ExileSourceCost());
|
this.addCost(new ExileSourceCost());
|
||||||
this.addCost(new CraftCost(target));
|
this.addCost(new CraftCost(target));
|
||||||
this.addSubAbility(new TransformAbility());
|
|
||||||
this.timing = TimingRule.SORCERY;
|
this.timing = TimingRule.SORCERY;
|
||||||
this.manaString = manaString;
|
this.manaString = manaString;
|
||||||
this.description = description;
|
this.description = description;
|
||||||
|
|
@ -173,7 +173,7 @@ class CraftEffect extends OneShotEffect {
|
||||||
if (player == null || card == null || card.getZoneChangeCounter(game) != source.getStackMomentSourceZCC() + 1) {
|
if (player == null || card == null || card.getZoneChangeCounter(game) != source.getStackMomentSourceZCC() + 1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
|
||||||
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
player.moveCards(card, Zone.BATTLEFIELD, source, game);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ public class DayboundAbility extends StaticAbility {
|
||||||
public DayboundAbility() {
|
public DayboundAbility() {
|
||||||
super(Zone.BATTLEFIELD, new DayboundEffect());
|
super(Zone.BATTLEFIELD, new DayboundEffect());
|
||||||
this.addHint(DayNightHint.instance);
|
this.addHint(DayNightHint.instance);
|
||||||
this.addSubAbility(new TransformAbility());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private DayboundAbility(final DayboundAbility ability) {
|
private DayboundAbility(final DayboundAbility ability) {
|
||||||
|
|
|
||||||
|
|
@ -1,177 +0,0 @@
|
||||||
package mage.abilities.keyword;
|
|
||||||
|
|
||||||
import mage.MageObject;
|
|
||||||
import mage.abilities.Ability;
|
|
||||||
import mage.abilities.Mode;
|
|
||||||
import mage.abilities.common.SimpleStaticAbility;
|
|
||||||
import mage.abilities.effects.ContinuousEffectImpl;
|
|
||||||
import mage.cards.Card;
|
|
||||||
import mage.constants.*;
|
|
||||||
import mage.game.Game;
|
|
||||||
import mage.game.MageObjectAttribute;
|
|
||||||
import mage.game.permanent.Permanent;
|
|
||||||
import mage.game.permanent.PermanentToken;
|
|
||||||
import mage.game.stack.Spell;
|
|
||||||
import mage.util.CardUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author nantuko
|
|
||||||
*/
|
|
||||||
public class TransformAbility extends SimpleStaticAbility {
|
|
||||||
|
|
||||||
// this state value controls if a permanent enters the battlefield already transformed
|
|
||||||
public static final String VALUE_KEY_ENTER_TRANSFORMED = "EnterTransformed";
|
|
||||||
|
|
||||||
public TransformAbility() {
|
|
||||||
super(Zone.BATTLEFIELD, new TransformEffect());
|
|
||||||
}
|
|
||||||
|
|
||||||
private TransformAbility(final TransformAbility ability) {
|
|
||||||
super(ability);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TransformAbility copy() {
|
|
||||||
return new TransformAbility(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getRule() {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Apply transform effect to permanent (copy characteristic and other things)
|
|
||||||
*/
|
|
||||||
public static boolean transformPermanent(Permanent permanent, Game game, Ability source) {
|
|
||||||
MageObject sourceCard = findSourceObjectForTransform(permanent);
|
|
||||||
if (sourceCard == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
permanent.setTransformed(true);
|
|
||||||
permanent.setName(sourceCard.getName());
|
|
||||||
permanent.getColor(game).setColor(sourceCard.getColor(game));
|
|
||||||
permanent.getManaCost().clear();
|
|
||||||
permanent.getManaCost().add(sourceCard.getManaCost().copy());
|
|
||||||
permanent.removeAllCardTypes(game);
|
|
||||||
for (CardType type : sourceCard.getCardType(game)) {
|
|
||||||
permanent.addCardType(game, type);
|
|
||||||
}
|
|
||||||
permanent.removeAllSubTypes(game);
|
|
||||||
permanent.copySubTypesFrom(game, sourceCard);
|
|
||||||
permanent.removeAllSuperTypes(game);
|
|
||||||
for (SuperType type : sourceCard.getSuperType(game)) {
|
|
||||||
permanent.addSuperType(game, type);
|
|
||||||
}
|
|
||||||
|
|
||||||
CardUtil.copySetAndCardNumber(permanent, sourceCard);
|
|
||||||
|
|
||||||
permanent.getAbilities().clear();
|
|
||||||
for (Ability ability : sourceCard.getAbilities()) {
|
|
||||||
// source == null -- call from init card (e.g. own abilities)
|
|
||||||
// source != null -- from apply effect
|
|
||||||
permanent.addAbility(ability, source == null ? permanent.getId() : source.getSourceId(), game, true);
|
|
||||||
}
|
|
||||||
permanent.getPower().setModifiedBaseValue(sourceCard.getPower().getValue());
|
|
||||||
permanent.getToughness().setModifiedBaseValue(sourceCard.getToughness().getValue());
|
|
||||||
permanent.setStartingLoyalty(sourceCard.getStartingLoyalty());
|
|
||||||
permanent.setStartingDefense(sourceCard.getStartingDefense());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static MageObject findSourceObjectForTransform(Permanent permanent) {
|
|
||||||
if (permanent == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// copies can't transform
|
|
||||||
if (permanent.isCopy()) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (permanent instanceof PermanentToken) {
|
|
||||||
return ((PermanentToken) permanent).getToken().getBackFace();
|
|
||||||
} else {
|
|
||||||
return permanent.getSecondCardFace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Card transformCardSpellStatic(Card mainSide, Card otherSide, Game game) {
|
|
||||||
// workaround to simulate transformed card on the stack (example: disturb ability)
|
|
||||||
// prepare static attributes
|
|
||||||
// TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides)
|
|
||||||
Card newCard = mainSide.copy();
|
|
||||||
newCard.setName(otherSide.getName());
|
|
||||||
|
|
||||||
// mana value must be from main side only
|
|
||||||
newCard.getManaCost().clear();
|
|
||||||
newCard.getManaCost().add(mainSide.getManaCost().copy());
|
|
||||||
|
|
||||||
game.getState().getCardState(newCard.getId()).clearAbilities();
|
|
||||||
for (Ability ability : otherSide.getAbilities()) {
|
|
||||||
game.getState().addOtherAbility(newCard, ability);
|
|
||||||
}
|
|
||||||
newCard.getPower().setModifiedBaseValue(otherSide.getPower().getValue());
|
|
||||||
newCard.getToughness().setModifiedBaseValue(otherSide.getToughness().getValue());
|
|
||||||
|
|
||||||
return newCard;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void transformCardSpellDynamic(Spell spell, Card otherSide, Game game) {
|
|
||||||
// workaround to simulate transformed card on the stack (example: disturb ability)
|
|
||||||
// prepare dynamic attributes
|
|
||||||
// TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides)
|
|
||||||
MageObjectAttribute moa = game.getState().getCreateMageObjectAttribute(spell.getCard(), game);
|
|
||||||
moa.getColor().setColor(otherSide.getColor(game));
|
|
||||||
moa.getCardType().clear();
|
|
||||||
moa.getCardType().addAll(otherSide.getCardType(game));
|
|
||||||
moa.getSuperType().clear();
|
|
||||||
moa.getSuperType().addAll(otherSide.getSuperType(game));
|
|
||||||
moa.getSubtype().clear();
|
|
||||||
moa.getSubtype().addAll(otherSide.getSubtype(game));
|
|
||||||
|
|
||||||
game.getState().getCardState(spell.getCard().getId()).clearAbilities();
|
|
||||||
for (Ability ability : otherSide.getAbilities()) {
|
|
||||||
game.getState().addOtherAbility(spell.getCard(), ability);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class TransformEffect extends ContinuousEffectImpl {
|
|
||||||
|
|
||||||
TransformEffect() {
|
|
||||||
super(Duration.WhileOnBattlefield, Layer.CopyEffects_1, SubLayer.CopyEffects_1a, Outcome.BecomeCreature);
|
|
||||||
staticText = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
private TransformEffect(final TransformEffect effect) {
|
|
||||||
super(effect);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean apply(Game game, Ability source) {
|
|
||||||
Permanent permanent = game.getPermanent(source.getSourceId());
|
|
||||||
if (permanent == null) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// only for transformed permanents
|
|
||||||
if (!permanent.isTransformed()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TransformAbility.transformPermanent(permanent, game, source);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TransformEffect copy() {
|
|
||||||
return new TransformEffect(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getText(Mode mode) {
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -73,7 +73,7 @@ public interface Card extends MageObject, Ownerable {
|
||||||
|
|
||||||
SpellAbility getSecondFaceSpellAbility();
|
SpellAbility getSecondFaceSpellAbility();
|
||||||
|
|
||||||
//TODO: remove after tdfc rework
|
//TODO: remove after meld converted to DFC
|
||||||
boolean isNightCard();
|
boolean isNightCard();
|
||||||
|
|
||||||
default boolean meldsWith(Card card) {
|
default boolean meldsWith(Card card) {
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,6 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
||||||
|
|
||||||
protected UUID ownerId;
|
protected UUID ownerId;
|
||||||
protected Rarity rarity;
|
protected Rarity rarity;
|
||||||
protected Class<? extends Card> secondSideCardClazz;
|
|
||||||
protected Class<? extends Card> meldsWithClazz;
|
protected Class<? extends Card> meldsWithClazz;
|
||||||
protected Class<? extends MeldCard> meldsToClazz;
|
protected Class<? extends MeldCard> meldsToClazz;
|
||||||
protected MeldCard meldsToCard;
|
protected MeldCard meldsToCard;
|
||||||
|
|
@ -121,19 +120,8 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
||||||
ownerId = card.ownerId;
|
ownerId = card.ownerId;
|
||||||
rarity = card.rarity;
|
rarity = card.rarity;
|
||||||
|
|
||||||
// TODO: wtf, do not copy card sides cause it must be re-created each time (see details in getSecondCardFace)
|
|
||||||
// must be reworked to normal copy and workable transform without such magic
|
|
||||||
|
|
||||||
nightCard = card.nightCard;
|
nightCard = card.nightCard;
|
||||||
secondSideCardClazz = card.secondSideCardClazz;
|
if (card.secondSideCard != null) {
|
||||||
secondSideCard = null; // will be set on first getSecondCardFace call if card has one
|
|
||||||
// TODO: temporary until cards tdfc cards are converted
|
|
||||||
// can do normal copy after
|
|
||||||
if (card.secondSideCard instanceof DoubleFacedCardHalf) {
|
|
||||||
secondSideCard = card.secondSideCard.copy();
|
|
||||||
}
|
|
||||||
if (card.secondSideCard instanceof MockableCard) {
|
|
||||||
// workaround to support gui's mock cards
|
|
||||||
secondSideCard = card.secondSideCard.copy();
|
secondSideCard = card.secondSideCard.copy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -667,27 +655,11 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
|
||||||
// If a spell or ability instructs a player to transform a permanent that
|
// If a spell or ability instructs a player to transform a permanent that
|
||||||
// isn’t represented by a transforming token or a transforming double-faced
|
// isn’t represented by a transforming token or a transforming double-faced
|
||||||
// card, nothing happens.
|
// card, nothing happens.
|
||||||
return this.secondSideCardClazz != null || this.nightCard || this.secondSideCard != null;
|
return this.secondSideCard != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final Card getSecondCardFace() {
|
public final Card getSecondCardFace() {
|
||||||
// init card side on first call
|
|
||||||
if (secondSideCardClazz == null && secondSideCard == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (secondSideCard == null) {
|
|
||||||
secondSideCard = initSecondSideCard(secondSideCardClazz);
|
|
||||||
if (secondSideCard != null && secondSideCard.getSpellAbility() != null) {
|
|
||||||
// TODO: wtf, why it set cast mode here?! Transform tests fails without it
|
|
||||||
// must be reworked without that magic, also see CardImpl'constructor for copy code
|
|
||||||
secondSideCard.getSpellAbility().setSourceId(this.getId());
|
|
||||||
secondSideCard.getSpellAbility().setSpellAbilityType(SpellAbilityType.BASE_ALTERNATE);
|
|
||||||
secondSideCard.getSpellAbility().setSpellAbilityCastMode(SpellAbilityCastMode.TRANSFORMED);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return secondSideCard;
|
return secondSideCard;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,9 @@ import java.util.UUID;
|
||||||
|
|
||||||
public abstract class TransformingDoubleFacedCard extends DoubleFacedCard {
|
public abstract class TransformingDoubleFacedCard extends DoubleFacedCard {
|
||||||
|
|
||||||
|
// this state value controls if a permanent enters the battlefield already transformed
|
||||||
|
public static final String VALUE_KEY_ENTER_TRANSFORMED = "EnterTransformed";
|
||||||
|
|
||||||
public TransformingDoubleFacedCard(
|
public TransformingDoubleFacedCard(
|
||||||
UUID ownerId, CardSetInfo setInfo,
|
UUID ownerId, CardSetInfo setInfo,
|
||||||
CardType[] typesLeft, SubType[] subTypesLeft, String costsLeft,
|
CardType[] typesLeft, SubType[] subTypesLeft, String costsLeft,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,10 @@
|
||||||
package mage.constants;
|
package mage.constants;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
import mage.cards.Card;
|
||||||
import mage.cards.*;
|
import mage.cards.Cards;
|
||||||
|
import mage.cards.CardsImpl;
|
||||||
|
import mage.cards.TransformingDoubleFacedCard;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
|
|
@ -93,7 +95,7 @@ public enum PutCards {
|
||||||
if (card instanceof TransformingDoubleFacedCard) {
|
if (card instanceof TransformingDoubleFacedCard) {
|
||||||
card = ((TransformingDoubleFacedCard) card).getRightHalfCard();
|
card = ((TransformingDoubleFacedCard) card).getRightHalfCard();
|
||||||
}
|
}
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), Boolean.TRUE);
|
||||||
case BATTLEFIELD:
|
case BATTLEFIELD:
|
||||||
case EXILED:
|
case EXILED:
|
||||||
case HAND:
|
case HAND:
|
||||||
|
|
@ -131,7 +133,7 @@ public enum PutCards {
|
||||||
case SHUFFLE:
|
case SHUFFLE:
|
||||||
return player.shuffleCardsToLibrary(cards, game, source);
|
return player.shuffleCardsToLibrary(cards, game, source);
|
||||||
case BATTLEFIELD_TRANSFORMED:
|
case BATTLEFIELD_TRANSFORMED:
|
||||||
cards.stream().forEach(uuid -> game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + uuid, Boolean.TRUE));
|
cards.stream().forEach(uuid -> game.getState().setValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + uuid, Boolean.TRUE));
|
||||||
case BATTLEFIELD:
|
case BATTLEFIELD:
|
||||||
case EXILED:
|
case EXILED:
|
||||||
case HAND:
|
case HAND:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
package mage.filter.predicate.permanent;
|
||||||
|
|
||||||
|
import mage.filter.predicate.Predicate;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
public enum TransformablePredicate implements Predicate<Permanent> {
|
||||||
|
instance;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Permanent input, Game game) {
|
||||||
|
return input.isTransformable();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "Transformable";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,7 +56,6 @@ import mage.game.mulligan.Mulligan;
|
||||||
import mage.game.permanent.Battlefield;
|
import mage.game.permanent.Battlefield;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.game.permanent.PermanentCard;
|
import mage.game.permanent.PermanentCard;
|
||||||
import mage.game.permanent.PermanentToken;
|
|
||||||
import mage.game.stack.Spell;
|
import mage.game.stack.Spell;
|
||||||
import mage.game.stack.SpellStack;
|
import mage.game.stack.SpellStack;
|
||||||
import mage.game.stack.StackAbility;
|
import mage.game.stack.StackAbility;
|
||||||
|
|
@ -2117,11 +2116,6 @@ public abstract class GameImpl implements Game {
|
||||||
BecomesFaceDownCreatureEffect.makeFaceDownObject(this, null, newBluePrint, faceDownType, null);
|
BecomesFaceDownCreatureEffect.makeFaceDownObject(this, null, newBluePrint, faceDownType, null);
|
||||||
}
|
}
|
||||||
newBluePrint.assignNewId();
|
newBluePrint.assignNewId();
|
||||||
// TODO: should be able to remove after tdfc rework
|
|
||||||
if (copyFromPermanent.isTransformed() && (copyFromPermanent instanceof PermanentToken || ((copyFromPermanent instanceof PermanentCard) &&
|
|
||||||
!(((PermanentCard) copyFromPermanent).getCard() instanceof DoubleFacedCardHalf)))) {
|
|
||||||
TransformAbility.transformPermanent(newBluePrint, this, source);
|
|
||||||
}
|
|
||||||
if (copyFromPermanent.isPrototyped()) {
|
if (copyFromPermanent.isPrototyped()) {
|
||||||
Abilities<Ability> abilities = copyFromPermanent.getAbilities();
|
Abilities<Ability> abilities = copyFromPermanent.getAbilities();
|
||||||
for (Ability ability : abilities) {
|
for (Ability ability : abilities) {
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
package mage.game;
|
package mage.game;
|
||||||
|
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.constants.Outcome;
|
import mage.constants.Outcome;
|
||||||
import mage.constants.Zone;
|
import mage.constants.Zone;
|
||||||
|
|
@ -91,8 +90,7 @@ public final class ZonesHandler {
|
||||||
Card card = game.getCard(info.event.getTargetId());
|
Card card = game.getCard(info.event.getTargetId());
|
||||||
if (card instanceof DoubleFacedCard || card instanceof DoubleFacedCardHalf) {
|
if (card instanceof DoubleFacedCard || card instanceof DoubleFacedCardHalf) {
|
||||||
boolean forceToMainSide = false;
|
boolean forceToMainSide = false;
|
||||||
// TODO: move transform key or have some other identifier after tdfc rework
|
Boolean enterTransformed = (Boolean) game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId());
|
||||||
Boolean enterTransformed = (Boolean) game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId());
|
|
||||||
if (enterTransformed == null) {
|
if (enterTransformed == null) {
|
||||||
enterTransformed = false;
|
enterTransformed = false;
|
||||||
}
|
}
|
||||||
|
|
@ -296,7 +294,7 @@ public final class ZonesHandler {
|
||||||
game.getPermanentsEntering().remove(permanent.getId());
|
game.getPermanentsEntering().remove(permanent.getId());
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new UnsupportedOperationException("to Zone " + toZone.toString() + " not supported yet");
|
throw new UnsupportedOperationException("to Zone " + toZone + " not supported yet");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -376,15 +374,13 @@ public final class ZonesHandler {
|
||||||
isGoodToMove = true;
|
isGoodToMove = true;
|
||||||
} else if (event.getToZone().equals(Zone.BATTLEFIELD)) {
|
} else if (event.getToZone().equals(Zone.BATTLEFIELD)) {
|
||||||
// non-permanents can't move to battlefield
|
// non-permanents can't move to battlefield
|
||||||
// TODO: possible bug with Nightbound, search all usage of getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED and insert additional check Ability.checkCard
|
// TODO: possible bug with Nightbound, search all usage of getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED and insert additional check Ability.checkCard
|
||||||
/*
|
/*
|
||||||
* 712.14a. If a spell or ability puts a transforming double-faced card onto the battlefield "transformed"
|
* 712.14a. If a spell or ability puts a double-faced card onto the battlefield "transformed" or "converted,"
|
||||||
* or "converted," it enters the battlefield with its back face up. If a player is instructed to put a card
|
* it enters the battlefield with its back face up. If a player is instructed to put a card that isn't a double-faced card
|
||||||
* that isn't a transforming double-faced card onto the battlefield transformed or converted, that card stays in
|
* onto the battlefield transformed or converted, that card stays in its current zone.
|
||||||
* its current zone.
|
|
||||||
*/
|
*/
|
||||||
// TODO: remove after tdfc rework
|
boolean wantToTransform = Boolean.TRUE.equals(game.getState().getValue(TransformingDoubleFacedCard.VALUE_KEY_ENTER_TRANSFORMED + card.getId()));
|
||||||
boolean wantToTransform = Boolean.TRUE.equals(game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()));
|
|
||||||
if (wantToTransform && !(card instanceof DoubleFacedCardHalf)) {
|
if (wantToTransform && !(card instanceof DoubleFacedCardHalf)) {
|
||||||
isGoodToMove = card.isTransformable() && card.getSecondCardFace().isPermanent(game);
|
isGoodToMove = card.isTransformable() && card.getSecondCardFace().isPermanent(game);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,6 @@ import mage.abilities.Ability;
|
||||||
import mage.abilities.common.RoomAbility;
|
import mage.abilities.common.RoomAbility;
|
||||||
import mage.abilities.costs.mana.ManaCost;
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
import mage.abilities.costs.mana.ManaCosts;
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
import mage.abilities.keyword.NightboundAbility;
|
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.constants.SpellAbilityType;
|
import mage.constants.SpellAbilityType;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
|
@ -103,16 +101,6 @@ public class PermanentCard extends PermanentImpl {
|
||||||
if (card instanceof LevelerCard) {
|
if (card instanceof LevelerCard) {
|
||||||
maxLevelCounters = ((LevelerCard) card).getMaxLevelCounters();
|
maxLevelCounters = ((LevelerCard) card).getMaxLevelCounters();
|
||||||
}
|
}
|
||||||
|
|
||||||
// if transformed on ETB
|
|
||||||
// TODO: remove after tdfc rework
|
|
||||||
if (card.isTransformable() && !(card instanceof DoubleFacedCardHalf)) {
|
|
||||||
if (game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId()) != null
|
|
||||||
|| NightboundAbility.checkCard(this, game)) {
|
|
||||||
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId(), null);
|
|
||||||
TransformAbility.transformPermanent(this, game, null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected PermanentCard(final PermanentCard permanent) {
|
protected PermanentCard(final PermanentCard permanent) {
|
||||||
|
|
@ -163,7 +151,7 @@ public class PermanentCard extends PermanentImpl {
|
||||||
} else if (card.getId() != this.getId()) {
|
} else if (card.getId() != this.getId()) {
|
||||||
// if different id, abilities need to be added to game state for continuous/triggers
|
// if different id, abilities need to be added to game state for continuous/triggers
|
||||||
for (Ability ability : card.getAbilities()) {
|
for (Ability ability : card.getAbilities()) {
|
||||||
this.addAbility(ability, card.getId(), game, true);
|
this.addAbility(ability, card.getId(), game, true);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// copy only own abilities; all dynamic added abilities must be added in the parent call
|
// copy only own abilities; all dynamic added abilities must be added in the parent call
|
||||||
|
|
@ -202,9 +190,6 @@ public class PermanentCard extends PermanentImpl {
|
||||||
this.setImageFileName(card.getImageFileName());
|
this.setImageFileName(card.getImageFileName());
|
||||||
this.setImageNumber(card.getImageNumber());
|
this.setImageNumber(card.getImageNumber());
|
||||||
|
|
||||||
if (card.getSecondCardFace() != null && !(card instanceof DoubleFacedCardHalf)) {
|
|
||||||
this.secondSideCardClazz = card.getSecondCardFace().getClass();
|
|
||||||
}
|
|
||||||
if (card.getMeldsToCard() != null) {
|
if (card.getMeldsToCard() != null) {
|
||||||
this.meldsToClazz = card.getMeldsToCard().getClass();
|
this.meldsToClazz = card.getMeldsToCard().getClass();
|
||||||
}
|
}
|
||||||
|
|
@ -249,7 +234,7 @@ public class PermanentCard extends PermanentImpl {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean turnFaceUp(Ability source, Game game, UUID playerId) {
|
public boolean turnFaceUp(Ability source, Game game, UUID playerId) {
|
||||||
if (!this.getBasicMageObject().isPermanent()){
|
if (!this.getBasicMageObject().isPermanent()) {
|
||||||
// 701.34g. If a manifested permanent that's represented by an instant or sorcery card would turn face up,
|
// 701.34g. If a manifested permanent that's represented by an instant or sorcery card would turn face up,
|
||||||
// its controller reveals it and leaves it face down. Abilities that trigger whenever a permanent
|
// its controller reveals it and leaves it face down. Abilities that trigger whenever a permanent
|
||||||
// is turned face up won't trigger.
|
// is turned face up won't trigger.
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package mage.game.permanent.token;
|
||||||
import mage.abilities.common.SimpleActivatedAbility;
|
import mage.abilities.common.SimpleActivatedAbility;
|
||||||
import mage.abilities.costs.mana.GenericManaCost;
|
import mage.abilities.costs.mana.GenericManaCost;
|
||||||
import mage.abilities.effects.common.TransformSourceEffect;
|
import mage.abilities.effects.common.TransformSourceEffect;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.constants.CardType;
|
import mage.constants.CardType;
|
||||||
import mage.constants.SubType;
|
import mage.constants.SubType;
|
||||||
|
|
||||||
|
|
@ -18,7 +17,6 @@ public final class IncubatorToken extends TokenImpl {
|
||||||
subtype.add(SubType.INCUBATOR);
|
subtype.add(SubType.INCUBATOR);
|
||||||
this.backFace = new Phyrexian00Token();
|
this.backFace = new Phyrexian00Token();
|
||||||
|
|
||||||
this.addAbility(new TransformAbility());
|
|
||||||
this.addAbility(new SimpleActivatedAbility(
|
this.addAbility(new SimpleActivatedAbility(
|
||||||
new TransformSourceEffect().setText("transform this artifact"), new GenericManaCost(2)
|
new TransformSourceEffect().setText("transform this artifact"), new GenericManaCost(2)
|
||||||
));
|
));
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import mage.abilities.costs.mana.ManaCost;
|
||||||
import mage.abilities.costs.mana.ManaCosts;
|
import mage.abilities.costs.mana.ManaCosts;
|
||||||
import mage.abilities.keyword.BestowAbility;
|
import mage.abilities.keyword.BestowAbility;
|
||||||
import mage.abilities.keyword.PrototypeAbility;
|
import mage.abilities.keyword.PrototypeAbility;
|
||||||
import mage.abilities.keyword.TransformAbility;
|
|
||||||
import mage.cards.*;
|
import mage.cards.*;
|
||||||
import mage.constants.*;
|
import mage.constants.*;
|
||||||
import mage.counters.Counter;
|
import mage.counters.Counter;
|
||||||
|
|
@ -81,11 +80,6 @@ public class Spell extends StackObjectImpl implements Card {
|
||||||
|
|
||||||
Card affectedCard = card;
|
Card affectedCard = card;
|
||||||
|
|
||||||
// TODO: must be removed after transform cards (one side) migrated to MDF engine (multiple sides)
|
|
||||||
if (ability.getSpellAbilityCastMode().isTransformed() && affectedCard.getSecondCardFace() != null) {
|
|
||||||
// simulate another side as new card (another code part in continues effect from disturb ability)
|
|
||||||
affectedCard = TransformAbility.transformCardSpellStatic(card, card.getSecondCardFace(), game);
|
|
||||||
}
|
|
||||||
if (ability instanceof PrototypeAbility) {
|
if (ability instanceof PrototypeAbility) {
|
||||||
affectedCard = ((PrototypeAbility) ability).prototypeCardSpell(card);
|
affectedCard = ((PrototypeAbility) ability).prototypeCardSpell(card);
|
||||||
this.prototyped = true;
|
this.prototyped = true;
|
||||||
|
|
|
||||||
|
|
@ -4110,7 +4110,7 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
TransformingDoubleFacedCard mainCard = (TransformingDoubleFacedCard) object;
|
TransformingDoubleFacedCard mainCard = (TransformingDoubleFacedCard) object;
|
||||||
getPlayableFromObjectSingle(game, fromZone, mainCard.getLeftHalfCard(), mainCard.getLeftHalfCard().getAbilities(game), availableMana, output);
|
getPlayableFromObjectSingle(game, fromZone, mainCard.getLeftHalfCard(), mainCard.getLeftHalfCard().getAbilities(game), availableMana, output);
|
||||||
getPlayableFromObjectSingle(game, fromZone, mainCard, mainCard.getSharedAbilities(game), availableMana, output);
|
getPlayableFromObjectSingle(game, fromZone, mainCard, mainCard.getSharedAbilities(game), availableMana, output);
|
||||||
} else if (object instanceof CardWithSpellOption) {
|
} else if (object instanceof CardWithSpellOption) {
|
||||||
// adventure must use different card characteristics for different spells (main or adventure)
|
// adventure must use different card characteristics for different spells (main or adventure)
|
||||||
CardWithSpellOption cardWithSpellOption = (CardWithSpellOption) object;
|
CardWithSpellOption cardWithSpellOption = (CardWithSpellOption) object;
|
||||||
getPlayableFromObjectSingle(game, fromZone, cardWithSpellOption.getSpellCard(), cardWithSpellOption.getSpellCard().getAbilities(game), availableMana, output);
|
getPlayableFromObjectSingle(game, fromZone, cardWithSpellOption.getSpellCard(), cardWithSpellOption.getSpellCard().getAbilities(game), availableMana, output);
|
||||||
|
|
@ -4952,16 +4952,6 @@ public abstract class PlayerImpl implements Player, Serializable {
|
||||||
for (Card card : cards) {
|
for (Card card : cards) {
|
||||||
fromZone = game.getState().getZone(card.getId());
|
fromZone = game.getState().getZone(card.getId());
|
||||||
|
|
||||||
// 712.14a. If a spell or ability puts a transforming double-faced card onto the battlefield "transformed"
|
|
||||||
// or "converted," it enters the battlefield with its back face up. If a player is instructed to put a card
|
|
||||||
// that isn't a transforming double-faced card onto the battlefield transformed or converted, that card stays in
|
|
||||||
// its current zone.
|
|
||||||
// TODO: can probably remove/change after tdfc rework, should only be sending transformed side
|
|
||||||
Boolean enterTransformed = (Boolean) game.getState().getValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + card.getId());
|
|
||||||
if (enterTransformed != null && enterTransformed && !card.isTransformable() && !(card instanceof TransformingDoubleFacedCardHalf)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 303.4g. If an Aura is entering the battlefield and there is no legal object or player for it to enchant,
|
// 303.4g. If an Aura is entering the battlefield and there is no legal object or player for it to enchant,
|
||||||
// the Aura remains in its current zone, unless that zone is the stack. In that case, the Aura is put into
|
// the Aura remains in its current zone, unless that zone is the stack. In that case, the Aura is put into
|
||||||
// its owner's graveyard instead of entering the battlefield. If the Aura is a token, it isn't created.
|
// its owner's graveyard instead of entering the battlefield. If the Aura is a token, it isn't created.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue