Implemented Chandra, Fire Artisan

This commit is contained in:
Evan Kranzler 2019-04-10 16:14:34 -04:00
parent 41d3cb7558
commit 785917deb6
5 changed files with 153 additions and 6 deletions

View file

@ -0,0 +1,135 @@
package mage.cards.c;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.LoyaltyAbility;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.common.PlaneswalkerEntersWithLoyaltyCountersAbility;
import mage.abilities.effects.ContinuousEffect;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.DamageTargetEffect;
import mage.abilities.effects.common.asthought.PlayFromNotOwnHandZoneTargetEffect;
import mage.cards.*;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.players.Player;
import mage.target.common.TargetOpponentOrPlaneswalker;
import mage.target.targetpointer.FixedTarget;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class ChandraFireArtisan extends CardImpl {
public ChandraFireArtisan(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.PLANESWALKER}, "{2}{R}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.CHANDRA);
this.addAbility(new PlaneswalkerEntersWithLoyaltyCountersAbility(4));
// Whenever one or more loyalty counters are removed from Chandra, Fire Artisan, she deals that much damage to target opponent or planeswalker.
this.addAbility(new ChandraFireArtisanTriggeredAbility());
// +1: Exile the top card of your library. You may play it this turn.
this.addAbility(new LoyaltyAbility(new ChandraFireArtisanEffect(false), 1));
// -7: Exile the top seven cards of your library. You may play them this turn.
this.addAbility(new LoyaltyAbility(new ChandraFireArtisanEffect(true), -7));
}
private ChandraFireArtisan(final ChandraFireArtisan card) {
super(card);
}
@Override
public ChandraFireArtisan copy() {
return new ChandraFireArtisan(this);
}
}
class ChandraFireArtisanTriggeredAbility extends TriggeredAbilityImpl {
ChandraFireArtisanTriggeredAbility() {
super(Zone.BATTLEFIELD, null);
this.addTarget(new TargetOpponentOrPlaneswalker());
}
private ChandraFireArtisanTriggeredAbility(final ChandraFireArtisanTriggeredAbility ability) {
super(ability);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.COUNTERS_REMOVED;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (event.getAmount() == 0 || event.getData() != "loyalty") {
return false;
}
this.getEffects().clear();
this.addEffect(new DamageTargetEffect(event.getAmount()));
return true;
}
@Override
public ChandraFireArtisanTriggeredAbility copy() {
return new ChandraFireArtisanTriggeredAbility(this);
}
@Override
public String getRule() {
return "Whenever one or more loyalty counters are removed from {this}, " +
"she deals that much damage to target opponent or planeswalker.";
}
}
class ChandraFireArtisanEffect extends OneShotEffect {
private final boolean exileSeven;
ChandraFireArtisanEffect(boolean exileSeven) {
super(Outcome.Detriment);
this.exileSeven = exileSeven;
if (exileSeven) {
staticText = "Exile the top seven cards of your library. You may play them this turn.";
} else {
staticText = "Exile the top card of your library. You may play it this turn";
}
}
private ChandraFireArtisanEffect(final ChandraFireArtisanEffect effect) {
super(effect);
this.exileSeven = effect.exileSeven;
}
@Override
public ChandraFireArtisanEffect copy() {
return new ChandraFireArtisanEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player controller = game.getPlayer(source.getControllerId());
MageObject sourceObject = source.getSourceObject(game);
if (controller == null || sourceObject == null) {
return false;
}
Cards cards = new CardsImpl(controller.getLibrary().getTopCards(game, (exileSeven ? 7 : 1)));
controller.moveCards(cards, Zone.EXILED, source, game);
for (Card card : cards.getCards(game)) {
if (card == null) {
continue;
}
ContinuousEffect effect = new PlayFromNotOwnHandZoneTargetEffect(Zone.EXILED, Duration.EndOfTurn);
effect.setTargetPointer(new FixedTarget(card, game));
game.addEffect(effect, source);
}
return true;
}
}

View file

@ -45,6 +45,7 @@ public final class WarOfTheSpark extends ExpansionSet {
cards.add(new SetCardInfo("Challenger Troll", 157, Rarity.UNCOMMON, mage.cards.c.ChallengerTroll.class));
cards.add(new SetCardInfo("Chandra's Pyrohelix", 120, Rarity.COMMON, mage.cards.c.ChandrasPyrohelix.class));
cards.add(new SetCardInfo("Chandra's Triumph", 121, Rarity.UNCOMMON, mage.cards.c.ChandrasTriumph.class));
cards.add(new SetCardInfo("Chandra, Fire Artisan", 119, Rarity.RARE, mage.cards.c.ChandraFireArtisan.class));
cards.add(new SetCardInfo("Courage in Crisis", 158, Rarity.COMMON, mage.cards.c.CourageInCrisis.class));
cards.add(new SetCardInfo("Cruel Celebrant", 188, Rarity.UNCOMMON, mage.cards.c.CruelCelebrant.class));
cards.add(new SetCardInfo("Crush Dissent", 47, Rarity.COMMON, mage.cards.c.CrushDissent.class));

View file

@ -720,6 +720,7 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
@Override
public void removeCounters(String name, int amount, Game game) {
int finalAmount = 0;
for (int i = 0; i < amount; i++) {
if (!getCounters(game).removeCounter(name, 1)) {
break;
@ -727,7 +728,12 @@ public abstract class CardImpl extends MageObjectImpl implements Card {
GameEvent event = GameEvent.getEvent(GameEvent.EventType.COUNTER_REMOVED, objectId, getControllerOrOwner());
event.setData(name);
game.fireEvent(event);
finalAmount++;
}
GameEvent event = GameEvent.getEvent(GameEvent.EventType.COUNTERS_REMOVED, objectId, getControllerOrOwner());
event.setData(name);
event.setAmount(finalAmount);
game.fireEvent(event);
}
@Override

View file

@ -292,7 +292,7 @@ public class GameEvent implements Serializable {
UNATTACH, UNATTACHED,
ADD_COUNTER, COUNTER_ADDED,
ADD_COUNTERS, COUNTERS_ADDED,
COUNTER_REMOVED,
COUNTER_REMOVED, COUNTERS_REMOVED,
LOSE_CONTROL,
/* LOST_CONTROL
targetId id of the creature that lost control

View file

@ -70,7 +70,6 @@ import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;
public abstract class PlayerImpl implements Player, Serializable {
@ -184,7 +183,6 @@ public abstract class PlayerImpl implements Player, Serializable {
put(PhaseStep.DECLARE_ATTACKERS, Step.StepPart.PRE).build();
public PlayerImpl(String name, RangeOfInfluence range) {
this(UUID.randomUUID());
this.name = name;
@ -739,7 +737,7 @@ public abstract class PlayerImpl implements Player, Serializable {
TargetDiscard target = new TargetDiscard(possibleAmount, possibleAmount, new FilterCard(CardUtil.numberToText(possibleAmount, "a") + " card" + (possibleAmount > 1 ? "s" : "")), playerId);
choose(Outcome.Discard, target, source == null ? null : source.getSourceId(), game);
for (UUID cardId : target.getTargets()) {
if(discard(this.getHand().get(cardId, game), source, game)) {
if (discard(this.getHand().get(cardId, game), source, game)) {
discardedCards.add(cardId);
}
}
@ -2046,6 +2044,7 @@ public abstract class PlayerImpl implements Player, Serializable {
@Override
public void removeCounters(String name, int amount, Ability source, Game game) {
int finalAmount = 0;
for (int i = 0; i < amount; i++) {
if (!counters.removeCounter(name, 1)) {
break;
@ -2055,7 +2054,13 @@ public abstract class PlayerImpl implements Player, Serializable {
event.setData(name);
event.setAmount(1);
game.fireEvent(event);
finalAmount++;
}
GameEvent event = GameEvent.getEvent(GameEvent.EventType.COUNTERS_REMOVED,
getId(), (source == null ? null : source.getSourceId()), (source == null ? null : source.getControllerId()));
event.setData(name);
event.setAmount(finalAmount);
game.fireEvent(event);
}
protected boolean canDamage(MageObject source, Game game) {