Merge pull request #5047 from NoahGleason/mourners-shield

Implement Mourner's Shield
This commit is contained in:
theelk801 2018-06-23 13:38:06 -04:00 committed by GitHub
commit c4d9bfe554
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 210 additions and 0 deletions

View file

@ -0,0 +1,170 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageObject;
import mage.MageObjectReference;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.PreventionEffectImpl;
import mage.abilities.effects.common.PreventDamageBySourceEffect;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.FilterObject;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.ColorPredicate;
import mage.filter.predicate.mageobject.ColorlessPredicate;
import mage.filter.predicate.mageobject.SharesColorPredicate;
import mage.game.ExileZone;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetSource;
import mage.target.common.TargetCardInGraveyard;
import mage.util.CardUtil;
/**
*
* @author noahg
*/
public final class MournersShield extends CardImpl {
public MournersShield(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// Imprint - When Mourner's Shield enters the battlefield, you may exile target card from a graveyard.
Ability ability = new EntersBattlefieldTriggeredAbility(new MournersShieldImprintEffect(), true, "Imprint — ");
ability.addTarget(new TargetCardInGraveyard());
this.addAbility(ability);
// {2}, {tap}: Prevent all damage that would be dealt this turn by a source of your choice that shares a color with the exiled card.
Ability preventAbility = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MournersShieldEffect(), new GenericManaCost(2));
preventAbility.addCost(new TapSourceCost());
this.addAbility(preventAbility);
}
public MournersShield(final MournersShield card) {
super(card);
}
@Override
public MournersShield copy() {
return new MournersShield(this);
}
}
class MournersShieldImprintEffect extends OneShotEffect {
MournersShieldImprintEffect() {
super(Outcome.Exile);
this.staticText = "you may exile target card from a graveyard";
}
MournersShieldImprintEffect(final MournersShieldImprintEffect effect) {
super(effect);
}
@Override
public MournersShieldImprintEffect copy() {
return new MournersShieldImprintEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
if (controller != null) {
Card card = game.getCard(this.getTargetPointer().getFirst(game, source));
if (card != null) {
controller.moveCardsToExile(card, source, game, true, CardUtil.getExileZoneId(game, source.getSourceId(), source.getSourceObjectZoneChangeCounter()), source.getSourceObject(game).getIdName());
Permanent sourcePermanent = game.getPermanent(source.getSourceId());
if (sourcePermanent != null) {
sourcePermanent.imprint(this.getTargetPointer().getFirst(game, source), game);
}
}
return true;
}
return false;
}
}
class MournersShieldEffect extends PreventionEffectImpl {
private TargetSource target;
private MageObjectReference mageObjectReference;
private boolean noneExiled;
public MournersShieldEffect() {
super(Duration.EndOfTurn);
noneExiled = false;
this.staticText = "Prevent all damage that would be dealt this turn by a source of your choice that shares a color with the exiled card.";
}
public MournersShieldEffect(final MournersShieldEffect effect) {
super(effect);
if (effect.target != null) {
this.target = effect.target.copy();
} else {
this.target = null;
}
this.mageObjectReference = effect.mageObjectReference;
this.noneExiled = effect.noneExiled;
}
@Override
public MournersShieldEffect copy() {
return new MournersShieldEffect(this);
}
@Override
public void init(Ability source, Game game) {
ObjectColor colorsAmongImprinted = new ObjectColor();
Permanent sourceObject = game.getPermanent(source.getSourceId());
ExileZone exileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source.getSourceId()));
if (sourceObject == null || sourceObject.getImprinted() == null) {
noneExiled = true;
return;
}
for (UUID imprinted : sourceObject.getImprinted()){
if (imprinted != null && exileZone.contains(imprinted)){
Card card = game.getCard(imprinted);
if (card != null) {
colorsAmongImprinted = colorsAmongImprinted.union(card.getColor(game));
}
}
}
FilterObject filterObject = new FilterObject("a source of your choice that shares a color with the exiled card");
filterObject.add(new SharesColorPredicate(colorsAmongImprinted));
this.target = new TargetSource(filterObject);
this.target.choose(Outcome.PreventDamage, source.getControllerId(), source.getSourceId(), game);
if (target.getFirstTarget() != null) {
mageObjectReference = new MageObjectReference(target.getFirstTarget(), game);
} else {
mageObjectReference = null;
}
}
@Override
public boolean applies(GameEvent event, Ability source, Game game) {
if (noneExiled || mageObjectReference == null){
return false;
}
if (super.applies(event, source, game)) {
MageObject mageObject = game.getObject(event.getSourceId());
return mageObjectReference.refersTo(mageObject, game);
}
return false;
}
}

View file

@ -176,6 +176,7 @@ public final class Mirrodin extends ExpansionSet {
cards.add(new SetCardInfo("Mountain", 300, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 300, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mountain", 301, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 301, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mountain", 302, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS)); cards.add(new SetCardInfo("Mountain", 302, Rarity.LAND, mage.cards.basiclands.Mountain.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Mourner's Shield", 209, Rarity.UNCOMMON, mage.cards.m.MournersShield.class));
cards.add(new SetCardInfo("Myr Adapter", 210, Rarity.COMMON, mage.cards.m.MyrAdapter.class)); cards.add(new SetCardInfo("Myr Adapter", 210, Rarity.COMMON, mage.cards.m.MyrAdapter.class));
cards.add(new SetCardInfo("Myr Enforcer", 211, Rarity.COMMON, mage.cards.m.MyrEnforcer.class)); cards.add(new SetCardInfo("Myr Enforcer", 211, Rarity.COMMON, mage.cards.m.MyrEnforcer.class));
cards.add(new SetCardInfo("Myr Incubator", 212, Rarity.RARE, mage.cards.m.MyrIncubator.class)); cards.add(new SetCardInfo("Myr Incubator", 212, Rarity.RARE, mage.cards.m.MyrIncubator.class));

View file

@ -0,0 +1,39 @@
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package mage.filter.predicate.mageobject;
import mage.MageObject;
import mage.ObjectColor;
import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.filter.predicate.Predicate;
import mage.game.Game;
/**
*
* @author noahg
*/
public class SharesColorPredicate implements Predicate<MageObject> {
private final ObjectColor color;
public SharesColorPredicate(ObjectColor color) {
this.color = color;
}
@Override
public boolean apply(MageObject input, Game game) {
return color != null && input.getColor(game).shares(color);
}
@Override
public String toString() {
return "shares a color";
}
}