Fixing issues with Changelings and general problems with creature types (ready to merge) (#7098)

* updated Changelings to use setIsAllCreatureTypes

* updated Dr Julius Jumblemorph and Mistform Ultimus to not use changeling

* added test for Mistform Ultimus

* updated effects which give all creature types to controlled creatures

* updated effects which give all creature types to targeted creatures

* Update LoseAllCreatureTypesTargetEffect.java

* updated effects which give all creature types to attached creatures

* Update EgoErasure.java

* added another test for changelings

* updated two tokens I left out before

* updated hasSubtype

* updated shareCreatureTypes

* fixed an incorrect test

* cleaned up some cards which check for shared creature types

* added new changeling test

* fixed issue with shareCreatureTypes

* fixed a text issue

* added new tests for subtype effects

* various individual card fixes and cleanups

* fixed and updated various effects

* many more fixes

* a few more fixes

* added test for One with the Stars

* added changeling verify test

* updated effects which add additional subtypes

* more miscellaneous fixes

* added additional test

* some fixes for card type checks

* updated methods for adding types to make it easier to avoid duplicates and illegal additions

* small test update

* fixed a recursive loop issue

* fixed another error

* fixed it for real this time

* streamlined type removal process

* streamlined subtype set generation
This commit is contained in:
Evan Kranzler 2020-10-30 22:32:59 -04:00 committed by GitHub
parent 42e00b7a37
commit 8617bc128e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
182 changed files with 2431 additions and 2820 deletions

View file

@ -1,28 +1,22 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BlocksSourceTriggeredAbility; import mage.abilities.common.BlocksSourceTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.LoseAbilitySourceEffect; import mage.abilities.effects.common.continuous.LoseAbilitySourceEffect;
import mage.constants.SubType;
import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.DefenderAbility;
import mage.abilities.keyword.FlyingAbility; import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author TheElk801 * @author TheElk801
*/ */
public final class AgelessSentinels extends CardImpl { public final class AgelessSentinels extends CardImpl {
@ -43,7 +37,7 @@ public final class AgelessSentinels extends CardImpl {
// When Ageless Sentinels blocks, it becomes a Bird Giant, and it loses defender. // When Ageless Sentinels blocks, it becomes a Bird Giant, and it loses defender.
Ability ability = new BlocksSourceTriggeredAbility(new AgelessSentinelsEffect(), false, false, true); Ability ability = new BlocksSourceTriggeredAbility(new AgelessSentinelsEffect(), false, false, true);
Effect effect = new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.WhileOnBattlefield); Effect effect = new LoseAbilitySourceEffect(DefenderAbility.getInstance(), Duration.WhileOnBattlefield);
effect.setText("and it loses defender"); effect.setText(", and it loses defender");
ability.addEffect(effect); ability.addEffect(effect);
this.addAbility(ability); this.addAbility(ability);
} }
@ -60,8 +54,8 @@ public final class AgelessSentinels extends CardImpl {
private class AgelessSentinelsEffect extends ContinuousEffectImpl { private class AgelessSentinelsEffect extends ContinuousEffectImpl {
public AgelessSentinelsEffect() { public AgelessSentinelsEffect() {
super(Duration.WhileOnBattlefield, Outcome.BecomeCreature); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
staticText = "it becomes a Bird Giant,"; staticText = "it becomes a Bird Giant";
} }
public AgelessSentinelsEffect(final AgelessSentinelsEffect effect) { public AgelessSentinelsEffect(final AgelessSentinelsEffect effect) {
@ -74,27 +68,16 @@ public final class AgelessSentinels extends CardImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) { if (permanent == null) {
return false; return false;
} }
switch (layer) { permanent.removeAllCreatureTypes(game);
case TypeChangingEffects_4: permanent.addSubType(game, SubType.BIRD, SubType.GIANT);
if (sublayer == SubLayer.NA) {
permanent.getSubtype(game).clear();
permanent.getSubtype(game).add(SubType.BIRD, SubType.GIANT);
}
break;
}
return true; return true;
} }
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override @Override
public boolean hasLayer(Layer layer) { public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4; return layer == Layer.TypeChangingEffects_4;

View file

@ -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.shareSubtypes(permanent, game)) { if (enchanted.shareCreatureTypes(permanent, game)) {
xValue += 2; xValue += 2;
} }
} }

View file

@ -7,6 +7,7 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.continuous.GainAllCreatureTypesTargetEffect;
import mage.abilities.effects.common.continuous.LoseAllCreatureTypesTargetEffect; import mage.abilities.effects.common.continuous.LoseAllCreatureTypesTargetEffect;
import mage.abilities.keyword.ChangelingAbility; import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -27,13 +28,13 @@ public final class AmoeboidChangeling extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); 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(Zone.BATTLEFIELD, Ability ability = new SimpleActivatedAbility(
new GainAbilityTargetEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn, null, false, Layer.TypeChangingEffects_4, SubLayer.NA), new TapSourceCost()); new GainAllCreatureTypesTargetEffect(Duration.EndOfTurn), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability); this.addAbility(ability);
// {tap}: Target creature loses all creature types until end of turn. // {tap}: Target creature loses all creature types until end of turn.

View file

@ -3,12 +3,10 @@ package mage.cards.a;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.effects.common.continuous.GainAllCreatureTypesAttachedEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType; import mage.constants.SubType;
@ -26,9 +24,7 @@ public final class AmorphousAxe extends CardImpl {
// Equipped creature gets +3/+0 and is every creature type. // Equipped creature gets +3/+0 and is every creature type.
Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(3, 0)); Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(3, 0));
ability.addEffect(new GainAbilityAttachedEffect( ability.addEffect(new GainAllCreatureTypesAttachedEffect());
ChangelingAbility.getInstance(), AttachmentType.EQUIPMENT
).setText("and is every creature type"));
this.addAbility(ability); this.addAbility(ability);
// Equip {3} // Equip {3}

View file

@ -116,8 +116,8 @@ class ConspyEffect extends ContinuousEffectImpl {
List<Permanent> creatures = game.getBattlefield().getAllActivePermanents( List<Permanent> creatures = game.getBattlefield().getAllActivePermanents(
new FilterControlledCreaturePermanent(), source.getControllerId(), game); new FilterControlledCreaturePermanent(), source.getControllerId(), game);
for (Permanent creature : creatures) { for (Permanent creature : creatures) {
if (creature != null && !creature.hasSubtype(subType, game)) { if (creature != null) {
creature.getSubtype(game).add(subType); creature.addSubType(game, subType);
} }
} }
return true; return true;

View file

@ -1,42 +1,37 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.Mana; import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility; import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility; import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition; import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect; import mage.abilities.effects.common.TapSourceEffect;
import mage.abilities.effects.common.counter.AddCountersSourceEffect; import mage.abilities.effects.common.counter.AddCountersSourceEffect;
import mage.abilities.effects.common.counter.RemoveCounterSourceEffect; import mage.abilities.effects.common.counter.RemoveCounterSourceEffect;
import mage.abilities.mana.SimpleManaAbility; import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration;
import mage.constants.Layer;
import static mage.constants.Layer.TypeChangingEffects_4;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class ArixmethesSlumberingIsle extends CardImpl { public final class ArixmethesSlumberingIsle extends CardImpl {
private static final Condition condition
= new SourceHasCounterCondition(CounterType.SLUMBER, 1, Integer.MAX_VALUE);
public ArixmethesSlumberingIsle(UUID ownerId, CardSetInfo setInfo) { public ArixmethesSlumberingIsle(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{U}");
@ -46,15 +41,18 @@ public final class ArixmethesSlumberingIsle extends CardImpl {
this.toughness = new MageInt(12); this.toughness = new MageInt(12);
// Arixmethes, Slumbering Isle enters the battlefield tapped with five slumber counters on it. // Arixmethes, Slumbering Isle enters the battlefield tapped with five slumber counters on it.
this.addAbility(new EntersBattlefieldTappedAbility()); Ability ability = new EntersBattlefieldAbility(
Effect effect = new AddCountersSourceEffect(CounterType.SLUMBER.createInstance(5)); new TapSourceEffect(true), false, null,
this.addAbility(new EntersBattlefieldAbility(effect, "with five slumber counters")); "{this} enters the battlefield tapped with five slumber counters on it", null
);
ability.addEffect(new AddCountersSourceEffect(CounterType.SLUMBER.createInstance(5)));
this.addAbility(ability);
// As long as Arixmethes, Slumbering Isle has a slumber counter on it, it's a land. // As long as Arixmethes, Slumbering Isle has a slumber counter on it, it's a land.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect( this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new ArixmethesIsLandEffect(), new ArixmethesIsLandEffect(), condition,
new SourceHasCounterCondition(CounterType.SLUMBER, 1, Integer.MAX_VALUE), "As long as {this} has a slumber counter on it, it's a land"
"As long as {this} has a slumber counter on it, it's a land"))); )));
// Whenever you cast a spell, you may remove a slumber counter from Arixmethes. // Whenever you cast a spell, you may remove a slumber counter from Arixmethes.
this.addAbility(new SpellCastControllerTriggeredAbility(new RemoveCounterSourceEffect(CounterType.SLUMBER.createInstance(1)), true)); this.addAbility(new SpellCastControllerTriggeredAbility(new RemoveCounterSourceEffect(CounterType.SLUMBER.createInstance(1)), true));
@ -75,44 +73,28 @@ public final class ArixmethesSlumberingIsle extends CardImpl {
class ArixmethesIsLandEffect extends ContinuousEffectImpl { class ArixmethesIsLandEffect extends ContinuousEffectImpl {
public ArixmethesIsLandEffect() { ArixmethesIsLandEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
this.staticText = "As long as {this} has a slumber counter on it, it's a land";
} }
public ArixmethesIsLandEffect(final ArixmethesIsLandEffect effect) { private ArixmethesIsLandEffect(final ArixmethesIsLandEffect effect) {
super(effect); super(effect);
} }
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override @Override
public ArixmethesIsLandEffect copy() { public ArixmethesIsLandEffect copy() {
return new ArixmethesIsLandEffect(this); return new ArixmethesIsLandEffect(this);
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
if (permanent != null) {
switch (layer) {
case TypeChangingEffects_4:
permanent.getCardType().clear();
permanent.addCardType(CardType.LAND);
permanent.getSubtype(game).clear();
break;
}
return true;
}
return false; return false;
} }
permanent.getCardType().clear();
@Override permanent.addCardType(CardType.LAND);
public boolean hasLayer(Layer layer) { permanent.removeAllSubTypes(game);
return layer == Layer.TypeChangingEffects_4; return true;
} }
} }

View file

@ -90,7 +90,7 @@ class AshayaSoulOfTheWildEffect extends ContinuousEffectImpl {
permanent.addCardType(CardType.LAND); permanent.addCardType(CardType.LAND);
} }
if (!permanent.hasSubtype(SubType.FOREST, game)) { if (!permanent.hasSubtype(SubType.FOREST, game)) {
permanent.getSubtype(game).add(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);
} }

View file

@ -1,7 +1,6 @@
package mage.cards.a; package mage.cards.a;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility; import mage.abilities.LoyaltyAbility;
@ -24,8 +23,9 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget; import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil; import mage.util.CardUtil;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class AshiokNightmareWeaver extends CardImpl { public final class AshiokNightmareWeaver extends CardImpl {
@ -149,7 +149,7 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect {
class AshiokNightmareWeaverAddTypeEffect extends ContinuousEffectImpl { class AshiokNightmareWeaverAddTypeEffect extends ContinuousEffectImpl {
public AshiokNightmareWeaverAddTypeEffect() { public AshiokNightmareWeaverAddTypeEffect() {
super(Duration.Custom, Outcome.Neutral); super(Duration.Custom, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "That creature is a Nightmare in addition to its other types"; staticText = "That creature is a Nightmare in addition to its other types";
} }
@ -162,34 +162,16 @@ class AshiokNightmareWeaverAddTypeEffect extends ContinuousEffectImpl {
return new AshiokNightmareWeaverAddTypeEffect(this); return new AshiokNightmareWeaverAddTypeEffect(this);
} }
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (creature != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
creature.getSubtype(game).add(SubType.NIGHTMARE);
}
break;
}
return true;
} else {
this.used = true;
}
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (creature == null) {
this.used = true;
return false; return false;
} }
creature.addSubType(game, SubType.NIGHTMARE);
@Override return true;
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
} }
} }
class AshiokNightmareWeaverExileAllEffect extends OneShotEffect { class AshiokNightmareWeaverExileAllEffect extends OneShotEffect {

View file

@ -22,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
this.addAbility(FlyingAbility.getInstance()); this.addAbility(FlyingAbility.getInstance());
} }

View file

@ -1,10 +1,7 @@
package mage.cards.b; package mage.cards.b;
import java.util.UUID;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostTargetEffect; import mage.abilities.effects.common.continuous.BoostTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect; import mage.abilities.effects.common.continuous.GainAllCreatureTypesTargetEffect;
import mage.abilities.keyword.ChangelingAbility; import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -13,8 +10,9 @@ import mage.constants.Duration;
import mage.constants.SubType; import mage.constants.SubType;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class BladesOfVelisVel extends CardImpl { public final class BladesOfVelisVel extends CardImpl {
@ -24,14 +22,14 @@ public final class BladesOfVelisVel extends CardImpl {
this.subtype.add(SubType.SHAPESHIFTER); this.subtype.add(SubType.SHAPESHIFTER);
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); 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.
Effect effect = new BoostTargetEffect(2,0, Duration.EndOfTurn); this.getSpellAbility().addEffect(new BoostTargetEffect(2, 0, Duration.EndOfTurn)
effect.setText("Up to two target creatures each get +2/+0"); .setText("Up to two target creatures each get +2/+0"));
this.getSpellAbility().addEffect(effect); this.getSpellAbility().addEffect(new GainAllCreatureTypesTargetEffect(Duration.EndOfTurn)
effect = new GainAbilityTargetEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn, "and gain all creature types until end of turn"); .setText("and gain all creature types until end of turn"));
this.getSpellAbility().addEffect(effect);
this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2)); this.getSpellAbility().addTarget(new TargetCreaturePermanent(0, 2));
} }

View file

@ -72,7 +72,7 @@ public final class BloodMoon extends CardImpl {
// 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.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(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);
break; break;

View file

@ -85,7 +85,7 @@ class BludgeonBrawlAddSubtypeEffect extends ContinuousEffectImpl {
List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game); List<Permanent> permanents = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), game);
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
if (permanent != null) { if (permanent != null) {
permanent.getSubtype(game).add(SubType.EQUIPMENT); permanent.addSubType(game, SubType.EQUIPMENT);
affectedPermanents.add(permanent.getId()); affectedPermanents.add(permanent.getId());
} }
} }

View file

@ -144,8 +144,8 @@ class BronzehideLionContinuousEffect extends ContinuousEffectImpl {
case TypeChangingEffects_4: case TypeChangingEffects_4:
lion.getCardType().clear(); lion.getCardType().clear();
lion.addCardType(CardType.ENCHANTMENT); lion.addCardType(CardType.ENCHANTMENT);
lion.getSubtype(game).clear(); lion.removeAllSubTypes(game);
lion.getSubtype(game).add(SubType.AURA); lion.addSubType(game, SubType.AURA);
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
List<Ability> toRemove = new ArrayList<>(); List<Ability> toRemove = new ArrayList<>();

View file

@ -30,6 +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(ChangelingAbility.getInstance()); 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.

View file

@ -1,12 +1,9 @@
package mage.cards.c; package mage.cards.c;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.OnEventTriggeredAbility; import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.EnchantAbility;
import mage.cards.*; import mage.cards.*;
import mage.constants.CardType; import mage.constants.CardType;
@ -15,21 +12,18 @@ 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.Predicate;
import mage.filter.predicate.Predicates;
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;
import mage.players.Player; import mage.players.Player;
import mage.target.TargetCard; import mage.target.TargetCard;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author North * @author North
*/ */
public final class CallToTheKindred extends CardImpl { public final class CallToTheKindred extends CardImpl {
@ -43,6 +37,7 @@ public final class CallToTheKindred extends CardImpl {
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature)); this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.addAbility(new EnchantAbility(auraTarget.getTargetName())); this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// At the beginning of your upkeep, you may look at the top five cards of your library. // At the beginning of your upkeep, you may look at the top five cards of your library.
// If you do, you may put a creature card that shares a creature type with enchanted creature from among them onto the battlefield, // If you do, you may put a creature card that shares a creature type with enchanted creature from among them onto the battlefield,
// then you put the rest of those cards on the bottom of your library in any order. // then you put the rest of those cards on the bottom of your library in any order.
@ -61,12 +56,14 @@ public final class CallToTheKindred extends CardImpl {
class CallToTheKindredEffect extends OneShotEffect { class CallToTheKindredEffect extends OneShotEffect {
public CallToTheKindredEffect() { CallToTheKindredEffect() {
super(Outcome.PutCreatureInPlay); super(Outcome.PutCreatureInPlay);
this.staticText = "look at the top five cards of your library. If you do, you may put a creature card that shares a creature type with enchanted creature from among them onto the battlefield, then you put the rest of those cards on the bottom of your library in any order"; this.staticText = "look at the top five cards of your library. If you do, you may put a creature card " +
"that shares a creature type with enchanted creature from among them onto the battlefield, " +
"then you put the rest of those cards on the bottom of your library in any order";
} }
public CallToTheKindredEffect(final CallToTheKindredEffect effect) { private CallToTheKindredEffect(final CallToTheKindredEffect effect) {
super(effect); super(effect);
} }
@ -90,36 +87,33 @@ class CallToTheKindredEffect extends OneShotEffect {
} }
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5)); Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
controller.lookAtCards(enchantment.getIdName(), cards, game);
FilterCreatureCard filter = new FilterCreatureCard(); FilterCreatureCard filter = new FilterCreatureCard();
filter.add(new CallToTheKindredPredicate(creature));
if (!creature.getAbilities().contains(ChangelingAbility.getInstance())) { if (cards.count(filter, game) > 0) {
StringBuilder sb = new StringBuilder("creature card with at least one subtype from: "); TargetCard target = new TargetCardInLibrary(0, 1, filter);
List<Predicate<MageObject>> subtypes = new ArrayList<>(); controller.choose(Outcome.PutCreatureInPlay, cards, target, game);
for (SubType subtype : creature.getSubtype(game)) {
subtypes.add(subtype.getPredicate());
sb.append(subtype).append(", ");
}
filter.add(Predicates.or(subtypes));
sb.delete(sb.length() - 2, sb.length());
filter.setMessage(sb.toString());
} else {
filter.setMessage("creature card that shares a creature type with enchanted creature");
}
if (cards.count(filter, game) > 0 && controller.chooseUse(Outcome.DrawCard, "Do you wish to put a creature card onto the battlefield?", source, game)) {
TargetCard target = new TargetCard(Zone.LIBRARY, filter);
if (controller.choose(Outcome.PutCreatureInPlay, cards, target, game)) {
Card card = cards.get(target.getFirstTarget(), game); Card card = cards.get(target.getFirstTarget(), game);
if (card != null) { if (card != null) {
cards.remove(card); cards.remove(card);
controller.moveCards(card, Zone.BATTLEFIELD, source, game); controller.moveCards(card, Zone.BATTLEFIELD, source, game);
} }
} }
}
controller.putCardsOnBottomOfLibrary(cards, game, source, true); controller.putCardsOnBottomOfLibrary(cards, game, source, true);
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

@ -1,7 +1,6 @@
package mage.cards.c; package mage.cards.c;
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;
@ -21,8 +20,9 @@ import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent; import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class CaptivatingVampire extends CardImpl { public final class CaptivatingVampire extends CardImpl {
@ -90,11 +90,7 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl {
} }
break; break;
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { permanent.addSubType(game, SubType.VAMPIRE);
if (!permanent.hasSubtype(SubType.VAMPIRE, game)) {
permanent.getSubtype(game).add(SubType.VAMPIRE);
}
}
break; break;
} }
return true; return true;

View file

@ -1,7 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -18,14 +16,15 @@ import mage.filter.common.FilterLandPermanent;
import mage.filter.common.FilterNonlandPermanent; import mage.filter.common.FilterNonlandPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.command.CommandObject; import mage.game.command.CommandObject;
import mage.game.command.Commander;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.players.ManaPoolItem; import mage.players.ManaPoolItem;
import mage.players.Player; import mage.players.Player;
import mage.game.command.Commander;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class CelestialDawn extends CardImpl { public final class CelestialDawn extends CardImpl {
@ -89,8 +88,8 @@ 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).clear(); land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(SubType.PLAINS); land.addSubType(game, SubType.PLAINS);
break; break;
} }
} }

View file

@ -31,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// Protection from black // Protection from black

View file

@ -24,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// Haste // Haste

View file

@ -24,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// Champion a creature // Champion a creature

View file

@ -24,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// Changeling Outcast can't block and can't be blocked. // Changeling Outcast can't block and can't be blocked.

View file

@ -22,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
this.addAbility(VigilanceAbility.getInstance()); this.addAbility(VigilanceAbility.getInstance());
} }

View file

@ -23,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// Champion a creature // Champion a creature

View file

@ -1,7 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility; import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
@ -15,8 +13,9 @@ import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public final class ChimericCoils extends CardImpl { public final class ChimericCoils extends CardImpl {
@ -25,7 +24,7 @@ public final class ChimericCoils extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{1}");
// {X}{1}: Chimeric Coils becomes an X/X Construct artifact creature. Sacrifice it at the beginning of thhe next end step. // {X}{1}: Chimeric Coils becomes an X/X Construct artifact creature. Sacrifice it at the beginning of thhe next end step.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChimericCoilsEffect(), new ManaCostsImpl("{X}{1}")); Ability ability = new SimpleActivatedAbility(new ChimericCoilsEffect(), new ManaCostsImpl("{X}{1}"));
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect()))); ability.addEffect(new CreateDelayedTriggeredAbilityEffect(new AtTheBeginOfNextEndStepDelayedTriggeredAbility(new SacrificeSourceEffect())));
this.addAbility(ability); this.addAbility(ability);
} }
@ -43,8 +42,8 @@ public final class ChimericCoils extends CardImpl {
class ChimericCoilsEffect extends ContinuousEffectImpl { class ChimericCoilsEffect extends ContinuousEffectImpl {
public ChimericCoilsEffect() { public ChimericCoilsEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature); super(Duration.Custom, Outcome.BecomeCreature);
setText(); staticText = "{this} becomes an X/X Construct artifact creature";
} }
public ChimericCoilsEffect(final ChimericCoilsEffect effect) { public ChimericCoilsEffect(final ChimericCoilsEffect effect) {
@ -59,13 +58,19 @@ class ChimericCoilsEffect 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) {
return false;
}
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { if (!permanent.isArtifact()) {
permanent.addCardType(CardType.CREATURE); permanent.addCardType(CardType.ARTIFACT);
permanent.getSubtype(game).add(SubType.CONSTRUCT);
} }
if (!permanent.isCreature()) {
permanent.addCardType(CardType.CREATURE);
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.CONSTRUCT);
break; break;
case PTChangingEffects_7: case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) { if (sublayer == SubLayer.SetPT_7b) {
@ -76,18 +81,12 @@ class ChimericCoilsEffect extends ContinuousEffectImpl {
} }
return true; return true;
} }
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return false; return false;
} }
private void setText() {
staticText = duration.toString() + " {this} becomes an X/X Construct artifact creature";
}
@Override @Override
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,7 +1,5 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
@ -12,8 +10,9 @@ import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author Backfir3 * @author Backfir3
*/ */
public final class ChimericStaff extends CardImpl { public final class ChimericStaff extends CardImpl {
@ -22,7 +21,7 @@ public final class ChimericStaff extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
// {X}: Chimeric Staff becomes an X/X Construct artifact creature until end of turn. // {X}: Chimeric Staff becomes an X/X Construct artifact creature until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ChimericStaffEffect(), new ManaCostsImpl("{X}"))); this.addAbility(new SimpleActivatedAbility(new ChimericStaffEffect(), new ManaCostsImpl("{X}")));
} }
public ChimericStaff(final ChimericStaff card) { public ChimericStaff(final ChimericStaff card) {
@ -39,7 +38,7 @@ class ChimericStaffEffect extends ContinuousEffectImpl {
public ChimericStaffEffect() { public ChimericStaffEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature); super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText(); staticText = "{this} becomes an X/X Construct artifact creature until end of turn";
} }
public ChimericStaffEffect(final ChimericStaffEffect effect) { public ChimericStaffEffect(final ChimericStaffEffect effect) {
@ -54,37 +53,35 @@ class ChimericStaffEffect 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) {
return false;
}
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { if (!permanent.isArtifact()) {
permanent.addCardType(CardType.CREATURE); permanent.addCardType(CardType.ARTIFACT);
permanent.getSubtype(game).add(SubType.CONSTRUCT);
} }
if (!permanent.isCreature()) {
permanent.addCardType(CardType.CREATURE);
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.CONSTRUCT);
break; break;
case PTChangingEffects_7: case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) { if (sublayer == SubLayer.SetPT_7b) {
int xValue = source.getManaCostsToPay().getX(); int xValue = source.getManaCostsToPay().getX();
if (xValue != 0) {
permanent.getPower().setValue(xValue); permanent.getPower().setValue(xValue);
permanent.getToughness().setValue(xValue); permanent.getToughness().setValue(xValue);
} }
} }
}
return true; return true;
} }
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return false; return false;
} }
private void setText() {
staticText = duration.toString() + " {this} becomes an X/X Construct artifact creature";
}
@Override @Override
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,22 +1,20 @@
package mage.cards.c; package mage.cards.c;
import java.util.List;
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;
import mage.abilities.keyword.ChangelingAbility;
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.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.SubTypeList;
import java.util.List;
import java.util.UUID;
/** /**
*
* @author North * @author North
*/ */
public final class CoatOfArms extends CardImpl { public final class CoatOfArms extends CardImpl {
@ -56,7 +54,9 @@ class CoatOfArmsEffect extends ContinuousEffectImpl {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
List<Permanent> permanents = game.getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game); List<Permanent> permanents = game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game
);
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
int amount = getAmount(permanents, permanent, game); int amount = getAmount(permanents, permanent, game);
permanent.addPower(amount); permanent.addPower(amount);
@ -67,20 +67,9 @@ 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;
SubTypeList targetSubtype = target.getSubtype(game);
if (target.getAbilities().contains(ChangelingAbility.getInstance()) || target.isAllCreatureTypes()) {
return permanents.size() - 1;
}
for (Permanent permanent : permanents) { for (Permanent permanent : permanents) {
if (!permanent.getId().equals(target.getId())) { if (!permanent.getId().equals(target.getId()) && permanent.shareCreatureTypes(target, game)) {
for (SubType subtype : targetSubtype) {
if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) {
if (permanent.hasSubtype(subtype, game)) {
amount++; amount++;
break;
}
}
}
} }
} }
return amount; return amount;

View file

@ -77,7 +77,7 @@ public final class Conversion extends CardImpl {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (land.getSubtype(game).contains(SubType.MOUNTAIN)) { if (land.getSubtype(game).contains(SubType.MOUNTAIN)) {
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(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);
break; break;

View file

@ -1,7 +1,5 @@
package mage.cards.c; package mage.cards.c;
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;
@ -18,8 +16,9 @@ import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import java.util.UUID;
/** /**
*
* @author North * @author North
*/ */
public final class ConvincingMirage extends CardImpl { public final class ConvincingMirage extends CardImpl {
@ -32,8 +31,10 @@ public final class ConvincingMirage extends CardImpl {
TargetPermanent auraTarget = new TargetLandPermanent(); TargetPermanent auraTarget = new TargetLandPermanent();
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment)); this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
// As Convincing Mirage enters the battlefield, choose a basic land type. // As Convincing Mirage enters the battlefield, choose a basic land type.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral))); this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral)));
// Enchanted land is the chosen type. // Enchanted land is the chosen type.
Ability ability = new EnchantAbility(auraTarget.getTargetName()); Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability); this.addAbility(ability);
@ -53,7 +54,7 @@ public final class ConvincingMirage extends CardImpl {
class ConvincingMirageContinousEffect extends ContinuousEffectImpl { class ConvincingMirageContinousEffect extends ContinuousEffectImpl {
public ConvincingMirageContinousEffect() { public ConvincingMirageContinousEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "Enchanted land is the chosen type"; staticText = "Enchanted land is the chosen type";
} }
@ -67,53 +68,59 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public void init(Ability source, Game game) {
super.init(source, game);
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY));
switch (choice) {
case FOREST:
dependencyTypes.add(DependencyType.BecomeForest);
break;
case PLAINS:
dependencyTypes.add(DependencyType.BecomePlains);
break;
case MOUNTAIN:
dependencyTypes.add(DependencyType.BecomeMountain);
break;
case ISLAND:
dependencyTypes.add(DependencyType.BecomeIsland);
break;
case SWAMP:
dependencyTypes.add(DependencyType.BecomeSwamp);
break;
}
}
@Override
public boolean apply(Game game, Ability source) {
Permanent enchantment = game.getPermanent(source.getSourceId()); Permanent enchantment = game.getPermanent(source.getSourceId());
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY)); SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY));
if (enchantment != null && enchantment.getAttachedTo() != null && choice != null) { if (enchantment == null || enchantment.getAttachedTo() == null || choice == null) {
return false;
}
Permanent land = game.getPermanent(enchantment.getAttachedTo()); Permanent land = game.getPermanent(enchantment.getAttachedTo());
if (land != null) { if (land == null) {
switch (layer) { return false;
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
land.getSubtype(game).clear();
land.getSubtype(game).add(choice);
} }
break; land.getSubtype(game).removeAll(SubType.getLandTypes());
case AbilityAddingRemovingEffects_6: land.addSubType(game, choice);
if (sublayer == SubLayer.NA) { land.removeAllAbilities(source.getSourceId(), game);
land.getAbilities().clear(); switch (choice) {
if (choice.equals(SubType.FOREST)) { case FOREST:
land.addAbility(new GreenManaAbility(), source.getSourceId(), game); land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.PLAINS)) { case PLAINS:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.MOUNTAIN)) { case MOUNTAIN:
land.addAbility(new RedManaAbility(), source.getSourceId(), game); land.addAbility(new RedManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.ISLAND)) { case ISLAND:
land.addAbility(new BlueManaAbility(), source.getSourceId(), game); land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.SWAMP)) { case SWAMP:
land.addAbility(new BlackManaAbility(), source.getSourceId(), game); land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
break; break;
} }
return true; return true;
} }
} }
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
}
}

View file

@ -1,25 +1,26 @@
package mage.cards.c; package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlashbackAbility; import mage.abilities.keyword.FlashbackAbility;
import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceImpl; import mage.choices.ChoiceCardType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.TimingRule; import mage.constants.TimingRule;
import mage.constants.Zone; import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import java.util.Arrays;
import java.util.UUID;
import java.util.stream.Collectors;
/** /**
*
* @author nantuko * @author nantuko
*/ */
public final class CreepingRenaissance extends CardImpl { public final class CreepingRenaissance extends CardImpl {
@ -58,40 +59,27 @@ class CreepingRenaissanceEffect extends OneShotEffect {
@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) {
Choice typeChoice = new ChoiceImpl();
typeChoice.setMessage("Choose permanent type");
typeChoice.getChoices().add(CardType.ARTIFACT.toString());
typeChoice.getChoices().add(CardType.CREATURE.toString());
typeChoice.getChoices().add(CardType.ENCHANTMENT.toString());
typeChoice.getChoices().add(CardType.LAND.toString());
typeChoice.getChoices().add(CardType.PLANESWALKER.toString());
if (controller.choose(Outcome.ReturnToHand, typeChoice, game)) {
String typeName = typeChoice.getChoice();
CardType chosenType = null;
for (CardType cardType : CardType.values()) {
if (cardType.toString().equals(typeName)) {
chosenType = cardType;
}
}
if (chosenType != null) {
for (Card card : controller.getGraveyard().getCards(game)) {
if (card.getCardType().contains(chosenType)) {
card.moveToZone(Zone.HAND, source.getSourceId(), game, false);
}
}
return true;
}
}
}
return false; return false;
} }
Choice typeChoice = new ChoiceCardType(true, Arrays.stream(CardType.values()).filter(CardType::isPermanentType).collect(Collectors.toList()));
typeChoice.setMessage("Choose a permanent type");
if (!controller.choose(Outcome.ReturnToHand, typeChoice, game)) {
return false;
}
String typeName = typeChoice.getChoice();
CardType chosenType = CardType.fromString(typeChoice.getChoice());
if (chosenType == null) {
return false;
}
FilterCard filter = new FilterCard(chosenType.toString().toLowerCase() + " card");
filter.add(chosenType.getPredicate());
return controller.moveCards(controller.getGraveyard().getCards(filter, source.getSourceId(), controller.getId(), game), Zone.HAND, source, game);
}
@Override @Override
public CreepingRenaissanceEffect copy() { public CreepingRenaissanceEffect copy() {
return new CreepingRenaissanceEffect(this); return new CreepingRenaissanceEffect(this);
} }
} }

View file

@ -28,6 +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(ChangelingAbility.getInstance()); 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());

View file

@ -1,52 +1,40 @@
package mage.cards.c; package mage.cards.c;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl; import mage.abilities.costs.CostImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect; import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
import mage.abilities.keyword.ChangelingAbility; 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.Outcome; import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.common.FilterControlledCreaturePermanent; import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreatureCard; import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate; import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledPermanent; import mage.target.common.TargetControlledPermanent;
import java.util.ArrayList; import java.util.HashSet;
import java.util.List; import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author spjspj * @author spjspj
*/ */
public final class CrypticGateway extends CardImpl { public final class CrypticGateway extends CardImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control");
static {
filter.add(Predicates.not(TappedPredicate.instance));
}
TargetControlledPermanent target;
public CrypticGateway(UUID ownerId, CardSetInfo setInfo) { public CrypticGateway(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
// Tap two untapped creatures you control: You may put a creature card from your hand that shares a creature type with each creature tapped this way onto the battlefield. // Tap two untapped creatures you control: You may put a creature card from your hand that shares a creature type with each creature tapped this way onto the battlefield.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new CrypticGatewayEffect(), new CrypticGatewayCost(new TargetControlledPermanent(filter)))); this.addAbility(new SimpleActivatedAbility(new CrypticGatewayEffect(), new CrypticGatewayCost()));
} }
public CrypticGateway(final CrypticGateway card) { public CrypticGateway(final CrypticGateway card) {
@ -61,29 +49,28 @@ public final class CrypticGateway extends CardImpl {
class CrypticGatewayCost extends CostImpl { class CrypticGatewayCost extends CostImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control"); private static final FilterControlledCreaturePermanent filter
private UUID targetCreatureId = null; = new FilterControlledCreaturePermanent("untapped creatures you control");
private UUID targetCreatureId2 = null;
TargetControlledPermanent target;
static { static {
filter.add(Predicates.not(TappedPredicate.instance)); filter.add(Predicates.not(TappedPredicate.instance));
} }
public CrypticGatewayCost(TargetControlledPermanent target) { private final TargetControlledPermanent target = new TargetControlledPermanent(2, filter);
this.target = target; private CrypticGatewayPredicate predicate;
public CrypticGatewayCost() {
this.text = "Tap two untapped creatures you control"; this.text = "Tap two untapped creatures you control";
} }
public CrypticGatewayCost(final CrypticGatewayCost cost) { public CrypticGatewayCost(final CrypticGatewayCost cost) {
super(cost); super(cost);
this.target = cost.target.copy();
} }
@Override @Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) { public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
int numTargets = 0; int numTargets = 0;
Set<Permanent> permanents = new HashSet<>();
while (numTargets < 2 && target.choose(Outcome.Tap, controllerId, sourceId, game)) { while (numTargets < 2 && target.choose(Outcome.Tap, controllerId, sourceId, game)) {
for (UUID targetId : target.getTargets()) { for (UUID targetId : target.getTargets()) {
Permanent permanent = game.getPermanent(targetId); Permanent permanent = game.getPermanent(targetId);
@ -94,15 +81,12 @@ class CrypticGatewayCost extends CostImpl {
if (paid) { if (paid) {
numTargets++; numTargets++;
target.clearChosen(); target.clearChosen();
} permanents.add(permanent);
for (Effect effect : ability.getEffects()) {
if (targetCreatureId == null) {
targetCreatureId = permanent.getId();
} else if (targetCreatureId2 == null) {
targetCreatureId2 = permanent.getId();
} }
} }
} }
if (paid) {
this.predicate = new CrypticGatewayPredicate(permanents);
} }
return paid; return paid;
} }
@ -112,18 +96,14 @@ class CrypticGatewayCost extends CostImpl {
return target.canChoose(controllerId, game); return target.canChoose(controllerId, game);
} }
public CrypticGatewayPredicate getPredicate() {
return predicate;
}
@Override @Override
public CrypticGatewayCost copy() { public CrypticGatewayCost copy() {
return new CrypticGatewayCost(this); return new CrypticGatewayCost(this);
} }
public UUID getTargetCreatureId() {
return targetCreatureId;
}
public UUID getTargetCreatureId2() {
return targetCreatureId2;
}
} }
class CrypticGatewayEffect extends OneShotEffect { class CrypticGatewayEffect extends OneShotEffect {
@ -147,59 +127,33 @@ class CrypticGatewayEffect extends OneShotEffect {
if (source.getCosts() == null) { if (source.getCosts() == null) {
return false; return false;
} }
FilterCard filter = new FilterCreatureCard("creature card from your hand that shares a creature type with each creature tapped this way"); FilterCard filter = new FilterCreatureCard("creature card from your hand that shares a creature type with each creature tapped this way");
for (Cost cost : source.getCosts()) { for (Cost cost : source.getCosts()) {
if (cost instanceof CrypticGatewayCost) { if (cost instanceof CrypticGatewayCost) {
UUID id = ((CrypticGatewayCost) cost).getTargetCreatureId(); Predicate predicate = ((CrypticGatewayCost) cost).getPredicate();
UUID id2 = ((CrypticGatewayCost) cost).getTargetCreatureId2(); filter.add(predicate);
Permanent creature = game.getPermanentOrLKIBattlefield(id); return new PutCardFromHandOntoBattlefieldEffect(filter).apply(game, source);
Permanent creature2 = game.getPermanentOrLKIBattlefield(id2);
if (creature == null || creature2 == null) {
return false;
}
boolean commonSubType = false;
boolean changeling = false;
boolean changeling2 = false;
if (creature.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature.isAllCreatureTypes()) {
changeling = true;
}
if (creature2.getAbilities().containsKey(ChangelingAbility.getInstance().getId()) || creature2.isAllCreatureTypes()) {
changeling2 = true;
}
List<SubType.SubTypePredicate> subtypes = new ArrayList<>();
for (SubType subtype : creature.getSubtype(game)) {
if (creature2.hasSubtype(subtype, game) || changeling2) {
subtypes.add(subtype.getPredicate());
commonSubType = true;
} }
} }
for (SubType subtype : creature2.getSubtype(game)) {
if (creature.hasSubtype(subtype, game) || changeling) {
subtypes.add(subtype.getPredicate());
commonSubType = true;
}
}
if (changeling && changeling2) {
filter = new FilterCreatureCard("creature card from your hand that shares a creature type with each creature tapped this way");
} else if (commonSubType) {
filter.add(Predicates.or(subtypes));
}
if (commonSubType) {
PutCardFromHandOntoBattlefieldEffect putIntoPlay = new PutCardFromHandOntoBattlefieldEffect(filter);
putIntoPlay.apply(game, source);
}
}
}
return false; return false;
} }
} }
class CrypticGatewayPredicate implements Predicate<Card> {
private final Set<Permanent> permanents = new HashSet<>();
CrypticGatewayPredicate(Set<Permanent> permanents) {
this.permanents.addAll(permanents);
}
@Override
public boolean apply(Card input, Game game) {
for (Permanent permanent : permanents) {
if (!permanent.shareCreatureTypes(input, game)) {
return false;
}
}
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.shareSubtypes(permanent, game)) { if (card.shareCreatureTypes(permanent, game)) {
found = true; found = true;
break; break;
} }

View file

@ -1,20 +1,31 @@
package mage.cards.d; package mage.cards.d;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.keyword.ChangelingAbility; import mage.abilities.common.EntersBattlefieldControlledTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect;
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.ComparisonType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone;
import mage.filter.FilterPermanent;
import mage.filter.predicate.mageobject.ConvertedManaCostPredicate;
import java.util.UUID;
/** /**
*
* @author vereena42 & L_J * @author vereena42 & L_J
*/ */
public final class DrJuliusJumblemorph extends CardImpl { public final class DrJuliusJumblemorph extends CardImpl {
private static final FilterPermanent filter = new FilterPermanent("a host");
static {
filter.add(new ConvertedManaCostPredicate(ComparisonType.FEWER_THAN, -1));
}
public DrJuliusJumblemorph(UUID ownerId, CardSetInfo setInfo) { public DrJuliusJumblemorph(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{W}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{W}");
this.addSuperType(SuperType.LEGENDARY); this.addSuperType(SuperType.LEGENDARY);
@ -22,10 +33,17 @@ 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.addAbility(ChangelingAbility.getInstance()); this.setIsAllCreatureTypes(true);
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
this.addAbility(new EntersBattlefieldControlledTriggeredAbility(
new InfoEffect("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."), filter
));
} }
public DrJuliusJumblemorph(final DrJuliusJumblemorph card) { public DrJuliusJumblemorph(final DrJuliusJumblemorph card) {

View file

@ -48,7 +48,7 @@ public final class Dragonshift extends CardImpl {
.withColor("UR") .withColor("UR")
.withSubType(SubType.DRAGON) .withSubType(SubType.DRAGON)
.withAbility(FlyingAbility.getInstance()), .withAbility(FlyingAbility.getInstance()),
null, filter, Duration.EndOfTurn, true)); null, filter, Duration.EndOfTurn, true, false, true));
this.addAbility(ability); this.addAbility(ability);
} }

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.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
@ -19,8 +18,9 @@ import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class DragonsoulKnight extends CardImpl { public final class DragonsoulKnight extends CardImpl {
@ -37,12 +37,12 @@ public final class DragonsoulKnight extends CardImpl {
this.addAbility(FirstStrikeAbility.getInstance()); this.addAbility(FirstStrikeAbility.getInstance());
// {W}{U}{B}{R}{G}: Until end of turn, Dragonsoul Knight becomes a Dragon, gets +5/+3, and gains flying and trample. // {W}{U}{B}{R}{G}: Until end of turn, Dragonsoul Knight becomes a Dragon, gets +5/+3, and gains flying and trample.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new DragonsoulKnightEffect(), new ManaCostsImpl("{W}{U}{B}{R}{G}")); Ability ability = new SimpleActivatedAbility(new DragonsoulKnightEffect(), new ManaCostsImpl("{W}{U}{B}{R}{G}"));
Effect effect = new BoostSourceEffect(5, 3, Duration.EndOfTurn); Effect effect = new BoostSourceEffect(5, 3, Duration.EndOfTurn);
effect.setText("gets +5/+3"); effect.setText(", gets +5/+3");
ability.addEffect(effect); ability.addEffect(effect);
effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gains flying"); effect.setText(", and gains flying");
ability.addEffect(effect); ability.addEffect(effect);
effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn); effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and trample"); effect.setText("and trample");
@ -60,14 +60,14 @@ public final class DragonsoulKnight extends CardImpl {
return new DragonsoulKnight(this); return new DragonsoulKnight(this);
} }
private class DragonsoulKnightEffect extends ContinuousEffectImpl { private static class DragonsoulKnightEffect extends ContinuousEffectImpl {
public DragonsoulKnightEffect() { private DragonsoulKnightEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature); super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
setText(); staticText = "Until end of turn, {this} becomes a Dragon";
} }
public DragonsoulKnightEffect(final DragonsoulKnightEffect effect) { private DragonsoulKnightEffect(final DragonsoulKnightEffect effect) {
super(effect); super(effect);
} }
@ -77,34 +77,14 @@ public final class DragonsoulKnight extends CardImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) { if (permanent == null) {
return false; return false;
} }
switch (layer) { permanent.removeAllCreatureTypes(game);
case TypeChangingEffects_4: permanent.addSubType(game, SubType.DRAGON);
if (sublayer == SubLayer.NA) {
permanent.getSubtype(game).clear();
permanent.getSubtype(game).add(SubType.DRAGON);
}
break;
}
return true; return true;
} }
@Override
public boolean apply(Game game, Ability source) {
return false;
}
private void setText() {
staticText = "Until end of turn, {this} becomes a Dragon, ";
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
}
} }
} }

View file

@ -16,7 +16,6 @@ import mage.game.permanent.Permanent;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author brikr * @author brikr
*/ */
public final class DralnusCrusade extends CardImpl { public final class DralnusCrusade extends CardImpl {
@ -53,9 +52,7 @@ class DralnusCrusadeEffect extends ContinuousEffectImpl {
for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE_GOBLINS, source.getControllerId(), source.getSourceId(), game)) { for (Permanent permanent : game.getState().getBattlefield().getActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE_GOBLINS, source.getControllerId(), source.getSourceId(), game)) {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (!permanent.hasSubtype(SubType.ZOMBIE, game)) { permanent.addSubType(game, SubType.ZOMBIE);
permanent.getSubtype(game).add(SubType.ZOMBIE);
}
break; break;
case ColorChangingEffects_5: case ColorChangingEffects_5:
permanent.getColor(game).setColor(ObjectColor.BLACK); permanent.getColor(game).setColor(ObjectColor.BLACK);

View file

@ -123,9 +123,7 @@ class DranaTheLastBloodchiefSubtypeEffect extends ContinuousEffectImpl {
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent creature = mor.getPermanent(game); Permanent creature = mor.getPermanent(game);
if (creature != null) { if (creature != null) {
if (!creature.hasSubtype(SubType.VAMPIRE, game)) { creature.addSubType(game, SubType.VAMPIRE);
creature.getSubtype(game).add(SubType.VAMPIRE);
}
return true; return true;
} else { } else {
this.used = true; this.used = true;

View file

@ -26,6 +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(ChangelingAbility.getInstance()); 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.
@ -76,7 +77,7 @@ class EgoErasureLoseEffect extends ContinuousEffectImpl {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) { for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) {
Permanent permanent = it.next().getPermanent(game); Permanent permanent = it.next().getPermanent(game);
if (permanent != null) { if (permanent != null) {
permanent.getSubtype(game).retainAll(SubType.getLandTypes()); permanent.removeAllCreatureTypes(game);
} else { } else {
it.remove(); it.remove();
} }

View file

@ -1,8 +1,5 @@
package mage.cards.e; package mage.cards.e;
import java.util.Iterator;
import java.util.UUID;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -17,14 +14,15 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceBasicLandType; import mage.choices.ChoiceBasicLandType;
import mage.constants.*; import mage.constants.*;
import mage.filter.common.FilterControlledLandPermanent; import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledPermanent;
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;
import java.util.Iterator;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class ElsewhereFlask extends CardImpl { public final class ElsewhereFlask extends CardImpl {
@ -36,7 +34,7 @@ public final class ElsewhereFlask extends CardImpl {
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
// Sacrifice Elsewhere Flask: Choose a basic land type. Each land you control becomes that type until end of turn. // Sacrifice Elsewhere Flask: Choose a basic land type. Each land you control becomes that type until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElsewhereFlaskEffect(), new SacrificeSourceCost())); this.addAbility(new SimpleActivatedAbility(new ElsewhereFlaskEffect(), new SacrificeSourceCost()));
} }
public ElsewhereFlask(final ElsewhereFlask card) { public ElsewhereFlask(final ElsewhereFlask card) {
@ -80,13 +78,11 @@ class ElsewhereFlaskEffect extends OneShotEffect {
class ElsewhereFlaskContinuousEffect extends ContinuousEffectImpl { class ElsewhereFlaskContinuousEffect extends ContinuousEffectImpl {
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent(); ElsewhereFlaskContinuousEffect() {
super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
public ElsewhereFlaskContinuousEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
} }
public ElsewhereFlaskContinuousEffect(final ElsewhereFlaskContinuousEffect effect) { private ElsewhereFlaskContinuousEffect(final ElsewhereFlaskContinuousEffect effect) {
super(effect); super(effect);
} }
@ -98,64 +94,68 @@ class ElsewhereFlaskContinuousEffect extends ContinuousEffectImpl {
@Override @Override
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) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
affectedObjectList.add(new MageObjectReference(permanent, game));
}
}
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_ElsewhereFlask")); SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_ElsewhereFlask"));
if (choice != null) { switch (choice) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { case FOREST:
Permanent land = it.next().getPermanent(game); dependencyTypes.add(DependencyType.BecomeForest);
if (land != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
land.getSubtype(game).clear();
land.getSubtype(game).add(choice);
}
break; break;
case AbilityAddingRemovingEffects_6: case PLAINS:
if (sublayer == SubLayer.NA) { dependencyTypes.add(DependencyType.BecomePlains);
land.getAbilities().clear(); break;
if (choice.equals(SubType.FOREST)) { case MOUNTAIN:
land.addAbility(new GreenManaAbility(), source.getSourceId(), game); dependencyTypes.add(DependencyType.BecomeMountain);
} break;
if (choice.equals(SubType.PLAINS)) { case ISLAND:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); dependencyTypes.add(DependencyType.BecomeIsland);
} break;
if (choice.equals(SubType.MOUNTAIN)) { case SWAMP:
land.addAbility(new RedManaAbility(), source.getSourceId(), game); dependencyTypes.add(DependencyType.BecomeSwamp);
}
if (choice.equals(SubType.ISLAND)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.SWAMP)) {
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
break; break;
} }
} else { if (this.affectedObjectsSet) {
it.remove(); game.getBattlefield()
.getActivePermanents(
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
source.getControllerId(), source.getSourceId(), game
).stream()
.map(permanent -> new MageObjectReference(permanent, game))
.forEach(affectedObjectList::add);
} }
} }
return true;
}
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_ElsewhereFlask"));
if (choice == null) {
return false; return false;
} }
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) {
@Override Permanent land = it.next().getPermanent(game);
public boolean hasLayer(Layer layer) { if (land == null) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; it.remove();
continue;
}
land.getSubtype(game).removeAll(SubType.getLandTypes());
land.addSubType(game, choice);
land.removeAllAbilities(source.getSourceId(), game);
switch (choice) {
case FOREST:
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break;
case PLAINS:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
break;
case MOUNTAIN:
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
case ISLAND:
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
break;
case SWAMP:
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
break;
}
}
return true;
} }
} }

View file

@ -1,19 +1,18 @@
package mage.cards.e; package mage.cards.e;
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;
import mage.abilities.effects.Effect;
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.FilterPermanent; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class EnchantedEvening extends CardImpl { public final class EnchantedEvening extends CardImpl {
@ -22,11 +21,7 @@ public final class EnchantedEvening extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W/U}{W/U}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{W/U}{W/U}");
// All permanents are enchantments in addition to their other types. // All permanents are enchantments in addition to their other types.
Effect effect = new EnchangedEveningEffect(CardType.ENCHANTMENT, this.addAbility(new SimpleStaticAbility(new EnchangedEveningEffect()));
Duration.WhileOnBattlefield, new FilterPermanent());
effect.setText("All permanents are enchantments in addition to their other types");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
} }
public EnchantedEvening(final EnchantedEvening card) { public EnchantedEvening(final EnchantedEvening card) {
@ -39,31 +34,27 @@ public final class EnchantedEvening extends CardImpl {
} }
// need to be enclosed class for dependent check of continuous effects // need to be enclosed class for dependent check of continuous effects
static class EnchangedEveningEffect extends ContinuousEffectImpl { private static class EnchangedEveningEffect extends ContinuousEffectImpl {
private final CardType addedCardType; private EnchangedEveningEffect() {
private final FilterPermanent filter; super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
public EnchangedEveningEffect(CardType addedCardType, Duration duration, FilterPermanent filter) {
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
this.addedCardType = addedCardType;
this.filter = filter;
this.dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); this.dependencyTypes.add(DependencyType.EnchantmentAddingRemoving);
this.dependencyTypes.add(DependencyType.AuraAddingRemoving); this.dependencyTypes.add(DependencyType.AuraAddingRemoving);
this.staticText = "All permanents are enchantments in addition to their other types";
} }
public EnchangedEveningEffect(final EnchangedEveningEffect effect) { private EnchangedEveningEffect(final EnchangedEveningEffect effect) {
super(effect); super(effect);
this.addedCardType = effect.addedCardType;
this.filter = effect.filter;
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { for (Permanent permanent : game.getBattlefield().getActivePermanents(
if (permanent != null StaticFilters.FILTER_PERMANENT, source.getControllerId(),
&& !permanent.getCardType().contains(addedCardType)) { source.getSourceId(), game
permanent.addCardType(addedCardType); )) {
if (permanent != null) {
permanent.addCardType(CardType.ENCHANTMENT);
} }
} }
return true; return true;

View file

@ -9,8 +9,8 @@ import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect; import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.hint.common.MyTurnHint; import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.mana.ActivatedManaAbilityImpl; import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.cards.CardImpl; import mage.cards.CardImpl;
@ -127,7 +127,7 @@ class ChimericStaffEffect extends ContinuousEffectImpl {
public ChimericStaffEffect() { public ChimericStaffEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature); super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText(); staticText = "{this} becomes an X/X Construct artifact creature until end of turn";
} }
public ChimericStaffEffect(final ChimericStaffEffect effect) { public ChimericStaffEffect(final ChimericStaffEffect effect) {
@ -142,37 +142,35 @@ class ChimericStaffEffect 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) {
return false;
}
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { if (!permanent.isArtifact()) {
permanent.addCardType(CardType.CREATURE); permanent.addCardType(CardType.ARTIFACT);
permanent.getSubtype(game).add(SubType.CONSTRUCT);
} }
if (!permanent.isCreature()) {
permanent.addCardType(CardType.CREATURE);
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.CONSTRUCT);
break; break;
case PTChangingEffects_7: case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) { if (sublayer == SubLayer.SetPT_7b) {
int xValue = source.getManaCostsToPay().getX(); int xValue = source.getManaCostsToPay().getX();
if (xValue != 0) {
permanent.getPower().setValue(xValue); permanent.getPower().setValue(xValue);
permanent.getToughness().setValue(xValue); permanent.getToughness().setValue(xValue);
} }
} }
}
return true; return true;
} }
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return false; return false;
} }
private void setText() {
staticText = duration.toString() + " {this} becomes an X/X Construct artifact creature";
}
@Override @Override
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

@ -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.shareSubtypes(permanent, game)) { if (!permanent.isTapped() && targetPermanent.shareCreatureTypes(permanent, game)) {
permanent.tap(game); permanent.tap(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.shareSubtypes(permanent, game)) { if (permanent.isTapped() && targetPermanent.shareCreatureTypes(permanent, game)) {
permanent.untap(game); permanent.untap(game);
} }
} }

View file

@ -27,6 +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(ChangelingAbility.getInstance()); 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.

View file

@ -22,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
this.addAbility(TrampleAbility.getInstance()); this.addAbility(TrampleAbility.getInstance());
} }

View file

@ -26,6 +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(ChangelingAbility.getInstance()); 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

@ -74,7 +74,7 @@ public final class Glaciers extends CardImpl {
// 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.getSubtype(game).contains(SubType.MOUNTAIN)) {
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(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);
break; break;

View file

@ -54,15 +54,15 @@ class GlasspoolMimicApplier extends ApplyToPermanent {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
permanent.getSubtype(game).add(SubType.SHAPESHIFTER); permanent.addSubType(game, SubType.SHAPESHIFTER);
permanent.getSubtype(game).add(SubType.ROGUE); permanent.addSubType(game, SubType.ROGUE);
return true; return true;
} }
@Override @Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
mageObject.getSubtype(game).add(SubType.SHAPESHIFTER); mageObject.addSubType(game, SubType.SHAPESHIFTER);
mageObject.getSubtype(game).add(SubType.ROGUE); mageObject.addSubType(game, SubType.ROGUE);
return true; return true;
} }
} }

View file

@ -88,8 +88,8 @@ class GodPharaohsGiftEffect extends OneShotEffect {
token.getPower().modifyBaseValue(4); token.getPower().modifyBaseValue(4);
token.getToughness().modifyBaseValue(4); token.getToughness().modifyBaseValue(4);
token.getColor(game).setColor(ObjectColor.BLACK); token.getColor(game).setColor(ObjectColor.BLACK);
token.getSubtype(game).clear(); token.removeAllCreatureTypes(game);
token.getSubtype(game).add(SubType.ZOMBIE); token.addSubType(game, SubType.ZOMBIE);
if (token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId())) { if (token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId())) {
Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken()); Permanent tokenPermanent = game.getPermanent(token.getLastAddedToken());
if (tokenPermanent != null) { if (tokenPermanent != null) {

View file

@ -27,6 +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(ChangelingAbility.getInstance()); 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.

View file

@ -1,9 +1,6 @@
package mage.cards.g; package mage.cards.g;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost; import mage.abilities.costs.common.DiscardTargetCost;
@ -24,8 +21,11 @@ import mage.game.permanent.Permanent;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/** /**
*
* @author BetaSteward * @author BetaSteward
*/ */
public final class GrimoireOfTheDead extends CardImpl { public final class GrimoireOfTheDead extends CardImpl {
@ -121,14 +121,10 @@ class GrimoireOfTheDeadEffect2 extends ContinuousEffectImpl {
if (permanent != null) { if (permanent != null) {
switch (layer) { switch (layer) {
case ColorChangingEffects_5: case ColorChangingEffects_5:
if (sublayer == SubLayer.NA) {
permanent.getColor(game).setBlack(true); permanent.getColor(game).setBlack(true);
}
break; break;
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { permanent.addSubType(game, SubType.ZOMBIE);
permanent.getSubtype(game).add(SubType.ZOMBIE);
}
break; break;
} }
return true; return true;

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.shareSubtypes(card, game)) { if (card != null && card.isCreature() && equipped.shareCreatureTypes(card, game)) {
controller.moveCardToHandWithInfo(card, source.getSourceId(), game, true); controller.moveCardToHandWithInfo(card, source.getSourceId(), game, true);
break; break;
} else { } else {

View file

@ -97,8 +97,8 @@ class HourOfEternityEffect extends OneShotEffect {
token.getPower().modifyBaseValue(4); token.getPower().modifyBaseValue(4);
token.getToughness().modifyBaseValue(4); token.getToughness().modifyBaseValue(4);
token.getColor(game).setColor(ObjectColor.BLACK); token.getColor(game).setColor(ObjectColor.BLACK);
token.getSubtype(game).clear(); token.removeAllCreatureTypes(game);
token.getSubtype(game).add(SubType.ZOMBIE); token.addSubType(game, SubType.ZOMBIE);
token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId()); token.putOntoBattlefield(1, game, source.getSourceId(), source.getControllerId());
} }
} }

View file

@ -95,7 +95,7 @@ class IllusionaryTerrainEffect extends ContinuousEffectImpl {
// 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.getSubtype(game).contains(firstChoice)) {
land.getSubtype(game).removeAll(SubType.getLandTypes()); land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(secondChoice); land.addSubType(game, secondChoice);
land.removeAllAbilities(source.getSourceId(), game); land.removeAllAbilities(source.getSourceId(), game);
if (land.getSubtype(game).contains(SubType.FOREST)) { if (land.getSubtype(game).contains(SubType.FOREST)) {
this.dependencyTypes.add(DependencyType.BecomeForest); this.dependencyTypes.add(DependencyType.BecomeForest);

View file

@ -22,6 +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(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
} }

View file

@ -24,6 +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(ChangelingAbility.getInstance()); 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.

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.shareSubtypes(equipedCreature, game)) { if (perm.shareCreatureTypes(equipedCreature, game)) {
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

@ -70,18 +70,13 @@ class LifeAndLimbEffect extends ContinuousEffectImpl {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
permanent.addCardType(CardType.CREATURE); permanent.addCardType(CardType.CREATURE);
if (!permanent.hasSubtype(SubType.SAPROLING, game)) { permanent.addCardType(CardType.LAND);
permanent.getSubtype(game).add(SubType.SAPROLING); permanent.addSubType(game, SubType.SAPROLING);
}
// land abilities are intrinsic, so add them here, not in layer 6 // land abilities are intrinsic, so add them here, not in layer 6
if (!permanent.hasSubtype(SubType.FOREST, game)) { permanent.addSubType(game, SubType.FOREST);
permanent.getSubtype(game).add(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);
} }
}
permanent.addCardType(CardType.LAND);
break; break;
case ColorChangingEffects_5: case ColorChangingEffects_5:
permanent.getColor(game).setColor(ObjectColor.GREEN); permanent.getColor(game).setColor(ObjectColor.GREEN);

View file

@ -78,7 +78,7 @@ public final class MagusOfTheMoon extends CardImpl {
// 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.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(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);
break; break;

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.shareSubtypes(perm, game)) { if (permanent.shareCreatureTypes(perm, game)) {
foundCreatures++; foundCreatures++;
} }
} }

View file

@ -86,9 +86,7 @@ class MephidrossVampireEffect extends ContinuousEffectImpl {
creature.addAbility(new DealsDamageToACreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, false, false), source.getSourceId(), game); creature.addAbility(new DealsDamageToACreatureTriggeredAbility(new AddCountersSourceEffect(CounterType.P1P1.createInstance()), false, false, false), source.getSourceId(), game);
break; break;
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (!creature.hasSubtype(SubType.VAMPIRE, game)) { creature.addSubType(game, SubType.VAMPIRE);
creature.getSubtype(game).add(SubType.VAMPIRE);
}
break; break;
} }
} }

View file

@ -74,21 +74,22 @@ class ChooseACreature extends OneShotEffect {
if (sourceObject == null) { if (sourceObject == null) {
sourceObject = game.getObject(source.getSourceId()); sourceObject = game.getObject(source.getSourceId());
} }
if (controller != null if (controller == null
&& sourceObject != null) { || sourceObject == null) {
return false;
}
Target target = new TargetCreaturePermanent(); Target target = new TargetCreaturePermanent();
target.setNotTarget(true); target.setNotTarget(true);
if (target.canChoose(source.getSourceId(), controller.getId(), game)) { if (!target.canChoose(source.getSourceId(), controller.getId(), game)) {
return true;
}
controller.choose(Outcome.Copy, target, source.getSourceId(), game); controller.choose(Outcome.Copy, target, source.getSourceId(), game);
Permanent chosenPermanent = game.getPermanent(target.getFirstTarget()); Permanent chosenPermanent = game.getPermanent(target.getFirstTarget());
if (chosenPermanent != null) { if (chosenPermanent != null) {
game.getState().setValue(source.getSourceId().toString() + INFO_KEY, chosenPermanent.copy()); game.getState().setValue(source.getSourceId().toString() + INFO_KEY, chosenPermanent.copy());
} }
}
return true; return true;
} }
return false;
}
@Override @Override
public ChooseACreature copy() { public ChooseACreature copy() {
@ -108,14 +109,17 @@ class MetamorphicAlterationEffect extends ContinuousEffectImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Permanent enchantment = game.getPermanent(source.getSourceId()); Permanent enchantment = game.getPermanent(source.getSourceId());
Permanent copied = (Permanent) game.getState().getValue(source.getSourceId().toString() + ChooseACreature.INFO_KEY); Permanent copied = (Permanent) game.getState().getValue(source.getSourceId().toString() + ChooseACreature.INFO_KEY);
if (enchantment != null if (enchantment == null
&& copied != null) { || copied == null) {
return false;
}
Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
if (permanent != null if (permanent == null) {
&& layer == Layer.CopyEffects_1) { return false;
}
permanent.setName(copied.getName()); permanent.setName(copied.getName());
permanent.getManaCost().clear(); permanent.getManaCost().clear();
permanent.getManaCost().addAll(copied.getManaCost()); permanent.getManaCost().addAll(copied.getManaCost());
@ -128,10 +132,10 @@ class MetamorphicAlterationEffect extends ContinuousEffectImpl {
for (CardType cardType : copied.getCardType()) { for (CardType cardType : copied.getCardType()) {
permanent.addCardType(cardType); permanent.addCardType(cardType);
} }
permanent.getSubtype(game).retainAll(SubType.getLandTypes()); permanent.removeAllSubTypes(game);
for (SubType subType : copied.getSubtype(game)) { permanent.setIsAllCreatureTypes(copied.isAllCreatureTypes());
permanent.getSubtype(game).add(subType); 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()) {
@ -141,14 +145,6 @@ class MetamorphicAlterationEffect extends ContinuousEffectImpl {
permanent.getToughness().setValue(copied.getToughness().getBaseValue()); permanent.getToughness().setValue(copied.getToughness().getBaseValue());
return true; return true;
} }
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override @Override
public MetamorphicAlterationEffect copy() { public MetamorphicAlterationEffect copy() {

View file

@ -1,35 +1,29 @@
package mage.cards.m; package mage.cards.m;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue; import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.Effect; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessAllEffect; import mage.abilities.effects.common.continuous.SetPowerToughnessAllEffect;
import mage.abilities.keyword.ChangelingAbility; import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType; import mage.filter.StaticFilters;
import mage.constants.Duration; import mage.game.Game;
import mage.constants.Layer; import mage.game.permanent.Permanent;
import mage.constants.SubLayer;
import mage.constants.Zone; import java.util.Iterator;
import mage.filter.common.FilterControlledCreaturePermanent; import java.util.UUID;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public final class MirrorEntity extends CardImpl { public final class MirrorEntity extends CardImpl {
static private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Creatures you control");
public MirrorEntity(UUID ownerId, CardSetInfo setInfo) { public MirrorEntity(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.SHAPESHIFTER); this.subtype.add(SubType.SHAPESHIFTER);
@ -38,15 +32,15 @@ public final class MirrorEntity extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); 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.
DynamicValue variableMana = ManacostVariableValue.instance; Ability ability = new SimpleActivatedAbility(new SetPowerToughnessAllEffect(
Effect effect = new SetPowerToughnessAllEffect(variableMana, variableMana, Duration.EndOfTurn, filter, true); ManacostVariableValue.instance, ManacostVariableValue.instance,
effect.setText("Until end of turn, creatures you control have base power and toughness X/X"); Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURES, true
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new VariableManaCost()); ).setText("Until end of turn, creatures you control have base power and toughness X/X"), new VariableManaCost());
effect = new GainAbilityAllEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn, filter, false, Layer.TypeChangingEffects_4, SubLayer.NA); ability.addEffect(new MirrorEntityEffect());
effect.setText("and gain all creature types");
ability.addEffect(effect);
this.addAbility(ability); this.addAbility(ability);
} }
@ -59,3 +53,43 @@ public final class MirrorEntity extends CardImpl {
return new MirrorEntity(this); return new MirrorEntity(this);
} }
} }
class MirrorEntityEffect extends ContinuousEffectImpl {
MirrorEntityEffect() {
super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
staticText = "and gain all creature types";
}
private MirrorEntityEffect(final MirrorEntityEffect effect) {
super(effect);
}
@Override
public MirrorEntityEffect copy() {
return new MirrorEntityEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
for (Permanent perm : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURES, source.getControllerId(), source.getSourceId(), game
)) {
affectedObjectList.add(new MageObjectReference(perm, game));
}
}
@Override
public boolean apply(Game game, Ability source) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) {
Permanent permanent = it.next().getPermanent(game);
if (permanent == null) {
it.remove(); // no longer on the battlefield, remove reference to object
continue;
}
permanent.setIsAllCreatureTypes(true);
}
return true;
}
}

View file

@ -1,17 +1,18 @@
package mage.cards.m; package mage.cards.m;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.keyword.ChangelingAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.common.InfoEffect;
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.SubType; import mage.constants.SubType;
import mage.constants.SuperType; import mage.constants.SuperType;
import mage.constants.Zone;
import java.util.UUID;
/** /**
*
* @author vereena42 * @author vereena42
*/ */
public final class MistformUltimus extends CardImpl { public final class MistformUltimus extends CardImpl {
@ -25,7 +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.addAbility(ChangelingAbility.getInstance()); this.setIsAllCreatureTypes(true);
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) { public MistformUltimus(final MistformUltimus card) {

View file

@ -24,6 +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(ChangelingAbility.getInstance()); 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

@ -40,6 +40,7 @@ public final class MorophonTheBoundless extends CardImpl {
this.toughness = new MageInt(6); this.toughness = new MageInt(6);
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// As Morophon, the Boundless enters the battlefield, choose a creature type. // As Morophon, the Boundless enters the battlefield, choose a creature type.

View file

@ -36,6 +36,7 @@ public final class MothdustChangeling extends CardImpl {
this.power = new MageInt(1); this.power = new MageInt(1);
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new TapTargetCost(new TargetControlledPermanent(filter)))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn), new TapTargetCost(new TargetControlledPermanent(filter))));
} }

View file

@ -25,6 +25,7 @@ public final class NamelessInversion extends CardImpl {
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// Target creature gets +3/-3 and loses all creature types until end of turn. // Target creature gets +3/-3 and loses all creature types until end of turn.

View file

@ -1,7 +1,6 @@
package mage.cards.n; package mage.cards.n;
import java.util.UUID;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -29,8 +28,9 @@ import mage.target.Target;
import mage.target.common.TargetCardInGraveyard; import mage.target.common.TargetCardInGraveyard;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class Necromancy extends CardImpl { public final class Necromancy extends CardImpl {
@ -175,19 +175,13 @@ class NecromancyChangeAbilityEffect extends ContinuousEffectImpl implements Sour
if (permanent != null) { if (permanent != null) {
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { permanent.addSubType(game, SubType.AURA);
if (!permanent.hasSubtype(SubType.AURA, game)) {
permanent.getSubtype(game).add(SubType.AURA);
}
}
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) {
permanent.addAbility(newAbility, source.getSourceId(), game); permanent.addAbility(newAbility, source.getSourceId(), game);
permanent.getSpellAbility().getTargets().clear(); permanent.getSpellAbility().getTargets().clear();
permanent.getSpellAbility().getTargets().add(target); permanent.getSpellAbility().getTargets().add(target);
} }
}
return true; return true;
} }
this.discard(); this.discard();

View file

@ -152,7 +152,7 @@ class ChangeCreatureTypeTargetEffect extends ContinuousEffectImpl {
if (targetObject.hasSubtype(fromSubType, game)) { if (targetObject.hasSubtype(fromSubType, game)) {
targetObject.getSubtype(game).remove(fromSubType); targetObject.getSubtype(game).remove(fromSubType);
if (!targetObject.hasSubtype(toSubType, game)) { if (!targetObject.hasSubtype(toSubType, game)) {
targetObject.getSubtype(game).add(toSubType); targetObject.addSubType(game, toSubType);
} }
} }
break; break;

View file

@ -39,17 +39,23 @@ public final class NimDeathmantle extends CardImpl {
this.subtype.add(SubType.EQUIPMENT); this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+2, has intimidate, and is a black Zombie. // Equipped creature gets +2/+2, has intimidate, and is a black Zombie.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2))); Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT))); ability.addEffect(new GainAbilityAttachedEffect(
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardColorAttachedEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT, SubType.ZOMBIE))); ).setText(", has intimidate"));
ability.addEffect(new SetCardColorAttachedEffect(
ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT
).setText(", and is"));
ability.addEffect(new SetCardSubtypeAttachedEffect(
Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT, SubType.ZOMBIE
).setText("black Zombie").concatBy("a"));
this.addAbility(ability);
// Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach Nim Deathmantle to it. // Whenever a nontoken creature is put into your graveyard from the battlefield, you may pay {4}. If you do, return that card to the battlefield and attach Nim Deathmantle to it.
this.addAbility(new NimDeathmantleTriggeredAbility()); this.addAbility(new NimDeathmantleTriggeredAbility());
// Equip {4} // Equip {4}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4))); this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4)));
} }
public NimDeathmantle(final NimDeathmantle card) { public NimDeathmantle(final NimDeathmantle card) {

View file

@ -1,6 +1,5 @@
package mage.cards.n; package mage.cards.n;
import mage.Mana;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility; import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -17,8 +16,6 @@ import mage.game.permanent.Permanent;
import mage.target.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
@ -30,18 +27,18 @@ public final class NyleasPresence extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.subtype.add(SubType.AURA); this.subtype.add(SubType.AURA);
// Enchant land // Enchant land
TargetPermanent auraTarget = new TargetLandPermanent(); TargetPermanent auraTarget = new TargetLandPermanent();
this.getSpellAbility().addTarget(auraTarget); this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility)); this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
Ability ability = new EnchantAbility(auraTarget.getTargetName()); Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability); this.addAbility(ability);
// When Nylea's Presence enters the battlefield, draw a card. // When Nylea's Presence enters the battlefield, draw a card.
this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1))); this.addAbility(new EntersBattlefieldTriggeredAbility(new DrawCardSourceControllerEffect(1)));
// Enchanted land is every basic land type in addition to its other types.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new NyleasPresenceLandTypeEffect()));
// Enchanted land is every basic land type in addition to its other types.
this.addAbility(new SimpleStaticAbility(new NyleasPresenceLandTypeEffect()));
} }
public NyleasPresence(final NyleasPresence card) { public NyleasPresence(final NyleasPresence card) {
@ -56,22 +53,18 @@ public final class NyleasPresence extends CardImpl {
class NyleasPresenceLandTypeEffect extends ContinuousEffectImpl { class NyleasPresenceLandTypeEffect extends ContinuousEffectImpl {
protected List<SubType> landTypes = new ArrayList<>();
public NyleasPresenceLandTypeEffect() { public NyleasPresenceLandTypeEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
landTypes.addAll(SubType.getBasicLands());
this.staticText = "Enchanted land is every basic land type in addition to its other types"; this.staticText = "Enchanted land is every basic land type in addition to its other types";
dependencyTypes.add(DependencyType.BecomePlains);
dependencyTypes.add(DependencyType.BecomeIsland);
dependencyTypes.add(DependencyType.BecomeSwamp);
dependencyTypes.add(DependencyType.BecomeMountain);
dependencyTypes.add(DependencyType.BecomeForest);
} }
public NyleasPresenceLandTypeEffect(final NyleasPresenceLandTypeEffect effect) { public NyleasPresenceLandTypeEffect(final NyleasPresenceLandTypeEffect effect) {
super(effect); super(effect);
this.landTypes.addAll(effect.landTypes);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
} }
@Override @Override
@ -80,52 +73,22 @@ class NyleasPresenceLandTypeEffect extends ContinuousEffectImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Permanent enchantment = game.getPermanent(source.getSourceId()); Permanent enchantment = game.getPermanent(source.getSourceId());
if (enchantment != null && enchantment.getAttachedTo() != null) { if (enchantment == null || enchantment.getAttachedTo() == null) {
Permanent land = game.getPermanent(enchantment.getAttachedTo());
if (land != null) {
switch (layer) {
case AbilityAddingRemovingEffects_6:
Mana mana = new Mana();
for (Ability ability : land.getAbilities()) {
if (ability instanceof BasicManaAbility) {
for (Mana netMana : ((BasicManaAbility) ability).getNetMana(game)) {
mana.add(netMana);
}
}
}
if (mana.getGreen() == 0 && landTypes.contains(SubType.FOREST)) {
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
}
if (mana.getRed() == 0 && landTypes.contains(SubType.MOUNTAIN)) {
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
}
if (mana.getBlue() == 0 && landTypes.contains(SubType.ISLAND)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
if (mana.getWhite() == 0 && landTypes.contains(SubType.PLAINS)) {
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
}
if (mana.getBlack() == 0 && landTypes.contains(SubType.SWAMP)) {
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
break;
case TypeChangingEffects_4:
for (SubType subtype : landTypes) {
if (!land.hasSubtype(subtype, game)) {
land.getSubtype(game).add(subtype);
}
}
break;
}
}
}
return true; return true;
} }
Permanent land = game.getPermanent(enchantment.getAttachedTo());
@Override if (land == null) {
public boolean hasLayer(Layer layer) { return true;
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; }
land.getSubtype(game).removeAll(SubType.getBasicLands());
land.getSubtype(game).addAll(SubType.getBasicLands());
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
return true;
} }
} }

View file

@ -87,6 +87,8 @@ class OneWithTheStarsEffect extends ContinuousEffectImpl {
if (permanent == null) { if (permanent == null) {
return false; return false;
} }
permanent.setIsAllCreatureTypes(false);
permanent.getSubtype(game).retainAll(SubType.getEnchantmentTypes());
permanent.getCardType().clear(); permanent.getCardType().clear();
permanent.addCardType(CardType.ENCHANTMENT); permanent.addCardType(CardType.ENCHANTMENT);
return true; return true;

View file

@ -1,6 +1,5 @@
package mage.cards.o; package mage.cards.o;
import java.util.UUID;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -13,23 +12,16 @@ import mage.abilities.effects.common.continuous.SourceEffect;
import mage.abilities.keyword.ProtectionAbility; import mage.abilities.keyword.ProtectionAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.DependencyType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SetTargetPointer;
import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterSpell; import mage.filter.FilterSpell;
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.game.stack.Spell; import mage.game.stack.Spell;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class OpalTitan extends CardImpl { public final class OpalTitan extends CardImpl {
@ -98,7 +90,8 @@ class OpalTitanBecomesCreatureEffect extends ContinuousEffectImpl implements Sou
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
permanent.getCardType().clear(); permanent.getCardType().clear();
permanent.addCardType(CardType.CREATURE); permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).add(SubType.GIANT); permanent.removeAllSubTypes(game);
permanent.addSubType(game, SubType.GIANT);
} }
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:

View file

@ -1,7 +1,5 @@
package mage.cards.p; package mage.cards.p;
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;
@ -19,8 +17,9 @@ import mage.constants.*;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class ParagonOfTheAmesha extends CardImpl { public final class ParagonOfTheAmesha extends CardImpl {
@ -37,18 +36,17 @@ public final class ParagonOfTheAmesha extends CardImpl {
this.addAbility(FirstStrikeAbility.getInstance()); this.addAbility(FirstStrikeAbility.getInstance());
// {W}{U}{B}{R}{G}: Until end of turn, Paragon of the Amesha becomes an Angel, gets +3/+3, and gains flying and lifelink. // {W}{U}{B}{R}{G}: Until end of turn, Paragon of the Amesha becomes an Angel, gets +3/+3, and gains flying and lifelink.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ParagonOfTheAmeshaEffect(), new ManaCostsImpl("{W}{U}{B}{R}{G}")); Ability ability = new SimpleActivatedAbility(new ParagonOfTheAmeshaEffect(), new ManaCostsImpl("{W}{U}{B}{R}{G}"));
Effect effect = new BoostSourceEffect(3, 3, Duration.EndOfTurn); Effect effect = new BoostSourceEffect(3, 3, Duration.EndOfTurn);
effect.setText("gets +3/+3,"); effect.setText(", gets +3/+3");
ability.addEffect(effect); ability.addEffect(effect);
effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn); effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gains flying"); effect.setText(", and gains flying");
ability.addEffect(effect); ability.addEffect(effect);
effect = new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn); effect = new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and lifelink"); effect.setText("and lifelink");
ability.addEffect(effect); ability.addEffect(effect);
this.addAbility(ability); this.addAbility(ability);
} }
public ParagonOfTheAmesha(final ParagonOfTheAmesha card) { public ParagonOfTheAmesha(final ParagonOfTheAmesha card) {
@ -62,12 +60,12 @@ public final class ParagonOfTheAmesha extends CardImpl {
private static class ParagonOfTheAmeshaEffect extends ContinuousEffectImpl { private static class ParagonOfTheAmeshaEffect extends ContinuousEffectImpl {
public ParagonOfTheAmeshaEffect() { private ParagonOfTheAmeshaEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature); super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
setText(); staticText = "Until end of turn, {this} becomes an Angel";
} }
public ParagonOfTheAmeshaEffect(final ParagonOfTheAmeshaEffect effect) { private ParagonOfTheAmeshaEffect(final ParagonOfTheAmeshaEffect effect) {
super(effect); super(effect);
} }
@ -77,34 +75,14 @@ public final class ParagonOfTheAmesha extends CardImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId()); Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) { if (permanent == null) {
return false; return false;
} }
switch (layer) { permanent.removeAllCreatureTypes(game);
case TypeChangingEffects_4: permanent.addSubType(game, SubType.ANGEL);
if (sublayer == SubLayer.NA) {
permanent.getSubtype(game).clear();
permanent.getSubtype(game).add(SubType.ANGEL);
}
break;
}
return true; return true;
} }
@Override
public boolean apply(Game game, Ability source) {
return false;
}
private void setText() {
staticText = "Until end of turn, {this} becomes an Angel, ";
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
}
} }
} }

View file

@ -5,23 +5,18 @@ import mage.abilities.DelayedTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility; import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect; import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.keyword.ScryEffect; import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.mana.CommanderColorIdentityManaAbility; import mage.abilities.mana.CommanderColorIdentityManaAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SubTypeSet;
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;
import mage.game.stack.Spell; import mage.game.stack.Spell;
import mage.players.Player; import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
/** /**
@ -92,8 +87,7 @@ class PathOfAncestryTriggeredAbility extends DelayedTriggeredAbility {
return false; return false;
} }
Spell spell = game.getStack().getSpell(event.getTargetId()); Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell == null || (spell.getSubtype(game).isEmpty() if (spell == null) {
&& !spell.hasAbility(ChangelingAbility.getInstance(), game))) {
return false; return false;
} }
Player player = game.getPlayer(getControllerId()); Player player = game.getPlayer(getControllerId());
@ -101,7 +95,6 @@ class PathOfAncestryTriggeredAbility extends DelayedTriggeredAbility {
return false; return false;
} }
boolean isAllA = false; boolean isAllA = false;
Set<SubType> subTypeSet = new HashSet<>();
for (UUID commanderId : game.getCommandersIds(player)) { for (UUID commanderId : game.getCommandersIds(player)) {
Card commander = game.getPermanent(commanderId); Card commander = game.getPermanent(commanderId);
if (commander == null) { if (commander == null) {
@ -110,20 +103,12 @@ class PathOfAncestryTriggeredAbility extends DelayedTriggeredAbility {
if (commander == null) { if (commander == null) {
continue; continue;
} }
if (commander.isAllCreatureTypes() if (spell.getCard().shareCreatureTypes(commander, game)) {
|| commander.hasAbility(ChangelingAbility.getInstance(), game)) { return true;
isAllA = true;
break;
} }
subTypeSet.addAll(commander.getSubtype(game));
} }
subTypeSet.removeIf(subType -> subType.getSubTypeSet() != SubTypeSet.CreatureType);
if (subTypeSet.isEmpty() && !isAllA) {
return false; return false;
} }
return spell.hasAbility(ChangelingAbility.getInstance(), game)
|| spell.getSubtype(game).stream().anyMatch(subTypeSet::contains);
}
@Override @Override
public String getRule() { public String getRule() {

View file

@ -30,9 +30,7 @@ public final class PhantasmalImage extends CardImpl {
private static final ApplyToPermanent phantasmalImageApplier = new ApplyToPermanent() { private static final ApplyToPermanent phantasmalImageApplier = new ApplyToPermanent() {
@Override @Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) { public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
if (!permanent.hasSubtype(SubType.ILLUSION, game)) { permanent.addSubType(game, SubType.ILLUSION);
permanent.getSubtype(game).add(SubType.ILLUSION);
}
// Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities
permanent.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); permanent.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()));
//permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game);
@ -41,9 +39,7 @@ public final class PhantasmalImage extends CardImpl {
@Override @Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) { public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
if (!mageObject.hasSubtype(SubType.ILLUSION, game)) { mageObject.addSubType(game, SubType.ILLUSION);
mageObject.getSubtype(game).add(SubType.ILLUSION);
}
// Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities // Add directly because the created permanent is only used to copy from, so there is no need to add the ability to e.g. TriggeredAbilities
mageObject.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect())); mageObject.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()));
//permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game); //permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game);

View file

@ -1,6 +1,5 @@
package mage.cards.p; package mage.cards.p;
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;
@ -8,28 +7,18 @@ import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.AttachEffect; import mage.abilities.effects.common.AttachEffect;
import mage.abilities.effects.common.ChooseBasicLandTypeEffect; import mage.abilities.effects.common.ChooseBasicLandTypeEffect;
import mage.abilities.keyword.EnchantAbility; import mage.abilities.keyword.EnchantAbility;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.*;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.DependencyType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
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.TargetPermanent; import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import java.util.UUID;
/** /**
*
* @author Quercitron * @author Quercitron
*/ */
public final class PhantasmalTerrain extends CardImpl { public final class PhantasmalTerrain extends CardImpl {
@ -60,14 +49,14 @@ public final class PhantasmalTerrain extends CardImpl {
return new PhantasmalTerrain(this); return new PhantasmalTerrain(this);
} }
class PhantasmalTerrainContinuousEffect extends ContinuousEffectImpl { private static class PhantasmalTerrainContinuousEffect extends ContinuousEffectImpl {
public PhantasmalTerrainContinuousEffect() { private PhantasmalTerrainContinuousEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
this.staticText = "enchanted land is the chosen type"; staticText = "Enchanted land is the chosen type";
} }
public PhantasmalTerrainContinuousEffect(final PhantasmalTerrainContinuousEffect effect) { private PhantasmalTerrainContinuousEffect(final PhantasmalTerrainContinuousEffect effect) {
super(effect); super(effect);
} }
@ -77,72 +66,60 @@ public final class PhantasmalTerrain extends CardImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public void init(Ability source, Game game) {
Permanent enchantment = game.getPermanent(source.getSourceId()); super.init(source, game);
SubType choice = SubType.byDescription((String) game.getState() SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY));
.getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY)); switch (choice) {
if (choice != null) { case FOREST:
if (choice.equals(SubType.MOUNTAIN)) {
dependencyTypes.add(DependencyType.BecomeMountain);
}
if (choice.equals(SubType.FOREST)) {
dependencyTypes.add(DependencyType.BecomeForest); dependencyTypes.add(DependencyType.BecomeForest);
} break;
if (choice.equals(SubType.SWAMP)) { case PLAINS:
dependencyTypes.add(DependencyType.BecomeSwamp);
}
if (choice.equals(SubType.ISLAND)) {
dependencyTypes.add(DependencyType.BecomeIsland);
}
if (choice.equals(SubType.PLAINS)) {
dependencyTypes.add(DependencyType.BecomePlains); dependencyTypes.add(DependencyType.BecomePlains);
break;
case MOUNTAIN:
dependencyTypes.add(DependencyType.BecomeMountain);
break;
case ISLAND:
dependencyTypes.add(DependencyType.BecomeIsland);
break;
case SWAMP:
dependencyTypes.add(DependencyType.BecomeSwamp);
break;
} }
} }
if (enchantment != null
&& enchantment.getAttachedTo() != null
&& choice != null) {
Permanent land = game.getPermanent(enchantment.getAttachedTo());
if (land != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
land.getSubtype(game).clear();
land.getSubtype(game).add(choice);
land.removeAllAbilities(source.getSourceId(), game);
// land ability is intrinsic, so apply at this layer, not layer 6 @Override
if (choice.equals(SubType.FOREST)) { public boolean apply(Game game, Ability source) {
Permanent enchantment = game.getPermanent(source.getSourceId());
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY));
if (enchantment == null || enchantment.getAttachedTo() == null || choice == null) {
return false;
}
Permanent land = game.getPermanent(enchantment.getAttachedTo());
if (land == null) {
return false;
}
land.getSubtype(game).removeAll(SubType.getLandTypes());
land.addSubType(game, choice);
land.removeAllAbilities(source.getSourceId(), game);
switch (choice) {
case FOREST:
land.addAbility(new GreenManaAbility(), source.getSourceId(), game); land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.PLAINS)) { case PLAINS:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.MOUNTAIN)) { case MOUNTAIN:
land.addAbility(new RedManaAbility(), source.getSourceId(), game); land.addAbility(new RedManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.ISLAND)) { case ISLAND:
land.addAbility(new BlueManaAbility(), source.getSourceId(), game); land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
} break;
if (choice.equals(SubType.SWAMP)) { case SWAMP:
land.addAbility(new BlackManaAbility(), source.getSourceId(), game); land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
break; break;
} }
return true; return true;
} }
} }
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
}
}
} }

View file

@ -1,27 +1,22 @@
package mage.cards.p; package mage.cards.p;
import java.util.Iterator;
import java.util.UUID;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.ObjectColor; import mage.ObjectColor;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.Duration; import mage.filter.StaticFilters;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.SubType;
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.TargetPlayer; import mage.target.TargetPlayer;
import java.util.Iterator;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class PolymorphistsJest extends CardImpl { public final class PolymorphistsJest extends CardImpl {
@ -29,11 +24,9 @@ public final class PolymorphistsJest extends CardImpl {
public PolymorphistsJest(UUID ownerId, CardSetInfo setInfo) { public PolymorphistsJest(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{U}"); super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{1}{U}{U}");
// Until end of turn, each creature target player controls loses all abilities and becomes a blue Frog with base power and toughness 1/1. // Until end of turn, each creature target player controls loses all abilities and becomes a blue Frog with base power and toughness 1/1.
this.getSpellAbility().addEffect(new PolymorphistsJestEffect()); this.getSpellAbility().addEffect(new PolymorphistsJestEffect());
this.getSpellAbility().addTarget(new TargetPlayer()); this.getSpellAbility().addTarget(new TargetPlayer());
} }
public PolymorphistsJest(final PolymorphistsJest card) { public PolymorphistsJest(final PolymorphistsJest card) {
@ -48,8 +41,6 @@ public final class PolymorphistsJest extends CardImpl {
class PolymorphistsJestEffect extends ContinuousEffectImpl { class PolymorphistsJestEffect extends ContinuousEffectImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public PolymorphistsJestEffect() { public PolymorphistsJestEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature); super(Duration.EndOfTurn, Outcome.BecomeCreature);
staticText = "Until end of turn, each creature target player controls loses all abilities and becomes a blue Frog with base power and toughness 1/1"; staticText = "Until end of turn, each creature target player controls loses all abilities and becomes a blue Frog with base power and toughness 1/1";
@ -68,9 +59,13 @@ class PolymorphistsJestEffect 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 (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, getTargetPointer().getFirst(game, source), game)) { game.getBattlefield()
affectedObjectList.add(new MageObjectReference(permanent, game)); .getActivePermanents(
} StaticFilters.FILTER_CONTROLLED_CREATURE,
getTargetPointer().getFirst(game, source), source.getSourceId(), game
).stream()
.map(permanent -> new MageObjectReference(permanent, game))
.forEach(affectedObjectList::add);
} }
} }
@ -78,24 +73,17 @@ class PolymorphistsJestEffect extends ContinuousEffectImpl {
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 permanent = it.next().getPermanent(game); Permanent permanent = it.next().getPermanent(game);
if (permanent != null) { if (permanent == null) {
it.remove();
continue;
}
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) { permanent.removeAllCreatureTypes(game);
permanent.getSubtype(game).clear(); permanent.addSubType(game, SubType.FROG);
permanent.getSubtype(game).add(SubType.FROG);
}
break; break;
case ColorChangingEffects_5: case ColorChangingEffects_5:
if (sublayer == SubLayer.NA) {
permanent.getColor(game).setBlack(false);
permanent.getColor(game).setGreen(false);
permanent.getColor(game).setBlue(false);
permanent.getColor(game).setWhite(false);
permanent.getColor(game).setBlack(false);
permanent.getColor(game).setColor(ObjectColor.BLUE); permanent.getColor(game).setColor(ObjectColor.BLUE);
}
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
permanent.removeAllAbilities(source.getSourceId(), game); permanent.removeAllAbilities(source.getSourceId(), game);
@ -106,9 +94,6 @@ class PolymorphistsJestEffect extends ContinuousEffectImpl {
permanent.getToughness().setValue(1); permanent.getToughness().setValue(1);
} }
} }
} else {
it.remove();
}
} }
return true; return true;
} }
@ -120,7 +105,10 @@ class PolymorphistsJestEffect 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.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; return layer == Layer.PTChangingEffects_7
|| layer == Layer.ColorChangingEffects_5
|| layer == Layer.AbilityAddingRemovingEffects_6
|| layer == Layer.TypeChangingEffects_4;
} }
} }

View file

@ -1,35 +1,22 @@
package mage.cards.r; package mage.cards.r;
import java.util.List;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
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;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.ChooseBasicLandTypeEffect; import mage.abilities.effects.common.ChooseBasicLandTypeEffect;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.*;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType; import mage.filter.StaticFilters;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class Realmwright extends CardImpl { public final class Realmwright extends CardImpl {
@ -46,7 +33,7 @@ public final class Realmwright extends CardImpl {
this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral))); this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral)));
// Lands you control are the chosen type in addition to their other types. // Lands you control are the chosen type in addition to their other types.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RealmwrightEffect2())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new RealmwrightEffect()));
} }
public Realmwright(final Realmwright card) { public Realmwright(final Realmwright card) {
@ -59,111 +46,81 @@ public final class Realmwright extends CardImpl {
} }
} }
class RealmwrightEffect2 extends ContinuousEffectImpl { class RealmwrightEffect extends ContinuousEffectImpl {
public RealmwrightEffect2() { public RealmwrightEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "Lands you control are the chosen type in addition to their other types"; staticText = "Lands you control are the chosen type in addition to their other types";
} }
public RealmwrightEffect2(final RealmwrightEffect2 effect) { public RealmwrightEffect(final RealmwrightEffect effect) {
super(effect); super(effect);
} }
@Override @Override
public RealmwrightEffect2 copy() { public RealmwrightEffect copy() {
return new RealmwrightEffect2(this); return new RealmwrightEffect(this);
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public void init(Ability source, Game game) {
Player you = game.getPlayer(source.getControllerId()); super.init(source, game);
List<Permanent> lands = game.getBattlefield().getAllActivePermanents(new FilterControlledLandPermanent(), source.getControllerId(), game);
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY)); SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY));
if (you != null && choice != null) { switch (choice) {
for (Permanent land : lands) { case PLAINS:
if (land != null) { dependencyTypes.add(DependencyType.BecomePlains);
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA && !land.hasSubtype(choice, game)) {
land.getSubtype(game).add(choice);
}
break; break;
case AbilityAddingRemovingEffects_6: case ISLAND:
if (sublayer == SubLayer.NA) { dependencyTypes.add(DependencyType.BecomeIsland);
boolean addAbility = true; break;
if (choice.equals(SubType.FOREST)) { case SWAMP:
for (Ability existingAbility : land.getAbilities()) { dependencyTypes.add(DependencyType.BecomeSwamp);
if (existingAbility instanceof GreenManaAbility) { break;
addAbility = false; case MOUNTAIN:
dependencyTypes.add(DependencyType.BecomeMountain);
break;
case FOREST:
dependencyTypes.add(DependencyType.BecomeForest);
break; break;
} }
} }
if (addAbility) {
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
}
}
if (choice.equals(SubType.PLAINS)) {
for (Ability existingAbility : land.getAbilities()) {
if (existingAbility instanceof WhiteManaAbility) {
addAbility = false;
break;
}
}
if (addAbility) {
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
}
}
if (choice.equals(SubType.MOUNTAIN)) {
for (Ability existingAbility : land.getAbilities()) {
if (existingAbility instanceof RedManaAbility) {
addAbility = false;
break;
}
}
if (addAbility) {
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
}
}
if (choice.equals(SubType.ISLAND)) {
for (Ability existingAbility : land.getAbilities()) {
if (existingAbility instanceof BlueManaAbility) {
addAbility = false;
break;
}
}
if (addAbility) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
}
if (choice.equals(SubType.SWAMP)) {
for (Ability existingAbility : land.getAbilities()) {
if (existingAbility instanceof BlackManaAbility) {
addAbility = false;
break;
}
}
if (addAbility) {
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
}
break;
}
}
}
return true;
}
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY));
if (choice == null) {
return false; return false;
} }
Ability ability;
@Override switch (choice) {
public boolean hasLayer(Layer layer) { case PLAINS:
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; ability = new WhiteManaAbility();
break;
case ISLAND:
ability = new BlueManaAbility();
break;
case SWAMP:
ability = new BlackManaAbility();
break;
case MOUNTAIN:
ability = new RedManaAbility();
break;
case FOREST:
ability = new GreenManaAbility();
break;
default:
ability = null;
}
for (Permanent land : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
source.getControllerId(), source.getSourceId(), game
)) {
if (land == null || land.hasSubtype(choice, game)) {
continue;
}
land.addSubType(game, choice);
land.addAbility(ability, source.getSourceId(), game);
}
return true;
} }
} }

View file

@ -4,21 +4,18 @@ import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect; import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SubTypeSet;
import mage.filter.StaticFilters; import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard; import mage.target.common.TargetCardInYourGraveyard;
import java.util.HashSet; import java.util.List;
import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.stream.Collectors;
/** /**
* @author TheElk801 * @author TheElk801
@ -73,12 +70,11 @@ class ReturnFromExtinctionTarget extends TargetCardInYourGraveyard {
if (targetOne == null || targetTwo == null) { if (targetOne == null || targetTwo == null) {
return false; return false;
} }
return targetOne.shareSubtypes(targetTwo, game); return targetOne.shareCreatureTypes(targetTwo, game);
} }
@Override @Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) { public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
Set<SubType> subTypes = new HashSet<>();
MageObject targetSource = game.getObject(sourceId); MageObject targetSource = game.getObject(sourceId);
Player player = game.getPlayer(sourceControllerId); Player player = game.getPlayer(sourceControllerId);
if (player == null) { if (player == null) {
@ -87,22 +83,21 @@ class ReturnFromExtinctionTarget extends TargetCardInYourGraveyard {
if (targetSource == null) { if (targetSource == null) {
return false; return false;
} }
for (Card card : player.getGraveyard().getCards(filter, sourceId, sourceControllerId, game)) { List<Card> cards = player.getGraveyard().getCards(
if (card.isAllCreatureTypes() || card.hasAbility(ChangelingAbility.getInstance(), game)) { filter, sourceId, sourceControllerId, game
if (!subTypes.isEmpty()) { ).stream().collect(Collectors.toList());
return true; if (cards.size() < 2) {
} else { return false;
subTypes.addAll(SubType.getCreatureTypes());
} }
for (int i = 0; i < cards.size(); i++) {
for (int j = 0; j < cards.size(); j++) {
if (i <= j) {
continue; continue;
} }
for (SubType subType : card.getSubtype(game)) { if (cards.get(i).shareCreatureTypes(cards.get(j), game)) {
if (subType.getSubTypeSet() == SubTypeSet.CreatureType && subTypes.contains(subType)) {
return true; return true;
} }
} }
subTypes.addAll(card.getSubtype(game));
subTypes.removeIf((SubType st) -> (st.getSubTypeSet() != SubTypeSet.CreatureType));
} }
return false; return false;
} }

View file

@ -1,25 +1,20 @@
package mage.cards.r; package mage.cards.r;
import java.util.UUID; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.BoostEquippedEffect; import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect; import mage.abilities.effects.common.continuous.GainAllCreatureTypesAttachedEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.keyword.EquipAbility; import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType; import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.Zone; import mage.constants.SubType;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class RunedStalactite extends CardImpl { public final class RunedStalactite extends CardImpl {
@ -29,10 +24,10 @@ public final class RunedStalactite extends CardImpl {
this.subtype.add(SubType.EQUIPMENT); this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +1/+1 and is every creature type. // Equipped creature gets +1/+1 and is every creature type.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1,1))); Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(1, 1));
Effect effect = new GainAbilityAttachedEffect(ChangelingAbility.getInstance(), AttachmentType.EQUIPMENT, Duration.WhileOnBattlefield); ability.addEffect(new GainAllCreatureTypesAttachedEffect());
effect.setText("Equipped creature is every creature type (Changeling)"); this.addAbility(ability);
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
// Equip {2} // Equip {2}
this.addAbility(new EquipAbility(Outcome.BoostCreature, new ManaCostsImpl("{2}"))); this.addAbility(new EquipAbility(Outcome.BoostCreature, new ManaCostsImpl("{2}")));
} }

View file

@ -91,8 +91,8 @@ class SarkhanTheDragonspeakerEffect extends ContinuousEffectImpl {
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
permanent.getCardType().clear(); permanent.getCardType().clear();
permanent.addCardType(CardType.CREATURE); permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).clear(); permanent.removeAllSubTypes(game);
permanent.getSubtype(game).add(SubType.DRAGON); permanent.addSubType(game, SubType.DRAGON);
permanent.getSuperType().clear(); permanent.getSuperType().clear();
permanent.addSuperType(SuperType.LEGENDARY); permanent.addSuperType(SuperType.LEGENDARY);
} }

View file

@ -127,8 +127,8 @@ class SarkhanTheMasterlessBecomeDragonEffect extends ContinuousEffectImpl {
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
permanent.getCardType().clear(); permanent.getCardType().clear();
permanent.addCardType(CardType.CREATURE); permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).clear(); permanent.removeAllSubTypes(game);
permanent.getSubtype(game).add(SubType.DRAGON); permanent.addSubType(game, SubType.DRAGON);
} }
break; break;
case ColorChangingEffects_5: case ColorChangingEffects_5:

View file

@ -1,31 +1,30 @@
package mage.cards.s; package mage.cards.s;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility; import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.combat.CantAttackUnlessDefenderControllsPermanent; import mage.abilities.effects.common.combat.CantAttackUnlessDefenderControllsPermanent;
import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect;
import mage.abilities.keyword.MonstrosityAbility; import mage.abilities.keyword.MonstrosityAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterLandPermanent; import mage.filter.common.FilterLandPermanent;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.common.TargetLandPermanent; import mage.target.common.TargetLandPermanent;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class SealockMonster extends CardImpl { public final class SealockMonster extends CardImpl {
private static final FilterPermanent filter = new FilterLandPermanent(SubType.ISLAND, "an Island");
public SealockMonster(UUID ownerId, CardSetInfo setInfo) { public SealockMonster(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{3}{U}{U}");
this.subtype.add(SubType.OCTOPUS); this.subtype.add(SubType.OCTOPUS);
@ -34,15 +33,17 @@ public final class SealockMonster extends CardImpl {
this.toughness = new MageInt(5); this.toughness = new MageInt(5);
// Sealock Monster can't attack unless defending player controls an Island. // Sealock Monster can't attack unless defending player controls an Island.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CantAttackUnlessDefenderControllsPermanent(new FilterLandPermanent(SubType.ISLAND,"an Island")))); this.addAbility(new SimpleStaticAbility(new CantAttackUnlessDefenderControllsPermanent(filter)));
// {5}{U}{U}: Monstrosity 3.</i> // {5}{U}{U}: Monstrosity 3.</i>
this.addAbility(new MonstrosityAbility("{5}{U}{U}", 3)); this.addAbility(new MonstrosityAbility("{5}{U}{U}", 3));
// When Sealock Monster becomes monstrous, target land becomes an island in addition to its other types.
Ability ability = new BecomesMonstrousSourceTriggeredAbility(new SealockMonsterBecomesIslandTargetEffect());
Target target = new TargetLandPermanent();
ability.addTarget(target);
this.addAbility(ability);
// When Sealock Monster becomes monstrous, target land becomes an island in addition to its other types.
Ability ability = new BecomesMonstrousSourceTriggeredAbility(
new AddCardSubTypeTargetEffect(SubType.ISLAND, Duration.EndOfTurn)
);
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
} }
public SealockMonster(final SealockMonster card) { public SealockMonster(final SealockMonster card) {
@ -54,56 +55,3 @@ public final class SealockMonster extends CardImpl {
return new SealockMonster(this); return new SealockMonster(this);
} }
} }
class SealockMonsterBecomesIslandTargetEffect extends ContinuousEffectImpl {
private static Ability islandAbility = new BlueManaAbility();
public SealockMonsterBecomesIslandTargetEffect() {
super(Duration.EndOfGame, Outcome.Detriment);
this.staticText = "target land becomes an island in addition to its other types";
}
public SealockMonsterBecomesIslandTargetEffect(final SealockMonsterBecomesIslandTargetEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public SealockMonsterBecomesIslandTargetEffect copy() {
return new SealockMonsterBecomesIslandTargetEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
for (UUID targetPermanent : targetPointer.getTargets(game, source)) {
Permanent land = game.getPermanent(targetPermanent);
if (land != null) {
switch (layer) {
case AbilityAddingRemovingEffects_6:
if (!land.getAbilities().containsRule(islandAbility)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
break;
case TypeChangingEffects_4:
if (!land.hasSubtype(SubType.ISLAND, game)) {
land.getSubtype(game).add(SubType.ISLAND);
}
break;
}
}
}
return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
}
}

View file

@ -35,6 +35,7 @@ public final class Shapesharer extends CardImpl {
this.power = new MageInt(1); this.power = new MageInt(1);
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// {2}{U}: Target Shapeshifter becomes a copy of target creature until your next turn. // {2}{U}: Target Shapeshifter becomes a copy of target creature until your next turn.

View file

@ -1,12 +1,10 @@
package mage.cards.s; package mage.cards.s;
import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.Mode; import mage.abilities.Mode;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility; import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.keyword.ChangelingAbility; 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.*;
@ -18,12 +16,9 @@ import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID; import java.util.UUID;
/** /**
*
* @author Plopman * @author Plopman
*/ */
public final class SharedAnimosity extends CardImpl { public final class SharedAnimosity extends CardImpl {
@ -32,7 +27,9 @@ public final class SharedAnimosity extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
// Whenever a creature you control attacks, it gets +1/+0 until end of turn for each other attacking creature that shares a creature type with it. // Whenever a creature you control attacks, it gets +1/+0 until end of turn for each other attacking creature that shares a creature type with it.
this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new SharedAnimosityEffect(), false, true)); this.addAbility(new AttacksCreatureYouControlTriggeredAbility(
new SharedAnimosityEffect(), false, true)
);
} }
public SharedAnimosity(final SharedAnimosity card) { public SharedAnimosity(final SharedAnimosity card) {
@ -69,29 +66,11 @@ class SharedAnimosityEffect extends ContinuousEffectImpl {
super.init(source, game); super.init(source, game);
Permanent permanent = game.getPermanent(this.targetPointer.getFirst(game, source)); Permanent permanent = game.getPermanent(this.targetPointer.getFirst(game, source));
if (permanent != null) { if (permanent != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent(); FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(Predicates.not(new PermanentIdPredicate(this.targetPointer.getFirst(game, source)))); filter.add(Predicates.not(new PermanentIdPredicate(this.targetPointer.getFirst(game, source))));
filter.add(AttackingPredicate.instance); filter.add(AttackingPredicate.instance);
boolean allCreatureTypes = false; filter.add(new SharedAnimosityPredicate(permanent));
if (permanent.isAllCreatureTypes()) { power = game.getBattlefield().count(filter, source.getControllerId(), source.getSourceId(), game);
allCreatureTypes = true;
} else {
for(Ability ability : permanent.getAbilities()){
if(ability instanceof ChangelingAbility){
allCreatureTypes = true;
}
}
}
if(!allCreatureTypes){
List<Predicate<MageObject>> predicateList = new ArrayList<>();
for(SubType subtype : permanent.getSubtype(game)){
predicateList.add(subtype.getPredicate());
}
filter.add(Predicates.or(predicateList));
}
power = game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source.getSourceId(), game).size();
} }
} }
@ -110,3 +89,17 @@ class SharedAnimosityEffect extends ContinuousEffectImpl {
return "it gets +1/+0 until end of turn for each other attacking creature that shares a creature type with it"; return "it gets +1/+0 until end of turn for each other attacking creature that shares a creature type with it";
} }
} }
class SharedAnimosityPredicate implements Predicate<Card> {
private final Permanent permanent;
SharedAnimosityPredicate(Permanent permanent) {
this.permanent = permanent;
}
@Override
public boolean apply(Card input, Game game) {
return permanent != null && input != null && permanent.shareCreatureTypes(input, game);
}
}

View file

@ -27,6 +27,7 @@ public final class ShieldsOfVelisVel extends CardImpl {
this.subtype.add(SubType.SHAPESHIFTER); this.subtype.add(SubType.SHAPESHIFTER);
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
//Creatures target player controls get +0/+1 and gain all creature types until end of turn. //Creatures target player controls get +0/+1 and gain all creature types until end of turn.
@ -78,7 +79,7 @@ class ShieldsOfVelisVelGainEffect extends ContinuousEffectImpl {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent permanent = it.next().getPermanent(game); Permanent permanent = it.next().getPermanent(game);
if (permanent != null) { if (permanent != null) {
permanent.addAbility(ChangelingAbility.getInstance(), source.getSourceId(), game); permanent.setIsAllCreatureTypes(true);
} else { } else {
it.remove(); it.remove();
} }

View file

@ -26,6 +26,7 @@ public final class SkeletalChangeling extends CardImpl {
this.power = new MageInt(1); this.power = new MageInt(1);
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// {1}{B}: Regenerate Skeletal Changeling. // {1}{B}: Regenerate Skeletal Changeling.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{B}"))); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new RegenerateSourceEffect(), new ManaCostsImpl("{1}{B}")));

View file

@ -1,7 +1,6 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost; import mage.abilities.costs.Cost;
@ -17,8 +16,9 @@ import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.target.common.TargetCardInHand; import mage.target.common.TargetCardInHand;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class SlumberingTora extends CardImpl { public final class SlumberingTora extends CardImpl {
@ -33,7 +33,7 @@ public final class SlumberingTora extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{3}");
// {2}, Discard a Spirit or Arcane card: Slumbering Tora becomes an X/X Cat artifact creature until end of turn, // {2}, Discard a Spirit or Arcane card: Slumbering Tora becomes an X/X Cat artifact creature until end of turn,
// where X is the discarded card's converted mana cost. // where X is the discarded card's converted mana cost.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new SlumberingToraEffect(), new ManaCostsImpl("{2}")); Ability ability = new SimpleActivatedAbility(new SlumberingToraEffect(), new ManaCostsImpl("{2}"));
ability.addCost(new DiscardTargetCost(new TargetCardInHand(filter))); ability.addCost(new DiscardTargetCost(new TargetCardInHand(filter)));
this.addAbility(ability); this.addAbility(ability);
} }
@ -49,12 +49,15 @@ public final class SlumberingTora extends CardImpl {
private static class SlumberingToraEffect extends ContinuousEffectImpl { private static class SlumberingToraEffect extends ContinuousEffectImpl {
public SlumberingToraEffect() { private int convManaCosts = 0;
private SlumberingToraEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature); super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText(); staticText = "{this} becomes an X/X Cat artifact creature until end of turn, " +
"where X is the discarded card's converted mana cost";
} }
public SlumberingToraEffect(final SlumberingToraEffect effect) { private SlumberingToraEffect(final SlumberingToraEffect effect) {
super(effect); super(effect);
} }
@ -64,47 +67,45 @@ public final class SlumberingTora extends CardImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public void init(Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId()); super.init(source, game);
if (permanent != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).add(SubType.CAT);
}
break;
case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) {
int convManaCosts = 0;
for (Cost cost : source.getCosts()) { for (Cost cost : source.getCosts()) {
if (cost instanceof DiscardTargetCost && !((DiscardTargetCost) cost).getCards().isEmpty()) { if (cost instanceof DiscardTargetCost && !((DiscardTargetCost) cost).getCards().isEmpty()) {
convManaCosts = ((DiscardTargetCost) cost).getCards().get(0).getConvertedManaCost(); convManaCosts = ((DiscardTargetCost) cost).getCards().get(0).getConvertedManaCost();
return;
}
}
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
return false;
}
switch (layer) {
case TypeChangingEffects_4:
permanent.addCardType(CardType.ARTIFACT);
permanent.addCardType(CardType.CREATURE);
permanent.addSubType(game, SubType.CAT);
break; break;
} case PTChangingEffects_7:
} if (sublayer == SubLayer.SetPT_7b) {
permanent.getPower().setValue(convManaCosts); permanent.getPower().setValue(convManaCosts);
permanent.getToughness().setValue(convManaCosts); permanent.getToughness().setValue(convManaCosts);
} }
} }
return true; return true;
} }
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
return false; return false;
} }
private void setText() {
staticText = "{this} becomes an X/X Cat artifact creature until end of turn, where X is the discarded card's converted mana cost";
}
@Override @Override
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,6 +1,5 @@
package mage.cards.s; package mage.cards.s;
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;
@ -9,20 +8,14 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.mana.GreenManaAbility; import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.DependencyType;
import mage.constants.Duration;
import mage.constants.Layer;
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.target.TargetPermanent; import mage.target.TargetPermanent;
import java.util.UUID;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public final class SongOfTheDryads extends CardImpl { public final class SongOfTheDryads extends CardImpl {
@ -40,7 +33,6 @@ public final class SongOfTheDryads extends CardImpl {
// Enchanted permanent is a colorless Forest land. // Enchanted permanent is a colorless Forest land.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesColorlessForestLandEffect())); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesColorlessForestLandEffect()));
} }
public SongOfTheDryads(final SongOfTheDryads card) { public SongOfTheDryads(final SongOfTheDryads card) {
@ -55,13 +47,13 @@ public final class SongOfTheDryads extends CardImpl {
class BecomesColorlessForestLandEffect extends ContinuousEffectImpl { class BecomesColorlessForestLandEffect extends ContinuousEffectImpl {
public BecomesColorlessForestLandEffect() { BecomesColorlessForestLandEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment); super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "Enchanted permanent is a colorless Forest land"; this.staticText = "Enchanted permanent is a colorless Forest land";
dependencyTypes.add(DependencyType.BecomeForest); dependencyTypes.add(DependencyType.BecomeForest);
} }
public BecomesColorlessForestLandEffect(final BecomesColorlessForestLandEffect effect) { private BecomesColorlessForestLandEffect(final BecomesColorlessForestLandEffect effect) {
super(effect); super(effect);
} }
@ -78,9 +70,13 @@ class BecomesColorlessForestLandEffect 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 enchantment = game.getPermanent(source.getSourceId()); Permanent enchantment = game.getPermanent(source.getSourceId());
if (enchantment != null && enchantment.getAttachedTo() != null) { if (enchantment == null || enchantment.getAttachedTo() == null) {
return false;
}
Permanent permanent = game.getPermanent(enchantment.getAttachedTo()); Permanent permanent = game.getPermanent(enchantment.getAttachedTo());
if (permanent != null) { if (permanent == null) {
return false;
}
switch (layer) { switch (layer) {
case ColorChangingEffects_5: case ColorChangingEffects_5:
permanent.getColor(game).setWhite(false); permanent.getColor(game).setWhite(false);
@ -89,27 +85,21 @@ class BecomesColorlessForestLandEffect extends ContinuousEffectImpl {
permanent.getColor(game).setBlue(false); permanent.getColor(game).setBlue(false);
permanent.getColor(game).setRed(false); permanent.getColor(game).setRed(false);
break; break;
case AbilityAddingRemovingEffects_6:
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break;
case TypeChangingEffects_4: case TypeChangingEffects_4:
permanent.removeAllAbilities(source.getSourceId(), game);
permanent.getCardType().clear(); permanent.getCardType().clear();
permanent.addCardType(CardType.LAND); permanent.addCardType(CardType.LAND);
permanent.getSubtype(game).clear(); permanent.removeAllSubTypes(game);
permanent.getSubtype(game).add(SubType.FOREST); permanent.addSubType(game, SubType.FOREST);
permanent.removeAllAbilities(source.getSourceId(), game);
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break; break;
} }
return true; return true;
} }
}
return false;
}
@Override @Override
public boolean hasLayer(Layer layer) { public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 return layer == Layer.ColorChangingEffects_5
|| layer == Layer.ColorChangingEffects_5
|| layer == Layer.TypeChangingEffects_4; || layer == Layer.TypeChangingEffects_4;
} }
} }

View file

@ -95,7 +95,7 @@ enum SorinVengefulBloodlordAdjuster implements TargetAdjuster {
class SorinVengefulBloodlordEffect extends ContinuousEffectImpl { class SorinVengefulBloodlordEffect extends ContinuousEffectImpl {
SorinVengefulBloodlordEffect() { SorinVengefulBloodlordEffect() {
super(Duration.Custom, Outcome.Neutral); super(Duration.Custom, Outcome.Neutral);
staticText = "That creature is a vampire in addition to its other types"; staticText = "That creature is a Vampire in addition to its other types";
} }
private SorinVengefulBloodlordEffect(final SorinVengefulBloodlordEffect effect) { private SorinVengefulBloodlordEffect(final SorinVengefulBloodlordEffect effect) {
@ -119,11 +119,7 @@ class SorinVengefulBloodlordEffect extends ContinuousEffectImpl {
} }
} }
if (creature != null) { if (creature != null) {
if (sublayer == SubLayer.NA) { creature.addSubType(game, SubType.VAMPIRE);
if (!creature.hasSubtype(SubType.VAMPIRE, game)) {
creature.getSubtype(game).add(SubType.VAMPIRE);
}
}
return true; return true;
} else { } else {
this.used = true; this.used = true;

View file

@ -1,6 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -10,29 +9,22 @@ import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.decorator.ConditionalContinuousEffect; import mage.abilities.decorator.ConditionalContinuousEffect;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.constants.SubType;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
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 mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.stack.StackObject; import mage.game.stack.StackObject;
import mage.target.common.TargetCreaturePermanent; import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/** /**
*
* @author jeffwadsworth * @author jeffwadsworth
*/ */
public final class SoulSculptor extends CardImpl { public final class SoulSculptor extends CardImpl {
final String rule = "Target creature becomes an enchantment and loses all abilities until a player casts a creature spell."; private static final String rule = "Target creature becomes an enchantment and loses all abilities until a player casts a creature spell.";
public SoulSculptor(UUID ownerId, CardSetInfo setInfo) { public SoulSculptor(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
@ -42,7 +34,7 @@ public final class SoulSculptor extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// {1}{W}, {tap}: Target creature becomes an enchantment and loses all abilities until a player casts a creature spell. // {1}{W}, {tap}: Target creature becomes an enchantment and loses all abilities until a player casts a creature spell.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(new SoulSculptorEffect(), SoulSculptorCondition.instance, rule), new ManaCostsImpl("{1}{W}")); Ability ability = new SimpleActivatedAbility(new ConditionalContinuousEffect(new SoulSculptorEffect(), SoulSculptorCondition.instance, rule), new ManaCostsImpl("{1}{W}"));
ability.addCost(new TapSourceCost()); ability.addCost(new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent()); ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability); this.addAbility(ability);
@ -90,16 +82,15 @@ class SoulSculptorEffect 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 = affectedObjectList.get(0).getPermanent(game); Permanent permanent = affectedObjectList.get(0).getPermanent(game);
if (permanent != null) { if (permanent == null) {
this.discard();
return false;
}
switch (layer) { switch (layer) {
case TypeChangingEffects_4: case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.getCardType().clear(); permanent.getCardType().clear();
permanent.getSubtype(game).clear(); permanent.getSubtype(game).retainAll(SubType.getEnchantmentTypes());
if (!permanent.getCardType().contains(CardType.ENCHANTMENT)) {
permanent.getCardType().add(CardType.ENCHANTMENT); permanent.getCardType().add(CardType.ENCHANTMENT);
}
}
break; break;
case AbilityAddingRemovingEffects_6: case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) { if (sublayer == SubLayer.NA) {
@ -109,9 +100,6 @@ class SoulSculptorEffect extends ContinuousEffectImpl {
} }
return true; return true;
} }
this.discard();
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {

View file

@ -1,10 +1,7 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.MageObject; import mage.MageObject;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect; import mage.abilities.effects.common.continuous.BecomesSubtypeAllEffect;
@ -16,8 +13,12 @@ import mage.constants.CardType;
import mage.constants.Duration; import mage.constants.Duration;
import mage.constants.Outcome; import mage.constants.Outcome;
import mage.constants.SubType; import mage.constants.SubType;
import mage.filter.StaticFilters;
import mage.game.Game; import mage.game.Game;
import mage.players.Player; import mage.players.Player;
import mage.util.SubTypeList;
import java.util.UUID;
/** /**
* @author EvilGeek * @author EvilGeek
@ -69,8 +70,10 @@ class StandardizeEffect extends OneShotEffect {
chosenType = typeChoice.getChoice(); chosenType = typeChoice.getChoice();
if (chosenType != null && !chosenType.isEmpty()) { if (chosenType != null && !chosenType.isEmpty()) {
// ADD TYPE TO TARGET // ADD TYPE TO TARGET
ContinuousEffect effect = new BecomesSubtypeAllEffect(Duration.EndOfTurn, SubType.byDescription(chosenType)); game.addEffect(new BecomesSubtypeAllEffect(
game.addEffect(effect, source); Duration.EndOfTurn, new SubTypeList(SubType.byDescription(chosenType)),
StaticFilters.FILTER_PERMANENT_CREATURE, true
), source);
return true; return true;
} }

View file

@ -59,7 +59,7 @@ class StoneforgeMasterworkDynamicValue implements DynamicValue {
if (equipped != null) { if (equipped != null) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, sourceAbility.getControllerId(), game)) { for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, sourceAbility.getControllerId(), game)) {
if (!permanent.getId().equals(equipped.getId())) { if (!permanent.getId().equals(equipped.getId())) {
if (equipped.shareSubtypes(permanent, game)) { if (equipped.shareCreatureTypes(permanent, game)) {
xValue++; xValue++;
} }
} }

View file

@ -4,6 +4,7 @@ import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.HasSubtypesSourceEffect;
import mage.abilities.mana.AnyColorManaAbility; import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
@ -22,16 +23,12 @@ public final class StoneworkPackbeast extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
this.subtype.add(SubType.BEAST); this.subtype.add(SubType.BEAST);
this.subtype.add(SubType.CLERIC);
this.subtype.add(SubType.ROGUE);
this.subtype.add(SubType.WARRIOR);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(2); this.power = new MageInt(2);
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Stonework Packbeast is also a Cleric, Rogue, Warrior, and Wizard. // Stonework Packbeast is also a Cleric, Rogue, Warrior, and Wizard.
this.addAbility(new SimpleStaticAbility( this.addAbility(new SimpleStaticAbility(
Zone.ALL, new InfoEffect("{this} is also a Cleric, Rogue, Warrior, and Wizard") Zone.ALL, new HasSubtypesSourceEffect(SubType.CLERIC, SubType.ROGUE, SubType.WARRIOR, SubType.WIZARD)
)); ));
// {2}: Add one mana of any color. // {2}: Add one mana of any color.

View file

@ -1,6 +1,5 @@
package mage.cards.s; package mage.cards.s;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility; import mage.abilities.common.SimpleStaticAbility;
@ -11,28 +10,23 @@ import mage.abilities.keyword.IslandwalkAbility;
import mage.abilities.mana.BlueManaAbility; import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.DependencyType; import mage.filter.StaticFilters;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.filter.common.FilterCreaturePermanent; import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicates; import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate; import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import java.util.UUID;
/** /**
*
* @author BetaSteward_at_googlemail.com * @author BetaSteward_at_googlemail.com
*/ */
public final class StormtideLeviathan extends CardImpl { public final class StormtideLeviathan extends CardImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent("Creatures without flying or islandwalk"); private static final FilterCreaturePermanent filter
= new FilterCreaturePermanent("Creatures without flying or islandwalk");
static { static {
filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class))); filter.add(Predicates.not(new AbilityPredicate(FlyingAbility.class)));
@ -48,12 +42,12 @@ public final class StormtideLeviathan extends CardImpl {
// Islandwalk (This creature can't be blocked as long as defending player controls an Island.) // Islandwalk (This creature can't be blocked as long as defending player controls an Island.)
this.addAbility(new IslandwalkAbility()); this.addAbility(new IslandwalkAbility());
// All lands are Islands in addition to their other types.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new StormtideLeviathanEffect()));
// Creatures without flying or islandwalk can't attack.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD,
new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter)));
// All lands are Islands in addition to their other types.
this.addAbility(new SimpleStaticAbility(new StormtideLeviathanEffect()));
// Creatures without flying or islandwalk can't attack.
this.addAbility(new SimpleStaticAbility(new CantAttackAnyPlayerAllEffect(Duration.WhileOnBattlefield, filter)));
} }
public StormtideLeviathan(final StormtideLeviathan card) { public StormtideLeviathan(final StormtideLeviathan card) {
@ -67,13 +61,13 @@ public final class StormtideLeviathan extends CardImpl {
class StormtideLeviathanEffect extends ContinuousEffectImpl { class StormtideLeviathanEffect extends ContinuousEffectImpl {
public StormtideLeviathanEffect() { private StormtideLeviathanEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral); super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "All lands are Islands in addition to their other types"; staticText = "All lands are Islands in addition to their other types";
this.dependencyTypes.add(DependencyType.BecomeIsland); this.dependencyTypes.add(DependencyType.BecomeIsland);
} }
public StormtideLeviathanEffect(final StormtideLeviathanEffect effect) { private StormtideLeviathanEffect(final StormtideLeviathanEffect effect) {
super(effect); super(effect);
} }
@ -83,32 +77,17 @@ public final class StormtideLeviathan extends CardImpl {
} }
@Override @Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) { public boolean apply(Game game, Ability source) {
for (Permanent land : game.getBattlefield().getActivePermanents( for (Permanent land : game.getBattlefield().getActivePermanents(
new FilterLandPermanent(), source.getControllerId(), game)) { StaticFilters.FILTER_LAND, source.getControllerId(), game
switch (layer) { )) {
case TypeChangingEffects_4:
// land abilities are intrinsic, so add them here, not in layer 6 // land abilities are intrinsic, so add them here, not in layer 6
if (!land.hasSubtype(SubType.ISLAND, game)) { land.addSubType(game, SubType.ISLAND);
land.getSubtype(game).add(SubType.ISLAND);
if (!land.getAbilities(game).containsClass(BlueManaAbility.class)) { if (!land.getAbilities(game).containsClass(BlueManaAbility.class)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game); land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
} }
} }
break;
}
}
return true; return true;
} }
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
}
} }
} }

View file

@ -7,11 +7,13 @@ import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.condition.common.KickedCondition; import mage.abilities.condition.common.KickedCondition;
import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility; import mage.abilities.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect; import mage.abilities.effects.common.continuous.HasSubtypesSourceEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.keyword.KickerAbility; import mage.abilities.keyword.KickerAbility;
import mage.cards.*; import mage.cards.*;
import mage.constants.*; import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard; import mage.filter.FilterCard;
import mage.filter.predicate.Predicate; import mage.filter.predicate.Predicate;
import mage.game.Game; import mage.game.Game;
@ -31,16 +33,12 @@ public final class TajuruParagon extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
this.subtype.add(SubType.ELF); this.subtype.add(SubType.ELF);
this.subtype.add(SubType.CLERIC);
this.subtype.add(SubType.ROGUE);
this.subtype.add(SubType.WARRIOR);
this.subtype.add(SubType.WIZARD);
this.power = new MageInt(3); this.power = new MageInt(3);
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// Tajuru Paragon is also a Cleric, Rogue, Warrior, and Wizard. // Tajuru Paragon is also a Cleric, Rogue, Warrior, and Wizard.
this.addAbility(new SimpleStaticAbility( this.addAbility(new SimpleStaticAbility(
Zone.ALL, new InfoEffect("{this} is also a Cleric, Rogue, Warrior, and Wizard") Zone.ALL, new HasSubtypesSourceEffect(SubType.CLERIC, SubType.ROGUE, SubType.WARRIOR, SubType.WIZARD)
)); ));
// Kicker {3} // Kicker {3}
@ -115,27 +113,6 @@ class TajuruParagonPredicate implements Predicate<Card> {
@Override @Override
public boolean apply(Card input, Game game) { public boolean apply(Card input, Game game) {
boolean isAllA = permanent.isAllCreatureTypes() return permanent != null && input != null && permanent.shareCreatureTypes(input, game);
|| permanent.hasAbility(ChangelingAbility.getInstance(), game);
boolean isAnyA = isAllA || permanent.getSubtype(game)
.stream()
.map(SubType::getSubTypeSet)
.anyMatch(SubTypeSet.CreatureType::equals);
boolean isAllB = input.isAllCreatureTypes()
|| input.hasAbility(ChangelingAbility.getInstance(), game);
boolean isAnyB = isAllB || input
.getSubtype(game)
.stream()
.map(SubType::getSubTypeSet)
.anyMatch(SubTypeSet.CreatureType::equals);
if (isAllA) {
return isAllB || isAnyB;
}
return isAnyA
&& (isAllB || permanent
.getSubtype(game)
.stream()
.filter(subType -> subType.getSubTypeSet() == SubTypeSet.CreatureType)
.anyMatch(subType -> input.hasSubtype(subType, game)));
} }
} }

View file

@ -26,6 +26,7 @@ public final class TaureanMauler extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// Changeling // Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance()); this.addAbility(ChangelingAbility.getInstance());
// Whenever an opponent casts a spell, you may put a +1/+1 counter on Taurean Mauler. // Whenever an opponent casts a spell, you may put a +1/+1 counter on Taurean Mauler.

View file

@ -1,8 +1,6 @@
package mage.cards.t; package mage.cards.t;
import java.util.Iterator;
import java.util.UUID;
import mage.MageInt; import mage.MageInt;
import mage.MageObjectReference; import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
@ -10,30 +8,21 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost; import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect; import mage.abilities.effects.OneShotEffect;
import mage.abilities.mana.BlackManaAbility; import mage.abilities.mana.*;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.choices.Choice; import mage.choices.Choice;
import mage.choices.ChoiceBasicLandType; import mage.choices.ChoiceBasicLandType;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType; import mage.filter.StaticFilters;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.common.FilterControlledPermanent;
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;
import java.util.Iterator;
import java.util.UUID;
/** /**
*
* @author emerald000 * @author emerald000
*/ */
public final class Terraformer extends CardImpl { public final class Terraformer extends CardImpl {
@ -46,7 +35,7 @@ public final class Terraformer extends CardImpl {
this.toughness = new MageInt(2); this.toughness = new MageInt(2);
// {1}: Choose a basic land type. Each land you control becomes that type until end of turn. // {1}: Choose a basic land type. Each land you control becomes that type until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TerraformerEffect(), new GenericManaCost(1))); this.addAbility(new SimpleActivatedAbility(new TerraformerEffect(), new GenericManaCost(1)));
} }
public Terraformer(final Terraformer card) { public Terraformer(final Terraformer card) {
@ -66,7 +55,7 @@ class TerraformerEffect extends OneShotEffect {
this.staticText = "Choose a basic land type. Each land you control becomes that type until end of turn"; this.staticText = "Choose a basic land type. Each land you control becomes that type until end of turn";
} }
TerraformerEffect(final TerraformerEffect effect) { private TerraformerEffect(final TerraformerEffect effect) {
super(effect); super(effect);
} }
@ -92,13 +81,11 @@ class TerraformerEffect extends OneShotEffect {
class TerraformerContinuousEffect extends ContinuousEffectImpl { class TerraformerContinuousEffect extends ContinuousEffectImpl {
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
TerraformerContinuousEffect() { TerraformerContinuousEffect() {
super(Duration.EndOfTurn, Outcome.Neutral); super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
} }
TerraformerContinuousEffect(final TerraformerContinuousEffect effect) { private TerraformerContinuousEffect(final TerraformerContinuousEffect effect) {
super(effect); super(effect);
} }
@ -110,64 +97,68 @@ class TerraformerContinuousEffect extends ContinuousEffectImpl {
@Override @Override
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) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, source.getControllerId(), game)) {
affectedObjectList.add(new MageObjectReference(permanent, game));
}
}
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_Terraformer")); SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_Terraformer"));
if (choice != null) { switch (choice) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) { case FOREST:
Permanent land = it.next().getPermanent(game); dependencyTypes.add(DependencyType.BecomeForest);
if (land != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
land.getSubtype(game).clear();
land.getSubtype(game).add(choice);
}
break; break;
case AbilityAddingRemovingEffects_6: case PLAINS:
if (sublayer == SubLayer.NA) { dependencyTypes.add(DependencyType.BecomePlains);
land.getAbilities().clear(); break;
if (choice.equals(SubType.FOREST)) { case MOUNTAIN:
land.addAbility(new GreenManaAbility(), source.getSourceId(), game); dependencyTypes.add(DependencyType.BecomeMountain);
} break;
if (choice.equals(SubType.PLAINS)) { case ISLAND:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game); dependencyTypes.add(DependencyType.BecomeIsland);
} break;
if (choice.equals(SubType.MOUNTAIN)) { case SWAMP:
land.addAbility(new RedManaAbility(), source.getSourceId(), game); dependencyTypes.add(DependencyType.BecomeSwamp);
}
if (choice.equals(SubType.ISLAND)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.SWAMP)) {
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
break; break;
} }
} else { if (this.affectedObjectsSet) {
it.remove(); game.getBattlefield()
.getActivePermanents(
StaticFilters.FILTER_CONTROLLED_PERMANENT_LAND,
source.getControllerId(), source.getSourceId(), game
).stream()
.map(permanent -> new MageObjectReference(permanent, game))
.forEach(affectedObjectList::add);
} }
} }
return true;
}
return false;
}
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_ElsewhereFlask"));
if (choice == null) {
return false; return false;
} }
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) {
@Override Permanent land = it.next().getPermanent(game);
public boolean hasLayer(Layer layer) { if (land == null) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; it.remove();
continue;
}
land.getSubtype(game).removeAll(SubType.getLandTypes());
land.addSubType(game, choice);
land.removeAllAbilities(source.getSourceId(), game);
switch (choice) {
case FOREST:
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break;
case PLAINS:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
break;
case MOUNTAIN:
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;
case ISLAND:
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
break;
case SWAMP:
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
break;
}
}
return true;
} }
} }

View file

@ -1,41 +1,38 @@
package mage.cards.t; package mage.cards.t;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability; import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility; import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.VariableManaCost; import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.ContinuousEffectImpl; import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.continuous.SourceEffect; import mage.abilities.effects.common.continuous.GainAbilitySourceEffect;
import mage.abilities.effects.common.continuous.SetPowerToughnessSourceEffect;
import mage.abilities.keyword.DefenderAbility; import mage.abilities.keyword.DefenderAbility;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.CardType; import mage.constants.*;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.game.Game; import mage.game.Game;
import mage.game.permanent.Permanent; import mage.game.permanent.Permanent;
import mage.game.permanent.token.TokenImpl;
import mage.game.permanent.token.Token; import java.util.UUID;
/** /**
* * @author TheElk801
* @author cbt33
*/ */
public final class TestamentOfFaith extends CardImpl { public final class TestamentOfFaith extends CardImpl {
public TestamentOfFaith(UUID ownerId, CardSetInfo setInfo) { public TestamentOfFaith(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}"); super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{W}");
// {X}: Testament of Faith becomes an X/X Wall creature with defender in addition to its other types until end of turn. // {X}: Testament of Faith becomes an X/X Wall creature with defender in addition to its other types until end of turn.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new TestamentOfFaithBecomesCreatureSourceEffect(new TestamentOfFaithToken(), "enchantment", Duration.EndOfTurn), new VariableManaCost())); Ability ability = new SimpleActivatedAbility(new SetPowerToughnessSourceEffect(
ManacostVariableValue.instance, Duration.EndOfTurn, SubLayer.SetPT_7b
).setText("{this} becomes an X/X"), new VariableManaCost());
ability.addEffect(new TestamentOfFaithEffect());
ability.addEffect(new GainAbilitySourceEffect(
DefenderAbility.getInstance(), Duration.EndOfTurn
).setText("with defender in addition to its other types until end of turn"));
this.addAbility(ability);
} }
public TestamentOfFaith(final TestamentOfFaith card) { public TestamentOfFaith(final TestamentOfFaith card) {
@ -48,121 +45,30 @@ public final class TestamentOfFaith extends CardImpl {
} }
} }
class TestamentOfFaithBecomesCreatureSourceEffect extends ContinuousEffectImpl implements SourceEffect { class TestamentOfFaithEffect extends ContinuousEffectImpl {
protected Token token; TestamentOfFaithEffect() {
protected String type; super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
protected int zoneChangeCounter; staticText = "Wall creature";
public TestamentOfFaithBecomesCreatureSourceEffect(Token token, String type, Duration duration) {
super(duration, Outcome.BecomeCreature);
this.token = token;
this.type = type;
setText();
} }
public TestamentOfFaithBecomesCreatureSourceEffect(final TestamentOfFaithBecomesCreatureSourceEffect effect) { private TestamentOfFaithEffect(final TestamentOfFaithEffect effect) {
super(effect); super(effect);
this.token = effect.token.copy();
this.type = effect.type;
} }
@Override @Override
public TestamentOfFaithBecomesCreatureSourceEffect copy() { public TestamentOfFaithEffect copy() {
return new TestamentOfFaithBecomesCreatureSourceEffect(this); return new TestamentOfFaithEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
this.getAffectedObjects().add(new MageObjectReference(source.getSourceId(), game));
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = affectedObjectList.get(0).getPermanent(game);
if (permanent != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
if (!token.getCardType().isEmpty()) {
for (CardType t : token.getCardType()) {
if (!permanent.getCardType().contains(t)) {
permanent.addCardType(t);
}
}
}
if (type != null && type.isEmpty() || type == null) {
permanent.getSubtype(game).clear();
}
if (!token.getSubtype(game).isEmpty()) {
permanent.getSubtype(game).addAll(token.getSubtype(game));
}
}
break;
case ColorChangingEffects_5:
if (sublayer == SubLayer.NA) {
if (token.getColor(game).hasColor()) {
permanent.getColor(game).setColor(token.getColor(game));
}
}
break;
case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) {
if (!token.getAbilities().isEmpty()) {
for (Ability ability: token.getAbilities()) {
permanent.addAbility(ability, source.getSourceId(), game);
}
}
}
break;
case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) {
MageInt power = new MageInt(source.getManaCosts().getVariableCosts().get(0).getAmount());
MageInt toughness = new MageInt(source.getManaCosts().getVariableCosts().get(0).getAmount());
permanent.getPower().setValue(power.getValue());
permanent.getToughness().setValue(toughness.getValue());
}
}
return true;
} else {
if (duration == Duration.Custom) {
this.discard();
}
}
return false;
} }
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
return false; return false;
} }
permanent.addCardType(CardType.CREATURE);
private void setText() { permanent.addSubType(game, SubType.WALL);
staticText = "{this} becomes an X/X Wall creature with defender in addition to its other types until end of turn"; return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.ColorChangingEffects_5 || layer == Layer.TypeChangingEffects_4;
}
}
class TestamentOfFaithToken extends TokenImpl {
TestamentOfFaithToken() {
super("Wall", "X/X Wall creature with defender");
cardType.add(CardType.CREATURE);
this.subtype.add(SubType.WALL);
color.setWhite(true);
this.addAbility(DefenderAbility.getInstance());
}
public TestamentOfFaithToken(final TestamentOfFaithToken token) {
super(token);
}
public TestamentOfFaithToken copy() {
return new TestamentOfFaithToken(this);
} }
} }

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