From e76cc902270a9367c6842a36fb885c6cb90f9e7d Mon Sep 17 00:00:00 2001 From: Grath <1895280+Grath@users.noreply.github.com> Date: Mon, 26 Sep 2022 12:21:39 -0400 Subject: [PATCH] [40K] Implement Biotransference (#9570) --- .../src/mage/cards/a/ArcaneAdaptation.java | 8 +- .../src/mage/cards/b/Biotransference.java | 140 ++++++++++++++++++ Mage.Sets/src/mage/sets/Warhammer40000.java | 1 + 3 files changed, 144 insertions(+), 5 deletions(-) create mode 100644 Mage.Sets/src/mage/cards/b/Biotransference.java diff --git a/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java index f9a6967e801..30a275a5abf 100644 --- a/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java +++ b/Mage.Sets/src/mage/cards/a/ArcaneAdaptation.java @@ -19,7 +19,6 @@ import mage.game.stack.Spell; import mage.game.stack.StackObject; import mage.players.Player; -import java.util.Iterator; import java.util.List; import java.util.UUID; @@ -88,7 +87,7 @@ class ArcaneAdaptationEffect extends ContinuousEffectImpl { } } // in Exile - for (Card card : game.getState().getExile().getAllCards(game)) { + for (Card card : game.getState().getExile().getAllCards(game, source.getControllerId())) { if (card.isCreature(game) && !card.hasSubtype(subType, game)) { game.getState().getCreateMageObjectAttribute(card, game).getSubtype().add(subType); } @@ -109,10 +108,9 @@ class ArcaneAdaptationEffect extends ContinuousEffectImpl { } } } - // TODO: Why is this not using the for-in loop like all the others? + // creature spells you control - for (Iterator iterator = game.getStack().iterator(); iterator.hasNext(); ) { - StackObject stackObject = iterator.next(); + for (StackObject stackObject : game.getStack()) { if (stackObject instanceof Spell && stackObject.isControlledBy(source.getControllerId()) && stackObject.isCreature(game) diff --git a/Mage.Sets/src/mage/cards/b/Biotransference.java b/Mage.Sets/src/mage/cards/b/Biotransference.java new file mode 100644 index 00000000000..6c4b7a3d2ac --- /dev/null +++ b/Mage.Sets/src/mage/cards/b/Biotransference.java @@ -0,0 +1,140 @@ +package mage.cards.b; + +import mage.abilities.Ability; +import mage.abilities.common.SimpleStaticAbility; +import mage.abilities.common.SpellCastControllerTriggeredAbility; +import mage.abilities.effects.ContinuousEffectImpl; +import mage.abilities.effects.common.CreateTokenEffect; +import mage.abilities.effects.common.LoseLifeSourceControllerEffect; +import mage.cards.Card; +import mage.cards.CardImpl; +import mage.cards.CardSetInfo; +import mage.constants.*; +import mage.filter.FilterSpell; +import mage.filter.common.FilterControlledCreaturePermanent; +import mage.game.Game; +import mage.game.command.CommandObject; +import mage.game.command.Commander; +import mage.game.permanent.Permanent; +import mage.game.permanent.token.NecronWarriorToken; +import mage.game.stack.Spell; +import mage.game.stack.StackObject; +import mage.players.Player; + +import java.util.List; +import java.util.UUID; + +public final class Biotransference extends CardImpl { + + private static final FilterSpell filter = new FilterSpell("an artifact spell"); + + static { + filter.add(CardType.ARTIFACT.getPredicate()); + } + + public Biotransference(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{B}{B}"); + + // Creatures you control are artifacts in addition to their other types. The same is true for creature spells you control and creature cards you own that aren’t on the battlefield. + this.addAbility(new SimpleStaticAbility(new BiotransferenceEffect())); + + // Whenever you cast an artifact spell, you lose 1 life and create a 2/2 black Necron Warrior artifact creature token. + Ability ability = new SpellCastControllerTriggeredAbility(new LoseLifeSourceControllerEffect(1), filter, false); + ability.addEffect(new CreateTokenEffect(new NecronWarriorToken(), 1).concatBy("and")); + this.addAbility(ability); + } + + private Biotransference(final Biotransference card) { + super(card); + } + + @Override + public Biotransference copy() { + return new Biotransference(this); + } +} + +class BiotransferenceEffect extends ContinuousEffectImpl { + + BiotransferenceEffect() { + super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit); + staticText = "Creatures you control are artifacts in addition to their other types. " + + "The same is true for creature spells you control and creature cards you own that aren't on the battlefield"; + this.dependencyTypes.add(DependencyType.ArtifactAddingRemoving); // March of the Machines + } + + private BiotransferenceEffect(final BiotransferenceEffect effect) { + super(effect); + } + + @Override + public BiotransferenceEffect copy() { + return new BiotransferenceEffect(this); + } + + @Override + public boolean apply(Game game, Ability source) { + Player controller = game.getPlayer(source.getControllerId()); + if (controller == null) { + return false; + } + // Creature cards you own that aren't on the battlefield + // in graveyard + for (UUID cardId : controller.getGraveyard()) { + Card card = game.getCard(cardId); + if (card != null && card.isCreature(game) && !card.isArtifact(game)) { + card.addCardType(game, CardType.ARTIFACT); + } + } + // on Hand + for (UUID cardId : controller.getHand()) { + Card card = game.getCard(cardId); + if (card != null && card.isCreature(game) && !card.isArtifact(game)) { + card.addCardType(game, CardType.ARTIFACT); + } + } + // in Exile + for (Card card : game.getState().getExile().getAllCards(game, source.getControllerId())) { + if (card.isCreature(game) && !card.isArtifact(game)) { + card.addCardType(game, CardType.ARTIFACT); + } + } + // in Library (e.g. for Mystical Teachings) + for (Card card : controller.getLibrary().getCards(game)) { + if (card.isOwnedBy(controller.getId()) && card.isCreature(game) && !card.isArtifact(game)) { + card.addCardType(game, CardType.ARTIFACT); + } + } + // commander in command zone + for (CommandObject commandObject : game.getState().getCommand()) { + if (commandObject instanceof Commander) { + Card card = game.getCard((commandObject).getId()); + if (card != null && card.isOwnedBy(controller.getId()) + && card.isCreature(game) && !card.isArtifact(game)) { + card.addCardType(game, CardType.ARTIFACT); + } + } + } + + // creature spells you control + for (StackObject stackObject : game.getStack()) { + if (stackObject instanceof Spell + && stackObject.isControlledBy(source.getControllerId()) + && stackObject.isCreature(game) + && !stackObject.isArtifact(game)) { + Card card = ((Spell) stackObject).getCard(); + card.addCardType(game, CardType.ARTIFACT); + } + } + // creatures you control + List creatures = game.getBattlefield().getAllActivePermanents( + new FilterControlledCreaturePermanent(), source.getControllerId(), game); + for (Permanent creature : creatures) { + if (creature != null) { + creature.addCardType(game, CardType.ARTIFACT); + } + } + return true; + + } +} diff --git a/Mage.Sets/src/mage/sets/Warhammer40000.java b/Mage.Sets/src/mage/sets/Warhammer40000.java index 4401534d6b3..ff7757818aa 100644 --- a/Mage.Sets/src/mage/sets/Warhammer40000.java +++ b/Mage.Sets/src/mage/sets/Warhammer40000.java @@ -41,6 +41,7 @@ public final class Warhammer40000 extends ExpansionSet { cards.add(new SetCardInfo("Be'lakor, the Dark Master", 6, Rarity.MYTHIC, mage.cards.b.BelakorTheDarkMaster.class)); cards.add(new SetCardInfo("Beacon of Unrest", 194, Rarity.RARE, mage.cards.b.BeaconOfUnrest.class)); cards.add(new SetCardInfo("Bile Blight", 195, Rarity.UNCOMMON, mage.cards.b.BileBlight.class)); + cards.add(new SetCardInfo("Biotransference", 30, Rarity.RARE, mage.cards.b.Biotransference.class)); cards.add(new SetCardInfo("Bituminous Blast", 221, Rarity.UNCOMMON, mage.cards.b.BituminousBlast.class)); cards.add(new SetCardInfo("Blasphemous Act", 204, Rarity.RARE, mage.cards.b.BlasphemousAct.class)); cards.add(new SetCardInfo("Blight Grenade", 31, Rarity.RARE, mage.cards.b.BlightGrenade.class));