mirror of
https://github.com/magefree/mage.git
synced 2025-12-22 03:22:00 -08:00
implement [LCI] Market Gnome
This commit is contained in:
parent
a5922457ad
commit
933d694b08
5 changed files with 191 additions and 8 deletions
81
Mage.Sets/src/mage/cards/m/MarketGnome.java
Normal file
81
Mage.Sets/src/mage/cards/m/MarketGnome.java
Normal file
|
|
@ -0,0 +1,81 @@
|
||||||
|
package mage.cards.m;
|
||||||
|
|
||||||
|
import mage.MageInt;
|
||||||
|
import mage.abilities.Ability;
|
||||||
|
import mage.abilities.TriggeredAbilityImpl;
|
||||||
|
import mage.abilities.common.DiesSourceTriggeredAbility;
|
||||||
|
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||||
|
import mage.abilities.effects.common.GainLifeEffect;
|
||||||
|
import mage.cards.CardImpl;
|
||||||
|
import mage.cards.CardSetInfo;
|
||||||
|
import mage.constants.CardType;
|
||||||
|
import mage.constants.SubType;
|
||||||
|
import mage.constants.Zone;
|
||||||
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
|
import mage.game.permanent.Permanent;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author xenohedron
|
||||||
|
*/
|
||||||
|
public final class MarketGnome extends CardImpl {
|
||||||
|
|
||||||
|
public MarketGnome(UUID ownerId, CardSetInfo setInfo) {
|
||||||
|
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{W}");
|
||||||
|
|
||||||
|
this.subtype.add(SubType.GNOME);
|
||||||
|
this.power = new MageInt(0);
|
||||||
|
this.toughness = new MageInt(3);
|
||||||
|
|
||||||
|
// When Market Gnome dies, you gain 1 life and draw a card.
|
||||||
|
Ability ability = new DiesSourceTriggeredAbility(new GainLifeEffect(1));
|
||||||
|
ability.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and"));
|
||||||
|
this.addAbility(ability);
|
||||||
|
|
||||||
|
// When Market Gnome is exiled from the battlefield while you're activating a craft ability, you gain 1 life and draw a card.
|
||||||
|
this.addAbility(new MarketGnomeTriggeredAbility());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private MarketGnome(final MarketGnome card) {
|
||||||
|
super(card);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MarketGnome copy() {
|
||||||
|
return new MarketGnome(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MarketGnomeTriggeredAbility extends TriggeredAbilityImpl {
|
||||||
|
|
||||||
|
MarketGnomeTriggeredAbility() {
|
||||||
|
super(Zone.BATTLEFIELD, new GainLifeEffect(1));
|
||||||
|
this.addEffect(new DrawCardSourceControllerEffect(1).concatBy("and"));
|
||||||
|
setTriggerPhrase("When {this} is exiled from the battlefield while you're activating a craft ability, ");
|
||||||
|
// setLeavesTheBattlefieldTrigger(true); // not needed as special event is fired prior to the actual exiling
|
||||||
|
}
|
||||||
|
|
||||||
|
private MarketGnomeTriggeredAbility(final MarketGnomeTriggeredAbility ability) {
|
||||||
|
super(ability);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MarketGnomeTriggeredAbility copy() {
|
||||||
|
return new MarketGnomeTriggeredAbility(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkEventType(GameEvent event, Game game) {
|
||||||
|
return event.getType() == GameEvent.EventType.EXILED_WHILE_CRAFTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean checkTrigger(GameEvent event, Game game) {
|
||||||
|
Permanent permanent = game.getPermanentOrLKIBattlefield(event.getTargetId());
|
||||||
|
Permanent sourcePermanent = game.getPermanentOrLKIBattlefield(getSourceId());
|
||||||
|
return permanent != null && sourcePermanent != null && permanent.getId().equals(sourcePermanent.getId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -203,6 +203,7 @@ public final class TheLostCavernsOfIxalan extends ExpansionSet {
|
||||||
cards.add(new SetCardInfo("Malcolm, Alluring Scoundrel", 63, Rarity.RARE, mage.cards.m.MalcolmAlluringScoundrel.class));
|
cards.add(new SetCardInfo("Malcolm, Alluring Scoundrel", 63, Rarity.RARE, mage.cards.m.MalcolmAlluringScoundrel.class));
|
||||||
cards.add(new SetCardInfo("Malicious Eclipse", 111, Rarity.UNCOMMON, mage.cards.m.MaliciousEclipse.class));
|
cards.add(new SetCardInfo("Malicious Eclipse", 111, Rarity.UNCOMMON, mage.cards.m.MaliciousEclipse.class));
|
||||||
cards.add(new SetCardInfo("Marauding Brinefang", 64, Rarity.COMMON, mage.cards.m.MaraudingBrinefang.class));
|
cards.add(new SetCardInfo("Marauding Brinefang", 64, Rarity.COMMON, mage.cards.m.MaraudingBrinefang.class));
|
||||||
|
cards.add(new SetCardInfo("Market Gnome", 22, Rarity.UNCOMMON, mage.cards.m.MarketGnome.class));
|
||||||
cards.add(new SetCardInfo("Master's Guide-Mural", 233, Rarity.UNCOMMON, mage.cards.m.MastersGuideMural.class));
|
cards.add(new SetCardInfo("Master's Guide-Mural", 233, Rarity.UNCOMMON, mage.cards.m.MastersGuideMural.class));
|
||||||
cards.add(new SetCardInfo("Master's Manufactory", 233, Rarity.UNCOMMON, mage.cards.m.MastersManufactory.class));
|
cards.add(new SetCardInfo("Master's Manufactory", 233, Rarity.UNCOMMON, mage.cards.m.MastersManufactory.class));
|
||||||
cards.add(new SetCardInfo("Mastercraft Raptor", 164, Rarity.UNCOMMON, mage.cards.m.MastercraftRaptor.class));
|
cards.add(new SetCardInfo("Mastercraft Raptor", 164, Rarity.UNCOMMON, mage.cards.m.MastercraftRaptor.class));
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@ import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||||
*/
|
*/
|
||||||
public class CraftTest extends CardTestPlayerBase {
|
public class CraftTest extends CardTestPlayerBase {
|
||||||
|
|
||||||
private static final String sawblades = "Spring-Loaded Sawblades";
|
private static final String sawblades = "Spring-Loaded Sawblades"; // Craft with artifact {3}{W}
|
||||||
private static final String chariot = "Bladewheel Chariot";
|
private static final String chariot = "Bladewheel Chariot"; // back side Vehicle
|
||||||
private static final String relic = "Darksteel Relic";
|
private static final String relic = "Darksteel Relic"; // Artifact {0} Indestructible
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testExilePermanent() {
|
public void testExilePermanent() {
|
||||||
|
|
@ -55,11 +55,13 @@ public class CraftTest extends CardTestPlayerBase {
|
||||||
assertExileCount(playerA, relic, 1);
|
assertExileCount(playerA, relic, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final String standard = "Sunbird Standard";
|
private static final String standard = "Sunbird Standard"; // Craft with one or more {5}
|
||||||
private static final String effigy = "Sunbird Effigy";
|
private static final String effigy = "Sunbird Effigy"; // back side artifact creature
|
||||||
private static final String thoctar = "Woolly Thoctar";
|
// Sunbird Effigy’s power and toughness are each equal to the number of colors among the exiled cards used to craft it.
|
||||||
private static final String watchwolf = "Watchwolf";
|
// {T}: For each color among the exiled cards used to craft Sunbird Effigy, add one mana of that color.
|
||||||
private static final String yearling = "Cerodon Yearling";
|
private static final String thoctar = "Woolly Thoctar"; // RGW 5/4
|
||||||
|
private static final String watchwolf = "Watchwolf"; // GW 3/3
|
||||||
|
private static final String yearling = "Cerodon Yearling"; // RW 2/2 Vigilance Haste
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEffigy() {
|
public void testEffigy() {
|
||||||
|
|
@ -109,4 +111,94 @@ public class CraftTest extends CardTestPlayerBase {
|
||||||
assertPermanentCount(playerA, thoctar, 1);
|
assertPermanentCount(playerA, thoctar, 1);
|
||||||
assertPowerToughness(playerA, effigy, 3, 3);
|
assertPowerToughness(playerA, effigy, 3, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final String gnome = "Market Gnome";
|
||||||
|
// When Market Gnome is exiled from the battlefield while you’re activating a craft ability, you gain 1 life and draw a card.
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarketGnomeExilePermanent() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, sawblades);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, gnome);
|
||||||
|
|
||||||
|
addTarget(playerA, gnome);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, sawblades, 0);
|
||||||
|
assertPermanentCount(playerA, chariot, 1);
|
||||||
|
assertPermanentCount(playerA, gnome, 0);
|
||||||
|
assertExileCount(playerA, gnome, 1);
|
||||||
|
assertLife(playerA, 21);
|
||||||
|
assertHandCount(playerA, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarketGnomeExileCard() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, sawblades);
|
||||||
|
addCard(Zone.GRAVEYARD, playerA, gnome);
|
||||||
|
|
||||||
|
addTarget(playerA, gnome);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, sawblades, 0);
|
||||||
|
assertPermanentCount(playerA, chariot, 1);
|
||||||
|
assertGraveyardCount(playerA, gnome, 0);
|
||||||
|
assertExileCount(playerA, gnome, 1);
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertHandCount(playerA, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarketGnomeExiledExileOther() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, sawblades);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, relic);
|
||||||
|
addCard(Zone.EXILED, playerA, gnome);
|
||||||
|
|
||||||
|
addTarget(playerA, relic);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, sawblades, 0);
|
||||||
|
assertPermanentCount(playerA, chariot, 1);
|
||||||
|
assertPermanentCount(playerA, relic, 0);
|
||||||
|
assertExileCount(playerA, relic, 1);
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertHandCount(playerA, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testMarketGnomeBattlefieldExileOther() {
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, "Plains", 4);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, sawblades);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, relic);
|
||||||
|
addCard(Zone.BATTLEFIELD, playerA, gnome);
|
||||||
|
|
||||||
|
addTarget(playerA, relic);
|
||||||
|
activateAbility(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Craft");
|
||||||
|
|
||||||
|
setStrictChooseMode(true);
|
||||||
|
setStopAt(1, PhaseStep.END_TURN);
|
||||||
|
execute();
|
||||||
|
|
||||||
|
assertPermanentCount(playerA, sawblades, 0);
|
||||||
|
assertPermanentCount(playerA, chariot, 1);
|
||||||
|
assertPermanentCount(playerA, relic, 0);
|
||||||
|
assertExileCount(playerA, relic, 1);
|
||||||
|
assertLife(playerA, 20);
|
||||||
|
assertHandCount(playerA, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ import mage.filter.common.FilterOwnedCard;
|
||||||
import mage.filter.predicate.Predicate;
|
import mage.filter.predicate.Predicate;
|
||||||
import mage.filter.predicate.mageobject.AnotherPredicate;
|
import mage.filter.predicate.mageobject.AnotherPredicate;
|
||||||
import mage.game.Game;
|
import mage.game.Game;
|
||||||
|
import mage.game.events.GameEvent;
|
||||||
import mage.game.permanent.Permanent;
|
import mage.game.permanent.Permanent;
|
||||||
import mage.players.Player;
|
import mage.players.Player;
|
||||||
import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
|
import mage.target.common.TargetCardInGraveyardBattlefieldOrStack;
|
||||||
|
|
@ -131,6 +132,8 @@ class CraftCost extends CostImpl {
|
||||||
.map(uuid -> {
|
.map(uuid -> {
|
||||||
Permanent permanent = game.getPermanent(uuid);
|
Permanent permanent = game.getPermanent(uuid);
|
||||||
if (permanent != null) {
|
if (permanent != null) {
|
||||||
|
game.fireEvent(GameEvent.getEvent(GameEvent.EventType.EXILED_WHILE_CRAFTING,
|
||||||
|
permanent.getId(), source, player.getId()));
|
||||||
return permanent;
|
return permanent;
|
||||||
}
|
}
|
||||||
return game.getCard(uuid);
|
return game.getCard(uuid);
|
||||||
|
|
|
||||||
|
|
@ -540,6 +540,12 @@ public class GameEvent implements Serializable {
|
||||||
flag not used for this event
|
flag not used for this event
|
||||||
*/
|
*/
|
||||||
DISCOVERED,
|
DISCOVERED,
|
||||||
|
/* Exiled while crafting (see Market Gnome)
|
||||||
|
targetId the permanent exiled
|
||||||
|
sourceId of the craft ability
|
||||||
|
playerId the player crafting
|
||||||
|
*/
|
||||||
|
EXILED_WHILE_CRAFTING,
|
||||||
//custom events
|
//custom events
|
||||||
CUSTOM_EVENT
|
CUSTOM_EVENT
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue