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

@ -61,7 +61,7 @@ class AlphaStatusDynamicValue implements DynamicValue {
if (enchanted != null) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, game)) {
if (!permanent.getId().equals(enchanted.getId())) {
if (enchanted.shareSubtypes(permanent, game)) {
if (enchanted.shareCreatureTypes(permanent, game)) {
xValue += 2;
}
}

View file

@ -7,6 +7,7 @@ import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.continuous.GainAllCreatureTypesTargetEffect;
import mage.abilities.effects.common.continuous.LoseAllCreatureTypesTargetEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
@ -27,13 +28,13 @@ public final class AmoeboidChangeling extends CardImpl {
this.toughness = new MageInt(1);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// {tap}: Target creature gains all creature types until end of turn.
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD,
new GainAbilityTargetEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn, null, false, Layer.TypeChangingEffects_4, SubLayer.NA), new TapSourceCost());
Ability ability = new SimpleActivatedAbility(
new GainAllCreatureTypesTargetEffect(Duration.EndOfTurn), new TapSourceCost());
ability.addTarget(new TargetCreaturePermanent());
this.addAbility(ability);
// {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.common.SimpleStaticAbility;
import mage.abilities.effects.common.continuous.BoostEquippedEffect;
import mage.abilities.effects.common.continuous.GainAbilityAttachedEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.effects.common.continuous.GainAllCreatureTypesAttachedEffect;
import mage.abilities.keyword.EquipAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.AttachmentType;
import mage.constants.CardType;
import mage.constants.SubType;
@ -26,9 +24,7 @@ public final class AmorphousAxe extends CardImpl {
// Equipped creature gets +3/+0 and is every creature type.
Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(3, 0));
ability.addEffect(new GainAbilityAttachedEffect(
ChangelingAbility.getInstance(), AttachmentType.EQUIPMENT
).setText("and is every creature type"));
ability.addEffect(new GainAllCreatureTypesAttachedEffect());
this.addAbility(ability);
// Equip {3}

View file

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

View file

@ -1,42 +1,37 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageInt;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldAbility;
import mage.abilities.common.EntersBattlefieldTappedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.SourceHasCounterCondition;
import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.decorator.ConditionalContinuousEffect;
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.RemoveCounterSourceEffect;
import mage.abilities.mana.SimpleManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
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.constants.*;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author spjspj
*/
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) {
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);
// Arixmethes, Slumbering Isle enters the battlefield tapped with five slumber counters on it.
this.addAbility(new EntersBattlefieldTappedAbility());
Effect effect = new AddCountersSourceEffect(CounterType.SLUMBER.createInstance(5));
this.addAbility(new EntersBattlefieldAbility(effect, "with five slumber counters"));
Ability ability = new EntersBattlefieldAbility(
new TapSourceEffect(true), false, null,
"{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.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new ConditionalContinuousEffect(
new ArixmethesIsLandEffect(),
new SourceHasCounterCondition(CounterType.SLUMBER, 1, Integer.MAX_VALUE),
"As long as {this} has a slumber counter on it, it's a land")));
this.addAbility(new SimpleStaticAbility(new ConditionalContinuousEffect(
new ArixmethesIsLandEffect(), condition,
"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.
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 {
public ArixmethesIsLandEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "As long as {this} has a slumber counter on it, it's a land";
ArixmethesIsLandEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
}
public ArixmethesIsLandEffect(final ArixmethesIsLandEffect effect) {
private ArixmethesIsLandEffect(final ArixmethesIsLandEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
public ArixmethesIsLandEffect copy() {
return new ArixmethesIsLandEffect(this);
}
@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());
if (permanent != null) {
switch (layer) {
case TypeChangingEffects_4:
permanent.getCardType().clear();
permanent.addCardType(CardType.LAND);
permanent.getSubtype(game).clear();
break;
}
return true;
}
if (permanent == null) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
permanent.getCardType().clear();
permanent.addCardType(CardType.LAND);
permanent.removeAllSubTypes(game);
return true;
}
}

View file

@ -90,7 +90,7 @@ class AshayaSoulOfTheWildEffect extends ContinuousEffectImpl {
permanent.addCardType(CardType.LAND);
}
if (!permanent.hasSubtype(SubType.FOREST, game)) {
permanent.getSubtype(game).add(SubType.FOREST);
permanent.addSubType(game, SubType.FOREST);
if (!permanent.getAbilities(game).containsClass(GreenManaAbility.class)) {
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
}

View file

@ -1,7 +1,6 @@
package mage.cards.a;
import java.util.UUID;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
@ -24,8 +23,9 @@ import mage.target.common.TargetOpponent;
import mage.target.targetpointer.FixedTarget;
import mage.util.CardUtil;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class AshiokNightmareWeaver extends CardImpl {
@ -149,7 +149,7 @@ class AshiokNightmareWeaverPutIntoPlayEffect extends OneShotEffect {
class AshiokNightmareWeaverAddTypeEffect extends ContinuousEffectImpl {
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";
}
@ -162,34 +162,16 @@ class AshiokNightmareWeaverAddTypeEffect extends ContinuousEffectImpl {
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
public boolean apply(Game game, Ability source) {
Permanent creature = game.getPermanent(this.getTargetPointer().getFirst(game, source));
if (creature == null) {
this.used = true;
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.TypeChangingEffects_4;
creature.addSubType(game, SubType.NIGHTMARE);
return true;
}
}
class AshiokNightmareWeaverExileAllEffect extends OneShotEffect {

View file

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

View file

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

View file

@ -72,7 +72,7 @@ public final class BloodMoon extends CardImpl {
// So the ability removing has to be done before Layer 6
// Lands have their mana ability intrinsically, so that is added in layer 4
land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(SubType.MOUNTAIN);
land.addSubType(game, SubType.MOUNTAIN);
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
break;

View file

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

View file

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

View file

@ -30,6 +30,7 @@ public final class CairnWanderer extends CardImpl {
this.toughness = new MageInt(4);
// Changeling
this.setIsAllCreatureTypes(true);
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.

View file

@ -1,12 +1,9 @@
package mage.cards.c;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.common.OnEventTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.keyword.EnchantAbility;
import mage.cards.*;
import mage.constants.CardType;
@ -15,27 +12,24 @@ import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetCard;
import mage.target.TargetPermanent;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCreaturePermanent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
*
* @author North
*/
public final class CallToTheKindred extends CardImpl {
public CallToTheKindred(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{U}");
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{U}");
this.subtype.add(SubType.AURA);
// Enchant creature
@ -43,6 +37,7 @@ public final class CallToTheKindred extends CardImpl {
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.BoostCreature));
this.addAbility(new EnchantAbility(auraTarget.getTargetName()));
// 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,
// 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 {
public CallToTheKindredEffect() {
CallToTheKindredEffect() {
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);
}
@ -90,36 +87,33 @@ class CallToTheKindredEffect extends OneShotEffect {
}
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, 5));
controller.lookAtCards(enchantment.getIdName(), cards, game);
FilterCreatureCard filter = new FilterCreatureCard();
filter.add(new CallToTheKindredPredicate(creature));
if (!creature.getAbilities().contains(ChangelingAbility.getInstance())) {
StringBuilder sb = new StringBuilder("creature card with at least one subtype from: ");
List<Predicate<MageObject>> subtypes = new ArrayList<>();
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)) {
if (cards.count(filter, game) > 0) {
TargetCard target = new TargetCardInLibrary(0, 1, filter);
controller.choose(Outcome.PutCreatureInPlay, cards, target, game);
Card card = cards.get(target.getFirstTarget(), game);
if (card != null) {
cards.remove(card);
controller.moveCards(card, Zone.BATTLEFIELD, source, game);
}
}
}
controller.putCardsOnBottomOfLibrary(cards, game, source, 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;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -21,8 +20,9 @@ import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
import mage.target.common.TargetCreaturePermanent;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
public final class CaptivatingVampire extends CardImpl {
@ -37,7 +37,7 @@ public final class CaptivatingVampire extends CardImpl {
}
public CaptivatingVampire(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{1}{B}{B}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{B}");
this.subtype.add(SubType.VAMPIRE);
this.power = new MageInt(2);
@ -90,11 +90,7 @@ class CaptivatingVampireEffect extends ContinuousEffectImpl {
}
break;
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
if (!permanent.hasSubtype(SubType.VAMPIRE, game)) {
permanent.getSubtype(game).add(SubType.VAMPIRE);
}
}
permanent.addSubType(game, SubType.VAMPIRE);
break;
}
return true;

View file

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

View file

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

View file

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

View file

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

View file

@ -24,6 +24,7 @@ public final class ChangelingOutcast extends CardImpl {
this.toughness = new MageInt(1);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// 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.toughness = new MageInt(2);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
this.addAbility(VigilanceAbility.getInstance());
}

View file

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

View file

@ -1,7 +1,5 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.delayed.AtTheBeginOfNextEndStepDelayedTriggeredAbility;
@ -15,17 +13,18 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author Plopman
*/
public final class ChimericCoils extends CardImpl {
public ChimericCoils(UUID ownerId, CardSetInfo setInfo) {
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.
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())));
this.addAbility(ability);
}
@ -43,8 +42,8 @@ public final class ChimericCoils extends CardImpl {
class ChimericCoilsEffect extends ContinuousEffectImpl {
public ChimericCoilsEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText();
super(Duration.Custom, Outcome.BecomeCreature);
staticText = "{this} becomes an X/X Construct artifact creature";
}
public ChimericCoilsEffect(final ChimericCoilsEffect effect) {
@ -59,13 +58,19 @@ class ChimericCoilsEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
if (permanent == null) {
return false;
}
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).add(SubType.CONSTRUCT);
if (!permanent.isArtifact()) {
permanent.addCardType(CardType.ARTIFACT);
}
if (!permanent.isCreature()) {
permanent.addCardType(CardType.CREATURE);
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.CONSTRUCT);
break;
case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) {
@ -76,18 +81,12 @@ class ChimericCoilsEffect extends ContinuousEffectImpl {
}
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
private void setText() {
staticText = duration.toString() + " {this} becomes an X/X Construct artifact creature";
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4;

View file

@ -1,7 +1,5 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
@ -12,17 +10,18 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author Backfir3
*/
public final class ChimericStaff extends CardImpl {
public ChimericStaff(UUID ownerId, CardSetInfo setInfo) {
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.
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) {
@ -39,7 +38,7 @@ class ChimericStaffEffect extends ContinuousEffectImpl {
public ChimericStaffEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText();
staticText = "{this} becomes an X/X Construct artifact creature until end of turn";
}
public ChimericStaffEffect(final ChimericStaffEffect effect) {
@ -54,37 +53,35 @@ class ChimericStaffEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
if (permanent == null) {
return false;
}
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).add(SubType.CONSTRUCT);
if (!permanent.isArtifact()) {
permanent.addCardType(CardType.ARTIFACT);
}
if (!permanent.isCreature()) {
permanent.addCardType(CardType.CREATURE);
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.CONSTRUCT);
break;
case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) {
int xValue = source.getManaCostsToPay().getX();
if (xValue != 0) {
permanent.getPower().setValue(xValue);
permanent.getToughness().setValue(xValue);
}
}
}
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
private void setText() {
staticText = duration.toString() + " {this} becomes an X/X Construct artifact creature";
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4;

View file

@ -1,28 +1,26 @@
package mage.cards.c;
import java.util.List;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.util.SubTypeList;
import java.util.List;
import java.util.UUID;
/**
*
* @author North
*/
public final class CoatOfArms extends CardImpl {
public CoatOfArms(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{5}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{5}");
// Each creature gets +1/+1 for each other creature on the battlefield that shares at least one creature type with it.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new CoatOfArmsEffect()));
@ -56,7 +54,9 @@ class CoatOfArmsEffect extends ContinuousEffectImpl {
@Override
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) {
int amount = getAmount(permanents, permanent, game);
permanent.addPower(amount);
@ -67,20 +67,9 @@ class CoatOfArmsEffect extends ContinuousEffectImpl {
private int getAmount(List<Permanent> permanents, Permanent target, Game game) {
int amount = 0;
SubTypeList targetSubtype = target.getSubtype(game);
if (target.getAbilities().contains(ChangelingAbility.getInstance()) || target.isAllCreatureTypes()) {
return permanents.size() - 1;
}
for (Permanent permanent : permanents) {
if (!permanent.getId().equals(target.getId())) {
for (SubType subtype : targetSubtype) {
if (subtype.getSubTypeSet() == SubTypeSet.CreatureType) {
if (permanent.hasSubtype(subtype, game)) {
if (!permanent.getId().equals(target.getId()) && permanent.shareCreatureTypes(target, game)) {
amount++;
break;
}
}
}
}
}
return amount;

View file

@ -77,7 +77,7 @@ public final class Conversion extends CardImpl {
case TypeChangingEffects_4:
if (land.getSubtype(game).contains(SubType.MOUNTAIN)) {
land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(SubType.PLAINS);
land.addSubType(game, SubType.PLAINS);
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
break;

View file

@ -1,7 +1,5 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -18,8 +16,9 @@ import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent;
import java.util.UUID;
/**
*
* @author North
*/
public final class ConvincingMirage extends CardImpl {
@ -32,8 +31,10 @@ public final class ConvincingMirage extends CardImpl {
TargetPermanent auraTarget = new TargetLandPermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.Detriment));
// As Convincing Mirage enters the battlefield, choose a basic land type.
this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral)));
// Enchanted land is the chosen type.
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
@ -53,7 +54,7 @@ public final class ConvincingMirage extends CardImpl {
class ConvincingMirageContinousEffect extends ContinuousEffectImpl {
public ConvincingMirageContinousEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "Enchanted land is the chosen type";
}
@ -67,53 +68,59 @@ class ConvincingMirageContinousEffect extends ContinuousEffectImpl {
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent enchantment = game.getPermanent(source.getSourceId());
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));
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);
}
switch (choice) {
case FOREST:
dependencyTypes.add(DependencyType.BecomeForest);
break;
case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) {
land.getAbilities().clear();
if (choice.equals(SubType.FOREST)) {
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.PLAINS)) {
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.MOUNTAIN)) {
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.ISLAND)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.SWAMP)) {
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
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;
}
return true;
}
}
return false;
}
@Override
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;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
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);
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,25 +1,26 @@
package mage.cards.c;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.keyword.FlashbackAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceImpl;
import mage.choices.ChoiceCardType;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.TimingRule;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.players.Player;
import java.util.Arrays;
import java.util.UUID;
import java.util.stream.Collectors;
/**
*
* @author nantuko
*/
public final class CreepingRenaissance extends CardImpl {
@ -58,40 +59,27 @@ class CreepingRenaissanceEffect extends OneShotEffect {
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
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;
}
}
}
if (controller == null) {
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
public CreepingRenaissanceEffect copy() {
return new CreepingRenaissanceEffect(this);
}
}

View file

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

View file

@ -1,52 +1,40 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
import mage.abilities.costs.CostImpl;
import mage.abilities.effects.Effect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.PutCardFromHandOntoBattlefieldEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.Zone;
import mage.filter.FilterCard;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.common.FilterCreatureCard;
import mage.filter.predicate.Predicate;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledPermanent;
import java.util.ArrayList;
import java.util.List;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author spjspj
*/
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) {
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.
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) {
@ -61,29 +49,28 @@ public final class CrypticGateway extends CardImpl {
class CrypticGatewayCost extends CostImpl {
private static final FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("untapped creatures you control");
private UUID targetCreatureId = null;
private UUID targetCreatureId2 = null;
TargetControlledPermanent target;
private static final FilterControlledCreaturePermanent filter
= new FilterControlledCreaturePermanent("untapped creatures you control");
static {
filter.add(Predicates.not(TappedPredicate.instance));
}
public CrypticGatewayCost(TargetControlledPermanent target) {
this.target = target;
private final TargetControlledPermanent target = new TargetControlledPermanent(2, filter);
private CrypticGatewayPredicate predicate;
public CrypticGatewayCost() {
this.text = "Tap two untapped creatures you control";
}
public CrypticGatewayCost(final CrypticGatewayCost cost) {
super(cost);
this.target = cost.target.copy();
}
@Override
public boolean pay(Ability ability, Game game, UUID sourceId, UUID controllerId, boolean noMana, Cost costToPay) {
int numTargets = 0;
Set<Permanent> permanents = new HashSet<>();
while (numTargets < 2 && target.choose(Outcome.Tap, controllerId, sourceId, game)) {
for (UUID targetId : target.getTargets()) {
Permanent permanent = game.getPermanent(targetId);
@ -94,15 +81,12 @@ class CrypticGatewayCost extends CostImpl {
if (paid) {
numTargets++;
target.clearChosen();
}
for (Effect effect : ability.getEffects()) {
if (targetCreatureId == null) {
targetCreatureId = permanent.getId();
} else if (targetCreatureId2 == null) {
targetCreatureId2 = permanent.getId();
permanents.add(permanent);
}
}
}
if (paid) {
this.predicate = new CrypticGatewayPredicate(permanents);
}
return paid;
}
@ -112,18 +96,14 @@ class CrypticGatewayCost extends CostImpl {
return target.canChoose(controllerId, game);
}
public CrypticGatewayPredicate getPredicate() {
return predicate;
}
@Override
public CrypticGatewayCost copy() {
return new CrypticGatewayCost(this);
}
public UUID getTargetCreatureId() {
return targetCreatureId;
}
public UUID getTargetCreatureId2() {
return targetCreatureId2;
}
}
class CrypticGatewayEffect extends OneShotEffect {
@ -147,59 +127,33 @@ class CrypticGatewayEffect extends OneShotEffect {
if (source.getCosts() == null) {
return false;
}
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()) {
if (cost instanceof CrypticGatewayCost) {
UUID id = ((CrypticGatewayCost) cost).getTargetCreatureId();
UUID id2 = ((CrypticGatewayCost) cost).getTargetCreatureId2();
Permanent creature = game.getPermanentOrLKIBattlefield(id);
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;
Predicate predicate = ((CrypticGatewayCost) cost).getPredicate();
filter.add(predicate);
return new PutCardFromHandOntoBattlefieldEffect(filter).apply(game, source);
}
}
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;
}
}
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();
boolean found = false;
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, controller.getId(), game)) {
if (card.shareSubtypes(permanent, game)) {
if (card.shareCreatureTypes(permanent, game)) {
found = true;
break;
}

View file

@ -1,20 +1,31 @@
package mage.cards.d;
import java.util.UUID;
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.CardSetInfo;
import mage.constants.CardType;
import mage.constants.ComparisonType;
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
*/
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) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{G}{W}");
this.addSuperType(SuperType.LEGENDARY);
@ -22,10 +33,17 @@ public final class DrJuliusJumblemorph extends CardImpl {
this.toughness = new MageInt(4);
// 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.
// 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) {

View file

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

View file

@ -1,7 +1,6 @@
package mage.cards.d;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -19,14 +18,15 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class DragonsoulKnight extends CardImpl {
public DragonsoulKnight(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{2}{R}");
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{R}");
this.subtype.add(SubType.HUMAN);
this.subtype.add(SubType.KNIGHT);
@ -37,12 +37,12 @@ public final class DragonsoulKnight extends CardImpl {
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.
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.setText("gets +5/+3");
effect.setText(", gets +5/+3");
ability.addEffect(effect);
effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gains flying");
effect.setText(", and gains flying");
ability.addEffect(effect);
effect = new GainAbilitySourceEffect(TrampleAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and trample");
@ -60,14 +60,14 @@ public final class DragonsoulKnight extends CardImpl {
return new DragonsoulKnight(this);
}
private class DragonsoulKnightEffect extends ContinuousEffectImpl {
private static class DragonsoulKnightEffect extends ContinuousEffectImpl {
public DragonsoulKnightEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText();
private DragonsoulKnightEffect() {
super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
staticText = "Until end of turn, {this} becomes a Dragon";
}
public DragonsoulKnightEffect(final DragonsoulKnightEffect effect) {
private DragonsoulKnightEffect(final DragonsoulKnightEffect effect) {
super(effect);
}
@ -77,34 +77,14 @@ public final class DragonsoulKnight extends CardImpl {
}
@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());
if (permanent == null) {
return false;
}
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.getSubtype(game).clear();
permanent.getSubtype(game).add(SubType.DRAGON);
}
break;
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.DRAGON);
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;
/**
*
* @author brikr
*/
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)) {
switch (layer) {
case TypeChangingEffects_4:
if (!permanent.hasSubtype(SubType.ZOMBIE, game)) {
permanent.getSubtype(game).add(SubType.ZOMBIE);
}
permanent.addSubType(game, SubType.ZOMBIE);
break;
case ColorChangingEffects_5:
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) {
Permanent creature = mor.getPermanent(game);
if (creature != null) {
if (!creature.hasSubtype(SubType.VAMPIRE, game)) {
creature.getSubtype(game).add(SubType.VAMPIRE);
}
creature.addSubType(game, SubType.VAMPIRE);
return true;
} else {
this.used = true;

View file

@ -26,6 +26,7 @@ public final class EgoErasure extends CardImpl {
this.subtype.add(SubType.SHAPESHIFTER);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
//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(); ) {
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
permanent.getSubtype(game).retainAll(SubType.getLandTypes());
permanent.removeAllCreatureTypes(game);
} else {
it.remove();
}

View file

@ -1,8 +1,5 @@
package mage.cards.e;
import java.util.Iterator;
import java.util.UUID;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
@ -17,14 +14,15 @@ import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceBasicLandType;
import mage.constants.*;
import mage.filter.common.FilterControlledLandPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.Iterator;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class ElsewhereFlask extends CardImpl {
@ -36,7 +34,7 @@ public final class ElsewhereFlask extends CardImpl {
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.
this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, new ElsewhereFlaskEffect(), new SacrificeSourceCost()));
this.addAbility(new SimpleActivatedAbility(new ElsewhereFlaskEffect(), new SacrificeSourceCost()));
}
public ElsewhereFlask(final ElsewhereFlask card) {
@ -80,13 +78,11 @@ class ElsewhereFlaskEffect extends OneShotEffect {
class ElsewhereFlaskContinuousEffect extends ContinuousEffectImpl {
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
public ElsewhereFlaskContinuousEffect() {
super(Duration.EndOfTurn, Outcome.Neutral);
ElsewhereFlaskContinuousEffect() {
super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
}
public ElsewhereFlaskContinuousEffect(final ElsewhereFlaskContinuousEffect effect) {
private ElsewhereFlaskContinuousEffect(final ElsewhereFlaskContinuousEffect effect) {
super(effect);
}
@ -98,64 +94,68 @@ class ElsewhereFlaskContinuousEffect extends ContinuousEffectImpl {
@Override
public void init(Ability source, Game 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"));
if (choice != null) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent land = it.next().getPermanent(game);
if (land != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
land.getSubtype(game).clear();
land.getSubtype(game).add(choice);
}
switch (choice) {
case FOREST:
dependencyTypes.add(DependencyType.BecomeForest);
break;
case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) {
land.getAbilities().clear();
if (choice.equals(SubType.FOREST)) {
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.PLAINS)) {
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.MOUNTAIN)) {
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.ISLAND)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.SWAMP)) {
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
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;
}
} else {
it.remove();
if (this.affectedObjectsSet) {
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
public boolean apply(Game game, Ability source) {
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_ElsewhereFlask"));
if (choice == null) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) {
Permanent land = it.next().getPermanent(game);
if (land == null) {
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;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.Effect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
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}");
// All permanents are enchantments in addition to their other types.
Effect effect = new EnchangedEveningEffect(CardType.ENCHANTMENT,
Duration.WhileOnBattlefield, new FilterPermanent());
effect.setText("All permanents are enchantments in addition to their other types");
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, effect));
this.addAbility(new SimpleStaticAbility(new EnchangedEveningEffect()));
}
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
static class EnchangedEveningEffect extends ContinuousEffectImpl {
private static class EnchangedEveningEffect extends ContinuousEffectImpl {
private final CardType addedCardType;
private final FilterPermanent filter;
public EnchangedEveningEffect(CardType addedCardType, Duration duration, FilterPermanent filter) {
super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
this.addedCardType = addedCardType;
this.filter = filter;
private EnchangedEveningEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
this.dependencyTypes.add(DependencyType.EnchantmentAddingRemoving);
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);
this.addedCardType = effect.addedCardType;
this.filter = effect.filter;
}
@Override
public boolean apply(Game game, Ability source) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) {
if (permanent != null
&& !permanent.getCardType().contains(addedCardType)) {
permanent.addCardType(addedCardType);
for (Permanent permanent : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_PERMANENT, source.getControllerId(),
source.getSourceId(), game
)) {
if (permanent != null) {
permanent.addCardType(CardType.ENCHANTMENT);
}
}
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.VariableManaCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.effects.common.discard.DiscardTargetEffect;
import mage.abilities.effects.mana.ManaEffect;
import mage.abilities.hint.common.MyTurnHint;
import mage.abilities.mana.ActivatedManaAbilityImpl;
import mage.cards.CardImpl;
@ -127,7 +127,7 @@ class ChimericStaffEffect extends ContinuousEffectImpl {
public ChimericStaffEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText();
staticText = "{this} becomes an X/X Construct artifact creature until end of turn";
}
public ChimericStaffEffect(final ChimericStaffEffect effect) {
@ -142,37 +142,35 @@ class ChimericStaffEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent != null) {
if (permanent == null) {
return false;
}
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).add(SubType.CONSTRUCT);
if (!permanent.isArtifact()) {
permanent.addCardType(CardType.ARTIFACT);
}
if (!permanent.isCreature()) {
permanent.addCardType(CardType.CREATURE);
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.CONSTRUCT);
break;
case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) {
int xValue = source.getManaCostsToPay().getX();
if (xValue != 0) {
permanent.getPower().setValue(xValue);
permanent.getToughness().setValue(xValue);
}
}
}
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
private void setText() {
staticText = duration.toString() + " {this} becomes an X/X Construct artifact creature";
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4;

View file

@ -62,13 +62,13 @@ class FacesOfThePastEffect extends OneShotEffect {
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)) {
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);
}
}
} else {
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);
}
}

View file

@ -27,6 +27,7 @@ public final class FireBellyChangeling extends CardImpl {
this.toughness = new MageInt(1);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// {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.toughness = new MageInt(4);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
this.addAbility(TrampleAbility.getInstance());
}

View file

@ -26,6 +26,7 @@ public final class GhostlyChangeling extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
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
if (land.getSubtype(game).contains(SubType.MOUNTAIN)) {
land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(SubType.PLAINS);
land.addSubType(game, SubType.PLAINS);
land.removeAllAbilities(source.getSourceId(), game);
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
break;

View file

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

View file

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

View file

@ -27,6 +27,7 @@ public final class Graveshifter extends CardImpl {
this.toughness = new MageInt(2);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// 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;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.common.DiscardTargetCost;
@ -24,14 +21,17 @@ import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.common.TargetCardInHand;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.UUID;
/**
*
* @author BetaSteward
*/
public final class GrimoireOfTheDead extends CardImpl {
public GrimoireOfTheDead(UUID ownerId, CardSetInfo setInfo) {
super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}");
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}");
addSuperType(SuperType.LEGENDARY);
// {1}, {tap}, Discard a card: Put a study counter on Grimoire of the Dead.
@ -121,14 +121,10 @@ class GrimoireOfTheDeadEffect2 extends ContinuousEffectImpl {
if (permanent != null) {
switch (layer) {
case ColorChangingEffects_5:
if (sublayer == SubLayer.NA) {
permanent.getColor(game).setBlack(true);
}
break;
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.getSubtype(game).add(SubType.ZOMBIE);
}
permanent.addSubType(game, SubType.ZOMBIE);
break;
}
return true;

View file

@ -82,7 +82,7 @@ class HeirloomBladeEffect extends OneShotEffect {
Cards otherCards = new CardsImpl();
for (Card card : controller.getLibrary().getCards(game)) {
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);
break;
} else {

View file

@ -97,8 +97,8 @@ class HourOfEternityEffect extends OneShotEffect {
token.getPower().modifyBaseValue(4);
token.getToughness().modifyBaseValue(4);
token.getColor(game).setColor(ObjectColor.BLACK);
token.getSubtype(game).clear();
token.getSubtype(game).add(SubType.ZOMBIE);
token.removeAllCreatureTypes(game);
token.addSubType(game, SubType.ZOMBIE);
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
if (land.getSubtype(game).contains(firstChoice)) {
land.getSubtype(game).removeAll(SubType.getLandTypes());
land.getSubtype(game).add(secondChoice);
land.addSubType(game, secondChoice);
land.removeAllAbilities(source.getSourceId(), game);
if (land.getSubtype(game).contains(SubType.FOREST)) {
this.dependencyTypes.add(DependencyType.BecomeForest);

View file

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

View file

@ -24,6 +24,7 @@ public final class IrregularCohort extends CardImpl {
this.toughness = new MageInt(2);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// 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());
if (equipedCreature != null) {
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.addToughness(toughness.calculate(game, source, this));

View file

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

View file

@ -65,7 +65,7 @@ class ManaEchoesEffect extends OneShotEffect {
if (controller != null && permanent != null) {
int foundCreatures = 0;
for (Permanent perm : game.getBattlefield().getAllActivePermanents(StaticFilters.FILTER_PERMANENT_CREATURE, source.getControllerId(), game)) {
if (permanent.shareSubtypes(perm, game)) {
if (permanent.shareCreatureTypes(perm, game)) {
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);
break;
case TypeChangingEffects_4:
if (!creature.hasSubtype(SubType.VAMPIRE, game)) {
creature.getSubtype(game).add(SubType.VAMPIRE);
}
creature.addSubType(game, SubType.VAMPIRE);
break;
}
}

View file

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

View file

@ -1,52 +1,46 @@
package mage.cards.m;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
import mage.abilities.effects.Effect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.continuous.SetPowerToughnessAllEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.SubLayer;
import mage.constants.Zone;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.Iterator;
import java.util.UUID;
/**
*
* @author Plopman
*/
public final class MirrorEntity extends CardImpl {
static private FilterControlledCreaturePermanent filter = new FilterControlledCreaturePermanent("Creatures you control");
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.power = new MageInt(1);
this.toughness = new MageInt(1);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// {X}: Until end of turn, creatures you control have base power and toughness X/X and gain all creature types.
DynamicValue variableMana = ManacostVariableValue.instance;
Effect effect = new SetPowerToughnessAllEffect(variableMana, variableMana, Duration.EndOfTurn, filter, true);
effect.setText("Until end of turn, creatures you control have base power and toughness X/X");
Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new VariableManaCost());
effect = new GainAbilityAllEffect(ChangelingAbility.getInstance(), Duration.EndOfTurn, filter, false, Layer.TypeChangingEffects_4, SubLayer.NA);
effect.setText("and gain all creature types");
ability.addEffect(effect);
Ability ability = new SimpleActivatedAbility(new SetPowerToughnessAllEffect(
ManacostVariableValue.instance, ManacostVariableValue.instance,
Duration.EndOfTurn, StaticFilters.FILTER_CONTROLLED_CREATURES, true
).setText("Until end of turn, creatures you control have base power and toughness X/X"), new VariableManaCost());
ability.addEffect(new MirrorEntityEffect());
this.addAbility(ability);
}
@ -59,3 +53,43 @@ public final class MirrorEntity extends CardImpl {
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;
import java.util.UUID;
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.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SuperType;
import mage.constants.Zone;
import java.util.UUID;
/**
*
* @author vereena42
*/
public final class MistformUltimus extends CardImpl {
@ -25,7 +26,10 @@ public final class MistformUltimus extends CardImpl {
this.toughness = new MageInt(3);
// 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) {

View file

@ -24,6 +24,7 @@ public final class MoongloveChangeling extends CardImpl {
this.power = new MageInt(2);
this.toughness = new MageInt(2);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
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);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// 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.toughness = new MageInt(1);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
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
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// Target creature gets +3/-3 and loses all creature types until end of turn.

View file

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

View file

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

View file

@ -39,17 +39,23 @@ public final class NimDeathmantle extends CardImpl {
this.subtype.add(SubType.EQUIPMENT);
// Equipped creature gets +2/+2, has intimidate, and is a black Zombie.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(2, 2)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new GainAbilityAttachedEffect(IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardColorAttachedEffect(ObjectColor.BLACK, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT)));
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new SetCardSubtypeAttachedEffect(Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT, SubType.ZOMBIE)));
Ability ability = new SimpleStaticAbility(new BoostEquippedEffect(2, 2));
ability.addEffect(new GainAbilityAttachedEffect(
IntimidateAbility.getInstance(), AttachmentType.EQUIPMENT
).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.
this.addAbility(new NimDeathmantleTriggeredAbility());
// Equip {4}
this.addAbility(new EquipAbility(Outcome.AddAbility, new GenericManaCost(4)));
}
public NimDeathmantle(final NimDeathmantle card) {
@ -93,7 +99,7 @@ class NimDeathmantleTriggeredAbility extends TriggeredAbilityImpl {
&& !(permanent instanceof PermanentToken)
&& permanent.isCreature()) {
getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game) +1));
getEffects().get(0).setTargetPointer(new FixedTarget(permanent.getId(), permanent.getZoneChangeCounter(game) + 1));
return true;
}
return false;

View file

@ -1,6 +1,5 @@
package mage.cards.n;
import mage.Mana;
import mage.abilities.Ability;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
@ -17,8 +16,6 @@ import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
@ -30,18 +27,18 @@ public final class NyleasPresence extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{1}{G}");
this.subtype.add(SubType.AURA);
// Enchant land
TargetPermanent auraTarget = new TargetLandPermanent();
this.getSpellAbility().addTarget(auraTarget);
this.getSpellAbility().addEffect(new AttachEffect(Outcome.AddAbility));
Ability ability = new EnchantAbility(auraTarget.getTargetName());
this.addAbility(ability);
// When Nylea's Presence enters the battlefield, draw a card.
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) {
@ -56,22 +53,18 @@ public final class NyleasPresence extends CardImpl {
class NyleasPresenceLandTypeEffect extends ContinuousEffectImpl {
protected List<SubType> landTypes = new ArrayList<>();
public NyleasPresenceLandTypeEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
landTypes.addAll(SubType.getBasicLands());
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Detriment);
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) {
super(effect);
this.landTypes.addAll(effect.landTypes);
}
@Override
public boolean apply(Game game, Ability source) {
return false;
}
@Override
@ -80,52 +73,22 @@ class NyleasPresenceLandTypeEffect extends ContinuousEffectImpl {
}
@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());
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;
}
}
}
if (enchantment == null || enchantment.getAttachedTo() == null) {
return true;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
Permanent land = game.getPermanent(enchantment.getAttachedTo());
if (land == null) {
return true;
}
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) {
return false;
}
permanent.setIsAllCreatureTypes(false);
permanent.getSubtype(game).retainAll(SubType.getEnchantmentTypes());
permanent.getCardType().clear();
permanent.addCardType(CardType.ENCHANTMENT);
return true;

View file

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

View file

@ -1,7 +1,5 @@
package mage.cards.p;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
@ -19,14 +17,15 @@ import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class ParagonOfTheAmesha extends CardImpl {
public ParagonOfTheAmesha(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.HUMAN);
this.subtype.add(SubType.KNIGHT);
@ -37,18 +36,17 @@ public final class ParagonOfTheAmesha extends CardImpl {
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.
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.setText("gets +3/+3,");
effect.setText(", gets +3/+3");
ability.addEffect(effect);
effect = new GainAbilitySourceEffect(FlyingAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and gains flying");
effect.setText(", and gains flying");
ability.addEffect(effect);
effect = new GainAbilitySourceEffect(LifelinkAbility.getInstance(), Duration.EndOfTurn);
effect.setText("and lifelink");
ability.addEffect(effect);
this.addAbility(ability);
}
public ParagonOfTheAmesha(final ParagonOfTheAmesha card) {
@ -62,12 +60,12 @@ public final class ParagonOfTheAmesha extends CardImpl {
private static class ParagonOfTheAmeshaEffect extends ContinuousEffectImpl {
public ParagonOfTheAmeshaEffect() {
super(Duration.EndOfTurn, Outcome.BecomeCreature);
setText();
private ParagonOfTheAmeshaEffect() {
super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
staticText = "Until end of turn, {this} becomes an Angel";
}
public ParagonOfTheAmeshaEffect(final ParagonOfTheAmeshaEffect effect) {
private ParagonOfTheAmeshaEffect(final ParagonOfTheAmeshaEffect effect) {
super(effect);
}
@ -77,34 +75,14 @@ public final class ParagonOfTheAmesha extends CardImpl {
}
@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());
if (permanent == null) {
return false;
}
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.getSubtype(game).clear();
permanent.getSubtype(game).add(SubType.ANGEL);
}
break;
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.ANGEL);
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.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.mana.CommanderColorIdentityManaAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.SubType;
import mage.constants.SubTypeSet;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.players.Player;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
@ -92,8 +87,7 @@ class PathOfAncestryTriggeredAbility extends DelayedTriggeredAbility {
return false;
}
Spell spell = game.getStack().getSpell(event.getTargetId());
if (spell == null || (spell.getSubtype(game).isEmpty()
&& !spell.hasAbility(ChangelingAbility.getInstance(), game))) {
if (spell == null) {
return false;
}
Player player = game.getPlayer(getControllerId());
@ -101,7 +95,6 @@ class PathOfAncestryTriggeredAbility extends DelayedTriggeredAbility {
return false;
}
boolean isAllA = false;
Set<SubType> subTypeSet = new HashSet<>();
for (UUID commanderId : game.getCommandersIds(player)) {
Card commander = game.getPermanent(commanderId);
if (commander == null) {
@ -110,20 +103,12 @@ class PathOfAncestryTriggeredAbility extends DelayedTriggeredAbility {
if (commander == null) {
continue;
}
if (commander.isAllCreatureTypes()
|| commander.hasAbility(ChangelingAbility.getInstance(), game)) {
isAllA = true;
break;
if (spell.getCard().shareCreatureTypes(commander, game)) {
return true;
}
subTypeSet.addAll(commander.getSubtype(game));
}
subTypeSet.removeIf(subType -> subType.getSubTypeSet() != SubTypeSet.CreatureType);
if (subTypeSet.isEmpty() && !isAllA) {
return false;
}
return spell.hasAbility(ChangelingAbility.getInstance(), game)
|| spell.getSubtype(game).stream().anyMatch(subTypeSet::contains);
}
@Override
public String getRule() {

View file

@ -30,9 +30,7 @@ public final class PhantasmalImage extends CardImpl {
private static final ApplyToPermanent phantasmalImageApplier = new ApplyToPermanent() {
@Override
public boolean apply(Game game, Permanent permanent, Ability source, UUID copyToObjectId) {
if (!permanent.hasSubtype(SubType.ILLUSION, game)) {
permanent.getSubtype(game).add(SubType.ILLUSION);
}
permanent.addSubType(game, 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
permanent.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()));
//permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game);
@ -41,9 +39,7 @@ public final class PhantasmalImage extends CardImpl {
@Override
public boolean apply(Game game, MageObject mageObject, Ability source, UUID copyToObjectId) {
if (!mageObject.hasSubtype(SubType.ILLUSION, game)) {
mageObject.getSubtype(game).add(SubType.ILLUSION);
}
mageObject.addSubType(game, 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
mageObject.getAbilities().add(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()));
//permanent.addAbility(new BecomesTargetTriggeredAbility(new SacrificeSourceEffect()), game);

View file

@ -1,6 +1,5 @@
package mage.cards.p;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
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.ChooseBasicLandTypeEffect;
import mage.abilities.keyword.EnchantAbility;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.abilities.mana.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
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.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import mage.target.common.TargetLandPermanent;
import java.util.UUID;
/**
*
* @author Quercitron
*/
public final class PhantasmalTerrain extends CardImpl {
@ -60,14 +49,14 @@ public final class PhantasmalTerrain extends CardImpl {
return new PhantasmalTerrain(this);
}
class PhantasmalTerrainContinuousEffect extends ContinuousEffectImpl {
private static class PhantasmalTerrainContinuousEffect extends ContinuousEffectImpl {
public PhantasmalTerrainContinuousEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
this.staticText = "enchanted land is the chosen type";
private PhantasmalTerrainContinuousEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "Enchanted land is the chosen type";
}
public PhantasmalTerrainContinuousEffect(final PhantasmalTerrainContinuousEffect effect) {
private PhantasmalTerrainContinuousEffect(final PhantasmalTerrainContinuousEffect effect) {
super(effect);
}
@ -77,72 +66,60 @@ public final class PhantasmalTerrain extends CardImpl {
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Permanent enchantment = game.getPermanent(source.getSourceId());
SubType choice = SubType.byDescription((String) game.getState()
.getValue(source.getSourceId().toString() + ChooseBasicLandTypeEffect.VALUE_KEY));
if (choice != null) {
if (choice.equals(SubType.MOUNTAIN)) {
dependencyTypes.add(DependencyType.BecomeMountain);
}
if (choice.equals(SubType.FOREST)) {
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);
}
if (choice.equals(SubType.SWAMP)) {
dependencyTypes.add(DependencyType.BecomeSwamp);
}
if (choice.equals(SubType.ISLAND)) {
dependencyTypes.add(DependencyType.BecomeIsland);
}
if (choice.equals(SubType.PLAINS)) {
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;
}
}
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
if (choice.equals(SubType.FOREST)) {
@Override
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);
}
if (choice.equals(SubType.PLAINS)) {
break;
case PLAINS:
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.MOUNTAIN)) {
break;
case MOUNTAIN:
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.ISLAND)) {
break;
case ISLAND:
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.SWAMP)) {
break;
case SWAMP:
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
break;
}
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,39 +1,32 @@
package mage.cards.p;
import java.util.Iterator;
import java.util.UUID;
import mage.MageObjectReference;
import mage.ObjectColor;
import mage.abilities.Ability;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Layer;
import mage.constants.Outcome;
import mage.constants.SubLayer;
import mage.constants.SubType;
import mage.filter.common.FilterCreaturePermanent;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPlayer;
import java.util.Iterator;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class PolymorphistsJest extends CardImpl {
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.
this.getSpellAbility().addEffect(new PolymorphistsJestEffect());
this.getSpellAbility().addTarget(new TargetPlayer());
}
public PolymorphistsJest(final PolymorphistsJest card) {
@ -48,8 +41,6 @@ public final class PolymorphistsJest extends CardImpl {
class PolymorphistsJestEffect extends ContinuousEffectImpl {
private static final FilterCreaturePermanent filter = new FilterCreaturePermanent();
public PolymorphistsJestEffect() {
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";
@ -68,34 +59,31 @@ class PolymorphistsJestEffect extends ContinuousEffectImpl {
public void init(Ability source, Game game) {
super.init(source, game);
if (this.affectedObjectsSet) {
for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, getTargetPointer().getFirst(game, source), game)) {
affectedObjectList.add(new MageObjectReference(permanent, game));
}
game.getBattlefield()
.getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
getTargetPointer().getFirst(game, source), source.getSourceId(), game
).stream()
.map(permanent -> new MageObjectReference(permanent, game))
.forEach(affectedObjectList::add);
}
}
@Override
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);
if (permanent != null) {
if (permanent == null) {
it.remove();
continue;
}
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.getSubtype(game).clear();
permanent.getSubtype(game).add(SubType.FROG);
}
permanent.removeAllCreatureTypes(game);
permanent.addSubType(game, SubType.FROG);
break;
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);
}
break;
case AbilityAddingRemovingEffects_6:
permanent.removeAllAbilities(source.getSourceId(), game);
@ -106,9 +94,6 @@ class PolymorphistsJestEffect extends ContinuousEffectImpl {
permanent.getToughness().setValue(1);
}
}
} else {
it.remove();
}
}
return true;
}
@ -120,7 +105,10 @@ class PolymorphistsJestEffect extends ContinuousEffectImpl {
@Override
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;
import java.util.List;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AsEntersBattlefieldAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.ChooseBasicLandTypeEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.abilities.mana.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
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.FilterControlledLandPermanent;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.UUID;
/**
*
* @author jeffwadsworth
*/
public final class Realmwright extends CardImpl {
@ -46,7 +33,7 @@ public final class Realmwright extends CardImpl {
this.addAbility(new AsEntersBattlefieldAbility(new ChooseBasicLandTypeEffect(Outcome.Neutral)));
// 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) {
@ -59,111 +46,81 @@ public final class Realmwright extends CardImpl {
}
}
class RealmwrightEffect2 extends ContinuousEffectImpl {
class RealmwrightEffect extends ContinuousEffectImpl {
public RealmwrightEffect2() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
public RealmwrightEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
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);
}
@Override
public RealmwrightEffect2 copy() {
return new RealmwrightEffect2(this);
public RealmwrightEffect copy() {
return new RealmwrightEffect(this);
}
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
Player you = game.getPlayer(source.getControllerId());
List<Permanent> lands = game.getBattlefield().getAllActivePermanents(new FilterControlledLandPermanent(), source.getControllerId(), 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));
if (you != null && choice != null) {
for (Permanent land : lands) {
if (land != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA && !land.hasSubtype(choice, game)) {
land.getSubtype(game).add(choice);
}
switch (choice) {
case PLAINS:
dependencyTypes.add(DependencyType.BecomePlains);
break;
case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) {
boolean addAbility = true;
if (choice.equals(SubType.FOREST)) {
for (Ability existingAbility : land.getAbilities()) {
if (existingAbility instanceof GreenManaAbility) {
addAbility = false;
case ISLAND:
dependencyTypes.add(DependencyType.BecomeIsland);
break;
case SWAMP:
dependencyTypes.add(DependencyType.BecomeSwamp);
break;
case MOUNTAIN:
dependencyTypes.add(DependencyType.BecomeMountain);
break;
case FOREST:
dependencyTypes.add(DependencyType.BecomeForest);
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
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;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
Ability ability;
switch (choice) {
case PLAINS:
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.Mode;
import mage.abilities.effects.common.ReturnFromGraveyardToHandTargetEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.SubType;
import mage.constants.SubTypeSet;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.players.Player;
import mage.target.common.TargetCardInYourGraveyard;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
/**
* @author TheElk801
@ -73,12 +70,11 @@ class ReturnFromExtinctionTarget extends TargetCardInYourGraveyard {
if (targetOne == null || targetTwo == null) {
return false;
}
return targetOne.shareSubtypes(targetTwo, game);
return targetOne.shareCreatureTypes(targetTwo, game);
}
@Override
public boolean canChoose(UUID sourceId, UUID sourceControllerId, Game game) {
Set<SubType> subTypes = new HashSet<>();
MageObject targetSource = game.getObject(sourceId);
Player player = game.getPlayer(sourceControllerId);
if (player == null) {
@ -87,22 +83,21 @@ class ReturnFromExtinctionTarget extends TargetCardInYourGraveyard {
if (targetSource == null) {
return false;
}
for (Card card : player.getGraveyard().getCards(filter, sourceId, sourceControllerId, game)) {
if (card.isAllCreatureTypes() || card.hasAbility(ChangelingAbility.getInstance(), game)) {
if (!subTypes.isEmpty()) {
return true;
} else {
subTypes.addAll(SubType.getCreatureTypes());
List<Card> cards = player.getGraveyard().getCards(
filter, sourceId, sourceControllerId, game
).stream().collect(Collectors.toList());
if (cards.size() < 2) {
return false;
}
for (int i = 0; i < cards.size(); i++) {
for (int j = 0; j < cards.size(); j++) {
if (i <= j) {
continue;
}
for (SubType subType : card.getSubtype(game)) {
if (subType.getSubTypeSet() == SubTypeSet.CreatureType && subTypes.contains(subType)) {
if (cards.get(i).shareCreatureTypes(cards.get(j), game)) {
return true;
}
}
subTypes.addAll(card.getSubtype(game));
subTypes.removeIf((SubType st) -> (st.getSubTypeSet() != SubTypeSet.CreatureType));
}
return false;
}

View file

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

View file

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

View file

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

View file

@ -1,48 +1,49 @@
package mage.cards.s;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BecomesMonstrousSourceTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.common.combat.CantAttackUnlessDefenderControllsPermanent;
import mage.abilities.effects.common.continuous.AddCardSubTypeTargetEffect;
import mage.abilities.keyword.MonstrosityAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl;
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.game.Game;
import mage.game.permanent.Permanent;
import mage.target.Target;
import mage.target.common.TargetLandPermanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class SealockMonster extends CardImpl {
private static final FilterPermanent filter = new FilterLandPermanent(SubType.ISLAND, "an Island");
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.power = new MageInt(5);
this.toughness = new MageInt(5);
// 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"))));
// {5}{U}{U}: Monstrosity 3.</i>
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);
this.addAbility(new SimpleStaticAbility(new CantAttackUnlessDefenderControllsPermanent(filter)));
// {5}{U}{U}: Monstrosity 3.</i>
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 AddCardSubTypeTargetEffect(SubType.ISLAND, Duration.EndOfTurn)
);
ability.addTarget(new TargetLandPermanent());
this.addAbility(ability);
}
public SealockMonster(final SealockMonster card) {
@ -54,56 +55,3 @@ public final class SealockMonster extends CardImpl {
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.toughness = new MageInt(1);
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// {2}{U}: Target Shapeshifter becomes a copy of target creature until your next turn.

View file

@ -1,12 +1,10 @@
package mage.cards.s;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.Mode;
import mage.abilities.common.AttacksCreatureYouControlTriggeredAbility;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.keyword.ChangelingAbility;
import mage.cards.Card;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.*;
@ -18,21 +16,20 @@ import mage.filter.predicate.permanent.PermanentIdPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
*
* @author Plopman
*/
public final class SharedAnimosity extends CardImpl {
public SharedAnimosity(UUID ownerId, CardSetInfo setInfo) {
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.
this.addAbility(new AttacksCreatureYouControlTriggeredAbility(new SharedAnimosityEffect(), false, true));
this.addAbility(new AttacksCreatureYouControlTriggeredAbility(
new SharedAnimosityEffect(), false, true)
);
}
public SharedAnimosity(final SharedAnimosity card) {
@ -69,29 +66,11 @@ class SharedAnimosityEffect extends ContinuousEffectImpl {
super.init(source, game);
Permanent permanent = game.getPermanent(this.targetPointer.getFirst(game, source));
if (permanent != null) {
FilterCreaturePermanent filter = new FilterCreaturePermanent();
filter.add(Predicates.not(new PermanentIdPredicate(this.targetPointer.getFirst(game, source))));
filter.add(AttackingPredicate.instance);
boolean allCreatureTypes = false;
if (permanent.isAllCreatureTypes()) {
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();
filter.add(new SharedAnimosityPredicate(permanent));
power = game.getBattlefield().count(filter, source.getControllerId(), source.getSourceId(), game);
}
}
@ -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";
}
}
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);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
//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();) {
Permanent permanent = it.next().getPermanent(game);
if (permanent != null) {
permanent.addAbility(ChangelingAbility.getInstance(), source.getSourceId(), game);
permanent.setIsAllCreatureTypes(true);
} else {
it.remove();
}

View file

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

View file

@ -1,7 +1,6 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.Cost;
@ -17,8 +16,9 @@ import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetCardInHand;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class SlumberingTora extends CardImpl {
@ -26,14 +26,14 @@ public final class SlumberingTora extends CardImpl {
private static final FilterCard filter = new FilterCard("Spirit or Arcane card");
static {
filter.add(Predicates.or(SubType.SPIRIT.getPredicate(),SubType.ARCANE.getPredicate()));
filter.add(Predicates.or(SubType.SPIRIT.getPredicate(), SubType.ARCANE.getPredicate()));
}
public SlumberingTora(UUID ownerId, CardSetInfo setInfo) {
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,
// 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)));
this.addAbility(ability);
}
@ -49,12 +49,15 @@ public final class SlumberingTora extends CardImpl {
private static class SlumberingToraEffect extends ContinuousEffectImpl {
public SlumberingToraEffect() {
private int convManaCosts = 0;
private SlumberingToraEffect() {
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);
}
@ -63,48 +66,46 @@ public final class SlumberingTora extends CardImpl {
return new SlumberingToraEffect(this);
}
@Override
public void init(Ability source, Game game) {
super.init(source, game);
for (Cost cost : source.getCosts()) {
if (cost instanceof DiscardTargetCost && !((DiscardTargetCost) cost).getCards().isEmpty()) {
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) {
if (permanent == null) {
return false;
}
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
permanent.addCardType(CardType.ARTIFACT);
permanent.addCardType(CardType.CREATURE);
permanent.getSubtype(game).add(SubType.CAT);
}
permanent.addSubType(game, SubType.CAT);
break;
case PTChangingEffects_7:
if (sublayer == SubLayer.SetPT_7b) {
int convManaCosts = 0;
for (Cost cost: source.getCosts()) {
if (cost instanceof DiscardTargetCost && !((DiscardTargetCost) cost).getCards().isEmpty()) {
convManaCosts = ((DiscardTargetCost)cost).getCards().get(0).getConvertedManaCost();
break;
}
}
permanent.getPower().setValue(convManaCosts);
permanent.getToughness().setValue(convManaCosts);
}
}
return true;
}
return false;
}
@Override
public boolean apply(Game game, Ability source) {
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
public boolean hasLayer(Layer layer) {
return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4;
}
}
}

View file

@ -1,6 +1,5 @@
package mage.cards.s;
import java.util.UUID;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.ContinuousEffectImpl;
@ -9,20 +8,14 @@ import mage.abilities.keyword.EnchantAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
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.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.TargetPermanent;
import java.util.UUID;
/**
*
* @author LevelX2
*/
public final class SongOfTheDryads extends CardImpl {
@ -40,7 +33,6 @@ public final class SongOfTheDryads extends CardImpl {
// Enchanted permanent is a colorless Forest land.
this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BecomesColorlessForestLandEffect()));
}
public SongOfTheDryads(final SongOfTheDryads card) {
@ -55,13 +47,13 @@ public final class SongOfTheDryads extends CardImpl {
class BecomesColorlessForestLandEffect extends ContinuousEffectImpl {
public BecomesColorlessForestLandEffect() {
BecomesColorlessForestLandEffect() {
super(Duration.WhileOnBattlefield, Outcome.Detriment);
this.staticText = "Enchanted permanent is a colorless Forest land";
dependencyTypes.add(DependencyType.BecomeForest);
}
public BecomesColorlessForestLandEffect(final BecomesColorlessForestLandEffect effect) {
private BecomesColorlessForestLandEffect(final BecomesColorlessForestLandEffect effect) {
super(effect);
}
@ -78,9 +70,13 @@ class BecomesColorlessForestLandEffect extends ContinuousEffectImpl {
@Override
public boolean apply(Layer layer, SubLayer sublayer, Ability source, Game game) {
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());
if (permanent != null) {
if (permanent == null) {
return false;
}
switch (layer) {
case ColorChangingEffects_5:
permanent.getColor(game).setWhite(false);
@ -89,27 +85,21 @@ class BecomesColorlessForestLandEffect extends ContinuousEffectImpl {
permanent.getColor(game).setBlue(false);
permanent.getColor(game).setRed(false);
break;
case AbilityAddingRemovingEffects_6:
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break;
case TypeChangingEffects_4:
permanent.removeAllAbilities(source.getSourceId(), game);
permanent.getCardType().clear();
permanent.addCardType(CardType.LAND);
permanent.getSubtype(game).clear();
permanent.getSubtype(game).add(SubType.FOREST);
permanent.removeAllSubTypes(game);
permanent.addSubType(game, SubType.FOREST);
permanent.removeAllAbilities(source.getSourceId(), game);
permanent.addAbility(new GreenManaAbility(), source.getSourceId(), game);
break;
}
return true;
}
}
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6
|| layer == Layer.ColorChangingEffects_5
return layer == Layer.ColorChangingEffects_5
|| layer == Layer.TypeChangingEffects_4;
}
}

View file

@ -95,7 +95,7 @@ enum SorinVengefulBloodlordAdjuster implements TargetAdjuster {
class SorinVengefulBloodlordEffect extends ContinuousEffectImpl {
SorinVengefulBloodlordEffect() {
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) {
@ -119,11 +119,7 @@ class SorinVengefulBloodlordEffect extends ContinuousEffectImpl {
}
}
if (creature != null) {
if (sublayer == SubLayer.NA) {
if (!creature.hasSubtype(SubType.VAMPIRE, game)) {
creature.getSubtype(game).add(SubType.VAMPIRE);
}
}
creature.addSubType(game, SubType.VAMPIRE);
return true;
} else {
this.used = true;

View file

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

View file

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

View file

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

View file

@ -4,6 +4,7 @@ import mage.MageInt;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.effects.common.continuous.HasSubtypesSourceEffect;
import mage.abilities.mana.AnyColorManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
@ -22,16 +23,12 @@ public final class StoneworkPackbeast extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{2}");
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.toughness = new MageInt(1);
// Stonework Packbeast is also a Cleric, Rogue, Warrior, and Wizard.
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.

View file

@ -1,6 +1,5 @@
package mage.cards.s;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
@ -11,28 +10,23 @@ import mage.abilities.keyword.IslandwalkAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
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.constants.*;
import mage.filter.StaticFilters;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.common.FilterLandPermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.AbilityPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import java.util.UUID;
/**
*
* @author BetaSteward_at_googlemail.com
*/
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 {
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.)
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) {
@ -67,13 +61,13 @@ public final class StormtideLeviathan extends CardImpl {
class StormtideLeviathanEffect extends ContinuousEffectImpl {
public StormtideLeviathanEffect() {
super(Duration.WhileOnBattlefield, Outcome.Neutral);
private StormtideLeviathanEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Neutral);
staticText = "All lands are Islands in addition to their other types";
this.dependencyTypes.add(DependencyType.BecomeIsland);
}
public StormtideLeviathanEffect(final StormtideLeviathanEffect effect) {
private StormtideLeviathanEffect(final StormtideLeviathanEffect effect) {
super(effect);
}
@ -83,32 +77,17 @@ public final class StormtideLeviathan extends CardImpl {
}
@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(
new FilterLandPermanent(), source.getControllerId(), game)) {
switch (layer) {
case TypeChangingEffects_4:
StaticFilters.FILTER_LAND, source.getControllerId(), game
)) {
// land abilities are intrinsic, so add them here, not in layer 6
if (!land.hasSubtype(SubType.ISLAND, game)) {
land.getSubtype(game).add(SubType.ISLAND);
land.addSubType(game, SubType.ISLAND);
if (!land.getAbilities(game).containsClass(BlueManaAbility.class)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
}
break;
}
}
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.decorator.ConditionalInterveningIfTriggeredAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.InfoEffect;
import mage.abilities.keyword.ChangelingAbility;
import mage.abilities.effects.common.continuous.HasSubtypesSourceEffect;
import mage.abilities.keyword.KickerAbility;
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.predicate.Predicate;
import mage.game.Game;
@ -31,16 +33,12 @@ public final class TajuruParagon extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{G}");
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.toughness = new MageInt(2);
// Tajuru Paragon is also a Cleric, Rogue, Warrior, and Wizard.
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}
@ -115,27 +113,6 @@ class TajuruParagonPredicate implements Predicate<Card> {
@Override
public boolean apply(Card input, Game game) {
boolean isAllA = permanent.isAllCreatureTypes()
|| 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)));
return permanent != null && input != null && permanent.shareCreatureTypes(input, game);
}
}

View file

@ -26,6 +26,7 @@ public final class TaureanMauler extends CardImpl {
this.toughness = new MageInt(2);
// Changeling
this.setIsAllCreatureTypes(true);
this.addAbility(ChangelingAbility.getInstance());
// 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;
import java.util.Iterator;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
@ -10,30 +8,21 @@ import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.mana.BlackManaAbility;
import mage.abilities.mana.BlueManaAbility;
import mage.abilities.mana.GreenManaAbility;
import mage.abilities.mana.RedManaAbility;
import mage.abilities.mana.WhiteManaAbility;
import mage.abilities.mana.*;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.choices.ChoiceBasicLandType;
import mage.constants.CardType;
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.FilterControlledLandPermanent;
import mage.filter.common.FilterControlledPermanent;
import mage.constants.*;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import java.util.Iterator;
import java.util.UUID;
/**
*
* @author emerald000
*/
public final class Terraformer extends CardImpl {
@ -46,7 +35,7 @@ public final class Terraformer extends CardImpl {
this.toughness = new MageInt(2);
// {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) {
@ -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";
}
TerraformerEffect(final TerraformerEffect effect) {
private TerraformerEffect(final TerraformerEffect effect) {
super(effect);
}
@ -92,13 +81,11 @@ class TerraformerEffect extends OneShotEffect {
class TerraformerContinuousEffect extends ContinuousEffectImpl {
private static final FilterControlledPermanent filter = new FilterControlledLandPermanent();
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);
}
@ -110,64 +97,68 @@ class TerraformerContinuousEffect extends ContinuousEffectImpl {
@Override
public void init(Ability source, Game 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"));
if (choice != null) {
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext();) {
Permanent land = it.next().getPermanent(game);
if (land != null) {
switch (layer) {
case TypeChangingEffects_4:
if (sublayer == SubLayer.NA) {
land.getSubtype(game).clear();
land.getSubtype(game).add(choice);
}
switch (choice) {
case FOREST:
dependencyTypes.add(DependencyType.BecomeForest);
break;
case AbilityAddingRemovingEffects_6:
if (sublayer == SubLayer.NA) {
land.getAbilities().clear();
if (choice.equals(SubType.FOREST)) {
land.addAbility(new GreenManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.PLAINS)) {
land.addAbility(new WhiteManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.MOUNTAIN)) {
land.addAbility(new RedManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.ISLAND)) {
land.addAbility(new BlueManaAbility(), source.getSourceId(), game);
}
if (choice.equals(SubType.SWAMP)) {
land.addAbility(new BlackManaAbility(), source.getSourceId(), game);
}
}
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;
}
} else {
it.remove();
if (this.affectedObjectsSet) {
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
public boolean apply(Game game, Ability source) {
SubType choice = SubType.byDescription((String) game.getState().getValue(source.getSourceId().toString() + "_ElsewhereFlask"));
if (choice == null) {
return false;
}
@Override
public boolean hasLayer(Layer layer) {
return layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4;
for (Iterator<MageObjectReference> it = affectedObjectList.iterator(); it.hasNext(); ) {
Permanent land = it.next().getPermanent(game);
if (land == null) {
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;
import java.util.UUID;
import mage.MageInt;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.costs.mana.VariableManaCost;
import mage.abilities.dynamicvalue.common.ManacostVariableValue;
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.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
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.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.TokenImpl;
import mage.game.permanent.token.Token;
import java.util.UUID;
/**
*
* @author cbt33
* @author TheElk801
*/
public final class TestamentOfFaith extends CardImpl {
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.
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) {
@ -48,121 +45,30 @@ public final class TestamentOfFaith extends CardImpl {
}
}
class TestamentOfFaithBecomesCreatureSourceEffect extends ContinuousEffectImpl implements SourceEffect {
class TestamentOfFaithEffect extends ContinuousEffectImpl {
protected Token token;
protected String type;
protected int zoneChangeCounter;
public TestamentOfFaithBecomesCreatureSourceEffect(Token token, String type, Duration duration) {
super(duration, Outcome.BecomeCreature);
this.token = token;
this.type = type;
setText();
TestamentOfFaithEffect() {
super(Duration.EndOfTurn, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.BecomeCreature);
staticText = "Wall creature";
}
public TestamentOfFaithBecomesCreatureSourceEffect(final TestamentOfFaithBecomesCreatureSourceEffect effect) {
private TestamentOfFaithEffect(final TestamentOfFaithEffect effect) {
super(effect);
this.token = effect.token.copy();
this.type = effect.type;
}
@Override
public TestamentOfFaithBecomesCreatureSourceEffect copy() {
return new TestamentOfFaithBecomesCreatureSourceEffect(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;
public TestamentOfFaithEffect copy() {
return new TestamentOfFaithEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = game.getPermanent(source.getSourceId());
if (permanent == null) {
return false;
}
private void setText() {
staticText = "{this} becomes an X/X Wall creature with defender in addition to its other types until end of turn";
}
@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);
permanent.addCardType(CardType.CREATURE);
permanent.addSubType(game, SubType.WALL);
return true;
}
}

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