forked from External/mage
[CLB] Implemented Jade Orb of Dragonkind (#10286)
* Working with oneshot * Swap to dual effects * adjust tests * adjust custom class names, fix text order * comparison fix, null check, access modifiers --------- Co-authored-by: Zelane <zelane@hollow.tech> Co-authored-by: xenohedron <xenohedron@users.noreply.github.com>
This commit is contained in:
parent
23cc483a09
commit
e49020e490
3 changed files with 259 additions and 0 deletions
139
Mage.Sets/src/mage/cards/j/JadeOrbOfDragonkind.java
Normal file
139
Mage.Sets/src/mage/cards/j/JadeOrbOfDragonkind.java
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
package mage.cards.j;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.common.delayed.ManaSpentDelayedTriggeredAbility;
|
||||
import mage.abilities.effects.ReplacementEffectImpl;
|
||||
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
|
||||
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
|
||||
import mage.abilities.keyword.HexproofAbility;
|
||||
import mage.abilities.mana.BasicManaAbility;
|
||||
import mage.abilities.mana.GreenManaAbility;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Duration;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.SubType;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.FilterSpell;
|
||||
import mage.filter.common.FilterCreatureSpell;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.EntersTheBattlefieldEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.game.stack.Spell;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author Zelane
|
||||
*/
|
||||
public final class JadeOrbOfDragonkind extends CardImpl {
|
||||
|
||||
private static final FilterSpell filter = new FilterCreatureSpell("a Dragon creature spell");
|
||||
static {
|
||||
filter.add(SubType.DRAGON.getPredicate());
|
||||
}
|
||||
|
||||
public JadeOrbOfDragonkind(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[] { CardType.ARTIFACT }, "{2}{G}");
|
||||
|
||||
// {T}: Add {G}. When you spend this mana to cast a Dragon creature spell, it enters the battlefield with an additional +1/+1 counter on it and gains hexproof until your next turn.
|
||||
BasicManaAbility ability = new GreenManaAbility();
|
||||
ManaSpentDelayedTriggeredAbility manaSpentAbility = new ManaSpentDelayedTriggeredAbility(
|
||||
new JadeOrbAdditionalCounterEffect(), filter);
|
||||
manaSpentAbility.addEffect(new JadeOrbGainHexproofEffect());
|
||||
ability.addEffect(new CreateDelayedTriggeredAbilityEffect(manaSpentAbility));
|
||||
ability.setUndoPossible(false);
|
||||
this.addAbility(ability);
|
||||
}
|
||||
|
||||
private JadeOrbOfDragonkind(final JadeOrbOfDragonkind card) {
|
||||
super(card);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadeOrbOfDragonkind copy() {
|
||||
return new JadeOrbOfDragonkind(this);
|
||||
}
|
||||
}
|
||||
|
||||
class JadeOrbGainHexproofEffect extends GainAbilityTargetEffect {
|
||||
|
||||
JadeOrbGainHexproofEffect() {
|
||||
super(HexproofAbility.getInstance(), Duration.UntilYourNextTurn, null, true);
|
||||
staticText = "and gains hexproof until your next turn";
|
||||
}
|
||||
|
||||
private JadeOrbGainHexproofEffect(final JadeOrbGainHexproofEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadeOrbGainHexproofEffect copy() {
|
||||
return new JadeOrbGainHexproofEffect(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Ability source, Game game) {
|
||||
super.init(source, game);
|
||||
|
||||
GameEvent event = ((ManaSpentDelayedTriggeredAbility) source).getTriggerEvent();
|
||||
if (event != null) {
|
||||
Spell spell = game.getStack().getSpell(event.getTargetId());
|
||||
if (spell != null) {
|
||||
affectedObjectList.add(new MageObjectReference(spell.getSourceId(), game));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JadeOrbAdditionalCounterEffect extends ReplacementEffectImpl {
|
||||
|
||||
JadeOrbAdditionalCounterEffect() {
|
||||
super(Duration.EndOfTurn, Outcome.BoostCreature);
|
||||
this.staticText = "it enters the battlefield with an additional +1/+1 counter on it";
|
||||
}
|
||||
|
||||
private JadeOrbAdditionalCounterEffect(final JadeOrbAdditionalCounterEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checksEventType(GameEvent event, Game game) {
|
||||
return event.getType() == GameEvent.EventType.ENTERS_THE_BATTLEFIELD;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean applies(GameEvent event, Ability source, Game game) {
|
||||
if (!(source instanceof ManaSpentDelayedTriggeredAbility)) {
|
||||
return false;
|
||||
}
|
||||
GameEvent manaUsedEvent = ((ManaSpentDelayedTriggeredAbility) source).getTriggerEvent();
|
||||
Spell spell = game.getStack().getSpell(manaUsedEvent.getTargetId());
|
||||
if (spell == null) {
|
||||
return false;
|
||||
}
|
||||
return event.getSourceId().equals(spell.getSourceId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceEvent(GameEvent event, Ability source, Game game) {
|
||||
Permanent target = ((EntersTheBattlefieldEvent) event).getTarget();
|
||||
if (target != null) {
|
||||
target.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game, event.getAppliedEffects());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JadeOrbAdditionalCounterEffect copy() {
|
||||
return new JadeOrbAdditionalCounterEffect(this);
|
||||
}
|
||||
}
|
||||
|
|
@ -327,6 +327,7 @@ public final class CommanderLegendsBattleForBaldursGate extends ExpansionSet {
|
|||
cards.add(new SetCardInfo("Izzet Boilerworks", 897, Rarity.UNCOMMON, mage.cards.i.IzzetBoilerworks.class));
|
||||
cards.add(new SetCardInfo("Izzet Chemister", 798, Rarity.RARE, mage.cards.i.IzzetChemister.class));
|
||||
cards.add(new SetCardInfo("Izzet Signet", 863, Rarity.COMMON, mage.cards.i.IzzetSignet.class));
|
||||
cards.add(new SetCardInfo("Jade Orb of Dragonkind", 236, Rarity.COMMON, mage.cards.j.JadeOrbOfDragonkind.class));
|
||||
cards.add(new SetCardInfo("Jaheira's Respite", 238, Rarity.RARE, mage.cards.j.JaheirasRespite.class));
|
||||
cards.add(new SetCardInfo("Jaheira, Friend of the Forest", 237, Rarity.RARE, mage.cards.j.JaheiraFriendOfTheForest.class));
|
||||
cards.add(new SetCardInfo("Jan Jansen, Chaos Crafter", 277, Rarity.RARE, mage.cards.j.JanJansenChaosCrafter.class));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,119 @@
|
|||
package org.mage.test.cards.single.clb;
|
||||
|
||||
import mage.abilities.keyword.HexproofAbility;
|
||||
import mage.constants.PhaseStep;
|
||||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import org.junit.Test;
|
||||
import org.mage.test.serverside.base.CardTestPlayerBase;
|
||||
|
||||
/**
|
||||
* {@link mage.cards.j.JadeOrbOfDragonkind Jade Orb of Dragonkind}
|
||||
* {2}{G}
|
||||
* Artifact
|
||||
* {T}: Add {G}. When you spend this mana to cast a Dragon creature spell, it enters the battlefield with an additional +1/+1 counter on it and gains hexproof until your next turn.
|
||||
* @author NicolasCamachoP, Zelane
|
||||
*/
|
||||
|
||||
public class JadeOrbOfDragonkindTest extends CardTestPlayerBase {
|
||||
private static final String jadeOrb = "Jade Orb of Dragonkind";
|
||||
private static final String arcades = "Arcades, the Strategist";
|
||||
private static final String mowu = "Mowu, Loyal Companion";
|
||||
|
||||
@Test
|
||||
public void manaAbility() {
|
||||
addCard(Zone.HAND, playerA, "Ancient Bronze Dragon");
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Mountain", 5);
|
||||
addCard(Zone.BATTLEFIELD, playerA, jadeOrb);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, "Ancient Bronze Dragon");
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.BEGIN_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, 8);
|
||||
assertTapped(jadeOrb, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void manaUsedEffects() {
|
||||
addCard(Zone.HAND, playerA, arcades);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, jadeOrb);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Kronch Wrangler");
|
||||
// Whenever a creature with power 4 or greater enters the battlefield under your control, put a +1/+1 counter on Kronch Wrangler.
|
||||
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcades);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, 6);
|
||||
assertTapped(jadeOrb, true);
|
||||
assertCounterCount(arcades, CounterType.P1P1, 1);
|
||||
assertPowerToughness(playerA, "Kronch Wrangler", 3, 2);
|
||||
assertAbility(playerA, arcades, HexproofAbility.getInstance(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hexproofDropOff() {
|
||||
addCard(Zone.HAND, playerA, arcades);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, jadeOrb);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcades);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, 5);
|
||||
assertTapped(jadeOrb, true);
|
||||
assertAbility(playerA, arcades, HexproofAbility.getInstance(), true);
|
||||
|
||||
setStopAt(4, PhaseStep.UPKEEP);
|
||||
execute();
|
||||
|
||||
assertAbility(playerA, arcades, HexproofAbility.getInstance(), false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void twoOrbs() {
|
||||
addCard(Zone.HAND, playerA, arcades);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Island", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, jadeOrb, 2);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, arcades);
|
||||
//setChoice(playerA, "When you spend"); // order identical triggers
|
||||
|
||||
setStrictChooseMode(false); // trigger order is problematic
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertPermanentCount(playerA, 5);
|
||||
assertTapped(jadeOrb, true);
|
||||
assertCounterCount(arcades, CounterType.P1P1, 2);
|
||||
assertAbility(playerA, arcades, HexproofAbility.getInstance(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void comboMowuAndMaskwoodNexus() {
|
||||
addCard(Zone.HAND, playerA, mowu);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Maskwood Nexus", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Forest", 2);
|
||||
addCard(Zone.BATTLEFIELD, playerA, "Plains", 1);
|
||||
addCard(Zone.BATTLEFIELD, playerA, jadeOrb);
|
||||
castSpell(1, PhaseStep.PRECOMBAT_MAIN, playerA, mowu);
|
||||
|
||||
setStrictChooseMode(true);
|
||||
setStopAt(1, PhaseStep.END_COMBAT);
|
||||
execute();
|
||||
|
||||
assertTapped(jadeOrb, true);
|
||||
assertCounterCount(mowu, CounterType.P1P1, 2);
|
||||
assertAbility(playerA, mowu, HexproofAbility.getInstance(), true);
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue