mirror of
https://github.com/correl/mage.git
synced 2025-01-13 11:01:58 +00:00
[ALL] reworked Fatal Lore and Misfortune to use mode selection
This commit is contained in:
parent
3fe6a60616
commit
80f9fdfb79
3 changed files with 98 additions and 85 deletions
|
@ -1,37 +1,46 @@
|
|||
package mage.cards.f;
|
||||
|
||||
import java.util.UUID;
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.dynamicvalue.common.StaticValue;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.DestroyTargetEffect;
|
||||
import mage.abilities.effects.common.DrawCardTargetEffect;
|
||||
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.filter.FilterPermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.Game;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetCreaturePermanent;
|
||||
import mage.target.common.TargetOpponent;
|
||||
import mage.target.targetpointer.FixedTarget;
|
||||
import mage.target.TargetPermanent;
|
||||
import mage.target.targetadjustment.TargetAdjuster;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jeffwadsworth
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class FatalLore extends CardImpl {
|
||||
|
||||
public FatalLore(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{2}{B}{B}");
|
||||
|
||||
// An opponent chooses one - You draw three cards; or you destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated.
|
||||
this.getSpellAbility().addEffect(new FatalLoreEffect());
|
||||
this.getSpellAbility().addTarget(new TargetOpponent(true));
|
||||
// An opponent chooses one —
|
||||
this.getSpellAbility().getModes().setModeChooser(TargetController.OPPONENT);
|
||||
|
||||
// • You draw three cards.
|
||||
this.getSpellAbility().addEffect(new DrawCardSourceControllerEffect(1).setText("you draw three cards"));
|
||||
|
||||
// • You destroy up to two target creatures that player controls. They can't be regenerated. That player draws up to three cards.
|
||||
this.getSpellAbility().addMode(new Mode(new DestroyTargetEffect(
|
||||
"you destroy up to two target creatures that player controls. " +
|
||||
"They can't be regenerated", true
|
||||
)).addEffect(new FatalLoreEffect()));
|
||||
this.getSpellAbility().setTargetAdjuster(FatalLoreAdjuster.instance);
|
||||
}
|
||||
|
||||
private FatalLore(final FatalLore card) {
|
||||
|
@ -44,14 +53,37 @@ public final class FatalLore extends CardImpl {
|
|||
}
|
||||
}
|
||||
|
||||
enum FatalLoreAdjuster implements TargetAdjuster {
|
||||
instance;
|
||||
|
||||
@Override
|
||||
public void adjustTargets(Ability ability, Game game) {
|
||||
Mode mode = ability.getModes().getMode();
|
||||
if (mode.getEffects().stream().noneMatch(DestroyTargetEffect.class::isInstance)) {
|
||||
return;
|
||||
}
|
||||
UUID playerId = mode
|
||||
.getEffects()
|
||||
.stream()
|
||||
.findFirst()
|
||||
.filter(Objects::nonNull)
|
||||
.map(effect -> (UUID) effect.getValue("choosingPlayer"))
|
||||
.orElse(null);
|
||||
FilterPermanent filter = new FilterCreaturePermanent("creatures controlled by " + game.getPlayer(playerId).getName());
|
||||
filter.add(new ControllerIdPredicate(playerId));
|
||||
mode.getTargets().clear();
|
||||
mode.addTarget(new TargetPermanent(0, 2, filter));
|
||||
}
|
||||
}
|
||||
|
||||
class FatalLoreEffect extends OneShotEffect {
|
||||
|
||||
public FatalLoreEffect() {
|
||||
super(Outcome.Neutral);
|
||||
staticText = "An opponent chooses one - You draw three cards; or you destroy up to two target creatures that opponent controls and that player draws up to three cards. Those creatures can't be regenerated";
|
||||
FatalLoreEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "That player draws up to three cards";
|
||||
}
|
||||
|
||||
public FatalLoreEffect(final FatalLoreEffect effect) {
|
||||
private FatalLoreEffect(final FatalLoreEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
@ -62,30 +94,11 @@ class FatalLoreEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Player chosenOpponent = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (controller != null
|
||||
&& chosenOpponent != null) {
|
||||
if (chosenOpponent.chooseUse(Outcome.Neutral, "If you choose Yes, the controller draws three cards. If no, the controller gets to destroy up to two target creatures that you control and you get to draw up to 3 cards. Those creatures can't be regenerated.", source, game)) {
|
||||
controller.drawCards(3, source, game);
|
||||
} else {
|
||||
FilterCreaturePermanent filter = new FilterCreaturePermanent("chosen opponent's creature");
|
||||
filter.add(new ControllerIdPredicate(chosenOpponent.getId()));
|
||||
TargetCreaturePermanent target = new TargetCreaturePermanent(0, 2, filter, false);
|
||||
if (target.canChoose(controller.getId(), source, game)
|
||||
&& controller.choose(Outcome.DestroyPermanent, target, source, game)) {
|
||||
for (UUID targetId : target.getTargets()) {
|
||||
Effect destroyCreature = new DestroyTargetEffect(true);
|
||||
destroyCreature.setTargetPointer(new FixedTarget(targetId, game));
|
||||
destroyCreature.apply(game, source);
|
||||
}
|
||||
Effect opponentDrawsCards = new DrawCardTargetEffect(StaticValue.get(3), false, true);
|
||||
opponentDrawsCards.setTargetPointer(new FixedTarget(chosenOpponent.getId()));
|
||||
opponentDrawsCards.apply(game, source);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Player player = game.getPlayer((UUID) getValue("choosingPlayer"));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
int toDraw = player.getAmount(0, 3, "Choose how many cards to draw", game);
|
||||
return player.drawCards(toDraw, source, game) > 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,34 +1,42 @@
|
|||
package mage.cards.m;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.abilities.effects.Effect;
|
||||
import mage.abilities.Mode;
|
||||
import mage.abilities.effects.OneShotEffect;
|
||||
import mage.abilities.effects.common.GainLifeEffect;
|
||||
import mage.abilities.effects.common.counter.AddCountersAllEffect;
|
||||
import mage.cards.CardImpl;
|
||||
import mage.cards.CardSetInfo;
|
||||
import mage.constants.CardType;
|
||||
import mage.constants.Outcome;
|
||||
import mage.constants.TargetController;
|
||||
import mage.counters.CounterType;
|
||||
import mage.filter.common.FilterControlledCreaturePermanent;
|
||||
import mage.filter.common.FilterCreaturePermanent;
|
||||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.filter.StaticFilters;
|
||||
import mage.game.Game;
|
||||
import mage.game.permanent.Permanent;
|
||||
import mage.players.Player;
|
||||
import mage.target.common.TargetOpponent;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* @author jeffwadsworth
|
||||
* @author TheElk801
|
||||
*/
|
||||
public final class Misfortune extends CardImpl {
|
||||
|
||||
public Misfortune(UUID ownerId, CardSetInfo setInfo) {
|
||||
super(ownerId, setInfo, new CardType[]{CardType.SORCERY}, "{1}{B}{R}{G}");
|
||||
|
||||
// An opponent chooses one - You put a +1/+1 counter on each creature you control and gain 4 life; or you put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to that player.
|
||||
this.getSpellAbility().addEffect(new MisfortuneEffect());
|
||||
this.getSpellAbility().addTarget(new TargetOpponent(true));
|
||||
// An opponent chooses one —
|
||||
this.getSpellAbility().getModes().setModeChooser(TargetController.OPPONENT);
|
||||
|
||||
// • You put a +1/+1 counter on each creature you control and gain 4 life.
|
||||
this.getSpellAbility().addEffect(new AddCountersAllEffect(
|
||||
CounterType.P1P1.createInstance(), StaticFilters.FILTER_CONTROLLED_CREATURE
|
||||
).setText("you put a +1/+1 counter on each creature you control"));
|
||||
this.getSpellAbility().addEffect(new GainLifeEffect(4).setText("and gain 4 life"));
|
||||
|
||||
// • You put a -1/-1 counter on each creature that player controls and Misfortune deals 4 damage to that player.
|
||||
this.getSpellAbility().addMode(new Mode(new MisfortuneEffect()));
|
||||
}
|
||||
|
||||
private Misfortune(final Misfortune card) {
|
||||
|
@ -43,15 +51,13 @@ public final class Misfortune extends CardImpl {
|
|||
|
||||
class MisfortuneEffect extends OneShotEffect {
|
||||
|
||||
public MisfortuneEffect() {
|
||||
super(Outcome.Neutral);
|
||||
staticText = "An opponent chooses one - "
|
||||
+ "You put a +1/+1 counter on each creature you control and gain "
|
||||
+ "4 life; or you put a -1/-1 counter on each creature that player "
|
||||
+ "controls and Misfortune deals 4 damage to that player";
|
||||
MisfortuneEffect() {
|
||||
super(Outcome.Benefit);
|
||||
staticText = "you put a -1/-1 counter on each creature that player controls " +
|
||||
"and {this} deals 4 damage to that player";
|
||||
}
|
||||
|
||||
public MisfortuneEffect(final MisfortuneEffect effect) {
|
||||
private MisfortuneEffect(final MisfortuneEffect effect) {
|
||||
super(effect);
|
||||
}
|
||||
|
||||
|
@ -62,27 +68,16 @@ class MisfortuneEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
Player controller = game.getPlayer(source.getControllerId());
|
||||
Player chosenOpponent = game.getPlayer(targetPointer.getFirst(game, source));
|
||||
if (controller != null
|
||||
&& chosenOpponent != null) {
|
||||
if (chosenOpponent.chooseUse(Outcome.Neutral, "If you choose Yes, the controller puts a +1/+1 counter"
|
||||
+ "on each creature they control and they gain 4 life. If no, the controller puts a -1/-1 counter"
|
||||
+ "on each creature you control and {this} deals 4 damage to you.", source, game)) {
|
||||
Effect putP1P1CounterOnEachControlledCreature = new AddCountersAllEffect(
|
||||
CounterType.P1P1.createInstance(), new FilterControlledCreaturePermanent());
|
||||
putP1P1CounterOnEachControlledCreature.apply(game, source);
|
||||
controller.gainLife(4, game, source);
|
||||
} else {
|
||||
FilterCreaturePermanent filterOpponentCreatures = new FilterCreaturePermanent();
|
||||
filterOpponentCreatures.add(new ControllerIdPredicate(chosenOpponent.getId()));
|
||||
Effect putM1M1CounterOnEachOpponentCreature = new AddCountersAllEffect(
|
||||
CounterType.M1M1.createInstance(), filterOpponentCreatures);
|
||||
putM1M1CounterOnEachOpponentCreature.apply(game, source);
|
||||
chosenOpponent.damage(4, source.getSourceId(), source, game);
|
||||
}
|
||||
return true;
|
||||
Player player = game.getPlayer((UUID) getValue("choosingPlayer"));
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
for (Permanent permanent : game.getBattlefield().getActivePermanents(
|
||||
StaticFilters.FILTER_CONTROLLED_CREATURE, player.getId(), source, game
|
||||
)) {
|
||||
permanent.addCounters(CounterType.M1M1.createInstance(), source.getControllerId(), source, game);
|
||||
}
|
||||
player.damage(4, source, game);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -306,19 +306,18 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
// Some spells and abilities specify that a player other than their controller chooses a mode for it.
|
||||
// In that case, the other player does so when the spell or ability's controller normally would do so.
|
||||
// If there is more than one other player who could make such a choice, the spell or ability's controller decides which of those players will make the choice.
|
||||
UUID playerId = null;
|
||||
UUID playerId;
|
||||
if (modeChooser == TargetController.OPPONENT) {
|
||||
TargetOpponent targetOpponent = new TargetOpponent();
|
||||
if (targetOpponent.choose(Outcome.Benefit, source.getControllerId(), source.getSourceId(), source, game)) {
|
||||
playerId = targetOpponent.getFirstTarget();
|
||||
}
|
||||
targetOpponent.choose(Outcome.Benefit, source.getControllerId(), source.getSourceId(), source, game);
|
||||
playerId = targetOpponent.getFirstTarget();
|
||||
} else {
|
||||
playerId = source.getControllerId();
|
||||
}
|
||||
if (playerId == null) {
|
||||
Player player = game.getPlayer(playerId);
|
||||
if (player == null) {
|
||||
return false;
|
||||
}
|
||||
Player player = game.getPlayer(playerId);
|
||||
|
||||
// player chooses modes manually
|
||||
this.currentMode = null;
|
||||
|
@ -341,7 +340,13 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
if (isEachModeOnlyOnce()) {
|
||||
setAlreadySelectedModes(source, game);
|
||||
}
|
||||
return true;
|
||||
if (modeChooser == TargetController.OPPONENT) {
|
||||
selectedModes
|
||||
.stream()
|
||||
.map(this::get)
|
||||
.map(Mode::getEffects)
|
||||
.forEach(effects -> effects.setValue("choosingPlayer", playerId));
|
||||
}
|
||||
} else {
|
||||
// only one mode available
|
||||
if (currentMode == null) {
|
||||
|
@ -350,8 +355,8 @@ public class Modes extends LinkedHashMap<UUID, Mode> {
|
|||
this.addSelectedMode(mode.getId());
|
||||
this.setActiveMode(mode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue