Refactoring subtypes to make Maskwood Nexus work (ready for review) (#7432)

* removed and renamed SubTypeList

* updated subtype test

* refactored Changeling to be an ability that actually does something

* moved isAllCreatureTypes into SubTypes class

* renamed copyTo method to copyFrom

* added removeAllCreatureTypes where usable

* replaced some subtype methods

* replaced some more subtype methods

* replaced subtype mass add/remove methods

* updated more subtype methods

* fixed some errors

* made common shared creature type predicate

* refactored another card involving subtypes

* Added usage of object attribute in subTypes's write operations;

* Refactor: use same param styles in subtype methods

* Refactor: simplified usage of copy appliers;

* Refactor: fixed code usage in CopyApplier

Co-authored-by: Oleg Agafonov <jaydi85@gmail.com>
This commit is contained in:
Evan Kranzler 2021-01-26 08:52:35 -05:00 committed by GitHub
parent 6f42b90305
commit dacf30f4b9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
259 changed files with 1857 additions and 1922 deletions

View file

@ -7,7 +7,7 @@ import mage.client.dialog.PreferencesDialog;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.MageObjectType; import mage.constants.MageObjectType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.util.SubTypeList; import mage.util.SubTypes;
import mage.view.CardView; import mage.view.CardView;
import mage.view.PermanentView; import mage.view.PermanentView;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -1466,7 +1466,7 @@ public class ModernCardRenderer extends CardRenderer {
// Determine which background paint to use from a set of colors // Determine which background paint to use from a set of colors
// and the current card. // and the current card.
protected static Paint getBackgroundPaint(ObjectColor colors, Collection<CardType> types, SubTypeList subTypes) { protected static Paint getBackgroundPaint(ObjectColor colors, Collection<CardType> types, SubTypes subTypes) {
if (subTypes.contains(SubType.VEHICLE)) { if (subTypes.contains(SubType.VEHICLE)) {
return BG_TEXTURE_VEHICLE; return BG_TEXTURE_VEHICLE;
} else if (types.contains(CardType.LAND)) { } else if (types.contains(CardType.LAND)) {
@ -1493,7 +1493,7 @@ public class ModernCardRenderer extends CardRenderer {
// Determine which background image to use from a set of colors // Determine which background image to use from a set of colors
// and the current card. // and the current card.
protected static BufferedImage getBackgroundImage(ObjectColor colors, Collection<CardType> types, SubTypeList subTypes, boolean isExped) { protected static BufferedImage getBackgroundImage(ObjectColor colors, Collection<CardType> types, SubTypes subTypes, boolean isExped) {
if (subTypes.contains(SubType.VEHICLE)) { if (subTypes.contains(SubType.VEHICLE)) {
return BG_IMG_VEHICLE; return BG_IMG_VEHICLE;
} else if (types.contains(CardType.LAND)) { } else if (types.contains(CardType.LAND)) {

View file

@ -5,7 +5,7 @@ import java.util.EnumSet;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.util.SubTypeList; import mage.util.SubTypes;
/** /**
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
@ -28,7 +28,7 @@ public class AbilityView extends CardView {
this.toughness = ""; this.toughness = "";
this.loyalty = ""; this.loyalty = "";
this.cardTypes = new ArrayList<>(); this.cardTypes = new ArrayList<>();
this.subTypes = new SubTypeList(); this.subTypes = new SubTypes();
this.superTypes = EnumSet.noneOf(SuperType.class); this.superTypes = EnumSet.noneOf(SuperType.class);
this.color = new ObjectColor(); this.color = new ObjectColor();
this.manaCostLeft = ability.getManaCosts().getSymbols(); this.manaCostLeft = ability.getManaCosts().getSymbols();

View file

@ -29,7 +29,7 @@ import mage.game.stack.StackAbility;
import mage.target.Target; import mage.target.Target;
import mage.target.Targets; import mage.target.Targets;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.util.SubTypeList; import mage.util.SubTypes;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -58,7 +58,7 @@ public class CardView extends SimpleCardView {
protected String loyalty = ""; protected String loyalty = "";
protected String startingLoyalty; protected String startingLoyalty;
protected ArrayList<CardType> cardTypes; protected ArrayList<CardType> cardTypes;
protected SubTypeList subTypes; protected SubTypes subTypes;
protected Set<SuperType> superTypes; protected Set<SuperType> superTypes;
protected ObjectColor color; protected ObjectColor color;
protected ObjectColor frameColor; protected ObjectColor frameColor;
@ -165,7 +165,7 @@ public class CardView extends SimpleCardView {
this.loyalty = cardView.loyalty; this.loyalty = cardView.loyalty;
this.startingLoyalty = cardView.startingLoyalty; this.startingLoyalty = cardView.startingLoyalty;
this.cardTypes = new ArrayList<>(cardView.cardTypes); this.cardTypes = new ArrayList<>(cardView.cardTypes);
this.subTypes = new SubTypeList(cardView.subTypes); this.subTypes = new SubTypes(cardView.subTypes);
this.superTypes = cardView.superTypes; this.superTypes = cardView.superTypes;
this.color = cardView.color; this.color = cardView.color;
@ -552,9 +552,9 @@ public class CardView extends SimpleCardView {
this.loyalty = ""; this.loyalty = "";
} }
this.cardTypes = object.getCardType(); this.cardTypes = object.getCardType();
this.subTypes = object.getSubtype(null); this.subTypes = object.getSubtype(game);
this.superTypes = object.getSuperType(); this.superTypes = object.getSuperType();
this.color = object.getColor(null); this.color = object.getColor(game);
this.manaCostLeft = object.getManaCost().getSymbols(); this.manaCostLeft = object.getManaCost().getSymbols();
this.manaCostRight = new ArrayList<>(); this.manaCostRight = new ArrayList<>();
this.convertedManaCost = object.getManaCost().convertedManaCost(); this.convertedManaCost = object.getManaCost().convertedManaCost();
@ -596,7 +596,7 @@ public class CardView extends SimpleCardView {
} }
} }
// Frame color // Frame color
this.frameColor = object.getFrameColor(null); this.frameColor = object.getFrameColor(game);
// Frame style // Frame style
this.frameStyle = object.getFrameStyle(); this.frameStyle = object.getFrameStyle();
// Starting loyalty. Must be extracted from an ability // Starting loyalty. Must be extracted from an ability
@ -671,7 +671,7 @@ public class CardView extends SimpleCardView {
this.loyalty = ""; this.loyalty = "";
this.startingLoyalty = ""; this.startingLoyalty = "";
this.cardTypes = new ArrayList<>(); this.cardTypes = new ArrayList<>();
this.subTypes = new SubTypeList(); this.subTypes = new SubTypes();
this.superTypes = EnumSet.noneOf(SuperType.class); this.superTypes = EnumSet.noneOf(SuperType.class);
this.color = new ObjectColor(); this.color = new ObjectColor();
this.frameColor = new ObjectColor(); this.frameColor = new ObjectColor();
@ -707,7 +707,7 @@ public class CardView extends SimpleCardView {
} }
CardView(Token token) { CardView(Token token, Game game) {
super(token.getId(), "", "0", false, "", ""); super(token.getId(), "", "0", false, "", "");
this.isToken = true; this.isToken = true;
this.id = token.getId(); this.id = token.getId();
@ -720,10 +720,10 @@ public class CardView extends SimpleCardView {
this.loyalty = ""; this.loyalty = "";
this.startingLoyalty = ""; this.startingLoyalty = "";
this.cardTypes = token.getCardType(); this.cardTypes = token.getCardType();
this.subTypes = token.getSubtype(null); this.subTypes = token.getSubtype(game);
this.superTypes = token.getSuperType(); this.superTypes = token.getSuperType();
this.color = token.getColor(null); this.color = token.getColor(game);
this.frameColor = token.getFrameColor(null); this.frameColor = token.getFrameColor(game);
this.frameStyle = token.getFrameStyle(); this.frameStyle = token.getFrameStyle();
this.manaCostLeft = token.getManaCost().getSymbols(); this.manaCostLeft = token.getManaCost().getSymbols();
this.manaCostRight = new ArrayList<>(); this.manaCostRight = new ArrayList<>();
@ -816,7 +816,7 @@ public class CardView extends SimpleCardView {
return cardTypes; return cardTypes;
} }
public SubTypeList getSubTypes() { public SubTypes getSubTypes() {
return subTypes; return subTypes;
} }

View file

@ -6,6 +6,7 @@ import mage.cards.Card;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken; import mage.game.permanent.PermanentToken;
import mage.game.permanent.token.Token;
import mage.players.Player; import mage.players.Player;
import java.util.ArrayList; import java.util.ArrayList;
@ -51,7 +52,7 @@ public class PermanentView extends CardView {
} }
this.attachedTo = permanent.getAttachedTo(); this.attachedTo = permanent.getAttachedTo();
if (isToken()) { if (isToken()) {
original = new CardView(((PermanentToken) permanent).getToken()); original = new CardView(((PermanentToken) permanent).getToken(), game);
original.expansionSetCode = permanent.getExpansionSetCode(); original.expansionSetCode = permanent.getExpansionSetCode();
tokenSetCode = original.getTokenSetCode(); tokenSetCode = original.getTokenSetCode();
tokenDescriptor = original.getTokenDescriptor(); tokenDescriptor = original.getTokenDescriptor();

View file

@ -56,7 +56,7 @@ public final class ArtificialScoringSystem {
//score + =cardDefinition.getActivations().size()*50; //score + =cardDefinition.getActivations().size()*50;
//score += cardDefinition.getManaActivations().size()*80; //score += cardDefinition.getManaActivations().size()*80;
} else { } else {
if (permanent.getSubtype(game).contains(SubType.EQUIPMENT)) { if (permanent.hasSubtype(SubType.EQUIPMENT, game)) {
score += 100; score += 100;
} }
} }

View file

@ -16,7 +16,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
/** /**
* *
@ -74,7 +74,7 @@ class AbsorbIdentityEffect extends OneShotEffect {
FilterCreaturePermanent filter = new FilterCreaturePermanent("shapeshifter"); FilterCreaturePermanent filter = new FilterCreaturePermanent("shapeshifter");
filter.add(SubType.SHAPESHIFTER.getPredicate()); filter.add(SubType.SHAPESHIFTER.getPredicate());
for (Permanent copyTo : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { for (Permanent copyTo : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
game.copyPermanent(Duration.EndOfTurn, copyFrom, copyTo.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(Duration.EndOfTurn, copyFrom, copyTo.getId(), source, new EmptyCopyApplier());
} }
} }
return true; return true;

View file

@ -1,7 +1,6 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
@ -18,8 +17,9 @@ import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author Eirkei * @author Eirkei
*/ */
public final class AlphaStatus extends CardImpl { public final class AlphaStatus extends CardImpl {
@ -61,7 +61,7 @@ class AlphaStatusDynamicValue implements DynamicValue {
if (enchanted != null) { if (enchanted != null) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, game)) {
if (!permanent.getId().equals(enchanted.getId())) { if (!permanent.getId().equals(enchanted.getId())) {
if (enchanted.shareCreatureTypes(permanent, game)) { if (enchanted.shareCreatureTypes(game, permanent)) {
xValue += 2; xValue += 2;
} }
} }

View file

@ -87,7 +87,7 @@ class AlpineMoonEffect extends ContinuousEffectImpl {
// 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects
// So the ability removing has to be done before Layer 6 // So the ability removing has to be done before Layer 6
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
land.addAbility(new AnyColorManaAbility(), source.getSourceId(), game); land.addAbility(new AnyColorManaAbility(), source.getSourceId(), game);

View file

@ -28,8 +28,7 @@ public final class AmoeboidChangeling extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// {tap}: Target creature gains all creature types until end of turn. // {tap}: Target creature gains all creature types until end of turn.
Ability ability = new SimpleActivatedAbility( Ability ability = new SimpleActivatedAbility(

View file

@ -1,8 +1,6 @@
package mage.cards.a; package mage.cards.a;
import java.util.Iterator; import mage.MageObject;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -21,6 +19,10 @@ import mage.game.stack.Spell;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.players.Player; import mage.players.Player;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
@ -31,11 +33,12 @@ public final class ArcaneAdaptation extends CardImpl {
// As Arcane Adaptation enters the battlefield, choose a creature type. // As Arcane Adaptation enters the battlefield, choose a creature type.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Neutral))); this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.Neutral)));
// Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield. // Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConspyEffect())); this.addAbility(new SimpleStaticAbility(new ArcaneAdaptationEffect()));
} }
public ArcaneAdaptation(final ArcaneAdaptation card) { private ArcaneAdaptation(final ArcaneAdaptation card) {
super(card); super(card);
} }
@ -45,27 +48,30 @@ public final class ArcaneAdaptation extends CardImpl {
} }
} }
class ConspyEffect extends ContinuousEffectImpl { class ArcaneAdaptationEffect extends ContinuousEffectImpl {
public ConspyEffect() { ArcaneAdaptationEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
staticText = "Creatures you control are the chosen type in addition to their other types. The same is true for creature spells you control and creature cards you own that aren't on the battlefield"; staticText = "Creatures you control are the chosen type in addition to their other types. " +
"The same is true for creature spells you control and creature cards you own that aren't on the battlefield";
} }
public ConspyEffect(final ConspyEffect effect) { private ArcaneAdaptationEffect(final ArcaneAdaptationEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public ConspyEffect copy() { public ArcaneAdaptationEffect copy() {
return new ConspyEffect(this); return new ArcaneAdaptationEffect(this);
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game); SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
if (controller != null && subType != null) { if (controller == null || subType == null) {
return false;
}
// Creature cards you own that aren't on the battlefield // Creature cards you own that aren't on the battlefield
// in graveyard // in graveyard
for (UUID cardId : controller.getGraveyard()) { for (UUID cardId : controller.getGraveyard()) {
@ -123,18 +129,13 @@ class ConspyEffect extends ContinuousEffectImpl {
} }
} }
return true; return true;
} }
return false; private void setCreatureSubtype(MageObject object, SubType subtype, Game game) {
if (object == null) {
return;
} }
game.getState().getCreateMageObjectAttribute(object, game).getSubtype().add(subtype);
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
} }
} }

View file

@ -13,7 +13,7 @@ import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
import java.util.UUID; import java.util.UUID;
@ -46,24 +46,18 @@ public final class ArtisanOfForms extends CardImpl {
static Ability createAbility() { static Ability createAbility() {
Ability ability = new HeroicAbility(new CopyPermanentEffect( Ability ability = new HeroicAbility(new CopyPermanentEffect(
StaticFilters.FILTER_PERMANENT_CREATURE, StaticFilters.FILTER_PERMANENT_CREATURE,
new ArtisanOfFormsApplyToPermanent(), true new ArtisanOfFormsCopyApplier(), true
).setText("have {this} become a copy of target creature, except it has this ability"), true); ).setText("have {this} become a copy of target creature, except it has this ability"), true);
ability.addTarget(new TargetCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent());
return ability; return ability;
} }
} }
class ArtisanOfFormsApplyToPermanent extends ApplyToPermanent { class ArtisanOfFormsCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
mageObject.getAbilities().add(ArtisanOfForms.createAbility()); blueprint.getAbilities().add(ArtisanOfForms.createAbility());
return true;
}
@Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
permanent.addAbility(ArtisanOfForms.createAbility(), source.getSourceId(), game);
return true; return true;
} }
} }

View file

@ -89,13 +89,11 @@ class AshayaSoulOfTheWildEffect extends ContinuousEffectImpl {
if (!permanent.isLand()) { if (!permanent.isLand()) {
permanent.addCardType(CardType.LAND); permanent.addCardType(CardType.LAND);
} }
if (!permanent.hasSubtype(SubType.FOREST, game)) {
permanent.addSubType(game, SubType.FOREST); permanent.addSubType(game, SubType.FOREST);
if (!permanent.getAbilities(game).containsClass(GreenManaAbility.class)) { if (!permanent.getAbilities(game).containsClass(GreenManaAbility.class)) {
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game); permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
} }
} }
}
return true; return true;
} }
} }

View file

@ -19,8 +19,8 @@ import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.SubTypeList;
import java.util.Arrays;
import java.util.UUID; import java.util.UUID;
/** /**
@ -44,10 +44,7 @@ public final class Aurification extends CardImpl {
this.addAbility(new AddGoldCountersAbility()); this.addAbility(new AddGoldCountersAbility());
// Each creature with a gold counter on it is a Wall in addition to its other creature types and has defender. // Each creature with a gold counter on it is a Wall in addition to its other creature types and has defender.
SubTypeList subtypes = new SubTypeList(); BecomesSubtypeAllEffect becomesSubtypeAllEffect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, Arrays.asList(SubType.WALL), filter, false);
subtypes.add(SubType.WALL);
BecomesSubtypeAllEffect becomesSubtypeAllEffect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, subtypes, filter, false);
becomesSubtypeAllEffect.setText(""); becomesSubtypeAllEffect.setText("");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, becomesSubtypeAllEffect)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, becomesSubtypeAllEffect));

View file

@ -22,8 +22,7 @@ public final class AvianChangeling extends CardImpl {
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
} }

View file

@ -60,7 +60,7 @@ class BakisCurseEffect extends OneShotEffect {
List<UUID> attachments = creature.getAttachments(); List<UUID> attachments = creature.getAttachments();
for (UUID attachmentId : attachments) { for (UUID attachmentId : attachments) {
Permanent attached = game.getPermanent(attachmentId); Permanent attached = game.getPermanent(attachmentId);
if (attached != null && attached.getSubtype(game).contains(SubType.AURA)) { if (attached != null && attached.hasSubtype(SubType.AURA, game)) {
count++; count++;
} }
} }

View file

@ -1,7 +1,7 @@
package mage.cards.b; package mage.cards.b;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.EquippedHasSubtypeCondition; import mage.abilities.condition.common.EquippedHasSubtypeCondition;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
@ -11,8 +11,10 @@ import mage.abilities.keyword.EquipAbility;
import mage.abilities.keyword.VigilanceAbility; import mage.abilities.keyword.VigilanceAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.AttachmentType;
import mage.util.SubTypeList; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import java.util.UUID; import java.util.UUID;
@ -22,27 +24,27 @@ import java.util.UUID;
public final class BladedBracers extends CardImpl { public final class BladedBracers extends CardImpl {
private static final String ruleText = "As long as equipped creature is a Human or an Angel, it has vigilance"; private static final String ruleText = "As long as equipped creature is a Human or an Angel, it has vigilance";
private static final Condition condition = new EquippedHasSubtypeCondition(SubType.HUMAN, SubType.ANGEL);
public BladedBracers(UUID ownerId, CardSetInfo setInfo) { public BladedBracers(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{1}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
this.subtype.add(SubType.EQUIPMENT); this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +1/+1. // Equipped creature gets +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1))); this.addAbility(new SimpleStaticAbility(new BoostEquippedEffect(1, 1)));
SubTypeList subTypes = new SubTypeList();
subTypes.add(SubType.HUMAN);
subTypes.add(SubType.ANGEL);
// As long as equipped creature is a Human or an Angel, it has vigilance. // As long as equipped creature is a Human or an Angel, it has vigilance.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new ConditionalContinuousEffect( new GainAbilityAttachedEffect(
new GainAbilityAttachedEffect(VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT), VigilanceAbility.getInstance(), AttachmentType.EQUIPMENT
new EquippedHasSubtypeCondition(subTypes), ruleText))); ), condition, ruleText
)));
// Equip {2} // Equip {2}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2))); this.addAbility(new EquipAbility(Outcome.BoostCreature, new GenericManaCost(2)));
} }
public BladedBracers(final BladedBracers card) { private BladedBracers(final BladedBracers card) {
super(card); super(card);
} }

View file

@ -22,8 +22,7 @@ public final class BladesOfVelisVel extends CardImpl {
this.subtype.add(SubType.SHAPESHIFTER); this.subtype.add(SubType.SHAPESHIFTER);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Up to two target creatures each get +2/+0 and gain all creature types until end of turn. // Up to two target creatures each get +2/+0 and gain all creature types until end of turn.
this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn) this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn)

View file

@ -1,6 +1,5 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
@ -13,8 +12,9 @@ import mage.filter.predicate.Predicates;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class BloodMoon extends CardImpl { public final class BloodMoon extends CardImpl {
@ -71,7 +71,7 @@ public final class BloodMoon extends CardImpl {
// 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects
// So the ability removing has to be done before Layer 6 // So the ability removing has to be done before Layer 6
// Lands have their mana ability intrinsically, so that is added in layer 4 // Lands have their mana ability intrinsically, so that is added in layer 4
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, SubType.MOUNTAIN); land.addSubType(game, SubType.MOUNTAIN);
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game); land.addAbility(new RedManaAbility(), source.getSourceId(), game);

View file

@ -40,8 +40,7 @@ public final class BloodlinePretender extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// As Bloodline Pretender enters the battlefield, choose a creature type. // As Bloodline Pretender enters the battlefield, choose a creature type.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature))); this.addAbility(new AsEntersBattlefieldAbility(new ChooseCreatureTypeEffect(Outcome.BoostCreature)));

View file

@ -19,7 +19,7 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.token.BrudicladTelchorMyrToken; import mage.game.permanent.token.BrudicladTelchorMyrToken;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
import java.util.UUID; import java.util.UUID;
@ -99,7 +99,7 @@ class BrudicladTelchorEngineerEffect extends OneShotEffect {
if (toCopyFromPermanent != null) { if (toCopyFromPermanent != null) {
for (Permanent toCopyToPermanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { for (Permanent toCopyToPermanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!toCopyToPermanent.equals(toCopyFromPermanent)) { if (!toCopyToPermanent.equals(toCopyFromPermanent)) {
game.copyPermanent(toCopyFromPermanent, toCopyToPermanent.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(toCopyFromPermanent, toCopyToPermanent.getId(), source, new EmptyCopyApplier());
} }
} }
return true; return true;

View file

@ -30,8 +30,7 @@ public final class CairnWanderer extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// As long as a creature card with flying is in a graveyard, Cairn Wanderer has flying. The same is true for fear, first strike, double strike, deathtouch, haste, landwalk, lifelink, protection, reach, trample, shroud, and vigilance. // As long as a creature card with flying is in a graveyard, Cairn Wanderer has flying. The same is true for fear, first strike, double strike, deathtouch, haste, landwalk, lifelink, protection, reach, trample, shroud, and vigilance.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CairnWandererEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CairnWandererEffect()));

View file

@ -11,7 +11,7 @@ import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicate; import mage.filter.predicate.permanent.SharesCreatureTypePredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
@ -88,7 +88,7 @@ class CallToTheKindredEffect extends OneShotEffect {
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5)); Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
FilterCreatureCard filter = new FilterCreatureCard(); FilterCreatureCard filter = new FilterCreatureCard();
filter.add(new CallToTheKindredPredicate(creature)); filter.add(new SharesCreatureTypePredicate(creature));
if (cards.count(filter, game) > 0) { if (cards.count(filter, game) > 0) {
TargetCard target = new TargetCardInLibrary(0, 1, filter); TargetCard target = new TargetCardInLibrary(0, 1, filter);
@ -103,17 +103,3 @@ class CallToTheKindredEffect extends OneShotEffect {
return true; return true;
} }
} }
class CallToTheKindredPredicate implements Predicate<Card> {
private final Permanent permanent;
CallToTheKindredPredicate(Permanent permanent) {
this.permanent = permanent;
}
@Override
public boolean apply(Card input, Game game) {
return permanent != null && input != null && permanent.shareCreatureTypes(input, game);
}
}

View file

@ -88,7 +88,7 @@ class CelestialDawnToPlainsEffect extends ContinuousEffectImpl {
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
break; break;
case TypeChangingEffects_4: case TypeChangingEffects_4:
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game,SubTypeSet.NonBasicLandType);
land.addSubType(game, SubType.PLAINS); land.addSubType(game, SubType.PLAINS);
break; break;
} }

View file

@ -19,7 +19,7 @@ import mage.filter.common.FilterCreaturePermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
/** /**
* *
@ -71,7 +71,7 @@ class CemeteryPucaEffect extends OneShotEffect {
if (copyToCreature != null) { if (copyToCreature != null) {
Permanent copyFromCreature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source); Permanent copyFromCreature = getTargetPointer().getFirstTargetPermanentOrLKI(game, source);
if (copyFromCreature != null) { if (copyFromCreature != null) {
game.copyPermanent(Duration.WhileOnBattlefield, copyFromCreature, copyToCreature.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(Duration.WhileOnBattlefield, copyFromCreature, copyToCreature.getId(), source, new EmptyCopyApplier());
ContinuousEffect effect = new GainAbilityTargetEffect(new DiesCreatureTriggeredAbility(new DoIfCostPaid(new CemeteryPucaEffect(), new ManaCostsImpl("{1}")), false, new FilterCreaturePermanent("a creature"), true), Duration.WhileOnBattlefield); ContinuousEffect effect = new GainAbilityTargetEffect(new DiesCreatureTriggeredAbility(new DoIfCostPaid(new CemeteryPucaEffect(), new ManaCostsImpl("{1}")), false, new FilterCreaturePermanent("a creature"), true), Duration.WhileOnBattlefield);
effect.setTargetPointer(new FixedTarget(copyToCreature.getId())); effect.setTargetPointer(new FixedTarget(copyToCreature.getId()));
game.addEffect(effect, source); game.addEffect(effect, source);

View file

@ -31,8 +31,7 @@ public final class ChameleonColossus extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// Changeling (This card is every creature type at all times.) // Changeling (This card is every creature type at all times.)
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Protection from black // Protection from black
this.addAbility(ProtectionAbility.from(ObjectColor.BLACK)); this.addAbility(ProtectionAbility.from(ObjectColor.BLACK));

View file

@ -24,8 +24,7 @@ public final class ChangelingBerserker extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Haste // Haste
this.addAbility(HasteAbility.getInstance()); this.addAbility(HasteAbility.getInstance());

View file

@ -24,8 +24,7 @@ public final class ChangelingHero extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Champion a creature // Champion a creature
this.addAbility(new ChampionAbility(this, true)); this.addAbility(new ChampionAbility(this, true));

View file

@ -24,8 +24,7 @@ public final class ChangelingOutcast extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Changeling Outcast can't block and can't be blocked. // Changeling Outcast can't block and can't be blocked.
this.addAbility(new CantBlockAbility()); this.addAbility(new CantBlockAbility());

View file

@ -22,8 +22,7 @@ public final class ChangelingSentinel extends CardImpl {
this.power = new MageInt(3); this.power = new MageInt(3);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
this.addAbility(VigilanceAbility.getInstance()); this.addAbility(VigilanceAbility.getInstance());
} }

View file

@ -23,8 +23,7 @@ public final class ChangelingTitan extends CardImpl {
this.toughness = new MageInt(7); this.toughness = new MageInt(7);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Champion a creature // Champion a creature
this.addAbility(new ChampionAbility(this, true)); this.addAbility(new ChampionAbility(this, true));

View file

@ -68,7 +68,7 @@ class CoatOfArmsEffect extends ContinuousEffectImpl {
private int getAmount(List<Permanent> permanents, Permanent target, Game game) { private int getAmount(List<Permanent> permanents, Permanent target, Game game) {
int amount = 0; int amount = 0;
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
if (!permanent.getId().equals(target.getId()) && permanent.shareCreatureTypes(target, game)) { if (!permanent.getId().equals(target.getId()) && permanent.shareCreatureTypes(game, target)) {
amount++; amount++;
} }
} }

View file

@ -1,8 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility; import mage.abilities.common.AsEntersBattlefieldAbility;
@ -20,7 +17,11 @@ import mage.game.permanent.Permanent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.players.Player; import mage.players.Player;
import mage.util.SubTypeList; import mage.util.SubTypes;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
/** /**
* @author bunchOfDevs * @author bunchOfDevs
@ -50,7 +51,7 @@ public final class Conspiracy extends CardImpl {
static class ConspiracyEffect extends ContinuousEffectImpl { static class ConspiracyEffect extends ContinuousEffectImpl {
public ConspiracyEffect() { private ConspiracyEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "Creatures you control are the chosen type. The same is " staticText = "Creatures you control are the chosen type. The same is "
+ "true for creature spells you control and creature cards " + "true for creature spells you control and creature cards "
@ -59,7 +60,7 @@ public final class Conspiracy extends CardImpl {
this.dependendToTypes.add(DependencyType.BecomeCreature); // Opalescence and Starfield of Nyx this.dependendToTypes.add(DependencyType.BecomeCreature); // Opalescence and Starfield of Nyx
} }
public ConspiracyEffect(final ConspiracyEffect effect) { private ConspiracyEffect(final ConspiracyEffect effect) {
super(effect); super(effect);
} }
@ -69,12 +70,12 @@ public final class Conspiracy extends CardImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game); SubType subType = ChooseCreatureTypeEffect.getChosenCreatureType(source.getSourceId(), game);
switch (layer) { if (controller == null || subType == null) {
case TypeChangingEffects_4: return true;
if (controller != null && subType != null) { }
// Creature cards you own that aren't on the battlefield // Creature cards you own that aren't on the battlefield
// in graveyard // in graveyard
for (UUID cardId : controller.getGraveyard()) { for (UUID cardId : controller.getGraveyard()) {
@ -112,7 +113,7 @@ public final class Conspiracy extends CardImpl {
} }
} }
// creature spells you control // creature spells you control
for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext();) { for (Iterator<StackObject> iterator = game.getStack().iterator(); iterator.hasNext(); ) {
StackObject stackObject = iterator.next(); StackObject stackObject = iterator.next();
if (stackObject instanceof Spell if (stackObject instanceof Spell
&& stackObject.isControlledBy(controller.getId()) && stackObject.isControlledBy(controller.getId())
@ -125,38 +126,21 @@ public final class Conspiracy extends CardImpl {
List<Permanent> permanents = game.getState().getBattlefield().getAllActivePermanents(controller.getId()); List<Permanent> permanents = game.getState().getBattlefield().getAllActivePermanents(controller.getId());
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
if (permanent.isCreature()) { if (permanent.isCreature()) {
setCreatureSubtype(permanent, subType, game); permanent.removeAllCreatureTypes(game);
} permanent.addSubType(game, subType);
} }
} }
return true; return true;
} }
return false;
}
private void setCreatureSubtype(MageObject object, SubType subtype, Game game) { private void setCreatureSubtype(MageObject object, SubType subtype, Game game) {
if (object != null) { if (object == null) {
setChosenSubtype(game.getState() return;
.getCreateMageObjectAttribute(object, game).getSubtype(), subtype);
} }
} SubTypes subTypes = game.getState().getCreateMageObjectAttribute(object, game).getSubtype();
subTypes.setIsAllCreatureTypes(false);
private void setChosenSubtype(SubTypeList subtype, SubType choice) { subTypes.removeAll(SubType.getCreatureTypes());
if (subtype.size() != 1 subTypes.add(subtype);
|| !subtype.contains(choice)) {
subtype.clear();
subtype.add(choice);
}
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
} }
} }
} }

View file

@ -1,9 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility; import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -19,8 +15,12 @@ import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class Conversion extends CardImpl { public final class Conversion extends CardImpl {
@ -75,8 +75,8 @@ public final class Conversion extends CardImpl {
for (Permanent land : game.getBattlefield().getAllActivePermanents(CardType.LAND)) { for (Permanent land : game.getBattlefield().getAllActivePermanents(CardType.LAND)) {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (land.getSubtype(game).contains(SubType.MOUNTAIN)) { if (land.hasSubtype(SubType.MOUNTAIN, game)) {
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, SubType.PLAINS); land.addSubType(game, SubType.PLAINS);
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);

View file

@ -101,7 +101,7 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl {
if (land == null) { if (land == null) {
return false; return false;
} }
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, choice); land.addSubType(game, choice);
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
switch (choice) { switch (choice) {

View file

@ -9,7 +9,7 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.filter.common.FilterArtifactPermanent; import mage.filter.common.FilterArtifactPermanent;
import mage.util.functions.CardTypeApplier; import mage.util.functions.CardTypeCopyApplier;
/** /**
* *
@ -22,7 +22,7 @@ public final class CopyArtifact extends CardImpl {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}"); super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{U}");
// You may have Copy Artifact enter the battlefield as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types. // You may have Copy Artifact enter the battlefield as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types.
Effect effect = new CopyPermanentEffect(new FilterArtifactPermanent(), new CardTypeApplier(CardType.ENCHANTMENT)); Effect effect = new CopyPermanentEffect(new FilterArtifactPermanent(), new CardTypeCopyApplier(CardType.ENCHANTMENT));
effect.setText("as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types"); effect.setText("as a copy of any artifact on the battlefield, except it's an enchantment in addition to its other types");
this.addAbility(new EntersBattlefieldAbility(effect, true)); this.addAbility(new EntersBattlefieldAbility(effect, true));
} }

View file

@ -28,8 +28,7 @@ public final class CribSwap extends CardImpl {
this.subtype.add(SubType.SHAPESHIFTER); this.subtype.add(SubType.SHAPESHIFTER);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Exile target creature. Its controller creates a 1/1 colorless Shapeshifter creature token with changeling. // Exile target creature. Its controller creates a 1/1 colorless Shapeshifter creature token with changeling.
this.getSpellAbility().addEffect(new ExileTargetEffect()); this.getSpellAbility().addEffect(new ExileTargetEffect());
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());

View file

@ -1,8 +1,6 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -17,24 +15,28 @@ import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
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.FirstStrikeAbility; import mage.abilities.keyword.FirstStrikeAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterOtherCreatureSharingCreatureSubtype; import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.MageObjectReferencePredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author t-schroeder * @author t-schroeder
*/ */
public final class CrownOfFury extends CardImpl { public final class CrownOfFury extends CardImpl {
public CrownOfFury(UUID ownerId, CardSetInfo setInfo) { public CrownOfFury(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{1}{R}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{R}");
this.subtype.add(SubType.AURA); this.subtype.add(SubType.AURA);
TargetPermanent auraTarget = new TargetCreaturePermanent(); TargetPermanent auraTarget = new TargetCreaturePermanent();
@ -69,6 +71,19 @@ public final class CrownOfFury extends CardImpl {
class CrownOfFuryEffect extends OneShotEffect { class CrownOfFuryEffect extends OneShotEffect {
private static class CrownOfFuryPredicate implements Predicate<Card> {
private final Card card;
private CrownOfFuryPredicate(Card card) {
this.card = card;
}
@Override
public boolean apply(Card input, Game game) {
return input.shareCreatureTypes(game, card);
}
}
public CrownOfFuryEffect() { public CrownOfFuryEffect() {
super(Outcome.Benefit); super(Outcome.Benefit);
this.staticText = "Enchanted creature and other creatures that share a creature type with it get +1/+0 and gain first strike until end of turn."; this.staticText = "Enchanted creature and other creatures that share a creature type with it get +1/+0 and gain first strike until end of turn.";
@ -94,7 +109,9 @@ class CrownOfFuryEffect extends OneShotEffect {
// ... and other creatures that share a creature type with it ... // ... and other creatures that share a creature type with it ...
Permanent enchantedCreature = game.getPermanent(source.getSourcePermanentOrLKI(game).getAttachedTo()); Permanent enchantedCreature = game.getPermanent(source.getSourcePermanentOrLKI(game).getAttachedTo());
FilterCreaturePermanent filter = new FilterOtherCreatureSharingCreatureSubtype(enchantedCreature, game); FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(new CrownOfFuryPredicate(enchantedCreature));
filter.add(Predicates.not(new MageObjectReferencePredicate(new MageObjectReference(enchantedCreature, game))));
game.addEffect(new BoostAllEffect(1, 0, Duration.EndOfTurn, filter, false), source); game.addEffect(new BoostAllEffect(1, 0, Duration.EndOfTurn, filter, false), source);
game.addEffect(new GainAbilityAllEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, filter), source); game.addEffect(new GainAbilityAllEffect(FirstStrikeAbility.getInstance(), Duration.EndOfTurn, filter), source);

View file

@ -150,7 +150,7 @@ class CrypticGatewayPredicate implements Predicate<Card> {
@Override @Override
public boolean apply(Card input, Game game) { public boolean apply(Card input, Game game) {
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
if (!permanent.shareCreatureTypes(input, game)) { if (!permanent.shareCreatureTypes(game, input)) {
return false; return false;
} }
} }

View file

@ -17,7 +17,7 @@ import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
import java.util.UUID; import java.util.UUID;
@ -76,23 +76,14 @@ class CryptoplasmEffect extends OneShotEffect {
public boolean apply(Game game, final Ability source) { public boolean apply(Game game, final Ability source) {
Permanent creatureToCopy = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent creatureToCopy = game.getPermanent(getTargetPointer().getFirst(game, source));
if (creatureToCopy != null) { if (creatureToCopy != null) {
ApplyToPermanent applier = new ApplyToPermanent() { CopyApplier applier = new CopyApplier() {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
Ability upkeepAbility = new BeginningOfUpkeepTriggeredAbility(new CryptoplasmEffect(), TargetController.YOU, true); Ability upkeepAbility = new BeginningOfUpkeepTriggeredAbility(new CryptoplasmEffect(), TargetController.YOU, true);
upkeepAbility.addTarget(new TargetCreaturePermanent()); upkeepAbility.addTarget(new TargetCreaturePermanent());
permanent.addAbility(upkeepAbility, source.getSourceId(), game); blueprint.getAbilities().add(upkeepAbility);
return true; return true;
} }
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
Ability upkeepAbility = new BeginningOfUpkeepTriggeredAbility(new CryptoplasmEffect(), TargetController.YOU, true);
upkeepAbility.addTarget(new TargetCreaturePermanent());
mageObject.getAbilities().add(upkeepAbility);
return true;
}
}; };
game.copyPermanent(creatureToCopy, source.getSourceId(), source, applier); game.copyPermanent(creatureToCopy, source.getSourceId(), source, applier);
} }

View file

@ -12,9 +12,8 @@ import mage.filter.FilterPermanent;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.AnotherPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
import java.util.UUID; import java.util.UUID;
@ -49,7 +48,7 @@ public final class CrystallineResonance extends CardImpl {
Ability ability = new CycleControllerTriggeredAbility( Ability ability = new CycleControllerTriggeredAbility(
new CopyPermanentEffect( new CopyPermanentEffect(
StaticFilters.FILTER_PERMANENT_CREATURE, StaticFilters.FILTER_PERMANENT_CREATURE,
new CrystallineResonanceApplier(), true new CrystallineResonanceCopyApplier(), true
).setDuration(Duration.UntilYourNextTurn).setText( ).setDuration(Duration.UntilYourNextTurn).setText(
"have {this} become a copy of another target permanent until your next turn, " + "have {this} become a copy of another target permanent until your next turn, " +
"except it has this ability" "except it has this ability"
@ -60,17 +59,11 @@ public final class CrystallineResonance extends CardImpl {
} }
} }
class CrystallineResonanceApplier extends ApplyToPermanent { class CrystallineResonanceCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
permanent.getAbilities().add(CrystallineResonance.createAbility()); blueprint.getAbilities().add(CrystallineResonance.createAbility());
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
mageObject.getAbilities().add(CrystallineResonance.createAbility());
return true; return true;
} }
} }

View file

@ -16,7 +16,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.Target; import mage.target.Target;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
/** /**
* *
@ -78,7 +78,7 @@ class CytoshapeEffect extends OneShotEffect {
if (copyFrom != null) { if (copyFrom != null) {
Permanent copyTo = game.getPermanentOrLKIBattlefield(ability.getTargets().get(1).getFirstTarget()); Permanent copyTo = game.getPermanentOrLKIBattlefield(ability.getTargets().get(1).getFirstTarget());
if (copyTo != null) { if (copyTo != null) {
game.copyPermanent(Duration.EndOfTurn, copyFrom, copyTo.getId(), ability, new EmptyApplyToPermanent()); game.copyPermanent(Duration.EndOfTurn, copyFrom, copyTo.getId(), ability, new EmptyCopyApplier());
} }
} }
return true; return true;

View file

@ -1,7 +1,6 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -17,10 +16,11 @@ import mage.constants.SubType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class DacksDuplicate extends CardImpl { public final class DacksDuplicate extends CardImpl {
@ -33,7 +33,7 @@ public final class DacksDuplicate extends CardImpl {
this.toughness = new MageInt(0); this.toughness = new MageInt(0);
// You may have Dack's Duplicate enter the battlefield as a copy of any creature on the battlefield except it has haste and dethrone. // You may have Dack's Duplicate enter the battlefield as a copy of any creature on the battlefield except it has haste and dethrone.
Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new DacksDuplicateApplyToPermanent()); Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new DacksDuplicateCopyApplier());
effect.setText("as a copy of any creature on the battlefield except it has haste and dethrone"); effect.setText("as a copy of any creature on the battlefield except it has haste and dethrone");
this.addAbility(new EntersBattlefieldAbility(effect, true)); this.addAbility(new EntersBattlefieldAbility(effect, true));
} }
@ -48,24 +48,15 @@ public final class DacksDuplicate extends CardImpl {
} }
} }
class DacksDuplicateApplyToPermanent extends ApplyToPermanent { class DacksDuplicateCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
/** /**
* 29/05/2014 The ability of Dack's Duplicate doesn't target the * 29/05/2014 The ability of Dack's Duplicate doesn't target the
* creature. * creature.
*/ */
permanent.addAbility(new DethroneAbility(), source.getSourceId(), game); blueprint.getAbilities().add(new DethroneAbility());
permanent.addAbility(HasteAbility.getInstance(), source.getSourceId(), game); blueprint.getAbilities().add(HasteAbility.getInstance());
return true; return true;
} }
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
mageObject.getAbilities().add(new DethroneAbility());
mageObject.getAbilities().add(HasteAbility.getInstance());
return true;
}
} }

View file

@ -79,7 +79,7 @@ class DescendantsPathEffect extends OneShotEffect {
FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent(); FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent();
boolean found = false; boolean found = false;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
if (card.shareCreatureTypes(permanent, game)) { if (card.shareCreatureTypes(game, permanent)) {
found = true; found = true;
break; break;
} }

View file

@ -21,7 +21,7 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentCard;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInGraveyard;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
/** /**
* *
@ -83,7 +83,7 @@ class DimirDoppelgangerEffect extends OneShotEffect {
controller.moveCards(cardsToExile, Zone.EXILED, source, game); controller.moveCards(cardsToExile, Zone.EXILED, source, game);
newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game); newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game);
newBluePrint.assignNewId(); newBluePrint.assignNewId();
ApplyToPermanent applier = new DimirDoppelgangerApplier(); CopyApplier applier = new DimirDoppelgangerCopyApplier();
applier.apply(game, newBluePrint, source, dimirDoppelganger.getId()); applier.apply(game, newBluePrint, source, dimirDoppelganger.getId());
CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, dimirDoppelganger.getId()); CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, dimirDoppelganger.getId());
copyEffect.newId(); copyEffect.newId();
@ -98,21 +98,13 @@ class DimirDoppelgangerEffect extends OneShotEffect {
} }
} }
class DimirDoppelgangerApplier extends ApplyToPermanent { class DimirDoppelgangerCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DimirDoppelgangerEffect(), new ManaCostsImpl("{1}{U}{B}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DimirDoppelgangerEffect(), new ManaCostsImpl("{1}{U}{B}"));
ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard"))); ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")));
permanent.getAbilities().add(ability); blueprint.getAbilities().add(ability);
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DimirDoppelgangerEffect(), new ManaCostsImpl("{1}{U}{B}"));
ability.addTarget(new TargetCardInGraveyard(new FilterCreatureCard("creature card in a graveyard")));
mageObject.getAbilities().add(ability);
return true; return true;
} }
} }

View file

@ -4,6 +4,7 @@ import mage.MageInt;
import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.IsAllCreatureTypesSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -33,10 +34,7 @@ public final class DrJuliusJumblemorph extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// Dr. Julius Jumblemorph is every creature type (even if this card isn't on the battlefield). // Dr. Julius Jumblemorph is every creature type (even if this card isn't on the battlefield).
this.setIsAllCreatureTypes(true); this.addAbility(new SimpleStaticAbility(Zone.ALL, new IsAllCreatureTypesSourceEffect()));
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect(
"{this} is every creature type <i>(even if this card isn't on the battlefield)</i>."
)));
// Whenever a host enters the battlefield under your control, you may search your library and/or graveyard for a card with augment and combine it with that host. If you search your library this way, shuffle it. // Whenever a host enters the battlefield under your control, you may search your library and/or graveyard for a card with augment and combine it with that host. If you search your library this way, shuffle it.
// TODO: Host currently isn't implemented, so this ability currently would never trigger // TODO: Host currently isn't implemented, so this ability currently would never trigger
@ -46,7 +44,7 @@ public final class DrJuliusJumblemorph extends CardImpl {
)); ));
} }
public DrJuliusJumblemorph(final DrJuliusJumblemorph card) { private DrJuliusJumblemorph(final DrJuliusJumblemorph card) {
super(card); super(card);
} }

View file

@ -113,35 +113,33 @@ class DuplicantContinuousEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) { if (permanent == null) {
if (!permanent.getImprinted().isEmpty()) { return false;
}
if (permanent.getImprinted().isEmpty()) {
return false;
}
List<UUID> imprinted = permanent.getImprinted(); List<UUID> imprinted = permanent.getImprinted();
if (imprinted == null || imprinted.isEmpty()) { if (imprinted == null || imprinted.isEmpty()) {
return false; return false;
} }
Card card = game.getCard(imprinted.get(imprinted.size() - 1)); Card card = game.getCard(imprinted.get(imprinted.size() - 1));
if (card != null && card.isCreature()) { if (card == null || !card.isCreature()) {
return false;
}
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { permanent.copySubTypesFrom(game, card, SubTypeSet.CreatureType);
permanent.getSubtype(game).addAll(card.getSubtype(game));
}
break; break;
case PTChangingEffects_7: case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) { if (sublayer == SubLayer.SetPT_7b) {
permanent.getPower().setValue(card.getPower().getValue()); permanent.getPower().setValue(card.getPower().getValue());
permanent.getToughness().setValue(card.getToughness().getValue()); permanent.getToughness().setValue(card.getToughness().getValue());
} }
} }
return true; return true;
}
}
} }
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
@ -152,5 +150,4 @@ class DuplicantContinuousEffect extends ContinuousEffectImpl {
public boolean hasLayer(Layer layer) { public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4; return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4;
} }
} }

View file

@ -1,10 +1,7 @@
package mage.cards.e; package mage.cards.e;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect; import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect;
import mage.abilities.effects.common.continuous.BoostControlledEffect; import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.abilities.keyword.SquirrellinkAbility; import mage.abilities.keyword.SquirrellinkAbility;
@ -14,20 +11,19 @@ import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.TargetController; import mage.constants.TargetController;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.permanent.TokenPredicate; import mage.filter.predicate.permanent.TokenPredicate;
import mage.util.SubTypeList;
import java.util.Arrays;
import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class EarlOfSquirrel extends CardImpl { public final class EarlOfSquirrel extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creature tokens you control"); private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creature tokens you control");
private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Other squirrels you control"); private static final FilterCreaturePermanent filter2 = new FilterCreaturePermanent("Squirrels you control");
static { static {
filter.add(TokenPredicate.instance); filter.add(TokenPredicate.instance);
@ -48,17 +44,17 @@ public final class EarlOfSquirrel extends CardImpl {
this.addAbility(SquirrellinkAbility.getInstance()); this.addAbility(SquirrellinkAbility.getInstance());
// Creature tokens you control are Squirrels in addition to their other creature types. // Creature tokens you control are Squirrels in addition to their other creature types.
SubTypeList subTypes = new SubTypeList(); this.addAbility(new SimpleStaticAbility(new BecomesSubtypeAllEffect(
subTypes.add(SubType.SQUIRREL); Duration.WhileOnBattlefield, Arrays.asList(SubType.SQUIRREL), filter, false
Effect effect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, subTypes, filter, false); ).setText("Creature tokens you control are Squirrels in addition to their other creature types")));
effect.setText("Creature tokens you control are Squirrels in addition to their other creature types");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
// Other Squirrels you control get +1/+1. // Other Squirrels you control get +1/+1.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostControlledEffect(1, 1, Duration.WhileOnBattlefield, filter2, true))); this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
1, 1, Duration.WhileOnBattlefield, filter2, true
)));
} }
public EarlOfSquirrel(final EarlOfSquirrel card) { private EarlOfSquirrel(final EarlOfSquirrel card) {
super(card); super(card);
} }

View file

@ -26,8 +26,7 @@ public final class EgoErasure extends CardImpl {
this.subtype.add(SubType.SHAPESHIFTER); this.subtype.add(SubType.SHAPESHIFTER);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
//Creatures target player controls get -2/+0 and lose all creature types until end of turn. //Creatures target player controls get -2/+0 and lose all creature types until end of turn.
this.getSpellAbility().addEffect(new EgoErasureBoostEffect()); this.getSpellAbility().addEffect(new EgoErasureBoostEffect());

View file

@ -135,7 +135,7 @@ class ElsewhereFlaskContinuousEffect extends ContinuousEffectImpl {
it.remove(); it.remove();
continue; continue;
} }
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, choice); land.addSubType(game, choice);
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
switch (choice) { switch (choice) {

View file

@ -1,9 +1,5 @@
package mage.cards.e; package mage.cards.e;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.common.SacrificeTargetCost; import mage.abilities.costs.common.SacrificeTargetCost;
@ -13,18 +9,18 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.SubTypeSet;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.permanent.SharesCreatureTypePredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import mage.util.SubTypeList;
import java.util.UUID;
import static mage.filter.StaticFilters.FILTER_CONTROLLED_CREATURE_SHORT_TEXT;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class EndemicPlague extends CardImpl { public final class EndemicPlague extends CardImpl {
@ -39,7 +35,7 @@ public final class EndemicPlague extends CardImpl {
this.getSpellAbility().addEffect(new EndemicPlagueEffect()); this.getSpellAbility().addEffect(new EndemicPlagueEffect());
} }
public EndemicPlague(final EndemicPlague card) { private EndemicPlague(final EndemicPlague card) {
super(card); super(card);
} }
@ -51,40 +47,34 @@ public final class EndemicPlague extends CardImpl {
class EndemicPlagueEffect extends OneShotEffect { class EndemicPlagueEffect extends OneShotEffect {
public EndemicPlagueEffect() { EndemicPlagueEffect() {
super(Outcome.DestroyPermanent); super(Outcome.DestroyPermanent);
staticText = "destroy all creatures that share a creature type with the sacrificed creature. They can't be regenerated"; staticText = "destroy all creatures that share a creature type with the sacrificed creature. They can't be regenerated";
} }
public EndemicPlagueEffect(final EndemicPlagueEffect effect) { private EndemicPlagueEffect(final EndemicPlagueEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller != null) { if (controller == null) {
SubTypeList subs = null; return false;
}
Permanent permanent = null;
for (Cost cost : source.getCosts()) { for (Cost cost : source.getCosts()) {
if (cost instanceof SacrificeTargetCost && !((SacrificeTargetCost) cost).getPermanents().isEmpty()) { if (cost instanceof SacrificeTargetCost && !((SacrificeTargetCost) cost).getPermanents().isEmpty()) {
subs = ((SacrificeTargetCost) cost).getPermanents().get(0).getSubtype(game); permanent = ((SacrificeTargetCost) cost).getPermanents().get(0);
break; break;
} }
} }
if (subs == null) { if (permanent == null) {
return false; return false;
} }
List<SubType.SubTypePredicate> preds = new ArrayList<>();
for (SubType subType : subs) {
if (subType.getSubTypeSet() == SubTypeSet.CreatureType) {
preds.add(subType.getPredicate());
}
}
FilterCreaturePermanent filter = new FilterCreaturePermanent(); FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(Predicates.or(preds)); filter.add(new SharesCreatureTypePredicate(permanent));
new DestroyAllEffect(filter, true).apply(game, source); return new DestroyAllEffect(filter, true).apply(game, source);
}
return true;
} }
@Override @Override

View file

@ -17,7 +17,7 @@ import mage.filter.FilterPermanent;
import mage.filter.common.FilterControlledEnchantmentPermanent; import mage.filter.common.FilterControlledEnchantmentPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
import java.util.UUID; import java.util.UUID;
@ -33,7 +33,7 @@ public final class EstridsInvocation extends CardImpl {
// You may have Estrid's Invocation enter the battlefield as a copy of any enchantment you control, except it gains "At the beginning of your upkeep, you may exile this enchantment. If you do, return it to the battlefield under its owner's control." // You may have Estrid's Invocation enter the battlefield as a copy of any enchantment you control, except it gains "At the beginning of your upkeep, you may exile this enchantment. If you do, return it to the battlefield under its owner's control."
this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect( this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(
filter, new EstridsInvocationApplier() filter, new EstridsInvocationCopyApplier()
).setText("as a copy of an enchantment you control, except it gains " ).setText("as a copy of an enchantment you control, except it gains "
+ "\"At the beginning of your upkeep, " + "\"At the beginning of your upkeep, "
+ "you may exile this enchantment. " + "you may exile this enchantment. "
@ -52,26 +52,16 @@ public final class EstridsInvocation extends CardImpl {
} }
} }
class EstridsInvocationApplier extends ApplyToPermanent { class EstridsInvocationCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
// At the beginning of your upkeep, you may exile this enchantment. If you do, return it to the battlefield under its owner's control. // At the beginning of your upkeep, you may exile this enchantment. If you do, return it to the battlefield under its owner's control.
permanent.addAbility(new BeginningOfUpkeepTriggeredAbility( blueprint.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(
new EstridsInvocationEffect(), TargetController.YOU, true
), source.getSourceId(), game);
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
// At the beginning of your upkeep, you may exile this enchantment. If you do, return it to the battlefield under its owner's control.
mageObject.getAbilities().add(new BeginningOfUpkeepTriggeredAbility(
new EstridsInvocationEffect(), TargetController.YOU, true new EstridsInvocationEffect(), TargetController.YOU, true
)); ));
return true; return true;
} }
} }
class EstridsInvocationEffect extends OneShotEffect { class EstridsInvocationEffect extends OneShotEffect {

View file

@ -23,7 +23,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
import java.util.UUID; import java.util.UUID;
@ -40,7 +40,7 @@ public final class EvilTwin extends CardImpl {
this.toughness = new MageInt(0); this.toughness = new MageInt(0);
// You may have Evil Twin enter the battlefield as a copy of any creature on the battlefield, except it has "{U}{B}, {T}: Destroy target creature with the same name as this creature." // You may have Evil Twin enter the battlefield as a copy of any creature on the battlefield, except it has "{U}{B}, {T}: Destroy target creature with the same name as this creature."
Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new EvilTwinApplyToPermanent()); Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new EvilTwinCopyApplier());
effect.setText("as a copy of any creature on the battlefield, except it has \"{U}{B}, {T}: Destroy target creature with the same name as this creature.\""); effect.setText("as a copy of any creature on the battlefield, except it has \"{U}{B}, {T}: Destroy target creature with the same name as this creature.\"");
this.addAbility(new EntersBattlefieldAbility(effect, true)); this.addAbility(new EntersBattlefieldAbility(effect, true));
@ -56,7 +56,7 @@ public final class EvilTwin extends CardImpl {
} }
} }
class EvilTwinApplyToPermanent extends ApplyToPermanent { class EvilTwinCopyApplier extends CopyApplier {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with the same name as this creature"); private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("creature with the same name as this creature");
@ -65,20 +65,11 @@ class EvilTwinApplyToPermanent extends ApplyToPermanent {
} }
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{U}{B}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{U}{B}"));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter)); ability.addTarget(new TargetCreaturePermanent(filter));
permanent.addAbility(ability, source.getSourceId(), game); blueprint.getAbilities().add(ability);
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DestroyTargetEffect(), new ManaCostsImpl("{U}{B}"));
ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent(filter));
mageObject.getAbilities().add(ability);
return true; return true;
} }

View file

@ -74,7 +74,7 @@ enum FaceOfDivinityCondition implements Condition {
for (UUID id : permanent.getAttachments()) { for (UUID id : permanent.getAttachments()) {
Permanent otherAura = game.getPermanent(id); Permanent otherAura = game.getPermanent(id);
if (otherAura != null && !otherAura.getId().equals(currentAura.getId()) if (otherAura != null && !otherAura.getId().equals(currentAura.getId())
&& otherAura.getSubtype(game).contains(SubType.AURA)) { && otherAura.hasSubtype(SubType.AURA, game)) {
return true; return true;
} }
} }

View file

@ -49,7 +49,7 @@ class FacelessHavenToken extends TokenImpl {
FacelessHavenToken() { FacelessHavenToken() {
super("", "4/3 creature with vigilance and all creature types"); super("", "4/3 creature with vigilance and all creature types");
cardType.add(CardType.CREATURE); cardType.add(CardType.CREATURE);
setIsAllCreatureTypes(true); subtype.setIsAllCreatureTypes(true);
power = new MageInt(4); power = new MageInt(4);
toughness = new MageInt(3); toughness = new MageInt(3);
addAbility(VigilanceAbility.getInstance()); addAbility(VigilanceAbility.getInstance());

View file

@ -62,13 +62,13 @@ class FacesOfThePastEffect extends OneShotEffect {
if (controller != null) { if (controller != null) {
if (controller.chooseUse(outcome, "Tap all untapped creatures that share a creature type with " + targetPermanent.getLogName() + "? (Otherwise, untaps all tapped)", source, game)) { if (controller.chooseUse(outcome, "Tap all untapped creatures that share a creature type with " + targetPermanent.getLogName() + "? (Otherwise, untaps all tapped)", source, game)) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, game)) {
if (!permanent.isTapped() && targetPermanent.shareCreatureTypes(permanent, game)) { if (!permanent.isTapped() && targetPermanent.shareCreatureTypes(game, permanent)) {
permanent.tap(source, game); permanent.tap(source, game);
} }
} }
} else { } else {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, game)) {
if (permanent.isTapped() && targetPermanent.shareCreatureTypes(permanent, game)) { if (permanent.isTapped() && targetPermanent.shareCreatureTypes(game, permanent)) {
permanent.untap(game); permanent.untap(game);
} }
} }

View file

@ -1,7 +1,6 @@
package mage.cards.f; package mage.cards.f;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -16,7 +15,8 @@ import mage.constants.Zone;
import mage.filter.common.FilterLandPermanent; import mage.filter.common.FilterLandPermanent;
import mage.game.permanent.token.custom.CreatureToken; import mage.game.permanent.token.custom.CreatureToken;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import mage.util.SubTypeList;
import java.util.UUID;
/** /**
* @author anonymous * @author anonymous
@ -30,7 +30,7 @@ public final class FendeepSummoner extends CardImpl {
} }
public FendeepSummoner(UUID ownerId, CardSetInfo setInfo) { public FendeepSummoner(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{4}{B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{4}{B}");
this.subtype.add(SubType.TREEFOLK); this.subtype.add(SubType.TREEFOLK);
this.subtype.add(SubType.SHAMAN); this.subtype.add(SubType.SHAMAN);
@ -39,7 +39,7 @@ public final class FendeepSummoner extends CardImpl {
// {T}: Up to two target Swamps each become 3/5 Treefolk Warrior creatures in addition to their other types until end of turn. // {T}: Up to two target Swamps each become 3/5 Treefolk Warrior creatures in addition to their other types until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureTargetEffect( Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new BecomesCreatureTargetEffect(
new CreatureToken(3, 5, "3/5 Treefolk Warrior", new SubTypeList(SubType.TREEFOLK, SubType.WARRIOR)), new CreatureToken(3, 5, "3/5 Treefolk Warrior", SubType.TREEFOLK, SubType.WARRIOR),
false, false, Duration.EndOfTurn), new TapSourceCost()); false, false, Duration.EndOfTurn), new TapSourceCost());
ability.addTarget(new TargetLandPermanent(0, 2, filter, false)); ability.addTarget(new TargetLandPermanent(0, 2, filter, false));
this.addAbility(ability); this.addAbility(ability);

View file

@ -27,8 +27,7 @@ public final class FireBellyChangeling extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// {R}: Fire-Belly Changeling gets +1/+0 until end of turn. Activate this ability no more than twice each turn. // {R}: Fire-Belly Changeling gets +1/+0 until end of turn. Activate this ability no more than twice each turn.
this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD, this.addAbility(new LimitedTimesPerTurnActivatedAbility(Zone.BATTLEFIELD,

View file

@ -22,8 +22,7 @@ public final class GameTrailChangeling extends CardImpl {
this.power = new MageInt(4); this.power = new MageInt(4);
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
this.addAbility(TrampleAbility.getInstance()); this.addAbility(TrampleAbility.getInstance());
} }

View file

@ -26,8 +26,7 @@ public final class GhostlyChangeling extends CardImpl {
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{1}{B}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new BoostSourceEffect(1, 1, Duration.EndOfTurn), new ManaCostsImpl("{1}{B}")));
} }

View file

@ -23,7 +23,7 @@ import mage.constants.Zone;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
/** /**
* *
@ -38,7 +38,7 @@ public final class Gigantoplasm extends CardImpl {
this.toughness = new MageInt(0); this.toughness = new MageInt(0);
// You may have Gigantoplasm enter the battlefield as a copy of any creature on the battlefield, except it has "{X}: This creature has base power and toughness X/X." // You may have Gigantoplasm enter the battlefield as a copy of any creature on the battlefield, except it has "{X}: This creature has base power and toughness X/X."
Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new GigantoplasmApplyToPermanent()); Effect effect = new CopyPermanentEffect(StaticFilters.FILTER_PERMANENT_CREATURE, new GigantoplasmCopyApplier());
effect.setText("a copy of any creature on the battlefield, except it has \"{X}: This creature has base power and toughness X/X.\""); effect.setText("a copy of any creature on the battlefield, except it has \"{X}: This creature has base power and toughness X/X.\"");
this.addAbility(new EntersBattlefieldAbility(effect, true)); this.addAbility(new EntersBattlefieldAbility(effect, true));
} }
@ -53,25 +53,15 @@ public final class Gigantoplasm extends CardImpl {
} }
} }
class GigantoplasmApplyToPermanent extends ApplyToPermanent { class GigantoplasmCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
DynamicValue variableMana = ManacostVariableValue.instance; DynamicValue variableMana = ManacostVariableValue.instance;
Effect effect = new SetPowerToughnessSourceEffect(variableMana, Duration.WhileOnBattlefield, SubLayer.SetPT_7b); Effect effect = new SetPowerToughnessSourceEffect(variableMana, Duration.WhileOnBattlefield, SubLayer.SetPT_7b);
effect.setText("This creature has base power and toughness X/X"); effect.setText("This creature has base power and toughness X/X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
permanent.getAbilities().add(ability); blueprint.getAbilities().add(ability);
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
DynamicValue variableMana = ManacostVariableValue.instance;
Effect effect = new SetPowerToughnessSourceEffect(variableMana, Duration.WhileOnBattlefield, SubLayer.SetPT_7b);
effect.setText("This creature has base power and toughness X/X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{X}"));
mageObject.getAbilities().add(ability);
return true; return true;
} }

View file

@ -72,8 +72,8 @@ public final class Glaciers extends CardImpl {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
// the land mana ability is intrinsic, so apply at this layer not layer 6 // the land mana ability is intrinsic, so apply at this layer not layer 6
if (land.getSubtype(game).contains(SubType.MOUNTAIN)) { if (land.hasSubtype(SubType.MOUNTAIN, game)) {
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, SubType.PLAINS); land.addSubType(game, SubType.PLAINS);
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);

View file

@ -36,8 +36,7 @@ public final class GladewalkerRitualist extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Whenever another creature named Gladewalker Ritualist enters the battlefield under your control, draw a card. // Whenever another creature named Gladewalker Ritualist enters the battlefield under your control, draw a card.
this.addAbility(new EntersBattlefieldControlledTriggeredAbility( this.addAbility(new EntersBattlefieldControlledTriggeredAbility(

View file

@ -13,8 +13,7 @@ import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.util.functions.CopyApplier;
import mage.util.functions.ApplyToPermanent;
import java.util.UUID; import java.util.UUID;
@ -36,7 +35,7 @@ public final class GlasspoolMimic extends ModalDoubleFacesCard {
// You may have Glasspool Mimic enter the battlefield as a copy of a creature you control, except it's a Shapeshifter Rogue in addition to its other types. // You may have Glasspool Mimic enter the battlefield as a copy of a creature you control, except it's a Shapeshifter Rogue in addition to its other types.
this.getLeftHalfCard().addAbility(new EntersBattlefieldAbility( this.getLeftHalfCard().addAbility(new EntersBattlefieldAbility(
new CopyPermanentEffect(StaticFilters.FILTER_CONTROLLED_CREATURE, new GlasspoolMimicApplier()), new CopyPermanentEffect(StaticFilters.FILTER_CONTROLLED_CREATURE, new GlasspoolMimicCopyApplier()),
true, null, "You may have {this} enter the battlefield as a copy of " + true, null, "You may have {this} enter the battlefield as a copy of " +
"a creature you control, except it's a Shapeshifter Rogue in addition to its other types.", "" "a creature you control, except it's a Shapeshifter Rogue in addition to its other types.", ""
)); ));
@ -62,19 +61,11 @@ public final class GlasspoolMimic extends ModalDoubleFacesCard {
} }
} }
class GlasspoolMimicApplier extends ApplyToPermanent { class GlasspoolMimicCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
permanent.addSubType(game, SubType.SHAPESHIFTER); blueprint.addSubType(SubType.SHAPESHIFTER, SubType.ROGUE);
permanent.addSubType(game, SubType.ROGUE);
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
mageObject.addSubType(game, SubType.SHAPESHIFTER);
mageObject.addSubType(game, SubType.ROGUE);
return true; return true;
} }
} }

View file

@ -76,14 +76,15 @@ class GodPharaohsGiftEffect extends OneShotEffect {
Card cardChosen = game.getCard(target.getFirstTarget()); Card cardChosen = game.getCard(target.getFirstTarget());
if (cardChosen != null if (cardChosen != null
&& cardChosen.moveToExile(exileId, sourceObject.getIdName(), source, game)) { && cardChosen.moveToExile(exileId, sourceObject.getIdName(), source, game)) {
// create token and modify all attributes permanently (without game usage)
EmptyToken token = new EmptyToken(); EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from(cardChosen, game); CardUtil.copyTo(token).from(cardChosen, game);
token.removePTCDA(); token.removePTCDA();
token.getPower().modifyBaseValue(4); token.getPower().modifyBaseValue(4);
token.getToughness().modifyBaseValue(4); token.getToughness().modifyBaseValue(4);
token.getColor(game).setColor(ObjectColor.BLACK); token.getColor().setColor(ObjectColor.BLACK);
token.removeAllCreatureTypes(game); token.removeAllCreatureTypes();
token.addSubType(game, SubType.ZOMBIE); token.addSubType(SubType.ZOMBIE);
if (token.putOntoBattlefield(1, game, source, source.getControllerId())) { if (token.putOntoBattlefield(1, game, source, source.getControllerId())) {
Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken()); Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken());
if (tokenPermanent != null) { if (tokenPermanent != null) {

View file

@ -27,8 +27,7 @@ public final class Graveshifter extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// When Graveshifter enters the battlefield, you may return target creature card from your graveyard to your hand. // When Graveshifter enters the battlefield, you may return target creature card from your graveyard to your hand.
Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true); Ability ability = new EntersBattlefieldTriggeredAbility(new ReturnToHandTargetEffect(), true);

View file

@ -27,8 +27,7 @@ public final class GuardianGladewalker extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// When Guardian Gladewalker enters the battlefield, put a +1/+1 counter on target creature. // When Guardian Gladewalker enters the battlefield, put a +1/+1 counter on target creature.
Ability ability = new EntersBattlefieldTriggeredAbility( Ability ability = new EntersBattlefieldTriggeredAbility(

View file

@ -82,7 +82,7 @@ class HeirloomBladeEffect extends OneShotEffect {
Cards otherCards = new CardsImpl(); Cards otherCards = new CardsImpl();
for (Card card : controller.getLibrary().getCards(game)) { for (Card card : controller.getLibrary().getCards(game)) {
revealed.add(card); revealed.add(card);
if (card != null && card.isCreature() && equipped.shareCreatureTypes(card, game)) { if (card != null && card.isCreature() && equipped.shareCreatureTypes(game, card)) {
controller.moveCardToHandWithInfo(card, source, game, true); controller.moveCardToHandWithInfo(card, source, game, true);
break; break;
} else { } else {

View file

@ -1,6 +1,5 @@
package mage.cards.h; package mage.cards.h;
import java.util.UUID;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect; import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect;
@ -9,7 +8,9 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.util.SubTypeList;
import java.util.Arrays;
import java.util.UUID;
/** /**
* Created by Alexsandr0x. * Created by Alexsandr0x.
@ -26,9 +27,7 @@ public final class Hivestone extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}");
// Creatures you control are Slivers in addition to their other creature types. // Creatures you control are Slivers in addition to their other creature types.
SubTypeList subTypes = new SubTypeList(); Effect effect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, Arrays.asList(SubType.SLIVER), filter, false);
subTypes.add(SubType.SLIVER);
Effect effect = new BecomesSubtypeAllEffect(Duration.WhileOnBattlefield, subTypes, filter, false);
effect.setText("Creatures you control are Slivers in addition to their other creature types"); effect.setText("Creatures you control are Slivers in addition to their other creature types");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect)); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
} }

View file

@ -90,14 +90,15 @@ class HourOfEternityEffect extends OneShotEffect {
controller.moveCardsToExile(cardsToExile, source, game, true, null, ""); controller.moveCardsToExile(cardsToExile, source, game, true, null, "");
for (Card card : cardsToExile) { for (Card card : cardsToExile) {
if (game.getState().getZone(card.getId()) == Zone.EXILED) { if (game.getState().getZone(card.getId()) == Zone.EXILED) {
// create token and modify all attributes permanently (without game usage)
EmptyToken token = new EmptyToken(); EmptyToken token = new EmptyToken();
CardUtil.copyTo(token).from(card, game); CardUtil.copyTo(token).from(card, game);
token.removePTCDA(); token.removePTCDA();
token.getPower().modifyBaseValue(4); token.getPower().modifyBaseValue(4);
token.getToughness().modifyBaseValue(4); token.getToughness().modifyBaseValue(4);
token.getColor(game).setColor(ObjectColor.BLACK); token.getColor().setColor(ObjectColor.BLACK);
token.removeAllCreatureTypes(game); token.removeAllCreatureTypes();
token.addSubType(game, SubType.ZOMBIE); token.addSubType(SubType.ZOMBIE);
token.putOntoBattlefield(1, game, source, source.getControllerId()); token.putOntoBattlefield(1, game, source, source.getControllerId());
} }
} }

View file

@ -43,7 +43,7 @@ class HydroformToken extends TokenImpl {
public HydroformToken() { public HydroformToken() {
super("", "3/3 Elemental creature with flying"); super("", "3/3 Elemental creature with flying");
this.cardType.add(CardType.CREATURE); this.cardType.add(CardType.CREATURE);
this.getSubtype(null).add(SubType.ELEMENTAL); this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(3); this.power = new MageInt(3);
this.toughness = new MageInt(3); this.toughness = new MageInt(3);

View file

@ -19,15 +19,10 @@ import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.choices.ChoiceBasicLandType; import mage.choices.ChoiceBasicLandType;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceImpl;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.DependencyType;
import mage.constants.Duration;
import mage.constants.Layer;
import static mage.constants.Layer.TypeChangingEffects_4; import static mage.constants.Layer.TypeChangingEffects_4;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.constants.Zone;
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,27 +88,27 @@ class IllusionaryTerrainEffect extends ContinuousEffectImpl {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
// the land mana ability is intrinsic, so add it here, not layer 6 // the land mana ability is intrinsic, so add it here, not layer 6
if (land.getSubtype(game).contains(firstChoice)) { if (land.hasSubtype(firstChoice, game)) {
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, secondChoice); land.addSubType(game, secondChoice);
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
if (land.getSubtype(game).contains(SubType.FOREST)) { if (land.hasSubtype(SubType.FOREST, game)) {
this.dependencyTypes.add(DependencyType.BecomeForest); this.dependencyTypes.add(DependencyType.BecomeForest);
land.addAbility(new GreenManaAbility(), source.getSourceId(), game); land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
} }
if (land.getSubtype(game).contains(SubType.PLAINS)) { if (land.hasSubtype(SubType.PLAINS, game)) {
this.dependencyTypes.add(DependencyType.BecomePlains); this.dependencyTypes.add(DependencyType.BecomePlains);
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
} }
if (land.getSubtype(game).contains(SubType.MOUNTAIN)) { if (land.hasSubtype(SubType.MOUNTAIN, game)) {
this.dependencyTypes.add(DependencyType.BecomeMountain); this.dependencyTypes.add(DependencyType.BecomeMountain);
land.addAbility(new RedManaAbility(), source.getSourceId(), game); land.addAbility(new RedManaAbility(), source.getSourceId(), game);
} }
if (land.getSubtype(game).contains(SubType.ISLAND)) { if (land.hasSubtype(SubType.ISLAND, game)) {
this.dependencyTypes.add(DependencyType.BecomeIsland); this.dependencyTypes.add(DependencyType.BecomeIsland);
land.addAbility(new BlueManaAbility(), source.getSourceId(), game); land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
} }
if (land.getSubtype(game).contains(SubType.SWAMP)) { if (land.hasSubtype(SubType.SWAMP, game)) {
this.dependencyTypes.add(DependencyType.BecomeSwamp); this.dependencyTypes.add(DependencyType.BecomeSwamp);
land.addAbility(new BlackManaAbility(), source.getSourceId(), game); land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
} }

View file

@ -22,8 +22,7 @@ public final class ImpostorOfTheSixthPride extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
} }
private ImpostorOfTheSixthPride(final ImpostorOfTheSixthPride card) { private ImpostorOfTheSixthPride(final ImpostorOfTheSixthPride card) {

View file

@ -27,7 +27,7 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentToken; import mage.game.permanent.PermanentToken;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
/** /**
* *
@ -89,7 +89,7 @@ class InfiniteReflectionTriggeredEffect extends OneShotEffect {
if (toCopyFromPermanent != null) { if (toCopyFromPermanent != null) {
for (Permanent toCopyToPermanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) { for (Permanent toCopyToPermanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
if (!toCopyToPermanent.equals(toCopyFromPermanent) && !(toCopyToPermanent instanceof PermanentToken)) { if (!toCopyToPermanent.equals(toCopyFromPermanent) && !(toCopyToPermanent instanceof PermanentToken)) {
game.copyPermanent(toCopyFromPermanent, toCopyToPermanent.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(toCopyFromPermanent, toCopyToPermanent.getId(), source, new EmptyCopyApplier());
} }
} }
return true; return true;
@ -129,7 +129,7 @@ class InfiniteReflectionEntersBattlefieldEffect extends ReplacementEffectImpl {
if (sourcePermanent != null && toCopyToObject != null && sourcePermanent.getAttachedTo() != null) { if (sourcePermanent != null && toCopyToObject != null && sourcePermanent.getAttachedTo() != null) {
Permanent toCopyFromPermanent = game.getPermanent(sourcePermanent.getAttachedTo()); Permanent toCopyFromPermanent = game.getPermanent(sourcePermanent.getAttachedTo());
if (toCopyFromPermanent != null) { if (toCopyFromPermanent != null) {
game.copyPermanent(toCopyFromPermanent, toCopyToObject.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(toCopyFromPermanent, toCopyToObject.getId(), source, new EmptyCopyApplier());
} }
} }
return false; return false;

View file

@ -24,8 +24,7 @@ public final class IrregularCohort extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// When Irregular Cohort enters the battlefield, create a 2/2 colorless Shapeshifter creature token with changeling. // When Irregular Cohort enters the battlefield, create a 2/2 colorless Shapeshifter creature token with changeling.
this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ShapeshifterToken()))); this.addAbility(new EntersBattlefieldTriggeredAbility(new CreateTokenEffect(new ShapeshifterToken())));

View file

@ -1,7 +1,5 @@
package mage.cards.j; package mage.cards.j;
import java.util.UUID;
import mage.abilities.condition.LockedInCondition; import mage.abilities.condition.LockedInCondition;
import mage.abilities.condition.common.SourceHasSubtypeCondition; import mage.abilities.condition.common.SourceHasSubtypeCondition;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
@ -14,29 +12,26 @@ import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.SubType; import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import mage.util.SubTypeList;
import java.util.UUID;
/** /**
*
* @author Styxo * @author Styxo
*/ */
public final class JarKaiBattleStance extends CardImpl { public final class JarKaiBattleStance extends CardImpl {
public JarKaiBattleStance(UUID ownerId, CardSetInfo setInfo) { public JarKaiBattleStance(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{1}{R}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{R}");
// Target creature gains double strike until end of turn. // Target creature gains double strike until end of turn.
this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn)); this.getSpellAbility().addEffect(new GainAbilityTargetEffect(DoubleStrikeAbility.getInstance(), Duration.EndOfTurn));
this.getSpellAbility().addTarget(new TargetCreaturePermanent()); this.getSpellAbility().addTarget(new TargetCreaturePermanent());
SubTypeList s = new SubTypeList();
s.add(SubType.JEDI);
s.add(SubType.SITH);
// If that creature is a Jedi or Sith, it also gains trample until end of turn. // If that creature is a Jedi or Sith, it also gains trample until end of turn.
this.getSpellAbility().addEffect(new ConditionalContinuousEffect( this.getSpellAbility().addEffect(new ConditionalContinuousEffect(
new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn), new GainAbilityTargetEffect(TrampleAbility.getInstance(), Duration.EndOfTurn),
new LockedInCondition(new SourceHasSubtypeCondition(s)), new LockedInCondition(new SourceHasSubtypeCondition(SubType.JEDI, SubType.SITH)),
"If that creature is a Jedi or Sith, it also gains trample until end of turn")); "If that creature is a Jedi or Sith, it also gains trample until end of turn"));
} }
public JarKaiBattleStance(final JarKaiBattleStance card) { public JarKaiBattleStance(final JarKaiBattleStance card) {

View file

@ -16,8 +16,9 @@ import mage.constants.*;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.AnotherPredicate; import mage.filter.predicate.permanent.AnotherPredicate;
import mage.util.SubTypeList;
import java.util.Arrays;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
@ -83,7 +84,7 @@ enum KaheeraTheOrphanguardCompanionCondition implements CompanionCondition {
return "Each creature card in your starting deck is a Cat, Elemental, Nightmare, Dinosaur or Beast card."; return "Each creature card in your starting deck is a Cat, Elemental, Nightmare, Dinosaur or Beast card.";
} }
private static final SubTypeList subtypes = new SubTypeList( private static final List<SubType> subtypes = Arrays.asList(
SubType.CAT, SubType.CAT,
SubType.ELEMENTAL, SubType.ELEMENTAL,
SubType.NIGHTMARE, SubType.NIGHTMARE,
@ -92,7 +93,7 @@ enum KaheeraTheOrphanguardCompanionCondition implements CompanionCondition {
); );
private static boolean checkTypes(Card card) { private static boolean checkTypes(Card card) {
return subtypes.stream().anyMatch(subtype -> card.hasSubtype(subtype, null)); return subtypes.stream().anyMatch(subtype -> card.getSubtype().contains(subtype));
} }
@Override @Override

View file

@ -109,7 +109,7 @@ class KondasBannerTypeBoostEffect extends BoostAllEffect {
Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo()); Permanent equipedCreature = game.getPermanent(equipment.getAttachedTo());
if (equipedCreature != null) { if (equipedCreature != null) {
for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) { for (Permanent perm : game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game)) {
if (perm.shareCreatureTypes(equipedCreature, game)) { if (perm.shareCreatureTypes(game, equipedCreature)) {
perm.addPower(power.calculate(game, source, this)); perm.addPower(power.calculate(game, source, this));
perm.addToughness(toughness.calculate(game, source, this)); perm.addToughness(toughness.calculate(game, source, this));

View file

@ -19,7 +19,7 @@ import mage.game.permanent.Permanent;
import mage.game.permanent.PermanentCard; import mage.game.permanent.PermanentCard;
import mage.players.Player; import mage.players.Player;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
/** /**
* *
@ -82,7 +82,7 @@ class LazavDimirMastermindEffect extends OneShotEffect {
if (copyFromCard != null) { if (copyFromCard != null) {
newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game); newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game);
newBluePrint.assignNewId(); newBluePrint.assignNewId();
ApplyToPermanent applier = new LazavDimirMastermindApplier(); CopyApplier applier = new LazavDimirMastermindCopyApplier();
applier.apply(game, newBluePrint, source, lazavDimirMastermind.getId()); applier.apply(game, newBluePrint, source, lazavDimirMastermind.getId());
CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, lazavDimirMastermind.getId()); CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, lazavDimirMastermind.getId());
copyEffect.newId(); copyEffect.newId();
@ -97,31 +97,18 @@ class LazavDimirMastermindEffect extends OneShotEffect {
} }
} }
class LazavDimirMastermindApplier extends ApplyToPermanent { class LazavDimirMastermindCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
Ability ability = new PutCardIntoGraveFromAnywhereAllTriggeredAbility( Ability ability = new PutCardIntoGraveFromAnywhereAllTriggeredAbility(
new LazavDimirMastermindEffect(), true, new LazavDimirMastermindEffect(), true,
new FilterCreatureCard("a creature card"), new FilterCreatureCard("a creature card"),
TargetController.OPPONENT, SetTargetPointer.CARD); TargetController.OPPONENT, SetTargetPointer.CARD);
permanent.getAbilities().add(ability); blueprint.getAbilities().add(ability);
permanent.setName("Lazav, Dimir Mastermind"); blueprint.setName("Lazav, Dimir Mastermind");
permanent.addSuperType(SuperType.LEGENDARY); blueprint.addSuperType(SuperType.LEGENDARY);
permanent.getAbilities().add(HexproofAbility.getInstance()); blueprint.getAbilities().add(HexproofAbility.getInstance());
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
Ability ability = new PutCardIntoGraveFromAnywhereAllTriggeredAbility(
new LazavDimirMastermindEffect(), true,
new FilterCreatureCard("a creature card"),
TargetController.OPPONENT, SetTargetPointer.CARD);
mageObject.getAbilities().add(ability);
mageObject.setName("Lazav, Dimir Mastermind");
mageObject.addSuperType(SuperType.LEGENDARY);
mageObject.getAbilities().add(HexproofAbility.getInstance());
return true; return true;
} }
} }

View file

@ -28,7 +28,7 @@ import mage.game.permanent.PermanentCard;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import mage.target.targetadjustment.TargetAdjuster; import mage.target.targetadjustment.TargetAdjuster;
import mage.util.functions.ApplyToPermanent; import mage.util.functions.CopyApplier;
/** /**
* *
@ -112,7 +112,7 @@ class LazavTheMultifariousEffect extends OneShotEffect {
if (copyFromCard != null) { if (copyFromCard != null) {
newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game); newBluePrint = new PermanentCard(copyFromCard, source.getControllerId(), game);
newBluePrint.assignNewId(); newBluePrint.assignNewId();
ApplyToPermanent applier = new LazavTheMultifariousApplier(); CopyApplier applier = new LazavTheMultifariousCopyApplier();
applier.apply(game, newBluePrint, source, lazavTheMultifarious.getId()); applier.apply(game, newBluePrint, source, lazavTheMultifarious.getId());
CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, lazavTheMultifarious.getId()); CopyEffect copyEffect = new CopyEffect(Duration.Custom, newBluePrint, lazavTheMultifarious.getId());
copyEffect.newId(); copyEffect.newId();
@ -127,31 +127,18 @@ class LazavTheMultifariousEffect extends OneShotEffect {
} }
} }
class LazavTheMultifariousApplier extends ApplyToPermanent { class LazavTheMultifariousCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
Ability ability = new SimpleActivatedAbility( Ability ability = new SimpleActivatedAbility(
new LazavTheMultifariousEffect(), new LazavTheMultifariousEffect(),
new ManaCostsImpl("{X}") new ManaCostsImpl("{X}")
); );
ability.setTargetAdjuster(LazavTheMultifariousAdjuster.instance); ability.setTargetAdjuster(LazavTheMultifariousAdjuster.instance);
permanent.getAbilities().add(ability); blueprint.getAbilities().add(ability);
permanent.setName("Lazav, the Multifarious"); blueprint.setName("Lazav, the Multifarious");
permanent.addSuperType(SuperType.LEGENDARY); blueprint.addSuperType(SuperType.LEGENDARY);
return true;
}
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
Ability ability = new SimpleActivatedAbility(
new LazavTheMultifariousEffect(),
new ManaCostsImpl("{X}")
);
ability.setTargetAdjuster(LazavTheMultifariousAdjuster.instance);
mageObject.getAbilities().add(ability);
mageObject.setName("Lazav, the Multifarious");
mageObject.addSuperType(SuperType.LEGENDARY);
return true; return true;
} }
} }

View file

@ -2,8 +2,6 @@
package mage.cards.l; package mage.cards.l;
import java.util.Iterator;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.ObjectColor; import mage.ObjectColor;
@ -20,20 +18,21 @@ import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.events.DamagedPlayerEvent; import mage.game.events.DamagedPlayerEvent;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.game.events.GameEvent.EventType;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.token.custom.ElementalCreatureToken; import mage.game.permanent.token.custom.ElementalCreatureToken;
import mage.target.Target; import mage.target.Target;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import java.util.Iterator;
import java.util.UUID;
/** /**
*
* @author Loki * @author Loki
*/ */
public final class LiegeOfTheTangle extends CardImpl { public final class LiegeOfTheTangle extends CardImpl {
public LiegeOfTheTangle (UUID ownerId, CardSetInfo setInfo) { public LiegeOfTheTangle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{6}{G}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{6}{G}{G}");
this.subtype.add(SubType.ELEMENTAL); this.subtype.add(SubType.ELEMENTAL);
this.power = new MageInt(8); this.power = new MageInt(8);
@ -42,7 +41,7 @@ public final class LiegeOfTheTangle extends CardImpl {
this.addAbility(new LiegeOfTheTangleTriggeredAbility()); this.addAbility(new LiegeOfTheTangleTriggeredAbility());
} }
public LiegeOfTheTangle (final LiegeOfTheTangle card) { public LiegeOfTheTangle(final LiegeOfTheTangle card) {
super(card); super(card);
} }
@ -76,7 +75,7 @@ class LiegeOfTheTangleTriggeredAbility extends TriggeredAbilityImpl {
@Override @Override
public boolean checkTrigger(GameEvent event, Game game) { public boolean checkTrigger(GameEvent event, Game game) {
DamagedPlayerEvent damageEvent = (DamagedPlayerEvent)event; DamagedPlayerEvent damageEvent = (DamagedPlayerEvent) event;
Permanent p = game.getPermanent(event.getSourceId()); Permanent p = game.getPermanent(event.getSourceId());
return damageEvent.isCombatDamage() && p != null && p.getId().equals(this.getSourceId()); return damageEvent.isCombatDamage() && p != null && p.getId().equals(this.getSourceId());
} }
@ -101,15 +100,20 @@ class LiegeOfTheTangleEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) {
Permanent perm = it.next().getPermanent(game); Permanent perm = it.next().getPermanent(game);
if (perm != null) { if (perm == null) {
if (perm.getCounters(game).getCount(CounterType.AWAKENING) > 0) { it.remove();
continue;
}
if (perm.getCounters(game).getCount(CounterType.AWAKENING) <= 0) {
continue;
}
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
perm.addCardTypes(token.getCardType()); perm.addCardTypes(token.getCardType());
perm.getSubtype(game).addAll(token.getSubtype(game)); perm.copySubTypesFrom(game, token);
} }
break; break;
case ColorChangingEffects_5: case ColorChangingEffects_5:
@ -125,10 +129,6 @@ class LiegeOfTheTangleEffect extends ContinuousEffectImpl {
break; break;
} }
} }
} else {
it.remove();
}
}
return true; return true;
} }
@ -141,7 +141,7 @@ class LiegeOfTheTangleEffect extends ContinuousEffectImpl {
public void init(Ability source, Game game) { public void init(Ability source, Game game) {
super.init(source, game); super.init(source, game);
if (this.affectedObjectsSet) { if (this.affectedObjectsSet) {
for (UUID permId: targetPointer.getTargets(game, source)) { for (UUID permId : targetPointer.getTargets(game, source)) {
affectedObjectList.add(new MageObjectReference(permId, game)); affectedObjectList.add(new MageObjectReference(permId, game));
} }
} }
@ -154,7 +154,9 @@ class LiegeOfTheTangleEffect extends ContinuousEffectImpl {
@Override @Override
public boolean hasLayer(Layer layer) { public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.ColorChangingEffects_5 || layer == layer.TypeChangingEffects_4; return layer == Layer.PTChangingEffects_7
|| layer == Layer.ColorChangingEffects_5
|| layer == layer.TypeChangingEffects_4;
} }
} }

View file

@ -82,7 +82,7 @@ class ChangeLandAttachedEffect extends ContinuousEffectImpl {
} }
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
permanent.getSubtype(game).removeAll(SubType.getLandTypes()); permanent.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
permanent.removeAllAbilities(source.getSourceId(), game); permanent.removeAllAbilities(source.getSourceId(), game);

View file

@ -33,8 +33,7 @@ public final class LittjaraGladeWarden extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// {2}{G}, {T}, Exile a creature card from your graveyard: Put two +1/+1 counters on target creature. Activate this ability only any time you could cast a sorcery. // {2}{G}, {T}, Exile a creature card from your graveyard: Put two +1/+1 counters on target creature. Activate this ability only any time you could cast a sorcery.
Ability ability = new ActivateAsSorceryActivatedAbility( Ability ability = new ActivateAsSorceryActivatedAbility(

View file

@ -31,8 +31,7 @@ public final class LittjaraKinseekers extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// When Littjara Kinseekers enters the battlefield, if you control three or more creatures that share a creature type, put a +1/+1 counter on Littjara Kinseekers, then scry 1. // When Littjara Kinseekers enters the battlefield, if you control three or more creatures that share a creature type, put a +1/+1 counter on Littjara Kinseekers, then scry 1.
Ability ability = new ConditionalInterveningIfTriggeredAbility( Ability ability = new ConditionalInterveningIfTriggeredAbility(

View file

@ -77,7 +77,7 @@ public final class MagusOfTheMoon extends CardImpl {
// 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects // 305.7 Note that this doesn't remove any abilities that were granted to the land by other effects
// So the ability removing has to be done before Layer 6 // So the ability removing has to be done before Layer 6
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.removeAllSubTypes(game, SubTypeSet.NonBasicLandType);
land.addSubType(game, SubType.MOUNTAIN); land.addSubType(game, SubType.MOUNTAIN);
// Mountains have the red mana ability intrinsically so the ability must be added in this layer // Mountains have the red mana ability intrinsically so the ability must be added in this layer
land.addAbility(new RedManaAbility(), source.getSourceId(), game); land.addAbility(new RedManaAbility(), source.getSourceId(), game);

View file

@ -65,7 +65,7 @@ class ManaEchoesEffect extends OneShotEffect {
if (controller != null && permanent != null) { if (controller != null && permanent != null) {
int foundCreatures = 0; int foundCreatures = 0;
for (Permanent perm : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) { for (Permanent perm : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) {
if (permanent.shareCreatureTypes(perm, game)) { if (permanent.shareCreatureTypes(game, perm)) {
foundCreatures++; foundCreatures++;
} }
} }

View file

@ -40,8 +40,7 @@ public final class MaskedVandal extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// When enters the battlefield, you may exile a creature card from your graveyard. If you do, exile target artifact or enchantment an opponent controls. // When enters the battlefield, you may exile a creature card from your graveyard. If you do, exile target artifact or enchantment an opponent controls.
Ability ability = new EntersBattlefieldAbility( Ability ability = new EntersBattlefieldAbility(

View file

@ -57,7 +57,7 @@ public final class MaskwoodNexus extends CardImpl {
class MaskwoodNexusEffect extends ContinuousEffectImpl { class MaskwoodNexusEffect extends ContinuousEffectImpl {
MaskwoodNexusEffect() { MaskwoodNexusEffect() {
super(Duration.WhileOnBattlefield, Outcome.Benefit); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
staticText = "Creatures you control are every creature type. " + staticText = "Creatures you control are every creature type. " +
"The same is true for creature spells you control " + "The same is true for creature spells you control " +
"and creature cards you own that aren't on the battlefield."; "and creature cards you own that aren't on the battlefield.";
@ -73,7 +73,7 @@ class MaskwoodNexusEffect extends ContinuousEffectImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId()); Player controller = game.getPlayer(source.getControllerId());
if (controller == null) { if (controller == null) {
return false; return false;
@ -83,26 +83,26 @@ class MaskwoodNexusEffect extends ContinuousEffectImpl {
for (UUID cardId : controller.getGraveyard()) { for (UUID cardId : controller.getGraveyard()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
if (card != null && card.isCreature()) { if (card != null && card.isCreature()) {
card.setIsAllCreatureTypes(true); game.getState().getCreateMageObjectAttribute(card, game).getSubtype().setIsAllCreatureTypes(true);
} }
} }
// on Hand // on Hand
for (UUID cardId : controller.getHand()) { for (UUID cardId : controller.getHand()) {
Card card = game.getCard(cardId); Card card = game.getCard(cardId);
if (card != null && card.isCreature()) { if (card != null && card.isCreature()) {
card.setIsAllCreatureTypes(true); game.getState().getCreateMageObjectAttribute(card, game).getSubtype().setIsAllCreatureTypes(true);
} }
} }
// in Exile // in Exile
for (Card card : game.getState().getExile().getAllCards(game)) { for (Card card : game.getState().getExile().getAllCards(game)) {
if (card.isCreature() && card.isOwnedBy(controller.getId())) { if (card.isCreature() && card.isOwnedBy(controller.getId())) {
card.setIsAllCreatureTypes(true); game.getState().getCreateMageObjectAttribute(card, game).getSubtype().setIsAllCreatureTypes(true);
} }
} }
// in Library (e.g. for Mystical Teachings) // in Library (e.g. for Mystical Teachings)
for (Card card : controller.getLibrary().getCards(game)) { for (Card card : controller.getLibrary().getCards(game)) {
if (card.isOwnedBy(controller.getId()) && card.isCreature()) { if (card.isOwnedBy(controller.getId()) && card.isCreature()) {
card.setIsAllCreatureTypes(true); game.getState().getCreateMageObjectAttribute(card, game).getSubtype().setIsAllCreatureTypes(true);
} }
} }
// commander in command zone // commander in command zone
@ -114,7 +114,7 @@ class MaskwoodNexusEffect extends ContinuousEffectImpl {
if (card != null if (card != null
&& card.isOwnedBy(controller.getId()) && card.isOwnedBy(controller.getId())
&& card.isCreature()) { && card.isCreature()) {
card.setIsAllCreatureTypes(true); game.getState().getCreateMageObjectAttribute(card, game).getSubtype().setIsAllCreatureTypes(true);
} }
} }
// creature spells you control // creature spells you control
@ -124,7 +124,7 @@ class MaskwoodNexusEffect extends ContinuousEffectImpl {
&& stackObject.isControlledBy(source.getControllerId()) && stackObject.isControlledBy(source.getControllerId())
&& stackObject.isCreature()) { && stackObject.isCreature()) {
Card card = ((Spell) stackObject).getCard(); Card card = ((Spell) stackObject).getCard();
card.setIsAllCreatureTypes(true); game.getState().getCreateMageObjectAttribute(card, game).getSubtype().setIsAllCreatureTypes(true);
} }
} }
// creatures you control // creatures you control
@ -132,16 +132,10 @@ class MaskwoodNexusEffect extends ContinuousEffectImpl {
new FilterControlledCreaturePermanent(), source.getControllerId(), game); new FilterControlledCreaturePermanent(), source.getControllerId(), game);
for (Permanent creature : creatures) { for (Permanent creature : creatures) {
if (creature != null) { if (creature != null) {
creature.setIsAllCreatureTypes(true); creature.setIsAllCreatureTypes(game, true);
} }
} }
return true; return true;
} }
@Override
public boolean apply(Game game, Ability source) {
return false;
}
} }

View file

@ -14,7 +14,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.token.GolemToken; import mage.game.permanent.token.GolemToken;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
import java.util.UUID; import java.util.UUID;
@ -71,7 +71,7 @@ class MasterfulReplicationEffect extends OneShotEffect {
} }
for (Permanent copyToArtifact : game.getBattlefield().getAllActivePermanents(source.getControllerId())) { for (Permanent copyToArtifact : game.getBattlefield().getAllActivePermanents(source.getControllerId())) {
if (copyToArtifact.isArtifact() && !copyToArtifact.getId().equals(copyFromArtifact.getId())) { if (copyToArtifact.isArtifact() && !copyToArtifact.getId().equals(copyFromArtifact.getId())) {
game.copyPermanent(Duration.EndOfTurn, copyFromArtifact, copyToArtifact.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(Duration.EndOfTurn, copyFromArtifact, copyToArtifact.getId(), source, new EmptyCopyApplier());
} }
} }
return true; return true;

View file

@ -13,7 +13,7 @@ import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.util.functions.AbilityApplier; import mage.util.functions.AbilityCopyApplier;
import java.util.UUID; import java.util.UUID;
@ -35,7 +35,7 @@ public final class MercurialPretender extends CardImpl {
// You may have Mercurial Pretender enter the battlefield as a copy of any creature you control, // You may have Mercurial Pretender enter the battlefield as a copy of any creature you control,
// except it has "{2}{U}{U}: Return this creature to its owner's hand." // except it has "{2}{U}{U}: Return this creature to its owner's hand."
Effect effect = new CopyPermanentEffect(new FilterControlledCreaturePermanent(), Effect effect = new CopyPermanentEffect(new FilterControlledCreaturePermanent(),
new AbilityApplier(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{U}{U}")))); new AbilityCopyApplier(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ReturnToHandSourceEffect(true), new ManaCostsImpl("{2}{U}{U}"))));
effect.setText(effectText); effect.setText(effectText);
this.addAbility(new EntersBattlefieldAbility(effect, true)); this.addAbility(new EntersBattlefieldAbility(effect, true));
} }

View file

@ -133,9 +133,7 @@ class MetamorphicAlterationEffect extends ContinuousEffectImpl {
permanent.addCardType(cardType); permanent.addCardType(cardType);
} }
permanent.removeAllSubTypes(game); permanent.removeAllSubTypes(game);
permanent.setIsAllCreatureTypes(copied.isAllCreatureTypes()); permanent.copySubTypesFrom(game, copied);
permanent.getSubtype(game).addAll(copied.getSubtype(game));
permanent.setIsAllCreatureTypes(copied.isAllCreatureTypes());
permanent.getColor(game).setColor(copied.getColor(game)); permanent.getColor(game).setColor(copied.getColor(game));
permanent.removeAllAbilities(source.getSourceId(), game); permanent.removeAllAbilities(source.getSourceId(), game);
for (Ability ability : copied.getAbilities()) { for (Ability ability : copied.getAbilities()) {

View file

@ -16,7 +16,7 @@ import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
/** /**
* *
@ -66,7 +66,7 @@ class MirageMirrorCopyEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (sourcePermanent != null && copyFromPermanent != null) { if (sourcePermanent != null && copyFromPermanent != null) {
game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyCopyApplier());
return true; return true;
} }
return false; return false;

View file

@ -32,8 +32,7 @@ public final class MirrorEntity extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// {X}: Until end of turn, creatures you control have base power and toughness X/X and gain all creature types. // {X}: Until end of turn, creatures you control have base power and toughness X/X and gain all creature types.
Ability ability = new SimpleActivatedAbility(new SetPowerToughnessAllEffect( Ability ability = new SimpleActivatedAbility(new SetPowerToughnessAllEffect(
@ -88,7 +87,7 @@ class MirrorEntityEffect extends ContinuousEffectImpl {
it.remove(); // no longer on the battlefield, remove reference to object it.remove(); // no longer on the battlefield, remove reference to object
continue; continue;
} }
permanent.setIsAllCreatureTypes(true); permanent.setIsAllCreatureTypes(game, true);
} }
return true; return true;
} }

View file

@ -19,7 +19,7 @@ import mage.filter.predicate.mageobject.ChosenSubtypePredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
import java.util.UUID; import java.util.UUID;
@ -77,7 +77,7 @@ class MirrorOfTheForebearsCopyEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (sourcePermanent != null && copyFromPermanent != null) { if (sourcePermanent != null && copyFromPermanent != null) {
game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyCopyApplier());
game.addEffect(new AddCardTypeSourceEffect(Duration.EndOfTurn, CardType.ARTIFACT), source); game.addEffect(new AddCardTypeSourceEffect(Duration.EndOfTurn, CardType.ARTIFACT), source);
return true; return true;
} }

View file

@ -17,7 +17,7 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
/** /**
* *
@ -77,7 +77,7 @@ class MirrorWeaveEffect extends OneShotEffect {
filter.add(Predicates.not(new PermanentIdPredicate(copyFromCreature.getId()))); filter.add(Predicates.not(new PermanentIdPredicate(copyFromCreature.getId())));
for (Permanent copyToCreature : game.getBattlefield().getAllActivePermanents(filter, game)) { for (Permanent copyToCreature : game.getBattlefield().getAllActivePermanents(filter, game)) {
if (copyToCreature != null) { if (copyToCreature != null) {
game.copyPermanent(Duration.EndOfTurn, copyFromCreature, copyToCreature.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(Duration.EndOfTurn, copyFromCreature, copyToCreature.getId(), source, new EmptyCopyApplier());
} }
} }
} }

View file

@ -2,7 +2,7 @@ package mage.cards.m;
import mage.MageInt; import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.IsAllCreatureTypesSourceEffect;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
@ -26,13 +26,10 @@ public final class MistformUltimus extends CardImpl {
this.toughness = new MageInt(3); this.toughness = new MageInt(3);
// Mistform Ultimus is every creature type. // Mistform Ultimus is every creature type.
this.setIsAllCreatureTypes(true); this.addAbility(new SimpleStaticAbility(Zone.ALL, new IsAllCreatureTypesSourceEffect()));
this.addAbility(new SimpleStaticAbility(Zone.ALL, new InfoEffect(
"{this} is every creature type <i>(even if this card isn't on the battlefield)</i>."
)));
} }
public MistformUltimus(final MistformUltimus card) { private MistformUltimus(final MistformUltimus card) {
super(card); super(card);
} }

View file

@ -1,7 +1,6 @@
package mage.cards.m; package mage.cards.m;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -9,24 +8,24 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.continuous.BecomesChosenCreatureTypeSourceEffect; import mage.abilities.effects.common.continuous.BecomesChosenCreatureTypeSourceEffect;
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect; import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
import mage.constants.SubType; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubTypeSet; import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.ObjectSourcePlayer; import mage.filter.predicate.ObjectSourcePlayer;
import mage.filter.predicate.ObjectSourcePlayerPredicate; import mage.filter.predicate.ObjectSourcePlayerPredicate;
import mage.game.Game; import mage.game.Game;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class MistformWarchief extends CardImpl { public final class MistformWarchief extends CardImpl {
private static final FilterCard filter = new FilterCard("Creature spells you cast that share a creature type with {this}"); private static final FilterCard filter = new FilterCard();
static { static {
filter.add(new MistformWarchiefPredicate()); filter.add(new MistformWarchiefPredicate());
@ -41,7 +40,6 @@ public final class MistformWarchief extends CardImpl {
// Creature spells you cast that share a creature type with Mistform Warchief cost {1} less to cast. // Creature spells you cast that share a creature type with Mistform Warchief cost {1} less to cast.
this.addAbility(new SimpleStaticAbility( this.addAbility(new SimpleStaticAbility(
Zone.BATTLEFIELD,
new SpellsCostReductionControllerEffect(filter, 1) new SpellsCostReductionControllerEffect(filter, 1)
.setText("Creature spells you cast that share a creature type with {this} cost {1} less to cast") .setText("Creature spells you cast that share a creature type with {this} cost {1} less to cast")
)); ));
@ -50,7 +48,7 @@ public final class MistformWarchief extends CardImpl {
this.addAbility(new SimpleActivatedAbility(new BecomesChosenCreatureTypeSourceEffect(), new TapSourceCost())); this.addAbility(new SimpleActivatedAbility(new BecomesChosenCreatureTypeSourceEffect(), new TapSourceCost()));
} }
public MistformWarchief(final MistformWarchief card) { private MistformWarchief(final MistformWarchief card) {
super(card); super(card);
} }
@ -60,20 +58,12 @@ public final class MistformWarchief extends CardImpl {
} }
} }
class MistformWarchiefPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<MageObject>> { class MistformWarchiefPredicate implements ObjectSourcePlayerPredicate<ObjectSourcePlayer<Card>> {
@Override @Override
public boolean apply(ObjectSourcePlayer<MageObject> input, Game game) { public boolean apply(ObjectSourcePlayer<Card> input, Game game) {
MageObject sourceObject = game.getObject(input.getSourceId()); MageObject sourceObject = game.getObject(input.getSourceId());
if (sourceObject != null) { return sourceObject != null && sourceObject.shareCreatureTypes(game, input.getObject());
for (SubType subType : sourceObject.getSubtype(game)) {
if (subType.getSubTypeSet() == SubTypeSet.CreatureType && input.getObject().hasSubtype(subType, game)) {
return true;
}
}
}
return false;
} }
@Override @Override

View file

@ -27,8 +27,7 @@ public final class Mistwalker extends CardImpl {
this.toughness = new MageInt(4); this.toughness = new MageInt(4);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// Flying // Flying
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());

View file

@ -15,7 +15,7 @@ import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetArtifactPermanent; import mage.target.common.TargetArtifactPermanent;
import mage.util.functions.EmptyApplyToPermanent; import mage.util.functions.EmptyCopyApplier;
/** /**
* *
@ -68,7 +68,7 @@ class MizziumTransreliquatCopyEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (sourcePermanent != null && copyFromPermanent != null) { if (sourcePermanent != null && copyFromPermanent != null) {
game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent()); game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyCopyApplier());
return true; return true;
} }
return false; return false;
@ -96,7 +96,7 @@ class MizziumTransreliquatCopyAndGainAbilityEffect extends OneShotEffect {
Permanent sourcePermanent = game.getPermanent(source.getSourceId()); Permanent sourcePermanent = game.getPermanent(source.getSourceId());
Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source)); Permanent copyFromPermanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (sourcePermanent != null && copyFromPermanent != null) { if (sourcePermanent != null && copyFromPermanent != null) {
Permanent newPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent()); Permanent newPermanent = game.copyPermanent(copyFromPermanent, sourcePermanent.getId(), source, new EmptyCopyApplier());
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MizziumTransreliquatCopyAndGainAbilityEffect(), new ManaCostsImpl("{1}{U}{R}")); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new MizziumTransreliquatCopyAndGainAbilityEffect(), new ManaCostsImpl("{1}{U}{R}"));
ability.addTarget(new TargetArtifactPermanent()); ability.addTarget(new TargetArtifactPermanent());
newPermanent.addAbility(ability, source.getSourceId(), game); newPermanent.addAbility(ability, source.getSourceId(), game);

View file

@ -24,8 +24,7 @@ public final class MoongloveChangeling extends CardImpl {
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.B))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(DeathtouchAbility.getInstance(), Duration.EndOfTurn), new ColoredManaCost(ColoredManaSymbol.B)));
} }

View file

@ -15,8 +15,7 @@ import mage.constants.SuperType;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.util.functions.CopyApplier;
import mage.util.functions.ApplyToPermanent;
import java.util.UUID; import java.util.UUID;
@ -35,12 +34,11 @@ public final class MoritteOfTheFrost extends CardImpl {
this.toughness = new MageInt(0); this.toughness = new MageInt(0);
// Changeling // Changeling
this.setIsAllCreatureTypes(true); this.addAbility(new ChangelingAbility());
this.addAbility(ChangelingAbility.getInstance());
// You may have Moritte of the Frost enter the battlefield as a copy of a permanent you control, except it's legendary and snow in addition to its other types and, if it's a creature, it enters with two additional +1/+1 counters on it and has changeling. // You may have Moritte of the Frost enter the battlefield as a copy of a permanent you control, except it's legendary and snow in addition to its other types and, if it's a creature, it enters with two additional +1/+1 counters on it and has changeling.
this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect( this.addAbility(new EntersBattlefieldAbility(new CopyPermanentEffect(
StaticFilters.FILTER_CONTROLLED_PERMANENT, new MoritteOfTheFrostApplier() StaticFilters.FILTER_CONTROLLED_PERMANENT, new MoritteOfTheFrostCopyApplier()
).setText("as a copy of a permanent you control, except it's legendary and snow in addition to its other types " + ).setText("as a copy of a permanent you control, except it's legendary and snow in addition to its other types " +
"and, if it's a creature, it enters with two additional +1/+1 counters on it and has changeling." "and, if it's a creature, it enters with two additional +1/+1 counters on it and has changeling."
), true)); ), true));
@ -56,24 +54,18 @@ public final class MoritteOfTheFrost extends CardImpl {
} }
} }
class MoritteOfTheFrostApplier extends ApplyToPermanent { class MoritteOfTheFrostCopyApplier extends CopyApplier {
@Override @Override
public boolean apply(Game game, Permanent copyFromBlueprint, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject blueprint, Ability source, UUID copyToObjectId) {
return apply(game, (MageObject) copyFromBlueprint, source, copyToObjectId); blueprint.addSuperType(SuperType.LEGENDARY);
} blueprint.addSuperType(SuperType.SNOW);
@Override if (!isCopyOfCopy(source, copyToObjectId) && blueprint.isCreature()) {
public boolean apply(Game game, MageObject copyFromBlueprint, Ability source, UUID copyToObjectId) { blueprint.getAbilities().add(new ChangelingAbility());
copyFromBlueprint.addSuperType(SuperType.LEGENDARY); blueprint.getAbilities().add(new EntersBattlefieldAbility(
copyFromBlueprint.addSuperType(SuperType.SNOW); new AddCountersSourceEffect(CounterType.P1P1.createInstance(2), false)
));
if (!isCopyOfCopy(source, copyToObjectId) && copyFromBlueprint.isCreature()) {
copyFromBlueprint.setIsAllCreatureTypes(true);
copyFromBlueprint.getAbilities().add(ChangelingAbility.getInstance());
new AddCountersSourceEffect(
CounterType.P1P1.createInstance(2), false
).apply(game, source);
} }
return true; return true;
} }

Some files were not shown because too many files have changed in this diff Show more