From b538d4714c45e80869899c8e99456f62c6be4059 Mon Sep 17 00:00:00 2001 From: Susucre <34709007+Susucre@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:40:54 +0100 Subject: [PATCH] [LCI] Implement Sunken Citadel --- Mage.Sets/src/mage/cards/s/SunkenCitadel.java | 121 ++++++++++++++++++ .../src/mage/sets/TheLostCavernsOfIxalan.java | 1 + .../AddConditionalManaChosenColorEffect.java | 59 +++++++++ 3 files changed, 181 insertions(+) create mode 100644 Mage.Sets/src/mage/cards/s/SunkenCitadel.java create mode 100644 Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaChosenColorEffect.java diff --git a/Mage.Sets/src/mage/cards/s/SunkenCitadel.java b/Mage.Sets/src/mage/cards/s/SunkenCitadel.java new file mode 100644 index 00000000000..4f50a1a809f --- /dev/null +++ b/Mage.Sets/src/mage/cards/s/SunkenCitadel.java @@ -0,0 +1,121 @@ +package mage.cards.s; + +import mage.ConditionalMana; +import mage.MageObject; +import mage.Mana; +import mage.abilities.Ability; +import mage.abilities.StaticAbility; +import mage.abilities.condition.Condition; +import mage.abilities.costs.common.TapSourceCost; +import mage.abilities.effects.Effect; +import mage.abilities.effects.EntersBattlefieldEffect; +import mage.abilities.effects.common.ChooseColorEffect; +import mage.abilities.effects.common.TapSourceEffect; +import mage.abilities.effects.mana.AddConditionalManaChosenColorEffect; +import mage.abilities.effects.mana.AddManaChosenColorEffect; +import mage.abilities.mana.SimpleManaAbility; +import mage.abilities.mana.builder.ConditionalManaBuilder; +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.game.Game; + +import java.util.UUID; + +/** + * @author Susucr + */ +public final class SunkenCitadel extends CardImpl { + + public SunkenCitadel(UUID ownerId, CardSetInfo setInfo) { + super(ownerId, setInfo, new CardType[]{CardType.LAND}, ""); + + this.subtype.add(SubType.CAVE); + + // Sunken Citadel enters the battlefield tapped. As it enters, choose a color. + this.addAbility(new SunkenCitadelEntersBattlefieldAbility()); + + // {T}: Add one mana of the chosen color. + this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AddManaChosenColorEffect(), new TapSourceCost())); + + // {T}: Add two mana of the chosen color. Spend this mana only to activate abilities of land sources. + this.addAbility(new SimpleManaAbility(Zone.BATTLEFIELD, new AddConditionalManaChosenColorEffect(2, new SunkenCitadelManaBuilder()), new TapSourceCost())); + } + + private SunkenCitadel(final SunkenCitadel card) { + super(card); + } + + @Override + public SunkenCitadel copy() { + return new SunkenCitadel(this); + } +} + +class SunkenCitadelEntersBattlefieldAbility extends StaticAbility { + + public SunkenCitadelEntersBattlefieldAbility() { + super(Zone.ALL, new EntersBattlefieldEffect(new TapSourceEffect(true))); + this.addEffect(new ChooseColorEffect(Outcome.Benefit)); + } + + private SunkenCitadelEntersBattlefieldAbility(final SunkenCitadelEntersBattlefieldAbility ability) { + super(ability); + } + + @Override + public SunkenCitadelEntersBattlefieldAbility copy() { + return new SunkenCitadelEntersBattlefieldAbility(this); + } + + @Override + public void addEffect(Effect effect) { + if (!getEffects().isEmpty()) { + Effect entersEffect = this.getEffects().get(0); + if (entersEffect instanceof EntersBattlefieldEffect) { + ((EntersBattlefieldEffect) entersEffect).addEffect(effect); + return; + } + } + super.addEffect(effect); + } + + @Override + public String getRule() { + return "{this} enters the battlefield tapped. As it enters, choose a color."; + } +} + +class SunkenCitadelManaBuilder extends ConditionalManaBuilder { + + @Override + public ConditionalMana build(Object... options) { + return new SunkenCitadelConditionalMana(this.mana); + } + + @Override + public String getRule() { + return "Spend this mana only to activate abilities of land sources"; + } +} + +class SunkenCitadelConditionalMana extends ConditionalMana { + + public SunkenCitadelConditionalMana(Mana mana) { + super(mana); + addCondition(SunkenCitadelCondition.instance); + } +} + +enum SunkenCitadelCondition implements Condition { + instance; + + @Override + public boolean apply(Game game, Ability source) { + MageObject object = game.getObject(source); + return object != null && object.isLand(game); + } +} diff --git a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java index 90ac8544181..e5d0e73e0ca 100644 --- a/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java +++ b/Mage.Sets/src/mage/sets/TheLostCavernsOfIxalan.java @@ -302,6 +302,7 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet { cards.add(new SetCardInfo("Sunbird Effigy", 262, Rarity.UNCOMMON, mage.cards.s.SunbirdEffigy.class)); cards.add(new SetCardInfo("Sunbird Standard", 262, Rarity.UNCOMMON, mage.cards.s.SunbirdStandard.class)); cards.add(new SetCardInfo("Sunfire Torch", 167, Rarity.COMMON, mage.cards.s.SunfireTorch.class)); + cards.add(new SetCardInfo("Sunken Citadel", 285, Rarity.RARE, mage.cards.s.SunkenCitadel.class)); cards.add(new SetCardInfo("Sunshot Militia", 168, Rarity.COMMON, mage.cards.s.SunshotMilitia.class)); cards.add(new SetCardInfo("Swamp", 289, Rarity.LAND, mage.cards.basiclands.Swamp.class, FULL_ART_UST_VARIOUS)); cards.add(new SetCardInfo("Swamp", 397, Rarity.LAND, mage.cards.basiclands.Swamp.class, NON_FULL_USE_VARIOUS)); diff --git a/Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaChosenColorEffect.java b/Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaChosenColorEffect.java new file mode 100644 index 00000000000..3561f247bc0 --- /dev/null +++ b/Mage/src/main/java/mage/abilities/effects/mana/AddConditionalManaChosenColorEffect.java @@ -0,0 +1,59 @@ +package mage.abilities.effects.mana; + +import mage.Mana; +import mage.ObjectColor; +import mage.abilities.Ability; +import mage.abilities.dynamicvalue.DynamicValue; +import mage.abilities.dynamicvalue.common.StaticValue; +import mage.abilities.mana.builder.ConditionalManaBuilder; +import mage.constants.ColoredManaSymbol; +import mage.game.Game; + +/** + * @author Susucr + */ +public class AddConditionalManaChosenColorEffect extends ManaEffect { + + private ObjectColor chosenColorInfo = null; + private final ConditionalManaBuilder manaBuilder; + private final DynamicValue amount; + + public AddConditionalManaChosenColorEffect(int amount, ConditionalManaBuilder manaBuilder) { + this(StaticValue.get(amount), manaBuilder); + } + + public AddConditionalManaChosenColorEffect(DynamicValue amount, ConditionalManaBuilder manaBuilder) { + super(); + this.amount = amount; + this.manaBuilder = manaBuilder; + staticText = "Add " + this.amount.toString() + " mana of the chosen color. " + manaBuilder.getRule(); + } + + private AddConditionalManaChosenColorEffect(final AddConditionalManaChosenColorEffect effect) { + super(effect); + this.chosenColorInfo = effect.chosenColorInfo; + this.manaBuilder = effect.manaBuilder; + this.amount = effect.amount; + } + + @Override + public AddConditionalManaChosenColorEffect copy() { + return new AddConditionalManaChosenColorEffect(this); + } + + @Override + public Mana produceMana(Game game, Ability source) { + if (game != null) { + ObjectColor color = (ObjectColor) game.getState().getValue(source.getSourceId() + "_color"); + int value = amount.calculate(game, source, this); + if (color != null && value > 0) { + this.chosenColorInfo = color; + return manaBuilder.setMana( + new Mana(ColoredManaSymbol.lookup(color.toString().charAt(0)), value), + source, game + ).build(); + } + } + return new Mana(); + } +}