mirror of
https://github.com/correl/mage.git
synced 2024-11-28 19:19:55 +00:00
Implemented Jace, Mirror Mage
This commit is contained in:
parent
c84c17a455
commit
6903dad861
7 changed files with 169 additions and 5 deletions
134
Mage.Sets/src/mage/cards/j/JaceMirrorMage.java
Normal file
134
Mage.Sets/src/mage/cards/j/JaceMirrorMage.java
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
package mage.cards.j;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.LoyaltyAbility;
|
||||||
|
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
|
||||||
|
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
|
||||||
|
import mage.abilities.condition.common.KickedCondition;
|
||||||
|
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
|
||||||
|
import mage.abilities.effects.OneShotEffect;
|
||||||
|
import mage.abilities.effects.common.CreateTokenCopyTargetEffect;
|
||||||
|
import mage.abilities.effects.keyword.ScryEffect;
|
||||||
|
import mage.cards.Card;
|
||||||
|
import mage.cards.CardsImpl;
|
||||||
|
import mage.constants.Outcome;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.SuperType;
|
||||||
|
import mage.abilities.costs.mana.ManaCostsImpl;
|
||||||
|
import mage.abilities.keyword.KickerAbility;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.counters.CounterType;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
import mage.players.Player;
|
||||||
|
import mage.target.targetpointer.FixedTarget;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author TheElk801
|
||||||
|
*/
|
||||||
|
public final class JaceMirrorMage extends CardImpl {
|
||||||
|
|
||||||
|
public JaceMirrorMage(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{1}{U}{U}");
|
||||||
|
|
||||||
|
this.addSuperType(SuperType.LEGENDARY);
|
||||||
|
this.subtype.add(SubType.JACE);
|
||||||
|
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
|
||||||
|
|
||||||
|
// Kicker {2}
|
||||||
|
this.addAbility(new KickerAbility(new ManaCostsImpl<>("{2}")));
|
||||||
|
|
||||||
|
// When Jace, Mirror Mage enters the battlefield, if Jace was kicked, create a token that's a copy of Jace, Mirror Mage except it's not legendary and its starting loyalty is 1.
|
||||||
|
this.addAbility(new ConditionalInterveningIfTriggeredAbility(
|
||||||
|
new EntersBattlefieldTriggeredAbility(new JaceMirrorMageCopyEffect()),
|
||||||
|
KickedCondition.instance, "When {this} enters the battlefield, if {this} was kicked, " +
|
||||||
|
"create a token that's a copy of {this} except it's not legendary and its starting loyalty is 1."
|
||||||
|
));
|
||||||
|
|
||||||
|
// +1: Scry 2.
|
||||||
|
this.addAbility(new LoyaltyAbility(new ScryEffect(2), 1));
|
||||||
|
|
||||||
|
// 0: Draw a card and reveal it. Remove a number of loyalty counters equal to that card's converted mana cost from Jace, Mirror Mage.
|
||||||
|
this.addAbility(new LoyaltyAbility(new JaceMirrorMageDrawEffect(), 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
private JaceMirrorMage(final JaceMirrorMage card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JaceMirrorMage copy() {
|
||||||
|
return new JaceMirrorMage(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JaceMirrorMageCopyEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
JaceMirrorMageCopyEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
}
|
||||||
|
|
||||||
|
private JaceMirrorMageCopyEffect(final JaceMirrorMageCopyEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JaceMirrorMageCopyEffect copy() {
|
||||||
|
return new JaceMirrorMageCopyEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
Permanent permanent = game.getPermanentOrLKIBattlefield(source.getSourceId());
|
||||||
|
if (permanent == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CreateTokenCopyTargetEffect effect = new CreateTokenCopyTargetEffect(source.getControllerId(), null, false, 1);
|
||||||
|
effect.setTargetPointer(new FixedTarget(source.getSourceId(), game));
|
||||||
|
effect.setIsntLegendary(true);
|
||||||
|
effect.setStartingLoyalty(1);
|
||||||
|
return effect.apply(game, source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class JaceMirrorMageDrawEffect extends OneShotEffect {
|
||||||
|
|
||||||
|
JaceMirrorMageDrawEffect() {
|
||||||
|
super(Outcome.Benefit);
|
||||||
|
staticText = "draw a card and reveal it. Remove a number of loyalty counters equal to that card's converted mana cost from {this}";
|
||||||
|
}
|
||||||
|
|
||||||
|
private JaceMirrorMageDrawEffect(final JaceMirrorMageDrawEffect effect) {
|
||||||
|
super(effect);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public JaceMirrorMageDrawEffect copy() {
|
||||||
|
return new JaceMirrorMageDrawEffect(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean apply(Game game, Ability source) {
|
||||||
|
// TODO: Make this and similar effects work with draw replacement correctly
|
||||||
|
Player player = game.getPlayer(source.getControllerId());
|
||||||
|
if (player == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Card card = player.getLibrary().getFromTop(game);
|
||||||
|
player.drawCards(1, source.getSourceId(), game);
|
||||||
|
player.revealCards(source, new CardsImpl(card), game);
|
||||||
|
if (card == null || card.getConvertedManaCost() == 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
|
||||||
|
if (permanent == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
permanent.removeCounters(CounterType.LOYALTY.createInstance(card.getConvertedManaCost()), game);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -26,5 +26,6 @@ public final class ZendikarRising extends ExpansionSet {
|
||||||
this.ratioBoosterMythic = 8;
|
this.ratioBoosterMythic = 8;
|
||||||
this.maxCardNumberInBooster = 280;
|
this.maxCardNumberInBooster = 280;
|
||||||
|
|
||||||
|
cards.add(new SetCardInfo("Jace, Mirror Mage", 63, Rarity.MYTHIC, mage.cards.j.JaceMirrorMage.class));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import mage.abilities.Abilities;
|
import mage.abilities.Abilities;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
import mage.abilities.costs.mana.ManaCost;
|
import mage.abilities.costs.mana.ManaCost;
|
||||||
|
@ -65,6 +66,8 @@ public interface MageObject extends MageItem, Serializable {
|
||||||
|
|
||||||
int getStartingLoyalty();
|
int getStartingLoyalty();
|
||||||
|
|
||||||
|
void setStartingLoyalty(int startingLoyalty);
|
||||||
|
|
||||||
void adjustCosts(Ability ability, Game game);
|
void adjustCosts(Ability ability, Game game);
|
||||||
|
|
||||||
void adjustTargets(Ability ability, Game game);
|
void adjustTargets(Ability ability, Game game);
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package mage;
|
package mage;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import mage.abilities.Abilities;
|
import mage.abilities.Abilities;
|
||||||
import mage.abilities.AbilitiesImpl;
|
import mage.abilities.AbilitiesImpl;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
@ -160,6 +161,15 @@ public abstract class MageObjectImpl implements MageObject {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setStartingLoyalty(int startingLoyalty) {
|
||||||
|
for (Ability ab : getAbilities()) {
|
||||||
|
if (ab instanceof PlaneswalkerEntersWithLoyaltyCountersAbility) {
|
||||||
|
((PlaneswalkerEntersWithLoyaltyCountersAbility) ab).setStartingLoyalty(startingLoyalty);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ObjectColor getColor(Game game) {
|
public ObjectColor getColor(Game game) {
|
||||||
return color;
|
return color;
|
||||||
|
@ -307,7 +317,7 @@ public abstract class MageObjectImpl implements MageObject {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void removePTCDA() {
|
public void removePTCDA() {
|
||||||
for (Iterator<Ability> iter = this.getAbilities().iterator(); iter.hasNext();) {
|
for (Iterator<Ability> iter = this.getAbilities().iterator(); iter.hasNext(); ) {
|
||||||
Ability ability = iter.next();
|
Ability ability = iter.next();
|
||||||
for (Effect effect : ability.getEffects()) {
|
for (Effect effect : ability.getEffects()) {
|
||||||
if (effect instanceof ContinuousEffect && ((ContinuousEffect) effect).getSublayer() == SubLayer.CharacteristicDefining_7a) {
|
if (effect instanceof ContinuousEffect && ((ContinuousEffect) effect).getSublayer() == SubLayer.CharacteristicDefining_7a) {
|
||||||
|
|
|
@ -9,12 +9,11 @@ import mage.abilities.effects.common.counter.AddCountersSourceEffect;
|
||||||
import mage.counters.CounterType;
|
import mage.counters.CounterType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
|
||||||
* @author LevelX2
|
* @author LevelX2
|
||||||
*/
|
*/
|
||||||
public class PlaneswalkerEntersWithLoyaltyCountersAbility extends EntersBattlefieldAbility {
|
public class PlaneswalkerEntersWithLoyaltyCountersAbility extends EntersBattlefieldAbility {
|
||||||
|
|
||||||
private final int startingLoyalty;
|
private int startingLoyalty;
|
||||||
|
|
||||||
public PlaneswalkerEntersWithLoyaltyCountersAbility(int loyalty) {
|
public PlaneswalkerEntersWithLoyaltyCountersAbility(int loyalty) {
|
||||||
super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(loyalty)));
|
super(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(loyalty)));
|
||||||
|
@ -31,6 +30,12 @@ public class PlaneswalkerEntersWithLoyaltyCountersAbility extends EntersBattlefi
|
||||||
return startingLoyalty;
|
return startingLoyalty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStartingLoyalty(int startingLoyalty) {
|
||||||
|
this.startingLoyalty = startingLoyalty;
|
||||||
|
this.getEffects().clear();
|
||||||
|
this.addEffect(new AddCountersSourceEffect(CounterType.LOYALTY.createInstance(startingLoyalty)));
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public PlaneswalkerEntersWithLoyaltyCountersAbility copy() {
|
public PlaneswalkerEntersWithLoyaltyCountersAbility copy() {
|
||||||
return new PlaneswalkerEntersWithLoyaltyCountersAbility(this);
|
return new PlaneswalkerEntersWithLoyaltyCountersAbility(this);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import mage.MageObject;
|
import mage.MageObject;
|
||||||
import mage.ObjectColor;
|
import mage.ObjectColor;
|
||||||
import mage.abilities.Ability;
|
import mage.abilities.Ability;
|
||||||
|
@ -46,6 +47,7 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
||||||
private ObjectColor color;
|
private ObjectColor color;
|
||||||
private boolean useLKI = false;
|
private boolean useLKI = false;
|
||||||
private boolean isntLegendary = false;
|
private boolean isntLegendary = false;
|
||||||
|
private int startingLoyalty = -1;
|
||||||
private final List<Ability> additionalAbilities = new ArrayList();
|
private final List<Ability> additionalAbilities = new ArrayList();
|
||||||
|
|
||||||
public CreateTokenCopyTargetEffect(boolean useLKI) {
|
public CreateTokenCopyTargetEffect(boolean useLKI) {
|
||||||
|
@ -176,6 +178,10 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
||||||
if (isntLegendary) {
|
if (isntLegendary) {
|
||||||
token.getSuperType().remove(SuperType.LEGENDARY);
|
token.getSuperType().remove(SuperType.LEGENDARY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (startingLoyalty!=-1){
|
||||||
|
token.setStartingLoyalty(startingLoyalty);
|
||||||
|
}
|
||||||
if (additionalCardType != null && !token.getCardType().contains(additionalCardType)) {
|
if (additionalCardType != null && !token.getCardType().contains(additionalCardType)) {
|
||||||
token.addCardType(additionalCardType);
|
token.addCardType(additionalCardType);
|
||||||
}
|
}
|
||||||
|
@ -288,6 +294,10 @@ public class CreateTokenCopyTargetEffect extends OneShotEffect {
|
||||||
this.hasHaste = hasHaste;
|
this.hasHaste = hasHaste;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setStartingLoyalty(int startingLoyalty) {
|
||||||
|
this.startingLoyalty = startingLoyalty;
|
||||||
|
}
|
||||||
|
|
||||||
public void exileTokensCreatedAtNextEndStep(Game game, Ability source) {
|
public void exileTokensCreatedAtNextEndStep(Game game, Ability source) {
|
||||||
for (Permanent tokenPermanent : addedTokenPermanents) {
|
for (Permanent tokenPermanent : addedTokenPermanents) {
|
||||||
ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD);
|
ExileTargetEffect exileEffect = new ExileTargetEffect(null, "", Zone.BATTLEFIELD);
|
||||||
|
|
|
@ -53,6 +53,7 @@ Ingest|new|
|
||||||
Islandcycling|cost|
|
Islandcycling|cost|
|
||||||
Islandwalk|new|
|
Islandwalk|new|
|
||||||
Jump-start|card|
|
Jump-start|card|
|
||||||
|
Kicker|cost|
|
||||||
Level up|cost|
|
Level up|cost|
|
||||||
Lifelink|instance|
|
Lifelink|instance|
|
||||||
Living weapon|new|
|
Living weapon|new|
|
||||||
|
|
Loading…
Reference in a new issue