[DMU] Implemented Rivaz of the Claw (#9523)

This commit is contained in:
Daniel Bomar 2022-09-15 21:35:52 -05:00 committed by GitHub
parent c7d3634f15
commit 3d3fde35ca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 206 additions and 92 deletions

View file

@ -1,32 +1,34 @@
package mage.cards.l; package mage.cards.l;
import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import mage.MageIdentifier;
import mage.MageInt; import mage.MageInt;
import mage.MageObject; import mage.MageObject;
import mage.MageObjectReference; import mage.abilities.common.CastFromGraveyardOnceStaticAbility;
import mage.abilities.Ability;
import mage.abilities.common.SimpleStaticAbility;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.abilities.keyword.CompanionAbility; import mage.abilities.keyword.CompanionAbility;
import mage.abilities.keyword.CompanionCondition; import mage.abilities.keyword.CompanionCondition;
import mage.abilities.keyword.LifelinkAbility; import mage.abilities.keyword.LifelinkAbility;
import mage.cards.Card; import mage.cards.Card;
import mage.cards.CardImpl; import mage.cards.CardImpl;
import mage.cards.CardSetInfo; import mage.cards.CardSetInfo;
import mage.constants.*; import mage.constants.CardType;
import mage.game.Game; import mage.constants.ComparisonType;
import mage.game.events.GameEvent; import mage.constants.SubType;
import mage.game.permanent.Permanent; import mage.constants.SuperType;
import mage.watchers.Watcher; import mage.filter.common.FilterPermanentCard;
import mage.filter.predicate.mageobject.ManaValuePredicate;
/** /**
* @author TheElk801 * @author TheElk801
*/ */
public final class LurrusOfTheDreamDen extends CardImpl { public final class LurrusOfTheDreamDen extends CardImpl {
private static final FilterPermanentCard filter = new FilterPermanentCard();
static {
filter.add(new ManaValuePredicate(ComparisonType.FEWER_THAN, 3));
}
public LurrusOfTheDreamDen(UUID ownerId, CardSetInfo setInfo) { public LurrusOfTheDreamDen(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W/B}{W/B}"); super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{W/B}{W/B}");
@ -43,9 +45,7 @@ public final class LurrusOfTheDreamDen extends CardImpl {
this.addAbility(LifelinkAbility.getInstance()); this.addAbility(LifelinkAbility.getInstance());
// During each of your turns, you may cast one permanent spell with converted mana cost 2 or less from your graveyard. // During each of your turns, you may cast one permanent spell with converted mana cost 2 or less from your graveyard.
this.addAbility(new SimpleStaticAbility(new LurrusOfTheDreamDenCastFromGraveyardEffect()) this.addAbility(new CastFromGraveyardOnceStaticAbility(filter, "During each of your turns, you may cast one permanent spell with mana value 2 or less from your graveyard"));
.setIdentifier(MageIdentifier.LurrusOfTheDreamDenWatcher),
new LurrusOfTheDreamDenWatcher());
} }
private LurrusOfTheDreamDen(final LurrusOfTheDreamDen card) { private LurrusOfTheDreamDen(final LurrusOfTheDreamDen card) {
@ -75,80 +75,3 @@ enum LurrusOfTheDreamDenCompanionCondition implements CompanionCondition {
.orElse(0) <= 2; .orElse(0) <= 2;
} }
} }
class LurrusOfTheDreamDenCastFromGraveyardEffect extends AsThoughEffectImpl {
LurrusOfTheDreamDenCastFromGraveyardEffect() {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit, true);
staticText = "During each of your turns, you may cast one permanent spell with mana value 2 or less from your graveyard";
}
private LurrusOfTheDreamDenCastFromGraveyardEffect(final LurrusOfTheDreamDenCastFromGraveyardEffect effect) {
super(effect);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public LurrusOfTheDreamDenCastFromGraveyardEffect copy() {
return new LurrusOfTheDreamDenCastFromGraveyardEffect(this);
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (source.isControlledBy(affectedControllerId)
&& Zone.GRAVEYARD.equals(game.getState().getZone(objectId))
&& game.isActivePlayer(source.getControllerId())) { // only during your turn
Card objectCard = game.getCard(objectId);
Permanent sourceObject = game.getPermanent(source.getSourceId());
if (sourceObject != null && objectCard != null
&& objectCard.isPermanent(game)
&& objectCard.isOwnedBy(source.getControllerId())
&& objectCard.getManaValue() < 3
&& objectCard.getSpellAbility() != null
&& objectCard.getSpellAbility().spellCanBeActivatedRegularlyNow(affectedControllerId, game)) {
LurrusOfTheDreamDenWatcher watcher = game.getState().getWatcher(LurrusOfTheDreamDenWatcher.class);
return watcher != null && !watcher.isAbilityUsed(new MageObjectReference(sourceObject, game));
}
}
if (!objectId.equals(getTargetPointer().getFirst(game, source))) {
return false;
}
if (!affectedControllerId.equals(source.getControllerId())) {
return false;
}
LurrusOfTheDreamDenWatcher watcher = game.getState().getWatcher(LurrusOfTheDreamDenWatcher.class);
return watcher != null && !watcher.isAbilityUsed(new MageObjectReference(source.getSourceId(), game));
}
}
class LurrusOfTheDreamDenWatcher extends Watcher {
private final Set<MageObjectReference> usedFrom = new HashSet<>();
LurrusOfTheDreamDenWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (GameEvent.EventType.SPELL_CAST.equals(event.getType())
&& event.hasApprovingIdentifier(MageIdentifier.LurrusOfTheDreamDenWatcher)) {
usedFrom.add(event.getAdditionalReference().getApprovingMageObjectReference());
}
}
@Override
public void reset() {
super.reset();
usedFrom.clear();
}
boolean isAbilityUsed(MageObjectReference mor) {
return usedFrom.contains(mor);
}
}

View file

@ -0,0 +1,76 @@
package mage.cards.r;
import java.util.UUID;
import mage.MageInt;
import mage.abilities.common.CastFromGraveyardOnceStaticAbility;
import mage.abilities.common.DiesSourceTriggeredAbility;
import mage.abilities.common.SpellCastControllerTriggeredAbility;
import mage.abilities.effects.common.ExileSourceEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.mana.ConditionalAnyColorManaAbility;
import mage.abilities.mana.conditional.ConditionalSpellManaBuilder;
import mage.constants.*;
import mage.abilities.keyword.MenaceAbility;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.filter.common.FilterCreatureCard;
import mage.filter.common.FilterCreatureSpell;
import mage.filter.predicate.card.CastFromZonePredicate;
/**
*
* @author weirddan455
*/
public final class RivazOfTheClaw extends CardImpl {
private static final FilterCreatureSpell manaAbilityFilter = new FilterCreatureSpell("Dragon creature spells");
private static final FilterCreatureCard staticAbilityFilter = new FilterCreatureCard();
private static final FilterCreatureSpell spellCastFilter = new FilterCreatureSpell("a Dragon creature spell from your graveyard");
static {
manaAbilityFilter.add(SubType.DRAGON.getPredicate());
staticAbilityFilter.add(SubType.DRAGON.getPredicate());
spellCastFilter.add(SubType.DRAGON.getPredicate());
spellCastFilter.add(new CastFromZonePredicate(Zone.GRAVEYARD));
}
public RivazOfTheClaw(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{1}{B}{R}");
this.addSuperType(SuperType.LEGENDARY);
this.subtype.add(SubType.VIASHINO);
this.subtype.add(SubType.WARLOCK);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// Menace
this.addAbility(new MenaceAbility(false));
// {T}: Add two mana in any combination of colors. Spend this mana only to cast Dragon creature spells.
this.addAbility(new ConditionalAnyColorManaAbility(2, new ConditionalSpellManaBuilder(manaAbilityFilter)));
// Once during each of your turns, you may cast a Dragon creature spell from your graveyard.
this.addAbility(new CastFromGraveyardOnceStaticAbility(staticAbilityFilter, "Once during each of your turns, you may cast a Dragon creature spell from your graveyard"));
// Whenever you cast a Dragon creature spell from your graveyard, it gains "When this creature dies, exile it."
this.addAbility(new SpellCastControllerTriggeredAbility(
Zone.BATTLEFIELD,
new GainAbilityTargetEffect(
new DiesSourceTriggeredAbility(new ExileSourceEffect().setText("exile it"), false),
Duration.Custom,
"it gains \"When this creature dies, exile it.\"",
true
),
spellCastFilter, false, true, true
));
}
private RivazOfTheClaw(final RivazOfTheClaw card) {
super(card);
}
@Override
public RivazOfTheClaw copy() {
return new RivazOfTheClaw(this);
}
}

View file

@ -207,6 +207,7 @@ public final class DominariaUnited extends ExpansionSet {
cards.add(new SetCardInfo("Relic of Legends", 236, Rarity.UNCOMMON, mage.cards.r.RelicOfLegends.class)); cards.add(new SetCardInfo("Relic of Legends", 236, Rarity.UNCOMMON, mage.cards.r.RelicOfLegends.class));
cards.add(new SetCardInfo("Resolute Reinforcements", 29, Rarity.UNCOMMON, mage.cards.r.ResoluteReinforcements.class)); cards.add(new SetCardInfo("Resolute Reinforcements", 29, Rarity.UNCOMMON, mage.cards.r.ResoluteReinforcements.class));
cards.add(new SetCardInfo("Rith, Liberated Primeval", 214, Rarity.MYTHIC, mage.cards.r.RithLiberatedPrimeval.class)); cards.add(new SetCardInfo("Rith, Liberated Primeval", 214, Rarity.MYTHIC, mage.cards.r.RithLiberatedPrimeval.class));
cards.add(new SetCardInfo("Rivaz of the Claw", 215, Rarity.RARE, mage.cards.r.RivazOfTheClaw.class));
cards.add(new SetCardInfo("Rona's Vortex", 63, Rarity.UNCOMMON, mage.cards.r.RonasVortex.class)); cards.add(new SetCardInfo("Rona's Vortex", 63, Rarity.UNCOMMON, mage.cards.r.RonasVortex.class));
cards.add(new SetCardInfo("Rona, Sheoldred's Faithful", 216, Rarity.UNCOMMON, mage.cards.r.RonaSheoldredsFaithful.class)); cards.add(new SetCardInfo("Rona, Sheoldred's Faithful", 216, Rarity.UNCOMMON, mage.cards.r.RonaSheoldredsFaithful.class));
cards.add(new SetCardInfo("Rulik Mons, Warren Chief", 217, Rarity.UNCOMMON, mage.cards.r.RulikMonsWarrenChief.class)); cards.add(new SetCardInfo("Rulik Mons, Warren Chief", 217, Rarity.UNCOMMON, mage.cards.r.RulikMonsWarrenChief.class));

View file

@ -7,12 +7,12 @@ package mage;
* @author LevelX2 * @author LevelX2
*/ */
public enum MageIdentifier { public enum MageIdentifier {
CastFromGraveyardOnceWatcher,
CemeteryIlluminatorWatcher, CemeteryIlluminatorWatcher,
GisaAndGeralfWatcher, GisaAndGeralfWatcher,
HaukensInsightWatcher, HaukensInsightWatcher,
KaradorGhostChieftainWatcher, KaradorGhostChieftainWatcher,
KessDissidentMageWatcher, KessDissidentMageWatcher,
LurrusOfTheDreamDenWatcher,
MuldrothaTheGravetideWatcher, MuldrothaTheGravetideWatcher,
ShareTheSpoilsWatcher, ShareTheSpoilsWatcher,
WishWatcher, WishWatcher,

View file

@ -0,0 +1,114 @@
package mage.abilities.common;
import mage.MageIdentifier;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.effects.AsThoughEffectImpl;
import mage.cards.Card;
import mage.constants.*;
import mage.filter.FilterCard;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.watchers.Watcher;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
/**
* Once during each of your turns, you may cast... from your graveyard
*
* See Lurrus of the Dream Den and Rivaz of the Claw
*
* @author weirddan455
*/
public class CastFromGraveyardOnceStaticAbility extends SimpleStaticAbility {
public CastFromGraveyardOnceStaticAbility(FilterCard filter, String text) {
super(new CastFromGraveyardOnceEffect(filter, text));
this.addWatcher(new CastFromGraveyardOnceWatcher());
this.setIdentifier(MageIdentifier.CastFromGraveyardOnceWatcher);
}
private CastFromGraveyardOnceStaticAbility(final CastFromGraveyardOnceStaticAbility ability) {
super(ability);
}
@Override
public CastFromGraveyardOnceStaticAbility copy() {
return new CastFromGraveyardOnceStaticAbility(this);
}
}
class CastFromGraveyardOnceEffect extends AsThoughEffectImpl {
private final FilterCard filter;
CastFromGraveyardOnceEffect(FilterCard filter, String text) {
super(AsThoughEffectType.PLAY_FROM_NOT_OWN_HAND_ZONE, Duration.WhileOnBattlefield, Outcome.Benefit, true);
this.filter = filter;
this.staticText = text;
}
private CastFromGraveyardOnceEffect(final CastFromGraveyardOnceEffect effect) {
super(effect);
this.filter = effect.filter;
}
@Override
public CastFromGraveyardOnceEffect copy() {
return new CastFromGraveyardOnceEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
return true;
}
@Override
public boolean applies(UUID objectId, Ability source, UUID affectedControllerId, Game game) {
if (source.isControlledBy(affectedControllerId)
&& Zone.GRAVEYARD.equals(game.getState().getZone(objectId))
&& game.isActivePlayer(affectedControllerId)) {
Card card = game.getCard(objectId);
Permanent sourceObject = source.getSourcePermanentIfItStillExists(game);
if (card != null && sourceObject != null
&& card.isOwnedBy(affectedControllerId)
&& card.getSpellAbility() != null
&& card.getSpellAbility().spellCanBeActivatedRegularlyNow(affectedControllerId, game)
&& filter.match(card, affectedControllerId, source, game)) {
CastFromGraveyardOnceWatcher watcher = game.getState().getWatcher(CastFromGraveyardOnceWatcher.class);
return watcher != null && watcher.abilityNotUsed(new MageObjectReference(sourceObject, game));
}
}
return false;
}
}
class CastFromGraveyardOnceWatcher extends Watcher {
private final Set<MageObjectReference> usedFrom = new HashSet<>();
CastFromGraveyardOnceWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (GameEvent.EventType.SPELL_CAST.equals(event.getType())
&& event.hasApprovingIdentifier(MageIdentifier.CastFromGraveyardOnceWatcher)) {
usedFrom.add(event.getAdditionalReference().getApprovingMageObjectReference());
}
}
@Override
public void reset() {
super.reset();
usedFrom.clear();
}
boolean abilityNotUsed(MageObjectReference mor) {
return !usedFrom.contains(mor);
}
}