[SNC] Implemented Rakish Revelers

This commit is contained in:
Evan Kranzler 2022-04-18 20:58:59 -04:00
parent bbad644aad
commit c12057af55
5 changed files with 229 additions and 2 deletions

View file

@ -0,0 +1,171 @@
package mage.abilities.common;
import mage.MageObjectReference;
import mage.abilities.Ability;
import mage.abilities.ActivatedAbilityImpl;
import mage.abilities.Mode;
import mage.abilities.costs.common.ExileSourceFromHandCost;
import mage.abilities.costs.mana.GenericManaCost;
import mage.abilities.effects.ContinuousEffectImpl;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.mana.*;
import mage.constants.*;
import mage.game.Game;
import mage.game.events.GameEvent;
import mage.game.permanent.Permanent;
import mage.game.stack.Spell;
import mage.target.common.TargetLandPermanent;
import mage.util.CardUtil;
import mage.watchers.Watcher;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public class GiveManaAbilityAndCastSourceAbility extends ActivatedAbilityImpl {
// TODO: write automated tests for this (it works in manual testing)
public GiveManaAbilityAndCastSourceAbility(String colors) {
super(Zone.HAND, new GainManaAbilitiesWhileExiledEffect(colors), new GenericManaCost(2));
this.addCost(new ExileSourceFromHandCost());
this.addEffect(new CastExiledFromHandCardEffect());
this.addTarget(new TargetLandPermanent());
this.addWatcher(new WasCastFromExileWatcher());
}
private GiveManaAbilityAndCastSourceAbility(final GiveManaAbilityAndCastSourceAbility ability) {
super(ability);
}
@Override
public GiveManaAbilityAndCastSourceAbility copy() {
return new GiveManaAbilityAndCastSourceAbility(this);
}
}
class CastExiledFromHandCardEffect extends OneShotEffect {
CastExiledFromHandCardEffect() {
super(Outcome.Benefit);
staticText = "You may cast {this} for as long as it remains exiled";
}
private CastExiledFromHandCardEffect(final CastExiledFromHandCardEffect effect) {
super(effect);
}
@Override
public CastExiledFromHandCardEffect copy() {
return new CastExiledFromHandCardEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Optional.of(getValue("exiledHandCardRef"))
.filter(Objects::nonNull)
.map(MageObjectReference.class::cast)
.map(mor -> mor.getCard(game))
.ifPresent(card -> CardUtil.makeCardPlayable(
game, source, card, Duration.Custom, false
));
return true;
}
}
class GainManaAbilitiesWhileExiledEffect extends ContinuousEffectImpl {
private final String colors;
GainManaAbilitiesWhileExiledEffect(String colors) {
super(Duration.Custom, Layer.AbilityAddingRemovingEffects_6, SubLayer.NA, Outcome.AddAbility);
this.colors = colors;
}
private GainManaAbilitiesWhileExiledEffect(final GainManaAbilitiesWhileExiledEffect effect) {
super(effect);
this.colors = effect.colors;
}
@Override
public GainManaAbilitiesWhileExiledEffect copy() {
return new GainManaAbilitiesWhileExiledEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
if (WasCastFromExileWatcher.check((MageObjectReference) getValue("exiledHandCardRef"), game)) {
discard();
return false;
}
Permanent permanent = game.getPermanent(getTargetPointer().getFirst(game, source));
if (permanent == null) {
discard();
return false;
}
for (char c : colors.toCharArray()) {
Ability ability;
switch (c) {
case 'W':
ability = new WhiteManaAbility();
break;
case 'U':
ability = new BlueManaAbility();
break;
case 'B':
ability = new BlackManaAbility();
break;
case 'R':
ability = new RedManaAbility();
break;
case 'G':
ability = new GreenManaAbility();
break;
default:
continue;
}
permanent.addAbility(ability, source.getSourceId(), game);
}
return true;
}
@Override
public String getText(Mode mode) {
return "target land gains \"{T}: Add " +
CardUtil.concatWithOr(
Arrays.stream(colors.split(""))
.map(s -> '{' + s + '}')
.collect(Collectors.toList())
) +
"\" until {this} is cast from exile";
}
}
class WasCastFromExileWatcher extends Watcher {
private final Set<MageObjectReference> morSet = new HashSet<>();
WasCastFromExileWatcher() {
super(WatcherScope.GAME);
}
@Override
public void watch(GameEvent event, Game game) {
if (event.getType() != GameEvent.EventType.SPELL_CAST || !Zone.EXILED.match(event.getZone())) {
return;
}
Spell spell = game.getSpell(event.getSourceId());
if (spell != null) {
morSet.add(new MageObjectReference(spell.getMainCard(), game, -1));
}
}
static boolean check(MageObjectReference mor, Game game) {
return game
.getState()
.getWatcher(WasCastFromExileWatcher.class)
.morSet
.contains(mor);
}
}