mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 21:12:04 -08:00
[SNC] Implemented Rakish Revelers
This commit is contained in:
parent
bbad644aad
commit
c12057af55
5 changed files with 229 additions and 2 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package mage.abilities.costs.common;
|
||||
|
||||
import mage.MageObjectReference;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.costs.Cost;
|
||||
import mage.abilities.costs.CostImpl;
|
||||
|
|
@ -29,6 +30,7 @@ public class ExileSourceFromHandCost extends CostImpl {
|
|||
Card card = game.getCard(source.getSourceId());
|
||||
if (player != null && player.getHand().contains(source.getSourceId()) && card != null) {
|
||||
paid = player.moveCards(card, Zone.EXILED, source, game);
|
||||
source.getEffects().setValue("exiledHandCardRef", new MageObjectReference(card, game));
|
||||
}
|
||||
return paid;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1531,14 +1531,22 @@ public final class CardUtil {
|
|||
return "T" + gameState.getTurnNum() + "." + gameState.getTurn().getStep().getType().getStepShortText();
|
||||
}
|
||||
|
||||
public static String concatWithOr(List<String> strings) {
|
||||
return concatWith(strings, "or");
|
||||
}
|
||||
|
||||
public static String concatWithAnd(List<String> strings) {
|
||||
return concatWith(strings, "and");
|
||||
}
|
||||
|
||||
private static String concatWith(List<String> strings, String last) {
|
||||
switch (strings.size()) {
|
||||
case 0:
|
||||
return "";
|
||||
case 1:
|
||||
return strings.get(0);
|
||||
case 2:
|
||||
return strings.get(0) + " and " + strings.get(1);
|
||||
return strings.get(0) + " " + last + " " + strings.get(1);
|
||||
}
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < strings.size(); i++) {
|
||||
|
|
@ -1548,7 +1556,8 @@ public final class CardUtil {
|
|||
}
|
||||
sb.append(", ");
|
||||
if (i == strings.size() - 2) {
|
||||
sb.append("and ");
|
||||
sb.append(last);
|
||||
sb.append(' ');
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue