Implement [M3C] Blaster Hulk/Create EnergySpentOrLostThisTurnCount and update Izzet Generatorium (#12426)

* Implement-M3C-Blaster-Hulk

* Update BlasterHulk.java

* Update BlasterHulk to fix number of targets

---------

Co-authored-by: Grath <1895280+Grath@users.noreply.github.com>
This commit is contained in:
grimreap124 2024-09-02 03:40:54 +10:00 committed by GitHub
parent f6d7ede7e5
commit 9f1031f286
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 152 additions and 63 deletions

View file

@ -0,0 +1,68 @@
package mage.cards.b;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.AttacksAloneSourceTriggeredAbility;
import mage.abilities.common.AttacksTriggeredAbility;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.common.delayed.ReflexiveTriggeredAbility;
import mage.abilities.condition.Condition;
import mage.abilities.condition.common.PermanentsOnTheBattlefieldCondition;
import mage.abilities.costs.common.PayEnergyCost;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.AttackingCreatureCount;
import mage.abilities.dynamicvalue.common.EnergySpentOrLostThisTurnCount;
import mage.abilities.effects.common.DamageMultiEffect;
import mage.abilities.effects.common.DoWhenCostPaid;
import mage.abilities.effects.common.cost.SpellCostReductionForEachSourceEffect;
import mage.abilities.effects.common.cost.SpellCostReductionSourceEffect;
import mage.abilities.effects.common.counter.GetEnergyCountersControllerEffect;
import mage.abilities.hint.ValueHint;
import mage.constants.SubType;
import mage.abilities.keyword.HasteAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Zone;
import mage.target.common.TargetAnyTargetAmount;
/**
*
* @author grimreap124
*/
public final class BlasterHulk extends CardImpl {
public BlasterHulk(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT, CardType.CREATURE}, "{6}{R}{R}");
this.subtype.add(SubType.PIRATE);
this.power = new MageInt(8);
this.toughness = new MageInt(8);
// This spell costs {1} less to cast for each {E} you've paid or lost this turn.
DynamicValue xValue = EnergySpentOrLostThisTurnCount.instance;
this.addAbility(new SimpleStaticAbility(Zone.ALL, new SpellCostReductionForEachSourceEffect(1, xValue))
.addHint(new ValueHint("{E} you've paid or lost this turn", xValue))
);
// Haste
this.addAbility(HasteAbility.getInstance());
// Whenever Blaster Hulk attacks, you get {E}{E}, then you may pay eight {E}. When you do, Blaster Hulk deals 8 damage divided as you choose among up to eight targets.
Ability ability = new AttacksTriggeredAbility(new GetEnergyCountersControllerEffect(2));
ReflexiveTriggeredAbility reflexiveAbility = new ReflexiveTriggeredAbility(new DamageMultiEffect(8).setText("{this} deals 8 damage divided as you choose among up to eight targets"), false);
reflexiveAbility.addTarget(new TargetAnyTargetAmount(8));
ability.addEffect(new DoWhenCostPaid(reflexiveAbility, new PayEnergyCost(8), "Pay eight {E} to deal 8 damage divided as you choose among up to eight targets?"));
this.addAbility(ability);
}
private BlasterHulk(final BlasterHulk card) {
super(card);
}
@Override
public BlasterHulk copy() {
return new BlasterHulk(this);
}
}

View file

@ -7,6 +7,7 @@ import mage.abilities.condition.Condition;
import mage.abilities.condition.IntCompareCondition; import mage.abilities.condition.IntCompareCondition;
import mage.abilities.costs.common.TapSourceCost; import mage.abilities.costs.common.TapSourceCost;
import mage.abilities.dynamicvalue.DynamicValue; import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.dynamicvalue.common.EnergySpentOrLostThisTurnCount;
import mage.abilities.effects.Effect; import mage.abilities.effects.Effect;
import mage.abilities.effects.ReplacementEffectImpl; import mage.abilities.effects.ReplacementEffectImpl;
import mage.abilities.effects.common.DrawCardSourceControllerEffect; import mage.abilities.effects.common.DrawCardSourceControllerEffect;
@ -20,6 +21,7 @@ import mage.game.Game;
import mage.game.events.GameEvent; import mage.game.events.GameEvent;
import mage.util.CardUtil; import mage.util.CardUtil;
import mage.watchers.Watcher; import mage.watchers.Watcher;
import mage.watchers.common.EnergySpentOrLostWatcher;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
@ -31,7 +33,7 @@ import java.util.UUID;
public final class IzzetGeneratorium extends CardImpl { public final class IzzetGeneratorium extends CardImpl {
private static final Condition condition = new IzzetGeneratoriumCondition(); private static final Condition condition = new IzzetGeneratoriumCondition();
private static final Hint hint = new ValueHint("{E} paid or lost this turn", IzzetGeneratoriumValue.instance); private static final Hint hint = new ValueHint("{E} paid or lost this turn", EnergySpentOrLostThisTurnCount.instance);
public IzzetGeneratorium(UUID ownerId, CardSetInfo setInfo) { public IzzetGeneratorium(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{U}{R}"); super(ownerId, setInfo, new CardType[]{CardType.ARTIFACT}, "{U}{R}");
@ -44,7 +46,7 @@ public final class IzzetGeneratorium extends CardImpl {
new DrawCardSourceControllerEffect(1), new DrawCardSourceControllerEffect(1),
new TapSourceCost(), new TapSourceCost(),
condition condition
).addHint(hint), new IzzetGeneratoriumWatcher()); ).addHint(hint), new EnergySpentOrLostWatcher());
} }
private IzzetGeneratorium(final IzzetGeneratorium card) { private IzzetGeneratorium(final IzzetGeneratorium card) {
@ -100,71 +102,11 @@ class IzzetGeneratoriumCondition extends IntCompareCondition {
@Override @Override
protected int getInputValue(Game game, Ability source) { protected int getInputValue(Game game, Ability source) {
return IzzetGeneratoriumValue.instance.calculate(game, source, null); return EnergySpentOrLostThisTurnCount.instance.calculate(game, source, null);
} }
@Override @Override
public String toString() { public String toString() {
return "if you've paid or lost four or more {E} this turn"; return "if you've paid or lost four or more {E} this turn";
} }
}
enum IzzetGeneratoriumValue implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return IzzetGeneratoriumWatcher.getAmountEnergyLostOrSpentThisTurn(game, sourceAbility.getControllerId());
}
@Override
public IzzetGeneratoriumValue copy() {
return this;
}
@Override
public String getMessage() {
return "{E} spent or lost this turn";
}
@Override
public String toString() {
return "X";
}
}
class IzzetGeneratoriumWatcher extends Watcher {
// player -> amount of energy spent or lost this turn
private final Map<UUID, Integer> energyLostOrSpent = new HashMap<>();
IzzetGeneratoriumWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.COUNTERS_REMOVED) {
return;
}
if (!event.getData().equals(CounterType.ENERGY.getName())) {
return;
}
int amount = event.getAmount();
if (amount <= 0) {
return;
}
energyLostOrSpent.compute(event.getTargetId(), (k, i) -> i == null ? amount : Integer.sum(i, amount));
}
@Override
public void reset() {
super.reset();
energyLostOrSpent.clear();
}
public static int getAmountEnergyLostOrSpentThisTurn(Game game, UUID playerId) {
IzzetGeneratoriumWatcher watcher = game.getState().getWatcher(IzzetGeneratoriumWatcher.class);
return watcher == null ? 0 : watcher.energyLostOrSpent.getOrDefault(playerId, 0);
}
} }

View file

@ -59,6 +59,7 @@ public final class ModernHorizons3Commander extends ExpansionSet {
cards.add(new SetCardInfo("Bismuth Mindrender", 51, Rarity.RARE, mage.cards.b.BismuthMindrender.class)); cards.add(new SetCardInfo("Bismuth Mindrender", 51, Rarity.RARE, mage.cards.b.BismuthMindrender.class));
cards.add(new SetCardInfo("Bituminous Blast", 255, Rarity.UNCOMMON, mage.cards.b.BituminousBlast.class)); cards.add(new SetCardInfo("Bituminous Blast", 255, Rarity.UNCOMMON, mage.cards.b.BituminousBlast.class));
cards.add(new SetCardInfo("Blast Zone", 322, Rarity.RARE, mage.cards.b.BlastZone.class)); cards.add(new SetCardInfo("Blast Zone", 322, Rarity.RARE, mage.cards.b.BlastZone.class));
cards.add(new SetCardInfo("Blaster Hulk", 55, Rarity.RARE, mage.cards.b.BlasterHulk.class));
cards.add(new SetCardInfo("Bloodbraid Challenger", 70, Rarity.RARE, mage.cards.b.BloodbraidChallenger.class)); cards.add(new SetCardInfo("Bloodbraid Challenger", 70, Rarity.RARE, mage.cards.b.BloodbraidChallenger.class));
cards.add(new SetCardInfo("Bloodbraid Elf", 256, Rarity.UNCOMMON, mage.cards.b.BloodbraidElf.class)); cards.add(new SetCardInfo("Bloodbraid Elf", 256, Rarity.UNCOMMON, mage.cards.b.BloodbraidElf.class));
cards.add(new SetCardInfo("Bonders' Enclave", 323, Rarity.RARE, mage.cards.b.BondersEnclave.class)); cards.add(new SetCardInfo("Bonders' Enclave", 323, Rarity.RARE, mage.cards.b.BondersEnclave.class));

View file

@ -0,0 +1,31 @@
package mage.abilities.dynamicvalue.common;
import mage.abilities.Ability;
import mage.abilities.dynamicvalue.DynamicValue;
import mage.abilities.effects.Effect;
import mage.game.Game;
import mage.watchers.common.EnergySpentOrLostWatcher;
public enum EnergySpentOrLostThisTurnCount implements DynamicValue {
instance;
@Override
public int calculate(Game game, Ability sourceAbility, Effect effect) {
return EnergySpentOrLostWatcher.getAmountEnergyLostOrSpentThisTurn(game, sourceAbility.getControllerId());
}
@Override
public EnergySpentOrLostThisTurnCount copy() {
return this;
}
@Override
public String getMessage() {
return "{E} spent or lost this turn";
}
@Override
public String toString() {
return "X";
}
}

View file

@ -0,0 +1,47 @@
package mage.watchers.common;
import mage.constants.WatcherScope;
import mage.counters.CounterType;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.watchers.Watcher;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
public class EnergySpentOrLostWatcher extends Watcher {
// player -> amount of energy spent or lost this turn
private final Map<UUID, Integer> energyLostOrSpent = new HashMap<>();
public EnergySpentOrLostWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.COUNTERS_REMOVED) {
return;
}
if (!event.getData().equals(CounterType.ENERGY.getName())) {
return;
}
int amount = event.getAmount();
if (amount <= 0) {
return;
}
energyLostOrSpent.compute(event.getTargetId(), (k, i) -> i == null ? amount : Integer.sum(i, amount));
}
@Override
public void reset() {
super.reset();
energyLostOrSpent.clear();
}
public static int getAmountEnergyLostOrSpentThisTurn(Game game, UUID playerId) {
EnergySpentOrLostWatcher watcher = game.getState().getWatcher(EnergySpentOrLostWatcher.class);
return watcher == null ? 0 : watcher.energyLostOrSpent.getOrDefault(playerId, 0);
}
}