[WHO] Implement Day of the Moon

This commit is contained in:
theelk801 2025-05-05 14:39:38 -04:00
parent 507991b9e2
commit 550562b1a9
4 changed files with 130 additions and 13 deletions

View file

@ -0,0 +1,111 @@
package mage.cards.d;
import mage.abilities.Ability;
import mage.abilities.common.SagaAbility;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.ChooseACardNameEffect;
import mage.abilities.effects.common.combat.GoadTargetEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.choices.Choice;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SagaChapter;
import mage.constants.SubType;
import mage.filter.FilterPermanent;
import mage.filter.common.FilterCreaturePermanent;
import mage.filter.predicate.Predicates;
import mage.filter.predicate.mageobject.NamePredicate;
import mage.game.Game;
import mage.players.Player;
import mage.target.targetpointer.FixedTargets;
import mage.util.CardUtil;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author TheElk801
*/
public final class DayOfTheMoon extends CardImpl {
public DayOfTheMoon(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.ENCHANTMENT}, "{2}{R}");
this.subtype.add(SubType.SAGA);
// (As this Saga enters and after your draw step, add a lore counter. Sacrifice after III.)
SagaAbility sagaAbility = new SagaAbility(this);
// I, II, III -- Choose a creature card name, then goad all creatures with a name chosen for Day of the Moon.
sagaAbility.addChapterEffect(this, SagaChapter.CHAPTER_I, SagaChapter.CHAPTER_III, new DayOfTheMoonEffect());
this.addAbility(sagaAbility);
}
private DayOfTheMoon(final DayOfTheMoon card) {
super(card);
}
@Override
public DayOfTheMoon copy() {
return new DayOfTheMoon(this);
}
}
class DayOfTheMoonEffect extends OneShotEffect {
DayOfTheMoonEffect() {
super(Outcome.Benefit);
staticText = "choose a creature card name, then goad all creatures with a name chosen for {this}";
}
private DayOfTheMoonEffect(final DayOfTheMoonEffect effect) {
super(effect);
}
@Override
public DayOfTheMoonEffect copy() {
return new DayOfTheMoonEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Choice cardChoice = ChooseACardNameEffect.TypeOfName.CREATURE_NAME.makeChoiceObject();
player.choose(outcome, cardChoice, game);
String cardName = cardChoice.getChoice();
List<String> names = getOrSetValue(game, source);
names.add(cardName);
names.removeIf(Objects::nonNull);
if (names.isEmpty()) {
return true;
}
game.informPlayers(
CardUtil.getSourceLogName(game, source) + ": " + player.getName() + ", chosen name: [" + cardName + ']'
);
Optional.ofNullable(source.getSourcePermanentIfItStillExists(game))
.ifPresent(permanent -> permanent.addInfo(
"NAMED_CARD", CardUtil.addToolTipMarkTags(
"Chosen names: " + CardUtil.concatWithAnd(names)
), game
));
FilterPermanent filter = new FilterCreaturePermanent();
filter.add(Predicates.or(names.stream().map(NamePredicate::new).collect(Collectors.toSet())));
game.addEffect(new GoadTargetEffect().setTargetPointer(new FixedTargets(
game.getBattlefield().getActivePermanents(filter, source.getControllerId(), source, game), game
)), source);
return true;
}
private List<String> getOrSetValue(Game game, Ability source) {
String key = source.getControllerId() + "_" + source.getSourceObjectZoneChangeCounter();
List<String> set = (List<String>) game.getState().getValue(key);
if (set != null) {
return set;
}
return game.getState().setValue(key, new ArrayList<>());
}
}

View file

@ -237,8 +237,8 @@ public final class DoctorWho extends ExpansionSet {
cards.add(new SetCardInfo("Day of Destiny", 206, Rarity.RARE, mage.cards.d.DayOfDestiny.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Day of Destiny", 464, Rarity.RARE, mage.cards.d.DayOfDestiny.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Day of Destiny", 797, Rarity.RARE, mage.cards.d.DayOfDestiny.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Day of the Moon", 684, Rarity.RARE, mage.cards.d.DayOfTheMoon.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Day of the Moon", 79, Rarity.RARE, mage.cards.d.DayOfTheMoon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Day of the Moon", 684, Rarity.RARE, mage.cards.d.DayOfTheMoon.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Day of the Moon", 79, Rarity.RARE, mage.cards.d.DayOfTheMoon.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Death in Heaven", 66, Rarity.RARE, mage.cards.d.DeathInHeaven.class, NON_FULL_USE_VARIOUS));
//cards.add(new SetCardInfo("Death in Heaven", 671, Rarity.RARE, mage.cards.d.DeathInHeaven.class, NON_FULL_USE_VARIOUS));
cards.add(new SetCardInfo("Decaying Time Loop", 685, Rarity.UNCOMMON, mage.cards.d.DecayingTimeLoop.class, NON_FULL_USE_VARIOUS));

View file

@ -50,14 +50,7 @@ public class ChooseACardNameEffect extends OneShotEffect {
return nameSupplier.get();
}
public String getChoice(Game game, Ability source) {
return getChoice(game.getPlayer(source.getControllerId()), game, source, true);
}
public String getChoice(Player player, Game game, Ability source, boolean setValue) {
if (player == null) {
return null;
}
public Choice makeChoiceObject() {
Choice cardChoice = new ChoiceImpl(true, ChoiceHintType.CARD);
Set<String> names = this.getNames();
if (names.isEmpty()) {
@ -68,6 +61,18 @@ public class ChooseACardNameEffect extends OneShotEffect {
cardChoice.setChoices(names);
cardChoice.setMessage(CardUtil.getTextWithFirstCharUpperCase(this.getMessage()));
cardChoice.clearChoice();
return cardChoice;
}
public String getChoice(Game game, Ability source) {
return getChoice(game.getPlayer(source.getControllerId()), game, source, true);
}
public String getChoice(Player player, Game game, Ability source, boolean setValue) {
if (player == null) {
return null;
}
Choice cardChoice = makeChoiceObject();
player.choose(Outcome.Detriment, cardChoice, game);
String cardName = cardChoice.getChoice();
if (cardName == null) {

View file

@ -724,7 +724,7 @@ public class GameState implements Serializable, Copyable<GameState> {
/**
* Returns a list of all players of the game ignoring range or if a player
* has lost or left the game.
*
* <p>
* Warning, it's ignore range, must be used by game engine only.
*/
public PlayerList getPlayerList() {
@ -734,7 +734,7 @@ public class GameState implements Serializable, Copyable<GameState> {
/**
* Returns a list of all active players of the game, setting the playerId to
* the current player of the list.
*
* <p>
* Warning, it's ignore range, must be used by game engine only.
*/
public PlayerList getPlayerList(UUID playerId) {
@ -1369,8 +1369,9 @@ public class GameState implements Serializable, Copyable<GameState> {
* @param valueId
* @param value
*/
public void setValue(String valueId, Object value) {
public <T> T setValue(String valueId, T value) {
values.put(valueId, value);
return value;
}
/**