[AFC] Implemented Hellish Rebuke

This commit is contained in:
Evan Kranzler 2021-08-21 11:20:16 -04:00
parent 898f8ca287
commit d20b15c7b6
3 changed files with 140 additions and 0 deletions

View file

@ -0,0 +1,123 @@
package mage.cards.h;
import mage.MageObject;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.LoseLifeSourceControllerEffect;
import mage.abilities.effects.common.SacrificeSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityAllEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Duration;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.watchers.common.SpellsCastWatcher;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class HellishRebuke extends CardImpl {
public HellishRebuke(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.INSTANT}, "{2}{B}");
// Until end of turn, permanents your opponents control gain "When this permanent deals damage to the player who cast Hellish Rebuke, sacrifice this permanent. You lose 2 life."
this.getSpellAbility().addEffect(new HellishRebukeEffect());
this.getSpellAbility().addWatcher(new SpellsCastWatcher());
}
private HellishRebuke(final HellishRebuke card) {
super(card);
}
@Override
public HellishRebuke copy() {
return new HellishRebuke(this);
}
}
class HellishRebukeEffect extends OneShotEffect {
HellishRebukeEffect() {
super(Outcome.Benefit);
staticText = "until end of turn, permanents your opponents control gain " +
"\"When this permanent deals damage to the player who cast {this}, " +
"sacrifice this permanent. You lose 2 life.\"";
}
private HellishRebukeEffect(final HellishRebukeEffect effect) {
super(effect);
}
@Override
public HellishRebukeEffect copy() {
return new HellishRebukeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
MageObject mageObject = source.getSourceObject(game);
game.addEffect(new GainAbilityAllEffect(
new HellishRebukeTriggeredAbility(source, game),
Duration.EndOfTurn, StaticFilters.FILTER_OPPONENTS_PERMANENT
), source);
return true;
}
}
class HellishRebukeTriggeredAbility extends TriggeredAbilityImpl {
private final String sourceName;
private final UUID casterId;
HellishRebukeTriggeredAbility(Ability source, Game game) {
super(Zone.BATTLEFIELD, new SacrificeSourceEffect());
this.addEffect(new LoseLifeSourceControllerEffect(2));
this.sourceName = getSourceName(source, game);
this.casterId = getCasterId(source, game);
}
private HellishRebukeTriggeredAbility(final HellishRebukeTriggeredAbility ability) {
super(ability);
this.sourceName = ability.sourceName;
this.casterId = ability.casterId;
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
return event.getSourceId().equals(getSourceId()) && event.getPlayerId().equals(casterId);
}
@Override
public HellishRebukeTriggeredAbility copy() {
return new HellishRebukeTriggeredAbility(this);
}
@Override
public String getRule() {
return "When this permanent deals damage to the player who cast "
+ sourceName + ", sacrifice this permanent. You lose 2 life.";
}
private static final String getSourceName(Ability source, Game game) {
MageObject object = source.getSourceObject(game);
return object != null ? object.getName() : "Hellish Rebuke";
}
private static final UUID getCasterId(Ability source, Game game) {
SpellsCastWatcher watcher = game.getState().getWatcher(SpellsCastWatcher.class);
return watcher.getCasterId(source, game);
}
}

View file

@ -125,6 +125,7 @@ public final class ForgottenRealmsCommander extends ExpansionSet {
cards.add(new SetCardInfo("Halimar Depths", 244, Rarity.COMMON, mage.cards.h.HalimarDepths.class));
cards.add(new SetCardInfo("Haven of the Spirit Dragon", 245, Rarity.RARE, mage.cards.h.HavenOfTheSpiritDragon.class));
cards.add(new SetCardInfo("Heirloom Blade", 208, Rarity.UNCOMMON, mage.cards.h.HeirloomBlade.class));
cards.add(new SetCardInfo("Hellish Rebuke", 26, Rarity.RARE, mage.cards.h.HellishRebuke.class));
cards.add(new SetCardInfo("Heroic Intervention", 161, Rarity.RARE, mage.cards.h.HeroicIntervention.class));
cards.add(new SetCardInfo("Hex", 101, Rarity.RARE, mage.cards.h.Hex.class));
cards.add(new SetCardInfo("High Market", 246, Rarity.RARE, mage.cards.h.HighMarket.class));

View file

@ -1,6 +1,8 @@
package mage.watchers.common;
import mage.MageObject;
import mage.abilities.Ability;
import mage.cards.Card;
import mage.constants.WatcherScope;
import mage.constants.Zone;
import mage.filter.StaticFilters;
@ -68,4 +70,18 @@ public class SpellsCastWatcher extends Watcher {
public int getNumberOfNonCreatureSpells() {
return nonCreatureSpells;
}
public UUID getCasterId(Ability source, Game game) {
for (Map.Entry<UUID, List<Spell>> entry : spellsCast.entrySet()) {
if (entry.getValue()
.stream()
.map(Spell::getCard)
.map(Card::getMainCard)
.anyMatch(card -> card.getId().equals(source.getSourceId())
&& card.getZoneChangeCounter(game) == source.getSourceObjectZoneChangeCounter())) {
return entry.getKey();
}
}
return null;
}
}