[NEO] Implemented Reconfigure abliity

This commit is contained in:
Evan Kranzler 2022-02-06 12:27:12 -05:00
parent 5945aaeda4
commit 495fc57540
5 changed files with 172 additions and 11 deletions

View file

@ -28,7 +28,7 @@ public final class BladeOfTheOni extends CardImpl {
this.toughness = new MageInt(1); this.toughness = new MageInt(1);
// Menace // Menace
this.addAbility(new MenaceAbility()); this.addAbility(new MenaceAbility(false));
// Equipped creature has base power and toughness 5/5, has menace, and is a black Demon in addition to its other colors and types. // Equipped creature has base power and toughness 5/5, has menace, and is a black Demon in addition to its other colors and types.
this.addAbility(new SimpleStaticAbility(new BladeOfTheOniEffect())); this.addAbility(new SimpleStaticAbility(new BladeOfTheOniEffect()));

View file

@ -36,6 +36,7 @@ public final class BronzeplateBoar extends CardImpl {
ability.addEffect(new GainAbilityAttachedEffect( ability.addEffect(new GainAbilityAttachedEffect(
TrampleAbility.getInstance(), AttachmentType.EQUIPMENT TrampleAbility.getInstance(), AttachmentType.EQUIPMENT
).setText("and has trample")); ).setText("and has trample"));
this.addAbility(ability);
// Reconfigure {5} // Reconfigure {5}
this.addAbility(new ReconfigureAbility("{5}")); this.addAbility(new ReconfigureAbility("{5}"));

View file

@ -4,15 +4,11 @@ import mage.cards.ExpansionSet;
import mage.constants.Rarity; import mage.constants.Rarity;
import mage.constants.SetType; import mage.constants.SetType;
import java.util.Arrays;
import java.util.List;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public final class KamigawaNeonDynasty extends ExpansionSet { public final class KamigawaNeonDynasty extends ExpansionSet {
private static final List<String> unfinished = Arrays.asList("Acquisition Octopus", "Armguard Familiar", "Blade of the Oni", "Bronzeplate Boar", "Chainflail Centipede", "Cloudsteel Kirin", "Leech Gauntlet", "Lion Sash", "Lizard Blades", "Ogre-Head Helm", "Rabbit Battery", "Simian Sling", "The Reality Chip", "Webspinner Cuff");
private static final KamigawaNeonDynasty instance = new KamigawaNeonDynasty(); private static final KamigawaNeonDynasty instance = new KamigawaNeonDynasty();
public static KamigawaNeonDynasty getInstance() { public static KamigawaNeonDynasty getInstance() {
@ -285,7 +281,5 @@ public final class KamigawaNeonDynasty extends ExpansionSet {
cards.add(new SetCardInfo("When We Were Young", 43, Rarity.UNCOMMON, mage.cards.w.WhenWeWereYoung.class)); cards.add(new SetCardInfo("When We Were Young", 43, Rarity.UNCOMMON, mage.cards.w.WhenWeWereYoung.class));
cards.add(new SetCardInfo("Wind-Scarred Crag", 282, Rarity.COMMON, mage.cards.w.WindScarredCrag.class)); cards.add(new SetCardInfo("Wind-Scarred Crag", 282, Rarity.COMMON, mage.cards.w.WindScarredCrag.class));
cards.add(new SetCardInfo("You Are Already Dead", 129, Rarity.COMMON, mage.cards.y.YouAreAlreadyDead.class)); cards.add(new SetCardInfo("You Are Already Dead", 129, Rarity.COMMON, mage.cards.y.YouAreAlreadyDead.class));
cards.removeIf(setCardInfo -> unfinished.contains(setCardInfo.getName())); // remove when mechanic is fully implemented
} }
} }

View file

@ -0,0 +1,82 @@
package org.mage.test.cards.abilities.activated;
import mage.abilities.keyword.TrampleAbility;
import mage.constants.CardType;
import mage.constants.PhaseStep;
import mage.constants.SubType;
import mage.constants.Zone;
import org.junit.Test;
import org.mage.test.serverside.base.CardTestPlayerBase;
/**
* @author TheElk801
*/
public class ReconfigureTest extends CardTestPlayerBase {
private static final String lion = "Silvercoat Lion";
private static final String boar = "Bronzeplate Boar";
private static final String aid = "Sigarda's Aid";
@Test
public void testAttach() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
addCard(Zone.BATTLEFIELD, playerA, lion);
addCard(Zone.BATTLEFIELD, playerA, boar);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reconfigure", lion);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertType(boar, CardType.CREATURE, false);
assertSubtype(boar, SubType.EQUIPMENT);
assertIsAttachedTo(playerA, boar, lion);
assertPowerToughness(playerA, lion, 2 + 3, 2 + 2);
assertAbility(playerA, lion, TrampleAbility.getInstance(), true);
}
@Test
public void testAttachDetach() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 10);
addCard(Zone.BATTLEFIELD, playerA, lion);
addCard(Zone.BATTLEFIELD, playerA, boar);
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Reconfigure", lion);
activateAbility(1, PhaseStep.POSTCOMBAT_MAIN, playerA, "{5}:");
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertType(boar, CardType.CREATURE, true);
assertSubtype(boar, SubType.EQUIPMENT);
assertPowerToughness(playerA, lion, 2, 2);
assertAbility(playerA, lion, TrampleAbility.getInstance(), false);
}
@Test
public void testSigardasAid() {
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 3);
addCard(Zone.BATTLEFIELD, playerA, lion);
addCard(Zone.BATTLEFIELD, playerA, aid);
addCard(Zone.HAND, playerA, boar);
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, boar);
addTarget(playerA, lion);
setChoice(playerA, true);
setStrictChooseMode(true);
setStopAt(1, PhaseStep.END_TURN);
execute();
assertAllCommandsUsed();
assertType(boar, CardType.CREATURE, false);
assertSubtype(boar, SubType.EQUIPMENT);
assertIsAttachedTo(playerA, boar, lion);
assertPowerToughness(playerA, lion, 2 + 3, 2 + 2);
assertAbility(playerA, lion, TrampleAbility.getInstance(), true);
}
}

View file

@ -1,7 +1,17 @@
package mage.abilities.keyword; package mage.abilities.keyword;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl; import mage.abilities.ActivatedAbilityImpl;
import mage.constants.Zone; import mage.abilities.common.ActivateAsSorceryActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.AttachEffect;
import mage.constants.*;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.target.common.TargetControlledCreaturePermanent;
/** /**
* @author TheElk801 * @author TheElk801
@ -11,9 +21,14 @@ public class ReconfigureAbility extends ActivatedAbilityImpl {
private final String manaString; private final String manaString;
public ReconfigureAbility(String manaString) { public ReconfigureAbility(String manaString) {
super(Zone.BATTLEFIELD, null); super(Zone.BATTLEFIELD, new AttachEffect(Outcome.BoostCreature), new ManaCostsImpl<>(manaString));
this.manaString = manaString; this.manaString = manaString;
// TODO: Implement this this.timing = TimingRule.SORCERY;
this.addTarget(new TargetControlledCreaturePermanent());
this.addSubAbility(new ReconfigureUnattachAbility(manaString));
Ability ability = new SimpleStaticAbility(new ReconfigureTypeEffect());
ability.setRuleVisible(false);
this.addSubAbility(ability);
} }
private ReconfigureAbility(final ReconfigureAbility ability) { private ReconfigureAbility(final ReconfigureAbility ability) {
@ -31,6 +46,75 @@ public class ReconfigureAbility extends ActivatedAbilityImpl {
return "Reconfigure " + manaString + " (" + manaString return "Reconfigure " + manaString + " (" + manaString
+ ": Attach to target creature you control; " + + ": Attach to target creature you control; " +
"or unattach from a creature. Reconfigure only as a sorcery. " + "or unattach from a creature. Reconfigure only as a sorcery. " +
"While attached, this isnt a creature.)"; "While attached, this isn't a creature.)";
}
}
class ReconfigureUnattachAbility extends ActivateAsSorceryActivatedAbility {
protected ReconfigureUnattachAbility(String manaString) {
super(Zone.BATTLEFIELD, new ReconfigureUnattachEffect(), new ManaCostsImpl<>(manaString));
this.setRuleVisible(true);
}
private ReconfigureUnattachAbility(final ReconfigureUnattachAbility ability) {
super(ability);
}
@Override
public ReconfigureUnattachAbility copy() {
return new ReconfigureUnattachAbility(this);
}
}
class ReconfigureUnattachEffect extends OneShotEffect {
ReconfigureUnattachEffect() {
super(Outcome.Benefit);
staticText = "unattach {this}";
}
private ReconfigureUnattachEffect(final ReconfigureUnattachEffect effect) {
super(effect);
}
@Override
public ReconfigureUnattachEffect copy() {
return new ReconfigureUnattachEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent != null) {
permanent.unattach(game);
}
return true;
}
}
class ReconfigureTypeEffect extends ContinuousEffectImpl {
ReconfigureTypeEffect() {
super(Duration.WhileOnBattlefield, Layer.TypeChangingEffects_4, SubLayer.NA, Outcome.Benefit);
}
private ReconfigureTypeEffect(final ReconfigureTypeEffect effect) {
super(effect);
}
@Override
public ReconfigureTypeEffect copy() {
return new ReconfigureTypeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Permanent permanent = source.getSourcePermanentIfItStillExists(game);
if (permanent == null || game.getPermanent(permanent.getAttachedTo()) == null) {
return false;
}
permanent.removeCardType(game, CardType.CREATURE);
return true;
} }
} }