more fixes

This commit is contained in:
theelk801 2023-08-29 21:52:49 -04:00
parent 5c1c02ba9e
commit 444242172d
14 changed files with 418 additions and 549 deletions

View file

@ -1,6 +1,7 @@
package mage.view;
import com.google.gson.annotations.Expose;
import mage.MageInt;
import mage.MageObject;
import mage.ObjectColor;
import mage.abilities.Abilities;
@ -11,9 +12,7 @@ import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.Effects;
import mage.abilities.icon.CardIcon;
import mage.abilities.icon.other.CommanderCardIcon;
import mage.abilities.icon.other.FaceDownCardIcon;
import mage.abilities.icon.other.VariableCostCardIcon;
import mage.abilities.icon.CardIconImpl;
import mage.abilities.keyword.AftermathAbility;
import mage.cards.*;
import mage.cards.mock.MockCard;
@ -76,8 +75,8 @@ public class CardView extends SimpleCardView {
protected ObjectColor frameColor;
protected FrameStyle frameStyle;
// can combine multiple costs for MockCard from deck editor or db (left/right, card/adventure)
protected String manaCostLeftStr;
protected String manaCostRightStr;
protected List<String> manaCostLeftStr;
protected List<String> manaCostRightStr;
protected int manaValue;
protected Rarity rarity;
@ -90,6 +89,7 @@ public class CardView extends SimpleCardView {
protected CardView ability;
protected int imageNumber;
protected boolean extraDeckCard;
protected boolean transformable; // can toggle one card side to another (transformable cards, modal double faces)
protected CardView secondCardFace;
protected boolean transformed;
@ -131,7 +131,13 @@ public class CardView extends SimpleCardView {
protected boolean inViewerOnly; // GUI render: show object as a card instead permanent (without PT, etc)
protected List<CardIcon> cardIcons = new ArrayList<>(); // additional icons to render
protected MageObject originalObject = null; // GUI related: additional info about current object (example: real PT)
// GUI related: additional info about current object (example: real PT)
protected MageInt originalPower = null;
protected MageInt originalToughness = null;
protected FilterMana originalColorIdentity = null;
protected UUID originalId = null;
protected boolean originalIsCopy = false;
protected boolean originalIsCard = false;
/**
* Non game usage like deck editor
@ -179,7 +185,7 @@ public class CardView extends SimpleCardView {
this.defense = cardView.defense;
this.startingDefense = cardView.startingDefense;
this.cardTypes = new ArrayList<>(cardView.cardTypes);
this.subTypes = new SubTypes(cardView.subTypes);
this.subTypes = cardView.subTypes.copy();
this.superTypes = cardView.superTypes;
this.expansionSetCode = cardView.expansionSetCode;
@ -237,10 +243,19 @@ public class CardView extends SimpleCardView {
this.canAttack = cardView.canAttack;
this.canBlock = cardView.canBlock;
this.inViewerOnly = cardView.inViewerOnly;
this.originalObject = cardView.originalObject == null ? null : cardView.originalObject.copy();
this.originalPower = cardView.originalPower;
this.originalToughness = cardView.originalToughness;
this.originalColorIdentity = cardView.originalColorIdentity;
this.originalId = cardView.originalId;
this.originalIsCard = cardView.originalIsCard;
this.originalIsCopy = cardView.originalIsCopy;
if (cardView.cardIcons != null) {
cardView.cardIcons.forEach(icon -> this.cardIcons.add(icon.copy()));
}
this.playableStats = cardView.playableStats.copy();
this.isChoosable = cardView.isChoosable;
this.isSelected = cardView.isSelected;
}
/**
@ -283,7 +298,7 @@ public class CardView extends SimpleCardView {
*/
public CardView(Card card, Game game, boolean controlled, boolean showFaceDownCard, boolean storeZone) {
super(card.getId(), card.getExpansionSetCode(), card.getCardNumber(), card.getUsesVariousArt(), game != null);
this.originalObject = card;
this.setOriginalValues(card);
this.imageNumber = card.getImageNumber();
// no information available for face down cards as long it's not a controlled face down morph card
@ -373,29 +388,29 @@ public class CardView extends SimpleCardView {
rightSplitTypeLine = getCardTypeLine(game, splitCard.getRightHalfCard());
fullCardName = card.getName(); // split card contains full name as normal
this.manaCostLeftStr = String.join("", splitCard.getLeftHalfCard().getManaCostSymbols());
this.manaCostRightStr = String.join("", splitCard.getRightHalfCard().getManaCostSymbols());
this.manaCostLeftStr = splitCard.getLeftHalfCard().getManaCostSymbols();
this.manaCostRightStr = splitCard.getRightHalfCard().getManaCostSymbols();
} else if (card instanceof DoubleFacedCard) {
this.isDoubleFacedCard = true;
DoubleFacedCard mainCard = ((DoubleFacedCard) card);
fullCardName = mainCard.getLeftHalfCard().getName() + MockCard.DOUBLE_FACED_NAME_SEPARATOR + mainCard.getRightHalfCard().getName();
this.manaCostLeftStr = String.join("", mainCard.getLeftHalfCard().getManaCostSymbols());
this.manaCostRightStr = String.join("", mainCard.getRightHalfCard().getManaCostSymbols());
this.manaCostLeftStr = mainCard.getLeftHalfCard().getManaCostSymbols();
this.manaCostRightStr = mainCard.getRightHalfCard().getManaCostSymbols();
} else if (card instanceof AdventureCard) {
AdventureCard adventureCard = ((AdventureCard) card);
AdventureCardSpell adventureCardSpell = adventureCard.getSpellCard();
fullCardName = adventureCard.getName() + MockCard.ADVENTURE_NAME_SEPARATOR + adventureCardSpell.getName();
this.manaCostLeftStr = String.join("", adventureCardSpell.getManaCostSymbols());
this.manaCostRightStr = String.join("", adventureCard.getManaCostSymbols());
this.manaCostLeftStr = adventureCardSpell.getManaCostSymbols();
this.manaCostRightStr = adventureCard.getManaCostSymbols();
} else if (card instanceof MockCard) {
// deck editor cards
fullCardName = ((MockCard) card).getFullName(true);
this.manaCostLeftStr = String.join("", ((MockCard) card).getManaCostStr(CardInfo.ManaCostSide.LEFT));
this.manaCostRightStr = String.join("", ((MockCard) card).getManaCostStr(CardInfo.ManaCostSide.RIGHT));
this.manaCostLeftStr = ((MockCard) card).getManaCostStr(CardInfo.ManaCostSide.LEFT);
this.manaCostRightStr = ((MockCard) card).getManaCostStr(CardInfo.ManaCostSide.RIGHT);
} else {
fullCardName = card.getName();
this.manaCostLeftStr = String.join("", card.getManaCostSymbols());
this.manaCostRightStr = "";
this.manaCostLeftStr = card.getManaCostSymbols();
this.manaCostRightStr = new ArrayList<>();
}
this.name = card.getName();
@ -433,15 +448,19 @@ public class CardView extends SimpleCardView {
});
// face down
if (permanent.isFaceDown(game)) {
this.cardIcons.add(FaceDownCardIcon.instance);
this.cardIcons.add(CardIconImpl.FACE_DOWN);
}
// commander
if (game != null) {
Player owner = game.getPlayer(game.getOwnerId(permanent));
if (owner != null && game.isCommanderObject(owner, permanent)) {
this.cardIcons.add(CommanderCardIcon.instance);
this.cardIcons.add(CardIconImpl.COMMANDER);
}
}
// Ring-bearer
if (permanent.isRingBearer()) {
this.cardIcons.add(CardIconImpl.RINGBEARER);
}
} else {
if (card.isCopy()) {
this.mageObjectType = MageObjectType.COPY_CARD;
@ -473,14 +492,14 @@ public class CardView extends SimpleCardView {
// other like Stack (can show x icon on stack only, so use normal source)
costX = ManacostVariableValue.REGULAR.calculate(game, card.getSpellAbility(), null);
}
this.cardIcons.add(new VariableCostCardIcon(costX));
this.cardIcons.add(CardIconImpl.variableCost(costX));
}
}
this.power = Integer.toString(card.getPower().getValue());
this.toughness = Integer.toString(card.getToughness().getValue());
this.cardTypes = new ArrayList<>(card.getCardType(game));
this.subTypes = new SubTypes(card.getSubtype(game));
this.subTypes = card.getSubtype(game).copy();
this.superTypes = card.getSuperType(game);
this.color = card.getColor(game).copy();
this.flipCard = card.isFlipCard();
@ -496,6 +515,8 @@ public class CardView extends SimpleCardView {
this.isToken = false;
}
this.extraDeckCard = card.isExtraDeckCard();
// transformable, double faces cards
this.transformable = card.isTransformable();
@ -602,7 +623,7 @@ public class CardView extends SimpleCardView {
public CardView(MageObject object, Game game) {
super(object.getId(), object.getExpansionSetCode(), object.getCardNumber(), false, true);
this.originalObject = object;
this.setOriginalValues(object);
this.imageNumber = object.getImageNumber();
this.name = object.getName();
@ -621,11 +642,11 @@ public class CardView extends SimpleCardView {
this.defense = "";
}
this.cardTypes = new ArrayList<>(object.getCardType(game));
this.subTypes = new SubTypes(object.getSubtype(game));
this.subTypes = object.getSubtype(game).copy();
this.superTypes = new ArrayList<>(object.getSuperType(game));
this.color = object.getColor(game).copy();
this.manaCostLeftStr = String.join("", object.getManaCostSymbols());
this.manaCostRightStr = "";
this.manaCostLeftStr = object.getManaCostSymbols();
this.manaCostRightStr = new ArrayList<>();
this.manaValue = object.getManaCost().manaValue();
if (object instanceof PermanentToken) {
this.mageObjectType = MageObjectType.TOKEN;
@ -680,7 +701,6 @@ public class CardView extends SimpleCardView {
public CardView(EmblemView emblem) {
this(true);
this.originalObject = null;
this.gameObject = true;
this.id = emblem.getId();
this.mageObjectType = MageObjectType.EMBLEM;
@ -692,13 +712,16 @@ public class CardView extends SimpleCardView {
this.frameStyle = FrameStyle.M15_NORMAL;
this.expansionSetCode = emblem.getExpansionSetCode();
this.cardNumber = "";
this.imageNumber = 0;
this.imageNumber = emblem.getImageNumber();
this.rarity = Rarity.COMMON;
this.playableStats = emblem.playableStats.copy();
this.isChoosable = emblem.isChoosable();
this.isSelected = emblem.isSelected();
}
public CardView(DungeonView dungeon) {
this(true);
this.originalObject = null;
this.gameObject = true;
this.id = dungeon.getId();
this.mageObjectType = MageObjectType.DUNGEON;
@ -712,11 +735,14 @@ public class CardView extends SimpleCardView {
this.cardNumber = "";
this.imageNumber = 0;
this.rarity = Rarity.COMMON;
this.playableStats = dungeon.playableStats.copy();
this.isChoosable = dungeon.isChoosable();
this.isSelected = dungeon.isSelected();
}
public CardView(PlaneView plane) {
this(true);
this.originalObject = null;
this.gameObject = true;
this.id = plane.getId();
this.mageObjectType = MageObjectType.PLANE;
@ -731,11 +757,14 @@ public class CardView extends SimpleCardView {
this.cardNumber = "";
this.imageNumber = 0;
this.rarity = Rarity.COMMON;
this.playableStats = plane.playableStats.copy();
this.isChoosable = plane.isChoosable();
this.isSelected = plane.isSelected();
}
public CardView(Designation designation, StackAbility stackAbility) {
this(true);
this.originalObject = null;
this.gameObject = true;
this.id = designation.getId();
this.mageObjectType = MageObjectType.NULL;
@ -761,7 +790,6 @@ public class CardView extends SimpleCardView {
}
private void fillEmpty(Card card, boolean controlled) {
this.originalObject = null;
this.name = "Face Down";
this.displayName = name;
this.displayFullName = name;
@ -778,8 +806,8 @@ public class CardView extends SimpleCardView {
this.color = new ObjectColor();
this.frameColor = new ObjectColor();
this.frameStyle = FrameStyle.M15_NORMAL;
this.manaCostLeftStr = "";
this.manaCostRightStr = "";
this.manaCostLeftStr = new ArrayList<>();
this.manaCostRightStr = new ArrayList<>();
this.manaValue = 0;
// the controller can see more information (e.g. enlarged image) than other players for face down cards (e.g. Morph played face down)
@ -825,13 +853,13 @@ public class CardView extends SimpleCardView {
this.defense = "";
this.startingDefense = "";
this.cardTypes = new ArrayList<>(token.getCardType(game));
this.subTypes = new SubTypes(token.getSubtype(game));
this.subTypes = token.getSubtype(game).copy();
this.superTypes = new ArrayList<>(token.getSuperType(game));
this.color = token.getColor(game).copy();
this.frameColor = token.getFrameColor(game).copy();
this.frameStyle = token.getFrameStyle();
this.manaCostLeftStr = String.join("", token.getManaCostSymbols());
this.manaCostRightStr = "";
this.manaCostLeftStr = token.getManaCostSymbols();
this.manaCostRightStr = new ArrayList<>();
this.rarity = Rarity.SPECIAL;
// source object is a token, so no card number
@ -867,6 +895,26 @@ public class CardView extends SimpleCardView {
this.targets.addAll(newTargets);
}
private void setOriginalValues(MageObject object) {
if (object == null) {
return;
}
// Only valid objects to transfer original values are Card and Token
if (object instanceof Card || object instanceof Token) {
this.originalPower = object.getPower();
this.originalToughness = object.getToughness();
this.originalIsCopy = object.isCopy();
this.originalId = object.getId();
if (object instanceof Card) {
this.originalColorIdentity = ((Card) object).getColorIdentity();
this.originalIsCard = true;
} else if (object instanceof Token) {
this.originalColorIdentity = ManaUtil.getColorIdentity((Token) object);
}
}
}
public String getName() {
return name;
}
@ -952,7 +1000,22 @@ public class CardView extends SimpleCardView {
}
public String getManaCostStr() {
return CardUtil.concatManaSymbols(CardInfo.SPLIT_MANA_SEPARATOR_FULL, this.manaCostLeftStr, this.manaCostRightStr);
return CardUtil.concatManaSymbols(
CardInfo.SPLIT_MANA_SEPARATOR_FULL,
String.join("", this.manaCostLeftStr),
String.join("", this.manaCostRightStr)
);
}
public List<String> getManaCostSymbols() {
List<String> symbols = new ArrayList<>();
for (String symbol : this.manaCostLeftStr) {
symbols.add(symbol);
}
for (String symbol : this.manaCostRightStr) {
symbols.add(symbol);
}
return symbols;
}
public int getManaValue() {
@ -965,12 +1028,8 @@ public class CardView extends SimpleCardView {
public String getColorIdentityStr() {
FilterMana colorInfo;
if (getOriginalCard() != null) {
// card
colorInfo = getOriginalCard().getColorIdentity();
} else if (getOriginalToken() != null) {
// token
colorInfo = ManaUtil.getColorIdentity(getOriginalToken());
if (this.originalColorIdentity != null) {
colorInfo = this.originalColorIdentity;
} else {
colorInfo = new FilterMana();
}
@ -1223,6 +1282,10 @@ public class CardView extends SimpleCardView {
return typeText.toString();
}
public boolean isExtraDeckCard() {
return this.extraDeckCard;
}
public boolean isLand() {
return cardTypes.contains(CardType.LAND);
}
@ -1255,20 +1318,24 @@ public class CardView extends SimpleCardView {
return inViewerOnly;
}
public Card getOriginalCard() {
if (this.originalObject instanceof Card) {
return (Card) this.originalObject;
} else {
return null;
}
public MageInt getOriginalPower() {
return this.originalPower;
}
public Token getOriginalToken() {
if (this.originalObject instanceof Token) {
return (Token) this.originalObject;
} else {
return null;
public MageInt getOriginalToughness() {
return this.originalToughness;
}
public UUID getOriginalId() {
return this.originalId;
}
public boolean isOriginalACopy() {
return this.originalIsCopy;
}
public boolean isOriginalACard() {
return this.originalIsCard;
}
public List<CardIcon> getCardIcons() {

View file

@ -55,7 +55,7 @@ enum IsBeingCastFromHandCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
MageObject object = game.getObject(source);
if (object instanceof SplitCardHalf || object instanceof AdventureCardSpell || object instanceof ModalDoubleFacedCardHalf) {
if (object instanceof SubCard || object instanceof AdventureCardSpell) {
UUID mainCardId = ((Card) object).getMainCard().getId();
object = game.getObject(mainCardId);
}

View file

@ -37,7 +37,7 @@ public final class DevotedGrafkeeper extends TransformingDoubleFacedCard {
this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new MillCardsControllerEffect(2)));
// Whenever you cast a spell from your graveyard, tap target creature you don't control.
Ability ability = new SpellCastControllerTriggeredAbility(
Ability ability = SpellCastControllerTriggeredAbility.createWithFromZone(
new TapTargetEffect(), StaticFilters.FILTER_SPELL_A, false, Zone.GRAVEYARD
);
ability.addTarget(new TargetPermanent(StaticFilters.FILTER_CREATURE_YOU_DONT_CONTROL));

View file

@ -41,7 +41,7 @@ public final class InvasionOfArcavios extends TransformingDoubleFacedCard {
this.getLeftHalfCard().addAbility(new EntersBattlefieldTriggeredAbility(new InvasionOfArcaviosEffect()));
// Whenever you cast an instant or sorcery spell from your hand, you may copy that spell. You may choose new targets for the copy.
this.getRightHalfCard().addAbility(new SpellCastControllerTriggeredAbility(
this.getRightHalfCard().addAbility(SpellCastControllerTriggeredAbility.createWithFromZone(
new InvocationOfTheFoundersEffect(), StaticFilters.FILTER_SPELL_AN_INSTANT_OR_SORCERY, true, Zone.HAND
));
}

View file

@ -1,50 +0,0 @@
package mage.cards.l;
import mage.MageInt;
import mage.abilities.common.LeavesBattlefieldAllTriggeredAbility;
import mage.abilities.common.PutIntoGraveFromAnywhereSourceAbility;
import mage.abilities.effects.common.ExileSourceEffect;
import mage.abilities.effects.common.GainLifeEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.filter.StaticFilters;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class LuminousPhantom extends CardImpl {
public LuminousPhantom(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "");
this.subtype.add(SubType.SPIRIT);
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(1);
this.toughness = new MageInt(1);
this.color.setWhite(true);
this.nightCard = true;
// Flying
this.addAbility(FlyingAbility.getInstance());
// Whenever another creature you control leaves the battlefield, you gain 1 life.
this.addAbility(new LeavesBattlefieldAllTriggeredAbility(new GainLifeEffect(1), StaticFilters.FILTER_ANOTHER_CREATURE_YOU_CONTROL));
// If Luminous Phantom would be put into a graveyard from anywhere, exile it instead.
this.addAbility(new PutIntoGraveFromAnywhereSourceAbility(new ExileSourceEffect().setText("exile it instead")));
}
private LuminousPhantom(final LuminousPhantom card) {
super(card);
}
@Override
public LuminousPhantom copy() {
return new LuminousPhantom(this);
}
}

View file

@ -1,161 +0,0 @@
package mage.cards.m;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.hint.StaticHint;
import mage.abilities.keyword.LivingMetalAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author Susucr
*/
public final class MegatronDestructiveForce extends CardImpl {
public MegatronDestructiveForce(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(4);
this.toughness = new MageInt(5);
this.color.setRed(true);
this.color.setWhite(true);
this.color.setBlack(true);
this.nightCard = true;
// Living metal
this.addAbility(new LivingMetalAbility());
// Whenever Megatron attacks, you may sacrifice another artifact. When you do, Megatron deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert Megatron.
this.addAbility(new AttacksTriggeredAbility(new MegatronDestructiveForceEffect()));
}
private MegatronDestructiveForce(final MegatronDestructiveForce card) {
super(card);
}
@Override
public MegatronDestructiveForce copy() {
return new MegatronDestructiveForce(this);
}
}
class MegatronDestructiveForceEffect extends OneShotEffect {
MegatronDestructiveForceEffect() {
super(Outcome.Benefit);
staticText = "you may sacrifice another artifact. When you do, {this} deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert {this}.";
}
private MegatronDestructiveForceEffect(final MegatronDestructiveForceEffect effect) {
super(effect);
}
@Override
public MegatronDestructiveForceEffect copy() {
return new MegatronDestructiveForceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
TargetPermanent target = new TargetPermanent(
0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_ARTIFACT_SHORT_TEXT, true
);
player.choose(outcome, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent == null) {
return false;
}
int manaValue = Math.max(permanent.getManaValue(), 0);
if (!permanent.sacrifice(source, game)) {
return false;
}
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new MegatronDestructiveForceReflexiveEffect(manaValue), false
);
ability.addHint(new StaticHint("Sacrificed artifact mana value: " + manaValue));
ability.addTarget(new TargetCreaturePermanent());
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}
class MegatronDestructiveForceReflexiveEffect extends OneShotEffect {
private final int value;
MegatronDestructiveForceReflexiveEffect(int value) {
super(Outcome.Damage);
staticText = "{this} deals damage equal to the sacrificed artifact's mana value to target " +
"creature. If excess damage would be dealt to that creature this way, instead that damage " +
"is dealt to that creature's controller and you convert {this}.";
this.value = value;
}
private MegatronDestructiveForceReflexiveEffect(final MegatronDestructiveForceReflexiveEffect effect) {
super(effect);
this.value = effect.value;
}
@Override
public MegatronDestructiveForceReflexiveEffect copy() {
return new MegatronDestructiveForceReflexiveEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = source.getSourcePermanentOrLKI(game);
if (sourcePermanent == null) {
return false;
}
if (value < 1) {
return false;
}
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null) {
return false;
}
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
int excess = value - lethal;
if (excess <= 0) {
// no excess damage.
permanent.damage(value, source.getSourceId(), source, game);
return true;
}
// excess damage. dealing excess to controller's instead. And convert Megatron.
permanent.damage(lethal, source.getSourceId(), source, game);
Player player = game.getPlayer(permanent.getControllerId());
if (player != null) {
player.damage(excess, source, game);
}
new TransformSourceEffect().apply(game, source);
return true;
}
}

View file

@ -1,60 +1,71 @@
package mage.cards.m;
import mage.MageInt;
import mage.MageObject;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.BeginningOfPostCombatMainTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.dynamicvalue.common.OpponentsLostLifeCount;
import mage.abilities.effects.ContinuousRuleModifyingEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.effects.mana.DynamicManaEffect;
import mage.abilities.hint.StaticHint;
import mage.abilities.keyword.LivingMetalAbility;
import mage.abilities.keyword.MoreThanMeetsTheEyeAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
* @author Susucr
*/
public final class MegatronTyrant extends CardImpl {
public final class MegatronTyrant extends TransformingDoubleFacedCard {
public MegatronTyrant(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{R}{W}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.ROBOT);
this.power = new MageInt(7);
this.toughness = new MageInt(5);
this.secondSideCardClazz = mage.cards.m.MegatronDestructiveForce.class;
super(
ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{3}{R}{W}{B}",
"Megatron, Destructive Force",
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "BRW"
);
this.getLeftHalfCard().setPT(7, 5);
this.getRightHalfCard().setPT(4, 5);
// More Than Meets the Eye {1}{R}{W}{B}
this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{1}{R}{W}{B}"));
this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{1}{R}{W}{B}"));
// Your opponents can't cast spells during combat.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new MegatronTyrantCantCastSpellsEffect()));
this.getLeftHalfCard().addAbility(new SimpleStaticAbility(new MegatronTyrantCantCastSpellsEffect()));
// At the beginning of your postcombat main phase, you may convert Megatron. If you do, add {C} for each 1 life your opponents have lost this turn.
TriggeredAbility trigger = new BeginningOfPostCombatMainTriggeredAbility(
Ability ability = new BeginningOfPostCombatMainTriggeredAbility(
new TransformSourceEffect().setText("convert {this}"),
TargetController.YOU,
true
TargetController.YOU, true
);
trigger.addEffect(
new DynamicManaEffect(
Mana.ColorlessMana(1),
OpponentsLostLifeCount.instance,
ability.addEffect(new DynamicManaEffect(
Mana.ColorlessMana(1), OpponentsLostLifeCount.instance,
"add {C} for each 1 life your opponents have lost this turn"
).concatBy("If you do,")
);
).concatBy("If you do,"));
this.getLeftHalfCard().addAbility(ability);
this.addAbility(trigger);
// Megatron, Destructive Force
// Living metal
this.getRightHalfCard().addAbility(new LivingMetalAbility());
// Whenever Megatron attacks, you may sacrifice another artifact. When you do, Megatron deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert Megatron.
this.getRightHalfCard().addAbility(new AttacksTriggeredAbility(new MegatronDestructiveForceEffect()));
}
private MegatronTyrant(final MegatronTyrant card) {
@ -109,3 +120,107 @@ class MegatronTyrantCantCastSpellsEffect extends ContinuousRuleModifyingEffectIm
}
}
class MegatronDestructiveForceEffect extends OneShotEffect {
MegatronDestructiveForceEffect() {
super(Outcome.Benefit);
staticText = "you may sacrifice another artifact. When you do, {this} deals damage equal to the sacrificed artifact's mana value to target creature. If excess damage would be dealt to that creature this way, instead that damage is dealt to that creature's controller and you convert {this}.";
}
private MegatronDestructiveForceEffect(final MegatronDestructiveForceEffect effect) {
super(effect);
}
@Override
public MegatronDestructiveForceEffect copy() {
return new MegatronDestructiveForceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
TargetPermanent target = new TargetPermanent(
0, 1, StaticFilters.FILTER_CONTROLLED_ANOTHER_ARTIFACT_SHORT_TEXT, true
);
player.choose(outcome, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
if (permanent == null) {
return false;
}
int manaValue = Math.max(permanent.getManaValue(), 0);
if (!permanent.sacrifice(source, game)) {
return false;
}
ReflexiveTriggeredAbility ability = new ReflexiveTriggeredAbility(
new MegatronDestructiveForceReflexiveEffect(manaValue), false
);
ability.addHint(new StaticHint("Sacrificed artifact mana value: " + manaValue));
ability.addTarget(new TargetCreaturePermanent());
game.fireReflexiveTriggeredAbility(ability, source);
return true;
}
}
class MegatronDestructiveForceReflexiveEffect extends OneShotEffect {
private final int value;
MegatronDestructiveForceReflexiveEffect(int value) {
super(Outcome.Damage);
staticText = "{this} deals damage equal to the sacrificed artifact's mana value to target " +
"creature. If excess damage would be dealt to that creature this way, instead that damage " +
"is dealt to that creature's controller and you convert {this}.";
this.value = value;
}
private MegatronDestructiveForceReflexiveEffect(final MegatronDestructiveForceReflexiveEffect effect) {
super(effect);
this.value = effect.value;
}
@Override
public MegatronDestructiveForceReflexiveEffect copy() {
return new MegatronDestructiveForceReflexiveEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent sourcePermanent = source.getSourcePermanentOrLKI(game);
if (sourcePermanent == null) {
return false;
}
if (value < 1) {
return false;
}
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null) {
return false;
}
int lethal = permanent.getLethalDamage(source.getSourceId(), game);
int excess = value - lethal;
if (excess <= 0) {
// no excess damage.
permanent.damage(value, source.getSourceId(), source, game);
return true;
}
// excess damage. dealing excess to controller's instead. And convert Megatron.
permanent.damage(lethal, source.getSourceId(), source, game);
Player player = game.getPlayer(permanent.getControllerId());
if (player != null) {
player.damage(excess, source, game);
}
new TransformSourceEffect().apply(game, source);
return true;
}
}

View file

@ -1,130 +0,0 @@
package mage.cards.o;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
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.keyword.LivingMetalAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.abilities.keyword.TransformAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
* @author xenohedron
*/
public final class OptimusPrimeAutobotLeader extends CardImpl {
public OptimusPrimeAutobotLeader(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(6);
this.toughness = new MageInt(8);
this.color.setWhite(true);
this.color.setBlue(true);
this.color.setRed(true);
this.nightCard = true;
// Living metal
this.addAbility(new LivingMetalAbility());
// Trample
this.addAbility(TrampleAbility.getInstance());
// Whenever you attack, bolster 2. The chosen creature gains trample until end of turn. When that creature deals combat damage to a player this turn, convert Optimus Prime.
this.addAbility(new AttacksWithCreaturesTriggeredAbility(new BolsterEffect(2)
.withAdditionalEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance()))
.withAdditionalEffect(new OptimusPrimeAutobotLeaderEffect())
.setText("bolster 2. The chosen creature gains trample until end of turn. When that creature deals combat damage to a player this turn, convert {this}"),
1));
// Transform Ability
this.addAbility(new TransformAbility());
}
private OptimusPrimeAutobotLeader(final OptimusPrimeAutobotLeader card) {
super(card);
}
@Override
public OptimusPrimeAutobotLeader copy() {
return new OptimusPrimeAutobotLeader(this);
}
}
class OptimusPrimeAutobotLeaderEffect extends OneShotEffect {
OptimusPrimeAutobotLeaderEffect() {
super(Outcome.Transform);
}
private OptimusPrimeAutobotLeaderEffect(final OptimusPrimeAutobotLeaderEffect effect) {
super(effect);
}
@Override
public OptimusPrimeAutobotLeaderEffect copy() {
return new OptimusPrimeAutobotLeaderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (creature == null) {
return false;
}
game.addDelayedTriggeredAbility(new OptimusPrimeAutobotLeaderDelayedTriggeredAbility(new MageObjectReference(creature, game)), source);
return true;
}
}
class OptimusPrimeAutobotLeaderDelayedTriggeredAbility extends DelayedTriggeredAbility {
private final MageObjectReference mor;
OptimusPrimeAutobotLeaderDelayedTriggeredAbility(MageObjectReference mor) {
super(new TransformSourceEffect().setText("convert {this}"), Duration.EndOfTurn);
this.mor = mor;
setTriggerPhrase("When that creature deals combat damage to a player this turn, ");
}
private OptimusPrimeAutobotLeaderDelayedTriggeredAbility(final OptimusPrimeAutobotLeaderDelayedTriggeredAbility ability) {
super(ability);
this.mor = ability.mor;
}
@Override
public OptimusPrimeAutobotLeaderDelayedTriggeredAbility copy() {
return new OptimusPrimeAutobotLeaderDelayedTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (((DamagedPlayerEvent) event).isCombatDamage()) {
Permanent permanent = game.getPermanent(event.getSourceId());
return mor.refersTo(permanent, game);
}
return false;
}
}

View file

@ -1,18 +1,26 @@
package mage.cards.o;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.AttacksWithCreaturesTriggeredAbility;
import mage.abilities.common.BeginningOfEndStepTriggeredAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
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.keyword.LivingMetalAbility;
import mage.abilities.keyword.MoreThanMeetsTheEyeAbility;
import mage.abilities.keyword.TransformAbility;
import mage.abilities.keyword.TrampleAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
@ -20,25 +28,40 @@ import java.util.UUID;
/**
* @author jbureau88
*/
public final class OptimusPrimeHero extends CardImpl {
public final class OptimusPrimeHero extends TransformingDoubleFacedCard {
public OptimusPrimeHero(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{U}{R}{W}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.ROBOT);
this.power = new MageInt(4);
this.toughness = new MageInt(8);
this.secondSideCardClazz = mage.cards.o.OptimusPrimeAutobotLeader.class;
super(
ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{3}{U}{R}{W}",
"Optimus Prime, Autobot Leader",
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "RUW"
);
this.getLeftHalfCard().setPT(4, 8);
this.getRightHalfCard().setPT(6, 8);
// More Than Meets the Eye {2}{U}{R}{W}
this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{U}{R}{W}"));
this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{U}{R}{W}"));
// At the beginning of each end step, bolster 1.
this.addAbility(new BeginningOfEndStepTriggeredAbility(new BolsterEffect(1), TargetController.ANY, false));
this.getLeftHalfCard().addAbility(new BeginningOfEndStepTriggeredAbility(new BolsterEffect(1), TargetController.ANY, false));
// When Optimus Prime dies, return it to the battlefield converted under its owners control.
this.addAbility(new DiesSourceTriggeredAbility(new OptimusPrimeHeroEffect()));
this.getLeftHalfCard().addAbility(new DiesSourceTriggeredAbility(new OptimusPrimeHeroEffect()));
// Optimus Prime, Autobot Leader
// Living metal
this.getRightHalfCard().addAbility(new LivingMetalAbility());
// Trample
this.getRightHalfCard().addAbility(TrampleAbility.getInstance());
// Whenever you attack, bolster 2. The chosen creature gains trample until end of turn. When that creature deals combat damage to a player this turn, convert Optimus Prime.
this.getRightHalfCard().addAbility(new AttacksWithCreaturesTriggeredAbility(new BolsterEffect(2)
.withAdditionalEffect(new GainAbilityTargetEffect(TrampleAbility.getInstance()))
.withAdditionalEffect(new OptimusPrimeAutobotLeaderEffect())
.setText("bolster 2. The chosen creature gains trample until end of turn. When that creature deals combat damage to a player this turn, convert {this}"),
1));
}
private OptimusPrimeHero(final OptimusPrimeHero card) {
@ -74,7 +97,70 @@ class OptimusPrimeHeroEffect extends OneShotEffect {
if (card == null || controller == null) {
return false;
}
game.getState().setValue(TransformAbility.VALUE_KEY_ENTER_TRANSFORMED + source.getSourceId(), Boolean.TRUE);
TransformingDoubleFacedCard.setCardTransformed(card, game);
return controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
}
class OptimusPrimeAutobotLeaderEffect extends OneShotEffect {
OptimusPrimeAutobotLeaderEffect() {
super(Outcome.Transform);
}
private OptimusPrimeAutobotLeaderEffect(final OptimusPrimeAutobotLeaderEffect effect) {
super(effect);
}
@Override
public OptimusPrimeAutobotLeaderEffect copy() {
return new OptimusPrimeAutobotLeaderEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(getTargetPointer().getFirst(game, source));
if (creature == null) {
return false;
}
game.addDelayedTriggeredAbility(new OptimusPrimeAutobotLeaderDelayedTriggeredAbility(new MageObjectReference(creature, game)), source);
return true;
}
}
class OptimusPrimeAutobotLeaderDelayedTriggeredAbility extends DelayedTriggeredAbility {
private final MageObjectReference mor;
OptimusPrimeAutobotLeaderDelayedTriggeredAbility(MageObjectReference mor) {
super(new TransformSourceEffect().setText("convert {this}"), Duration.EndOfTurn);
this.mor = mor;
setTriggerPhrase("When that creature deals combat damage to a player this turn, ");
}
private OptimusPrimeAutobotLeaderDelayedTriggeredAbility(final OptimusPrimeAutobotLeaderDelayedTriggeredAbility ability) {
super(ability);
this.mor = ability.mor;
}
@Override
public OptimusPrimeAutobotLeaderDelayedTriggeredAbility copy() {
return new OptimusPrimeAutobotLeaderDelayedTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (((DamagedPlayerEvent) event).isCombatDamage()) {
Permanent permanent = game.getPermanent(event.getSourceId());
return mor.refersTo(permanent, game);
}
return false;
}
}

View file

@ -1,17 +1,19 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.TriggeredAbility;
import mage.abilities.common.BecomesMonarchSourceControllerTriggeredAbility;
import mage.abilities.common.CombatDamageDealtToYouTriggeredAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.common.DrawCardControllerTriggeredAbility;
import mage.abilities.condition.common.MonarchIsNotSetCondition;
import mage.abilities.condition.common.MonarchIsSourceControllerCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.BecomesMonarchTargetEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.MoreThanMeetsTheEyeAbility;
import mage.cards.CardImpl;
import mage.abilities.keyword.*;
import mage.cards.CardSetInfo;
import mage.cards.TransformingDoubleFacedCard;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
@ -22,22 +24,23 @@ import java.util.UUID;
/**
* @author Susucr
*/
public final class StarscreamPowerHungry extends CardImpl {
public final class StarscreamPowerHungry extends TransformingDoubleFacedCard {
public StarscreamPowerHungry(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{3}{B}");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.ROBOT);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
this.secondSideCardClazz = mage.cards.s.StarscreamSeekerLeader.class;
super(
ownerId, setInfo,
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, new SubType[]{SubType.ROBOT}, "{3}{B}",
"Starscream, Seeker Leader",
new SuperType[]{SuperType.LEGENDARY}, new CardType[]{CardType.ARTIFACT}, new SubType[]{SubType.VEHICLE}, "B"
);
this.getLeftHalfCard().setPT(2, 3);
this.getRightHalfCard().setPT(2, 3);
// More Than Meets the Eye {2}{B}
this.addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{B}"));
this.getLeftHalfCard().addAbility(new MoreThanMeetsTheEyeAbility(this, "{2}{B}"));
// Flying
this.addAbility(FlyingAbility.getInstance());
this.getLeftHalfCard().addAbility(FlyingAbility.getInstance());
// Whenever you draw a card, if you're the monarch, target opponent loses 2 life.
TriggeredAbility trigger = new ConditionalInterveningIfTriggeredAbility(
@ -46,10 +49,35 @@ public final class StarscreamPowerHungry extends CardImpl {
"Whenever you draw a card, if you're the monarch, target opponent loses 2 life."
);
trigger.addTarget(new TargetOpponent());
this.addAbility(trigger);
this.getLeftHalfCard().addAbility(trigger);
// Whenever one or more creatures deal combat damage to you, convert Starscream.
this.addAbility(new CombatDamageDealtToYouTriggeredAbility(
this.getLeftHalfCard().addAbility(new CombatDamageDealtToYouTriggeredAbility(
new TransformSourceEffect().setText("convert {this}")
));
// Starscream, Seeker Leader
// Living metal
this.getRightHalfCard().addAbility(new LivingMetalAbility());
// Flying
this.getRightHalfCard().addAbility(FlyingAbility.getInstance());
// Menace
this.getRightHalfCard().addAbility(new MenaceAbility(false));
// Haste
this.getRightHalfCard().addAbility(HasteAbility.getInstance());
// Whenever Starscream deals combat damage to a player, if there is no monarch, that player becomes the monarch.
this.getRightHalfCard().addAbility(new ConditionalInterveningIfTriggeredAbility(
new DealsCombatDamageToAPlayerTriggeredAbility(new BecomesMonarchTargetEffect(), false, true),
MonarchIsNotSetCondition.instance,
"Whenever {this} deals combat damage to a player, if there is no monarch, that player becomes the monarch."
));
// Whenever you become the monarch, convert Starscream.
this.getRightHalfCard().addAbility(new BecomesMonarchSourceControllerTriggeredAbility(
new TransformSourceEffect().setText("convert {this}")
));
}

View file

@ -1,70 +0,0 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.common.BecomesMonarchSourceControllerTriggeredAbility;
import mage.abilities.common.DealsCombatDamageToAPlayerTriggeredAbility;
import mage.abilities.condition.common.MonarchIsNotSetCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.common.BecomesMonarchTargetEffect;
import mage.abilities.effects.common.TransformSourceEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.abilities.keyword.HasteAbility;
import mage.abilities.keyword.LivingMetalAbility;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import java.util.UUID;
/**
* @author Susucr
*/
public final class StarscreamSeekerLeader extends CardImpl {
public StarscreamSeekerLeader(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "");
this.supertype.add(SuperType.LEGENDARY);
this.subtype.add(SubType.VEHICLE);
this.power = new MageInt(2);
this.toughness = new MageInt(3);
this.color.setBlack(true);
this.nightCard = true;
// Living metal
this.addAbility(new LivingMetalAbility());
// Flying
this.addAbility(FlyingAbility.getInstance());
// Menace
this.addAbility(new MenaceAbility(false));
// Haste
this.addAbility(HasteAbility.getInstance());
// Whenever Starscream deals combat damage to a player, if there is no monarch, that player becomes the monarch.
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
new DealsCombatDamageToAPlayerTriggeredAbility(new BecomesMonarchTargetEffect(), false, true),
MonarchIsNotSetCondition.instance,
"Whenever {this} deals combat damage to a player, if there is no monarch, that player becomes the monarch."
));
// Whenever you become the monarch, convert Starscream.
this.addAbility(new BecomesMonarchSourceControllerTriggeredAbility(
new TransformSourceEffect().setText("convert {this}")
));
}
private StarscreamSeekerLeader(final StarscreamSeekerLeader card) {
super(card);
}
@Override
public StarscreamSeekerLeader copy() {
return new StarscreamSeekerLeader(this);
}
}

View file

@ -720,7 +720,6 @@ public class SecretLairDrop extends ExpansionSet {
cards.add(new SetCardInfo("Thought-Knot Seer", 720, Rarity.RARE, mage.cards.t.ThoughtKnotSeer.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Diabolic Tutor", 721, Rarity.RARE, mage.cards.d.DiabolicTutor.class));
cards.add(new SetCardInfo("Delver of Secrets", 722, Rarity.RARE, mage.cards.d.DelverOfSecrets.class));
cards.add(new SetCardInfo("Insectile Aberration", 722, Rarity.RARE, mage.cards.i.InsectileAberration.class));
cards.add(new SetCardInfo("Lightning Strike", 724, Rarity.RARE, mage.cards.l.LightningStrike.class));
cards.add(new SetCardInfo("Zur the Enchanter", 726, Rarity.RARE, mage.cards.z.ZurTheEnchanter.class));
cards.add(new SetCardInfo("Fabled Passage", 727, Rarity.RARE, mage.cards.f.FabledPassage.class, NON_FULL_USE_VARIOUS));
@ -882,13 +881,9 @@ public class SecretLairDrop extends ExpansionSet {
cards.add(new SetCardInfo("Eldrazi Temple", 1154, Rarity.RARE, mage.cards.e.EldraziTemple.class));
cards.add(new SetCardInfo("Esika, God of the Tree", 1155, Rarity.MYTHIC, mage.cards.e.EsikaGodOfTheTree.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Archangel Avacyn", 1156, Rarity.MYTHIC, mage.cards.a.ArchangelAvacyn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Avacyn, the Purifier", 1156, Rarity.MYTHIC, mage.cards.a.AvacynThePurifier.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bloodline Keeper", 1157, Rarity.RARE, mage.cards.b.BloodlineKeeper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lord of Lineage", 1157, Rarity.RARE, mage.cards.l.LordOfLineage.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nicol Bolas, the Ravager", 1158, Rarity.MYTHIC, mage.cards.n.NicolBolasTheRavager.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nicol Bolas, the Arisen", 1158, Rarity.MYTHIC, mage.cards.n.NicolBolasTheArisen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Westvale Abbey", 1159, Rarity.RARE, mage.cards.w.WestvaleAbbey.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ormendahl, Profane Prince", 1159, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Baral, Chief of Compliance", 1164, Rarity.RARE, mage.cards.b.BaralChiefOfCompliance.class));
cards.add(new SetCardInfo("Spellseeker", 1165, Rarity.RARE, mage.cards.s.Spellseeker.class));
cards.add(new SetCardInfo("Magus of the Wheel", 1166, Rarity.RARE, mage.cards.m.MagusOfTheWheel.class));
@ -935,13 +930,9 @@ public class SecretLairDrop extends ExpansionSet {
cards.add(new SetCardInfo("Inkmoth Nexus", 1207, Rarity.RARE, mage.cards.i.InkmothNexus.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Esika, God of the Tree", 1208, Rarity.MYTHIC, mage.cards.e.EsikaGodOfTheTree.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Archangel Avacyn", 1209, Rarity.MYTHIC, mage.cards.a.ArchangelAvacyn.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Avacyn, the Purifier", 1209, Rarity.MYTHIC, mage.cards.a.AvacynThePurifier.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Bloodline Keeper", 1210, Rarity.RARE, mage.cards.b.BloodlineKeeper.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Lord of Lineage", 1210, Rarity.RARE, mage.cards.l.LordOfLineage.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nicol Bolas, the Ravager", 1211, Rarity.MYTHIC, mage.cards.n.NicolBolasTheRavager.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Nicol Bolas, the Arisen", 1211, Rarity.MYTHIC, mage.cards.n.NicolBolasTheArisen.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Westvale Abbey", 1212, Rarity.RARE, mage.cards.w.WestvaleAbbey.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ormendahl, Profane Prince", 1212, Rarity.RARE, mage.cards.o.OrmendahlProfanePrince.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Phyrexian Unlife", 1213, Rarity.RARE, mage.cards.p.PhyrexianUnlife.class));
cards.add(new SetCardInfo("Phyrexian Crusader", 1214, Rarity.RARE, mage.cards.p.PhyrexianCrusader.class));
cards.add(new SetCardInfo("Plague Engineer", 1215, Rarity.RARE, mage.cards.p.PlagueEngineer.class));

View file

@ -24,16 +24,11 @@ public final class Transformers extends ExpansionSet {
cards.add(new SetCardInfo("Flamewar, Brash Veteran", 10, Rarity.MYTHIC, mage.cards.f.FlamewarBrashVeteran.class));
cards.add(new SetCardInfo("Goldbug, Humanity's Ally", 11, Rarity.MYTHIC, mage.cards.g.GoldbugHumanitysAlly.class));
cards.add(new SetCardInfo("Jetfire, Ingenious Scientist", 3, Rarity.MYTHIC, mage.cards.j.JetfireIngeniousScientist.class));
cards.add(new SetCardInfo("Megatron, Destructive Force", 12, Rarity.MYTHIC, mage.cards.m.MegatronDestructiveForce.class));
cards.add(new SetCardInfo("Megatron, Tyrant", 12, Rarity.MYTHIC, mage.cards.m.MegatronTyrant.class));
cards.add(new SetCardInfo("Optimus Prime, Autobot Leader", 13, Rarity.MYTHIC, mage.cards.o.OptimusPrimeAutobotLeader.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Optimus Prime, Hero", 13, Rarity.MYTHIC, mage.cards.o.OptimusPrimeHero.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Optimus Prime, Autobot Leader", 27, Rarity.MYTHIC, mage.cards.o.OptimusPrimeAutobotLeader.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Optimus Prime, Hero", 27, Rarity.MYTHIC, mage.cards.o.OptimusPrimeHero.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Ratchet, Field Medic", 2, Rarity.MYTHIC, mage.cards.r.RatchetFieldMedic.class));
cards.add(new SetCardInfo("Ratchet, Rescue Racer", 2, Rarity.MYTHIC, mage.cards.r.RatchetRescueRacer.class));
cards.add(new SetCardInfo("Starscream, Power Hungry", 5, Rarity.MYTHIC, mage.cards.s.StarscreamPowerHungry.class));
cards.add(new SetCardInfo("Starscream, Seeker Leader", 5, Rarity.MYTHIC, mage.cards.s.StarscreamSeekerLeader.class));
cards.add(new SetCardInfo("Ultra Magnus, Tactician", 15, Rarity.MYTHIC, mage.cards.u.UltraMagnusTactician.class));
}
}

View file

@ -1,13 +1,11 @@
package mage.abilities.condition.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.condition.Condition;
import mage.cards.AdventureCardSpell;
import mage.cards.Card;
import mage.cards.ModalDoubleFacedCardHalf;
import mage.cards.SplitCardHalf;
import mage.cards.SubCard;
import mage.constants.Zone;
import mage.game.Game;
import mage.game.stack.Spell;
@ -20,7 +18,7 @@ public enum IsBeingCastFromHandCondition implements Condition {
@Override
public boolean apply(Game game, Ability source) {
MageObject object = game.getObject(source);
if (object instanceof SplitCardHalf || object instanceof AdventureCardSpell || object instanceof ModalDoubleFacedCardHalf) {
if (object instanceof SubCard || object instanceof AdventureCardSpell) {
UUID mainCardId = ((Card) object).getMainCard().getId();
object = game.getObject(mainCardId);
}