From 519eae42fcdbbf1e1ddbf27d35b3bd58828c2f17 Mon Sep 17 00:00:00 2001 From: LevelX2 Date: Sun, 31 Dec 2017 11:31:58 +0100 Subject: [PATCH] * Fixed some problems with abilities that let permanents become artifact creatures but only added creature card type instead of artifact and creature card type (fixes #4290). --- .../src/mage/cards/a/ArbiterOfTheIdeal.java | 2 +- .../src/mage/cards/a/ArgentMutation.java | 2 +- .../src/mage/cards/a/AshnodsTransmogrant.java | 2 +- .../src/mage/cards/f/FleetwheelCruiser.java | 16 +- Mage.Sets/src/mage/cards/h/HeartOfKiran.java | 9 +- Mage.Sets/src/mage/cards/k/KarnsTouch.java | 3 + .../src/mage/cards/l/LiquimetalCoating.java | 2 +- Mage.Sets/src/mage/cards/m/Memnarch.java | 2 +- .../mage/cards/m/MirrorOfTheForebears.java | 2 +- Mage.Sets/src/mage/cards/m/MyrLandshaper.java | 2 +- .../src/mage/cards/p/PeacewalkerColossus.java | 2 +- .../src/mage/cards/s/SilverskinArmor.java | 7 +- .../src/mage/cards/s/SydriGalvanicGenius.java | 7 +- .../mage/cards/t/TezzeretAgentOfBolas.java | 35 ++- Mage.Sets/src/mage/cards/t/ThranForge.java | 2 +- Mage.Sets/src/mage/cards/t/TitaniasSong.java | 26 +-- Mage.Sets/src/mage/cards/t/Toymaker.java | 5 +- Mage.Sets/src/mage/cards/x/XathridGorgon.java | 2 +- .../src/mage/cards/x/XenicPoltergeist.java | 9 +- .../continuous/AddCardTypeAttachedEffect.java | 9 +- .../continuous/AddCardTypeSourceEffect.java | 202 ++++++++++-------- .../continuous/AddCardTypeTargetEffect.java | 44 +++- .../mage/abilities/keyword/CrewAbility.java | 4 +- .../emblems/TezzeretTheSchemerEmblem.java | 6 +- 24 files changed, 225 insertions(+), 177 deletions(-) diff --git a/Mage.Sets/src/mage/cards/a/ArbiterOfTheIdeal.java b/Mage.Sets/src/mage/cards/a/ArbiterOfTheIdeal.java index 6a91a5f897e..31453ff15bf 100644 --- a/Mage.Sets/src/mage/cards/a/ArbiterOfTheIdeal.java +++ b/Mage.Sets/src/mage/cards/a/ArbiterOfTheIdeal.java @@ -119,7 +119,7 @@ class ArbiterOfTheIdealEffect extends OneShotEffect { Permanent permanent = game.getPermanent(card.getId()); if (permanent != null) { permanent.addCounters(new Counter("Manifestation"), source, game); - ContinuousEffect effect = new AddCardTypeTargetEffect(CardType.ENCHANTMENT, Duration.Custom); + ContinuousEffect effect = new AddCardTypeTargetEffect(Duration.Custom, CardType.ENCHANTMENT); effect.setTargetPointer(new FixedTarget(permanent.getId())); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/cards/a/ArgentMutation.java b/Mage.Sets/src/mage/cards/a/ArgentMutation.java index 4f0bd3b6afb..f115d399c46 100644 --- a/Mage.Sets/src/mage/cards/a/ArgentMutation.java +++ b/Mage.Sets/src/mage/cards/a/ArgentMutation.java @@ -46,7 +46,7 @@ public class ArgentMutation extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.INSTANT},"{2}{U}"); - this.getSpellAbility().addEffect(new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.EndOfTurn)); + this.getSpellAbility().addEffect(new AddCardTypeTargetEffect(Duration.EndOfTurn, CardType.ARTIFACT)); this.getSpellAbility().addTarget(new TargetPermanent()); this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1)); } diff --git a/Mage.Sets/src/mage/cards/a/AshnodsTransmogrant.java b/Mage.Sets/src/mage/cards/a/AshnodsTransmogrant.java index d75cdec650b..6c285b30c11 100644 --- a/Mage.Sets/src/mage/cards/a/AshnodsTransmogrant.java +++ b/Mage.Sets/src/mage/cards/a/AshnodsTransmogrant.java @@ -65,7 +65,7 @@ public class AshnodsTransmogrant extends CardImpl { // {T}, Sacrifice Ashnod's Transmogrant: Put a +1/+1 counter on target nonartifact creature. That creature becomes an artifact in addition to its other types. Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCountersTargetEffect(CounterType.P1P1.createInstance()), new TapSourceCost()); ability.addCost(new SacrificeSourceCost()); - Effect effect = new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.WhileOnBattlefield); + Effect effect = new AddCardTypeTargetEffect(Duration.WhileOnBattlefield, CardType.ARTIFACT); effect.setText("That creature becomes an artifact in addition to its other types"); ability.addEffect(effect); ability.addTarget(new TargetCreaturePermanent(filter)); diff --git a/Mage.Sets/src/mage/cards/f/FleetwheelCruiser.java b/Mage.Sets/src/mage/cards/f/FleetwheelCruiser.java index e2e32e699b1..71ec564a9aa 100644 --- a/Mage.Sets/src/mage/cards/f/FleetwheelCruiser.java +++ b/Mage.Sets/src/mage/cards/f/FleetwheelCruiser.java @@ -27,10 +27,9 @@ */ package mage.cards.f; +import java.util.UUID; import mage.MageInt; -import mage.abilities.Ability; import mage.abilities.common.EntersBattlefieldTriggeredAbility; -import mage.abilities.effects.Effect; import mage.abilities.effects.common.continuous.AddCardTypeSourceEffect; import mage.abilities.keyword.CrewAbility; import mage.abilities.keyword.HasteAbility; @@ -41,8 +40,6 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.SubType; -import java.util.UUID; - /** * * @author emerald000 @@ -50,7 +47,7 @@ import java.util.UUID; public class FleetwheelCruiser extends CardImpl { public FleetwheelCruiser(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{4}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{4}"); this.subtype.add(SubType.VEHICLE); this.power = new MageInt(5); this.toughness = new MageInt(3); @@ -62,13 +59,8 @@ public class FleetwheelCruiser extends CardImpl { this.addAbility(HasteAbility.getInstance()); // When Fleetwheel Cruiser enters the battlefield, it becomes an artifact creature until the end of turn. - Effect effect = new AddCardTypeSourceEffect(CardType.ARTIFACT, Duration.EndOfTurn); - effect.setText("it becomes an artifact"); - Ability ability = new EntersBattlefieldTriggeredAbility(effect); - effect = new AddCardTypeSourceEffect(CardType.CREATURE, Duration.EndOfTurn); - effect.setText(" creature until end of turn"); - ability.addEffect(effect); - this.addAbility(ability); + this.addAbility(new EntersBattlefieldTriggeredAbility( + new AddCardTypeSourceEffect(Duration.EndOfTurn, CardType.ARTIFACT, CardType.CREATURE))); // Crew 2 this.addAbility(new CrewAbility(2)); diff --git a/Mage.Sets/src/mage/cards/h/HeartOfKiran.java b/Mage.Sets/src/mage/cards/h/HeartOfKiran.java index 6ef4ab322a4..728776ed328 100644 --- a/Mage.Sets/src/mage/cards/h/HeartOfKiran.java +++ b/Mage.Sets/src/mage/cards/h/HeartOfKiran.java @@ -27,6 +27,7 @@ */ package mage.cards.h; +import java.util.UUID; import mage.MageInt; import mage.abilities.Ability; import mage.abilities.common.SimpleActivatedAbility; @@ -48,8 +49,6 @@ import mage.game.permanent.Permanent; import mage.target.Target; import mage.target.common.TargetControlledPermanent; -import java.util.UUID; - /** * @author JRHerlehy */ @@ -74,7 +73,7 @@ public class HeartOfKiran extends CardImpl { // You may remove a loyalty counter from a planeswalker you control rather than pay Heart of Kiran's crew cost. Cost cost = new HeartOfKiranAlternateCrewCost(CounterType.LOYALTY, 1); - Effect effect = new AddCardTypeSourceEffect(CardType.CREATURE, Duration.EndOfTurn); + Effect effect = new AddCardTypeSourceEffect(Duration.EndOfTurn, CardType.CREATURE, CardType.CREATURE); effect.setText("You may remove a loyalty counter from a planeswalker you control rather than pay {this}'s crew cost"); this.addAbility(new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, cost)); } @@ -91,8 +90,8 @@ public class HeartOfKiran extends CardImpl { class HeartOfKiranAlternateCrewCost extends CostImpl { - private CounterType counterTypeToRemove; - private int countersToRemove; + private final CounterType counterTypeToRemove; + private final int countersToRemove; private static final FilterControlledPlaneswalkerPermanent filter = new FilterControlledPlaneswalkerPermanent("planeswalker you control"); diff --git a/Mage.Sets/src/mage/cards/k/KarnsTouch.java b/Mage.Sets/src/mage/cards/k/KarnsTouch.java index 1d108e1261a..40801e90f57 100644 --- a/Mage.Sets/src/mage/cards/k/KarnsTouch.java +++ b/Mage.Sets/src/mage/cards/k/KarnsTouch.java @@ -99,6 +99,9 @@ class KarnsTouchEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { + if (!artifact.isArtifact()) { + artifact.addCardType(CardType.ARTIFACT); + } if (!artifact.isCreature()) { artifact.addCardType(CardType.CREATURE); } diff --git a/Mage.Sets/src/mage/cards/l/LiquimetalCoating.java b/Mage.Sets/src/mage/cards/l/LiquimetalCoating.java index 6883d4f7d3b..844e2c7cf05 100644 --- a/Mage.Sets/src/mage/cards/l/LiquimetalCoating.java +++ b/Mage.Sets/src/mage/cards/l/LiquimetalCoating.java @@ -50,7 +50,7 @@ public class LiquimetalCoating extends CardImpl { super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); // {T}: Target permanent becomes an artifact in addition to its other types until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.EndOfTurn), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCardTypeTargetEffect(Duration.EndOfTurn, CardType.ARTIFACT), new TapSourceCost()); ability.addTarget(new TargetPermanent()); this.addAbility(ability); } diff --git a/Mage.Sets/src/mage/cards/m/Memnarch.java b/Mage.Sets/src/mage/cards/m/Memnarch.java index 1d4e583c06f..504671d340b 100644 --- a/Mage.Sets/src/mage/cards/m/Memnarch.java +++ b/Mage.Sets/src/mage/cards/m/Memnarch.java @@ -60,7 +60,7 @@ public class Memnarch extends CardImpl { this.toughness = new MageInt(5); // {1}{U}{U}: Target permanent becomes an artifact in addition to its other types. - Effect effect = new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.WhileOnBattlefield); + Effect effect = new AddCardTypeTargetEffect(Duration.WhileOnBattlefield, CardType.ARTIFACT); effect.setText("Target permanent becomes an artifact in addition to its other types"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}{U}{U}")); ability.addTarget(new TargetPermanent()); diff --git a/Mage.Sets/src/mage/cards/m/MirrorOfTheForebears.java b/Mage.Sets/src/mage/cards/m/MirrorOfTheForebears.java index 2481c41ee86..ca3972d3992 100644 --- a/Mage.Sets/src/mage/cards/m/MirrorOfTheForebears.java +++ b/Mage.Sets/src/mage/cards/m/MirrorOfTheForebears.java @@ -103,7 +103,7 @@ class MirrorOfTheForebearsCopyEffect extends OneShotEffect { if (sourcePermanent != null && copyFromPermanent != null) { game.copyPermanent(Duration.EndOfTurn, copyFromPermanent, sourcePermanent.getId(), source, new EmptyApplyToPermanent()); if (!copyFromPermanent.isArtifact()) { - ContinuousEffect effect = new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.EndOfTurn); + ContinuousEffect effect = new AddCardTypeTargetEffect(Duration.EndOfTurn, CardType.ARTIFACT); effect.setTargetPointer(new FixedTarget(sourcePermanent, game)); game.addEffect(effect, source); } diff --git a/Mage.Sets/src/mage/cards/m/MyrLandshaper.java b/Mage.Sets/src/mage/cards/m/MyrLandshaper.java index ce9b56dad4d..09eff4a6220 100644 --- a/Mage.Sets/src/mage/cards/m/MyrLandshaper.java +++ b/Mage.Sets/src/mage/cards/m/MyrLandshaper.java @@ -55,7 +55,7 @@ public class MyrLandshaper extends CardImpl { this.toughness = new MageInt(1); // {tap}: Target land becomes an artifact in addition to its other types until end of turn. - Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.EndOfTurn), new TapSourceCost()); + Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, new AddCardTypeTargetEffect(Duration.EndOfTurn, CardType.ARTIFACT), new TapSourceCost()); Target target = new TargetLandPermanent(); ability.addTarget(target); this.addAbility(ability); diff --git a/Mage.Sets/src/mage/cards/p/PeacewalkerColossus.java b/Mage.Sets/src/mage/cards/p/PeacewalkerColossus.java index 2026de28a92..0f8ac6c009a 100644 --- a/Mage.Sets/src/mage/cards/p/PeacewalkerColossus.java +++ b/Mage.Sets/src/mage/cards/p/PeacewalkerColossus.java @@ -67,7 +67,7 @@ public class PeacewalkerColossus extends CardImpl { this.toughness = new MageInt(6); // {1}{W}: Another target Vehicle you control becomes an artifact creature until end of turn. - Effect effect = new AddCardTypeTargetEffect(CardType.CREATURE, Duration.EndOfTurn); + Effect effect = new AddCardTypeTargetEffect(Duration.EndOfTurn, CardType.CREATURE); effect.setText("Another target Vehicle you control becomes an artifact creature until end of turn"); Ability ability = new SimpleActivatedAbility(Zone.BATTLEFIELD, effect, new ManaCostsImpl("{1}{W}")); ability.addTarget(new TargetControlledPermanent(filter)); diff --git a/Mage.Sets/src/mage/cards/s/SilverskinArmor.java b/Mage.Sets/src/mage/cards/s/SilverskinArmor.java index 9dfbc072d74..ef3629a1e61 100644 --- a/Mage.Sets/src/mage/cards/s/SilverskinArmor.java +++ b/Mage.Sets/src/mage/cards/s/SilverskinArmor.java @@ -44,12 +44,15 @@ import mage.constants.*; public class SilverskinArmor extends CardImpl { public SilverskinArmor(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ARTIFACT},"{2}"); + super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{2}"); this.subtype.add(SubType.EQUIPMENT); - this.addAbility(new EquipAbility(Outcome.BoostCreature, new ManaCostsImpl("{2}"))); + // Equipped creature gets +1/+1 and is an artifact in addition to its other types. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new BoostEquippedEffect(1, 1, Duration.WhileOnBattlefield))); this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new AddCardTypeAttachedEffect(CardType.ARTIFACT, Duration.WhileOnBattlefield, AttachmentType.EQUIPMENT))); + + // Equip {2} + this.addAbility(new EquipAbility(Outcome.BoostCreature, new ManaCostsImpl("{2}"))); } public SilverskinArmor(final SilverskinArmor card) { diff --git a/Mage.Sets/src/mage/cards/s/SydriGalvanicGenius.java b/Mage.Sets/src/mage/cards/s/SydriGalvanicGenius.java index abb6bd3e3ce..fcd691c172a 100644 --- a/Mage.Sets/src/mage/cards/s/SydriGalvanicGenius.java +++ b/Mage.Sets/src/mage/cards/s/SydriGalvanicGenius.java @@ -56,6 +56,7 @@ public class SydriGalvanicGenius extends CardImpl { private static final FilterPermanent filter = new FilterPermanent("artifact creature"); private static final FilterArtifactPermanent filterNonCreature = new FilterArtifactPermanent("noncreature artifact"); + static { filter.add(new CardTypePredicate(CardType.ARTIFACT)); filter.add(new CardTypePredicate(CardType.CREATURE)); @@ -63,7 +64,7 @@ public class SydriGalvanicGenius extends CardImpl { } public SydriGalvanicGenius(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.CREATURE},"{W}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{W}{U}{B}"); addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.HUMAN); this.subtype.add(SubType.ARTIFICER); @@ -119,6 +120,9 @@ class SydriGalvanicGeniusEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { + if (!artifact.isArtifact()) { + artifact.addCardType(CardType.ARTIFACT); + } if (!artifact.isCreature()) { artifact.addCardType(CardType.CREATURE); } @@ -140,7 +144,6 @@ class SydriGalvanicGeniusEffect extends ContinuousEffectImpl { return false; } - @Override public boolean hasLayer(Layer layer) { return layer == Layer.PTChangingEffects_7 || layer == Layer.TypeChangingEffects_4; diff --git a/Mage.Sets/src/mage/cards/t/TezzeretAgentOfBolas.java b/Mage.Sets/src/mage/cards/t/TezzeretAgentOfBolas.java index caf6fb786b3..b4a15138749 100644 --- a/Mage.Sets/src/mage/cards/t/TezzeretAgentOfBolas.java +++ b/Mage.Sets/src/mage/cards/t/TezzeretAgentOfBolas.java @@ -31,7 +31,6 @@ import java.util.UUID; import mage.abilities.Ability; import mage.abilities.LoyaltyAbility; import mage.abilities.common.PlanswalkerEntersWithLoyalityCountersAbility; -import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.common.PermanentsOnBattlefieldCount; import mage.abilities.effects.Effect; import mage.abilities.effects.OneShotEffect; @@ -41,12 +40,12 @@ import mage.abilities.effects.common.continuous.SetPowerToughnessTargetEffect; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; -import mage.constants.SubType; import mage.constants.Duration; import mage.constants.Outcome; +import mage.constants.SubType; import mage.constants.SuperType; import mage.filter.FilterCard; -import mage.filter.common.FilterControlledPermanent; +import mage.filter.StaticFilters; import mage.filter.predicate.mageobject.CardTypePredicate; import mage.game.Game; import mage.players.Player; @@ -66,7 +65,7 @@ public class TezzeretAgentOfBolas extends CardImpl { } public TezzeretAgentOfBolas(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.PLANESWALKER},"{2}{U}{B}"); + super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{U}{B}"); this.addSuperType(SuperType.LEGENDARY); this.subtype.add(SubType.TEZZERET); @@ -76,7 +75,7 @@ public class TezzeretAgentOfBolas extends CardImpl { this.addAbility(new LoyaltyAbility(new LookLibraryAndPickControllerEffect(5, 1, filter, true), 1)); // -1: Target artifact becomes an artifact creature with base power and toughness 5/5. - Effect effect = new AddCardTypeTargetEffect(CardType.CREATURE, Duration.EndOfGame); + Effect effect = new AddCardTypeTargetEffect(Duration.EndOfGame, CardType.ARTIFACT, CardType.CREATURE); effect.setText("Target artifact becomes an artifact creature"); LoyaltyAbility ability1 = new LoyaltyAbility(effect, -1); effect = new SetPowerToughnessTargetEffect(5, 5, Duration.EndOfGame); @@ -105,12 +104,6 @@ public class TezzeretAgentOfBolas extends CardImpl { class TezzeretAgentOfBolasEffect2 extends OneShotEffect { - final static FilterControlledPermanent filter = new FilterControlledPermanent("artifacts"); - - static { - filter.add(new CardTypePredicate(CardType.ARTIFACT)); - } - public TezzeretAgentOfBolasEffect2() { super(Outcome.DrawCard); staticText = "Target player loses X life and you gain X life, where X is twice the number of artifacts you control"; @@ -127,16 +120,16 @@ class TezzeretAgentOfBolasEffect2 extends OneShotEffect { @Override public boolean apply(Game game, Ability source) { - DynamicValue value = new PermanentsOnBattlefieldCount(filter); - int count = value.calculate(game, source, this) * 2; - - Player player = game.getPlayer(source.getFirstTarget()); - if (player != null) { - player.loseLife(count, game, false); - } - Player controller = game.getPlayer(source.getControllerId()); - if (controller != null) { - controller.gainLife(count, game); + int count = new PermanentsOnBattlefieldCount(StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT).calculate(game, source, this) * 2; + if (count > 0) { + Player targetPlayer = game.getPlayer(getTargetPointer().getFirst(game, source)); + if (targetPlayer != null) { + targetPlayer.loseLife(count, game, false); + } + Player controller = game.getPlayer(source.getControllerId()); + if (controller != null) { + controller.gainLife(count, game); + } } return true; } diff --git a/Mage.Sets/src/mage/cards/t/ThranForge.java b/Mage.Sets/src/mage/cards/t/ThranForge.java index b3a9c66ed18..3d9a2e6887e 100644 --- a/Mage.Sets/src/mage/cards/t/ThranForge.java +++ b/Mage.Sets/src/mage/cards/t/ThranForge.java @@ -65,7 +65,7 @@ public class ThranForge extends CardImpl { .setText("Until end of turn, target nonartifact creature gets +1/+0"), new GenericManaCost(2)); ability.addEffect( - new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.EndOfTurn) + new AddCardTypeTargetEffect(Duration.EndOfTurn, CardType.ARTIFACT) .setText("and becomes an artifact in addition to its other types") ); ability.addTarget(new TargetPermanent(filter)); diff --git a/Mage.Sets/src/mage/cards/t/TitaniasSong.java b/Mage.Sets/src/mage/cards/t/TitaniasSong.java index a4a04855809..8856103e824 100644 --- a/Mage.Sets/src/mage/cards/t/TitaniasSong.java +++ b/Mage.Sets/src/mage/cards/t/TitaniasSong.java @@ -55,11 +55,11 @@ import mage.game.permanent.Permanent; public class TitaniasSong extends CardImpl { public TitaniasSong(UUID ownerId, CardSetInfo setInfo) { - super(ownerId,setInfo,new CardType[]{CardType.ENCHANTMENT},"{3}{G}"); + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{3}{G}"); // Each noncreature artifact loses all abilities and becomes an artifact creature with power and toughness each equal to its converted mana cost. If Titania's Song leaves the battlefield, this effect continues until end of turn. this.addAbility(new SimpleStaticAbility(Zone.BATTLEFIELD, new TitaniasSongEffect(Duration.WhileOnBattlefield))); - this.addAbility(new LeavesBattlefieldTriggeredAbility(new TitaniasSongEffect(Duration.EndOfTurn), false)); + this.addAbility(new LeavesBattlefieldTriggeredAbility(new TitaniasSongEffect(Duration.EndOfTurn), false)); } public TitaniasSong(final TitaniasSong card) { @@ -71,12 +71,15 @@ public class TitaniasSong extends CardImpl { return new TitaniasSong(this); } } + class TitaniasSongEffect extends ContinuousEffectImpl { private static final FilterArtifactPermanent filter = new FilterArtifactPermanent(); + static { filter.add(Predicates.not(new CardTypePredicate(CardType.CREATURE))); } + public TitaniasSongEffect(Duration duration) { super(duration, Outcome.BecomeCreature); staticText = "Each noncreature artifact loses its abilities and is an artifact creature with power and toughness each equal to its converted mana cost"; @@ -97,8 +100,8 @@ class TitaniasSongEffect extends ContinuousEffectImpl { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { affectedObjectList.clear(); - for(Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)){ - if(permanent != null){ + for (Permanent permanent : game.getBattlefield().getAllActivePermanents(filter, game)) { + if (permanent != null) { affectedObjectList.add(new MageObjectReference(permanent, game)); permanent.addCardType(CardType.CREATURE); } @@ -106,18 +109,18 @@ class TitaniasSongEffect extends ContinuousEffectImpl { } break; case AbilityAddingRemovingEffects_6: - for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { - Permanent permanent = it.next().getPermanent(game); - if (permanent != null){ - permanent.removeAllAbilities(source.getSourceId(), game); - } + for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { + Permanent permanent = it.next().getPermanent(game); + if (permanent != null) { + permanent.removeAllAbilities(source.getSourceId(), game); } - break; + } + break; case PTChangingEffects_7: if (sublayer == SubLayer.SetPT_7b) { for (Iterator it = affectedObjectList.iterator(); it.hasNext();) { Permanent permanent = it.next().getPermanent(game); - if (permanent != null){ + if (permanent != null) { int manaCost = permanent.getConvertedManaCost(); permanent.getPower().setValue(manaCost); permanent.getToughness().setValue(manaCost); @@ -133,7 +136,6 @@ class TitaniasSongEffect extends ContinuousEffectImpl { return false; } - @Override public boolean hasLayer(Layer layer) { return layer == Layer.PTChangingEffects_7 || layer == Layer.AbilityAddingRemovingEffects_6 || layer == Layer.TypeChangingEffects_4; diff --git a/Mage.Sets/src/mage/cards/t/Toymaker.java b/Mage.Sets/src/mage/cards/t/Toymaker.java index 19e1b673581..dd3cfa42e0e 100644 --- a/Mage.Sets/src/mage/cards/t/Toymaker.java +++ b/Mage.Sets/src/mage/cards/t/Toymaker.java @@ -35,7 +35,6 @@ import mage.abilities.costs.common.DiscardCardCost; import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.mana.ManaCostsImpl; import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.SubType; import mage.cards.CardImpl; import mage.cards.CardSetInfo; import mage.constants.CardType; @@ -43,6 +42,7 @@ 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.filter.common.FilterArtifactPermanent; import mage.filter.predicate.Predicates; @@ -113,6 +113,9 @@ class ToymakerEffect extends ContinuousEffectImpl { switch (layer) { case TypeChangingEffects_4: if (sublayer == SubLayer.NA) { + if (!artifact.isArtifact()) { + artifact.addCardType(CardType.ARTIFACT); + } if (!artifact.isCreature()) { artifact.addCardType(CardType.CREATURE); } diff --git a/Mage.Sets/src/mage/cards/x/XathridGorgon.java b/Mage.Sets/src/mage/cards/x/XathridGorgon.java index df29417c955..87979a66624 100644 --- a/Mage.Sets/src/mage/cards/x/XathridGorgon.java +++ b/Mage.Sets/src/mage/cards/x/XathridGorgon.java @@ -76,7 +76,7 @@ public class XathridGorgon extends CardImpl { Effect effect = new GainAbilityTargetEffect(DefenderAbility.getInstance(), Duration.Custom); effect.setText("It gains defender"); ability.addEffect(effect); - effect = new AddCardTypeTargetEffect(CardType.ARTIFACT, Duration.Custom); + effect = new AddCardTypeTargetEffect(Duration.Custom, CardType.ARTIFACT); effect.setText("and becomes a colorless artifact in addition to its other types"); ability.addEffect(effect); ability.addEffect(new BecomesColorTargetEffect(new ObjectColor(), Duration.Custom, "")); diff --git a/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java b/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java index c17170e71d2..74fb2c78ed6 100644 --- a/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java +++ b/Mage.Sets/src/mage/cards/x/XenicPoltergeist.java @@ -36,12 +36,12 @@ import mage.abilities.effects.ContinuousEffectImpl; 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.PhaseStep; import mage.constants.SubLayer; +import mage.constants.SubType; import mage.constants.Zone; import mage.filter.common.FilterArtifactPermanent; import mage.filter.predicate.Predicates; @@ -125,7 +125,12 @@ class XenicPoltergeistEffect extends ContinuousEffectImpl { UUID permanentId = targetPointer.getFirst(game, source); Permanent permanent = game.getPermanentOrLKIBattlefield(permanentId); if (permanent != null) { - permanent.addCardType(CardType.CREATURE); + if (!permanent.isArtifact()) { + permanent.addCardType(CardType.ARTIFACT); + } + if (!permanent.isCreature()) { + permanent.addCardType(CardType.CREATURE); + } } } break; diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java index 360091fca26..9b8c56f771c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeAttachedEffect.java @@ -25,7 +25,6 @@ * authors and should not be interpreted as representing official policies, either expressed * or implied, of BetaSteward_at_googlemail.com. */ - package mage.abilities.effects.common.continuous; import mage.abilities.Ability; @@ -38,8 +37,9 @@ import mage.game.permanent.Permanent; * @author nantuko */ public class AddCardTypeAttachedEffect extends ContinuousEffectImpl { - private CardType addedCardType; - private AttachmentType attachmentType; + + private final CardType addedCardType; + private final AttachmentType attachmentType; public AddCardTypeAttachedEffect(CardType addedCardType, Duration duration, AttachmentType attachmentType) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); @@ -59,8 +59,9 @@ public class AddCardTypeAttachedEffect extends ContinuousEffectImpl { Permanent equipment = game.getPermanent(source.getSourceId()); if (equipment != null && equipment.getAttachedTo() != null) { Permanent target = game.getPermanent(equipment.getAttachedTo()); - if (target != null && !target.getCardType().contains(addedCardType)) + if (target != null && !target.getCardType().contains(addedCardType)) { target.addCardType(addedCardType); + } } return true; } diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java index 6fe7d4d7ab2..4858b6e169b 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeSourceEffect.java @@ -1,90 +1,112 @@ -/* - * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, are - * permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, this list of - * conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, this list - * of conditions and the following disclaimer in the documentation and/or other materials - * provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * The views and conclusions contained in the software and documentation are those of the - * authors and should not be interpreted as representing official policies, either expressed - * or implied, of BetaSteward_at_googlemail.com. - */ -package mage.abilities.effects.common.continuous; - -import mage.MageObjectReference; -import mage.abilities.Ability; -import mage.abilities.Mode; -import mage.abilities.effects.ContinuousEffectImpl; -import mage.constants.*; -import mage.game.Game; -import mage.game.permanent.Permanent; - -/** - * @author emerald000 - */ -public class AddCardTypeSourceEffect extends ContinuousEffectImpl { - - private final CardType addedCardType; - - public AddCardTypeSourceEffect(CardType addedCardType, Duration duration) { - super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); - this.addedCardType = addedCardType; - if (addedCardType == CardType.ENCHANTMENT) { - dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); - } - } - - public AddCardTypeSourceEffect(final AddCardTypeSourceEffect effect) { - super(effect); - this.addedCardType = effect.addedCardType; - } - - @Override - public void init(Ability source, Game game) { - super.init(source, game); - affectedObjectList.add(new MageObjectReference(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()), game)); - } - - @Override - public boolean apply(Game game, Ability source) { - Permanent permanent = game.getPermanent(source.getSourceId()); - if (permanent != null && affectedObjectList.contains(new MageObjectReference(permanent, game))) { - permanent.addCardType(addedCardType); - return true; - } else if (this.getDuration() == Duration.Custom) { - this.discard(); - } - return false; - } - - @Override - public AddCardTypeSourceEffect copy() { - return new AddCardTypeSourceEffect(this); - } - - @Override - public String getText(Mode mode) { - if (staticText != null && !staticText.isEmpty()) { - return staticText; - } - StringBuilder sb = new StringBuilder(); - sb.append("{this} becomes ").append(addedCardType.toString()).append(" in addition to its other types " + this.getDuration().toString()); - return sb.toString(); - } -} +/* + * Copyright 2010 BetaSteward_at_googlemail.com. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are + * permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of + * conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, this list + * of conditions and the following disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY BetaSteward_at_googlemail.com ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BetaSteward_at_googlemail.com OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the + * authors and should not be interpreted as representing official policies, either expressed + * or implied, of BetaSteward_at_googlemail.com. + */ +package mage.abilities.effects.common.continuous; + +import java.util.ArrayList; +import mage.MageObjectReference; +import mage.abilities.Ability; +import mage.abilities.Mode; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.constants.*; +import mage.game.Game; +import mage.game.permanent.Permanent; + +/** + * @author emerald000 + */ +public class AddCardTypeSourceEffect extends ContinuousEffectImpl { + + private final ArrayList addedCardTypes = new ArrayList<>(); + + public AddCardTypeSourceEffect(Duration duration, CardType... addedCardType) { + super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + for (CardType cardType : addedCardType) { + this.addedCardTypes.add(cardType); + if (cardType == CardType.ENCHANTMENT) { + dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); + } else if (cardType == CardType.ARTIFACT) { + dependencyTypes.add(DependencyType.ArtifactAddingRemoving); + } + } + } + + public AddCardTypeSourceEffect(final AddCardTypeSourceEffect effect) { + super(effect); + this.addedCardTypes.addAll(effect.addedCardTypes); + } + + @Override + public void init(Ability source, Game game) { + super.init(source, game); + affectedObjectList.add(new MageObjectReference(source.getSourceId(), game.getState().getZoneChangeCounter(source.getSourceId()), game)); + } + + @Override + public boolean apply(Game game, Ability source) { + Permanent permanent = game.getPermanent(source.getSourceId()); + if (permanent != null && affectedObjectList.contains(new MageObjectReference(permanent, game))) { + for (CardType cardType : addedCardTypes) { + if (!permanent.getCardType().contains(cardType)) { + permanent.addCardType(cardType); + } + } + return true; + } else if (this.getDuration() == Duration.Custom) { + this.discard(); + } + return false; + } + + @Override + public AddCardTypeSourceEffect copy() { + return new AddCardTypeSourceEffect(this); + } + + @Override + public String getText(Mode mode) { + if (staticText != null && !staticText.isEmpty()) { + return staticText; + } + StringBuilder sb = new StringBuilder(); + sb.append("{this} becomes "); + boolean article = false; + for (CardType cardType : addedCardTypes) { + if (!article) { + if (cardType.toString().startsWith("A") || cardType.toString().startsWith("E")) { + sb.append("an "); + } else { + sb.append("a "); + } + article = true; + } + sb.append(cardType.toString().toLowerCase()).append(" "); + } + sb.append(" in addition to its other types ").append(this.getDuration().toString()); + return sb.toString(); + } +} diff --git a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java index 33c325bdc40..24fd3a05d4c 100644 --- a/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java +++ b/Mage/src/main/java/mage/abilities/effects/common/continuous/AddCardTypeTargetEffect.java @@ -27,6 +27,7 @@ */ package mage.abilities.effects.common.continuous; +import java.util.ArrayList; import java.util.UUID; import mage.abilities.Ability; import mage.abilities.Mode; @@ -45,21 +46,24 @@ import mage.game.permanent.Permanent; */ public class AddCardTypeTargetEffect extends ContinuousEffectImpl { - private final CardType addedCardType; + private final ArrayList addedCardTypes = new ArrayList<>(); - public AddCardTypeTargetEffect(CardType addedCardType, Duration duration) { + public AddCardTypeTargetEffect(Duration duration, CardType... addedCardType) { super(duration, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); - this.addedCardType = addedCardType; - if (addedCardType == CardType.ENCHANTMENT) { - dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); - } else if (addedCardType == CardType.ARTIFACT) { - dependencyTypes.add(DependencyType.ArtifactAddingRemoving); + for (CardType cardType : addedCardType) { + this.addedCardTypes.add(cardType); + if (cardType == CardType.ENCHANTMENT) { + dependencyTypes.add(DependencyType.EnchantmentAddingRemoving); + } else if (cardType == CardType.ARTIFACT) { + dependencyTypes.add(DependencyType.ArtifactAddingRemoving); + } } + } public AddCardTypeTargetEffect(final AddCardTypeTargetEffect effect) { super(effect); - this.addedCardType = effect.addedCardType; + this.addedCardTypes.addAll(effect.addedCardTypes); } @Override @@ -68,8 +72,10 @@ public class AddCardTypeTargetEffect extends ContinuousEffectImpl { for (UUID targetId : targetPointer.getTargets(game, source)) { Permanent target = game.getPermanent(targetId); if (target != null) { - if (!target.getCardType().contains(addedCardType)) { - target.addCardType(addedCardType); + for (CardType cardType : addedCardTypes) { + if (!target.getCardType().contains(cardType)) { + target.addCardType(cardType); + } } result = true; } @@ -93,7 +99,23 @@ public class AddCardTypeTargetEffect extends ContinuousEffectImpl { return staticText; } StringBuilder sb = new StringBuilder(); - sb.append("Target ").append(mode.getTargets().get(0).getTargetName()).append(" becomes ").append(addedCardType.toString()).append(" in addition to its other types until end of turn"); + sb.append("Target ").append(mode.getTargets().get(0).getTargetName()).append(" becomes "); + boolean article = false; + for (CardType cardType : addedCardTypes) { + if (!article) { + if (cardType.toString().startsWith("A") || cardType.toString().startsWith("E")) { + sb.append("an "); + } else { + sb.append("a "); + } + article = true; + } + sb.append(cardType.toString().toLowerCase()).append(" "); + } + sb.append("in addition to its other types"); + if (getDuration().equals(Duration.EndOfTurn)) { + sb.append(" until end of turn"); + } return sb.toString(); } } diff --git a/Mage/src/main/java/mage/abilities/keyword/CrewAbility.java b/Mage/src/main/java/mage/abilities/keyword/CrewAbility.java index a17d5ad6e74..5175c3ce81b 100644 --- a/Mage/src/main/java/mage/abilities/keyword/CrewAbility.java +++ b/Mage/src/main/java/mage/abilities/keyword/CrewAbility.java @@ -54,8 +54,8 @@ public class CrewAbility extends SimpleActivatedAbility { private final int value; public CrewAbility(int value) { - super(Zone.BATTLEFIELD, new AddCardTypeSourceEffect(CardType.ARTIFACT, Duration.EndOfTurn), new CrewCost(value)); - this.addEffect(new AddCardTypeSourceEffect(CardType.CREATURE, Duration.EndOfTurn)); + super(Zone.BATTLEFIELD, new AddCardTypeSourceEffect(Duration.EndOfTurn, CardType.ARTIFACT), new CrewCost(value)); + this.addEffect(new AddCardTypeSourceEffect(Duration.EndOfTurn, CardType.ARTIFACT, CardType.CREATURE)); this.value = value; } diff --git a/Mage/src/main/java/mage/game/command/emblems/TezzeretTheSchemerEmblem.java b/Mage/src/main/java/mage/game/command/emblems/TezzeretTheSchemerEmblem.java index 82cab888b4a..2de6910fdd2 100644 --- a/Mage/src/main/java/mage/game/command/emblems/TezzeretTheSchemerEmblem.java +++ b/Mage/src/main/java/mage/game/command/emblems/TezzeretTheSchemerEmblem.java @@ -36,7 +36,7 @@ import mage.constants.CardType; import mage.constants.Duration; import mage.constants.TargetController; import mage.constants.Zone; -import mage.filter.common.FilterControlledArtifactPermanent; +import static mage.filter.StaticFilters.FILTER_CONTROLLED_PERMANENT_ARTIFACT; import mage.game.command.Emblem; import mage.target.TargetPermanent; @@ -49,13 +49,13 @@ public class TezzeretTheSchemerEmblem extends Emblem { public TezzeretTheSchemerEmblem() { this.setName("Emblem Tezzeret"); - Effect effect = new AddCardTypeTargetEffect(CardType.CREATURE, Duration.EndOfGame); + Effect effect = new AddCardTypeTargetEffect(Duration.EndOfGame, CardType.ARTIFACT, CardType.CREATURE); effect.setText("target artifact you control becomes an artifact creature"); Ability ability = new BeginningOfCombatTriggeredAbility(Zone.COMMAND, effect, TargetController.YOU, false, true); effect = new SetPowerToughnessTargetEffect(5, 5, Duration.EndOfGame); effect.setText("with base power and toughness 5/5"); ability.addEffect(effect); - ability.addTarget(new TargetPermanent(new FilterControlledArtifactPermanent())); + ability.addTarget(new TargetPermanent(FILTER_CONTROLLED_PERMANENT_ARTIFACT)); this.getAbilities().add(ability); } }