[OTC] Implement Thunderclap Drake

This commit is contained in:
Susucre 2024-04-09 13:08:10 +02:00
parent 803243ae64
commit e62d1c2124
5 changed files with 162 additions and 39 deletions

View file

@ -1,18 +1,12 @@
package mage.cards.c;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.dynamicvalue.common.CommanderCastFromCommandZoneValue;
import mage.abilities.effects.common.continuous.BoostControlledEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.CommanderCardType;
import mage.constants.Duration;
import mage.game.Game;
import mage.players.Player;
import mage.watchers.common.CommanderPlaysCountWatcher;
import java.util.UUID;
@ -25,9 +19,11 @@ public final class CommandersInsignia extends CardImpl {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{W}{W}");
// Creatures you control get +1/+1 for each time you've cast your commander from the command zone this game.
this.addAbility(new SimpleStaticAbility(new BoostControlledEffect(
CommandersInsigniaValue.instance, CommandersInsigniaValue.instance, Duration.WhileOnBattlefield
).setText("Creatures you control get +1/+1 for each time you've cast your commander from the command zone this game.")));
this.addAbility(new SimpleStaticAbility(
new BoostControlledEffect(
CommanderCastFromCommandZoneValue.instance, CommanderCastFromCommandZoneValue.instance, Duration.WhileOnBattlefield
).setText("Creatures you control get +1/+1 for each time you've cast your commander from the command zone this game.")
).addHint(CommanderCastFromCommandZoneValue.getHint()));
}
private CommandersInsignia(final CommandersInsignia card) {
@ -38,32 +34,4 @@ public final class CommandersInsignia extends CardImpl {
public CommandersInsignia copy() {
return new CommandersInsignia(this);
}
}
enum CommandersInsigniaValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Player player = game.getPlayer(sourceAbility.getControllerId());
CommanderPlaysCountWatcher watcher = game.getState().getWatcher(CommanderPlaysCountWatcher.class);
if (player == null || watcher == null) {
return 0;
}
return game
.getCommandersIds(player, CommanderCardType.COMMANDER_OR_OATHBREAKER, false)
.stream()
.mapToInt(watcher::getPlaysCount)
.sum();
}
@Override
public DynamicValue copy() {
return instance;
}
@Override
public String getMessage() {
return "";
}
}

View file

@ -0,0 +1,108 @@
package mage.cards.t;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.SimpleActivatedAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.CopyNextSpellDelayedTriggeredAbility;
import mage.abilities.costs.common.SacrificeSourceCost;
import mage.abilities.costs.mana.ManaCostsImpl;
import mage.abilities.dynamicvalue.common.CommanderCastFromCommandZoneValue;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateDelayedTriggeredAbilityEffect;
import mage.abilities.effects.common.cost.SpellsCostReductionControllerEffect;
import mage.abilities.keyword.FlyingAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.filter.FilterCard;
import mage.filter.StaticFilters;
import mage.filter.common.FilterInstantOrSorceryCard;
import mage.game.Game;
import mage.game.stack.Spell;
import mage.players.Player;
import mage.util.CardUtil;
import java.util.UUID;
/**
* @author Susucr
*/
public final class ThunderclapDrake extends CardImpl {
private static final FilterCard filter = new FilterInstantOrSorceryCard("instant and sorcery spells");
public ThunderclapDrake(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{U}");
this.subtype.add(SubType.DRAKE);
this.power = new MageInt(2);
this.toughness = new MageInt(1);
// Flying
this.addAbility(FlyingAbility.getInstance());
// Instant and sorcery spells you cast cost {1} less to cast.
this.addAbility(new SimpleStaticAbility(new SpellsCostReductionControllerEffect(filter, 1)));
// {2}{U}, Sacrifice Thunderclap Drake: When you cast your next instant or sorcery spell this turn, copy it for each time you've cast your commander from the command zone this game. You may choose new targets for the copies.
Ability ability = new SimpleActivatedAbility(
new CreateDelayedTriggeredAbilityEffect(
new CopyNextSpellDelayedTriggeredAbility(
StaticFilters.FILTER_SPELL_INSTANT_OR_SORCERY,
new ThunderclapDrakeEffect(),
"When you cast your next instant or sorcery spell this turn, "
+ "copy it for each time you've cast your commander from the command zone this game. "
+ "You may choose new targets for the copies."
)
),
new ManaCostsImpl<>("{2}{U}")
);
ability.addCost(new SacrificeSourceCost());
ability.addHint(CommanderCastFromCommandZoneValue.getHint());
this.addAbility(ability);
}
private ThunderclapDrake(final ThunderclapDrake card) {
super(card);
}
@Override
public ThunderclapDrake copy() {
return new ThunderclapDrake(this);
}
}
// Inspired by CommanderStormEffect
class ThunderclapDrakeEffect extends OneShotEffect {
ThunderclapDrakeEffect() {
super(Outcome.Copy);
staticText = "copy it for each time you've cast your commander from the command zone this game. "
+ "You may choose new targets for the copies";
}
private ThunderclapDrakeEffect(final ThunderclapDrakeEffect effect) {
super(effect);
}
@Override
public ThunderclapDrakeEffect copy() {
return new ThunderclapDrakeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
Spell spell = (Spell) this.getValue("spellCast");
int count = CommanderCastFromCommandZoneValue.instance.calculate(game, source, this);
if (spell == null || player == null || count <= 0) {
return false;
}
game.informPlayers(spell.getLogName() + " will be copied " + count + " time" + (count > 1 ? "s" : "") + CardUtil.getSourceLogName(game, source));
spell.createCopyOnStack(game, source, source.getControllerId(), true, count);
return true;
}
}

View file

@ -282,6 +282,7 @@ public final class OutlawsOfThunderJunctionCommander extends ExpansionSet {
cards.add(new SetCardInfo("Third Path Iconoclast", 244, Rarity.UNCOMMON, mage.cards.t.ThirdPathIconoclast.class));
cards.add(new SetCardInfo("Three Visits", 209, Rarity.UNCOMMON, mage.cards.t.ThreeVisits.class));
cards.add(new SetCardInfo("Thrilling Discovery", 245, Rarity.COMMON, mage.cards.t.ThrillingDiscovery.class));
cards.add(new SetCardInfo("Thunderclap Drake", 17, Rarity.RARE, mage.cards.t.ThunderclapDrake.class));
cards.add(new SetCardInfo("Titania, Protector of Argoth", 210, Rarity.MYTHIC, mage.cards.t.TitaniaProtectorOfArgoth.class));
cards.add(new SetCardInfo("Tower Winder", 34, Rarity.RARE, mage.cards.t.TowerWinder.class));
cards.add(new SetCardInfo("Trailblazer's Boots", 269, Rarity.UNCOMMON, mage.cards.t.TrailblazersBoots.class));

View file

@ -33,7 +33,7 @@ public class CopyNextSpellDelayedTriggeredAbility extends DelayedTriggeredAbilit
this.rule = rule;
}
private CopyNextSpellDelayedTriggeredAbility(final CopyNextSpellDelayedTriggeredAbility ability) {
protected CopyNextSpellDelayedTriggeredAbility(final CopyNextSpellDelayedTriggeredAbility ability) {
super(ability);
this.filter = ability.filter;
this.rule = ability.rule;

View file

@ -0,0 +1,46 @@
package mage.abilities.dynamicvalue.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.abilities.hint.Hint;
import mage.abilities.hint.ValueHint;
import mage.constants.CommanderCardType;
import mage.game.Game;
import mage.players.Player;
import mage.watchers.common.CommanderPlaysCountWatcher;
public enum CommanderCastFromCommandZoneValue implements DynamicValue {
instance;
private static final Hint hint = new ValueHint("Number of times you cast your commander from command zone", instance);
public static Hint getHint() {
return hint;
}
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
Player player = game.getPlayer(sourceAbility.getControllerId());
CommanderPlaysCountWatcher watcher = game.getState().getWatcher(CommanderPlaysCountWatcher.class);
if (player == null || watcher == null) {
return 0;
}
return game
.getCommandersIds(player, CommanderCardType.COMMANDER_OR_OATHBREAKER, false)
.stream()
.mapToInt(watcher::getPlaysCount)
.sum();
}
@Override
public DynamicValue copy() {
return instance;
}
@Override
public String getMessage() {
return "";
}
}