[CLB] Implemented White Plume Adventurer

This commit is contained in:
Evan Kranzler 2022-05-17 20:18:18 -04:00
parent 4777466b50
commit 86dad5e54f
13 changed files with 524 additions and 9 deletions

View file

@ -54,6 +54,7 @@ public class PlayerView implements Serializable {
private final boolean passedAllTurns; // F9 private final boolean passedAllTurns; // F9
private final boolean passedUntilEndStepBeforeMyTurn; // F11 private final boolean passedUntilEndStepBeforeMyTurn; // F11
private final boolean monarch; private final boolean monarch;
private final boolean initiative;
private final List<String> designationNames = new ArrayList<>(); private final List<String> designationNames = new ArrayList<>();
public PlayerView(Player player, GameState state, Game game, UUID createdForPlayerId, UUID watcherUserId) { public PlayerView(Player player, GameState state, Game game, UUID createdForPlayerId, UUID watcherUserId) {
@ -153,6 +154,7 @@ public class PlayerView implements Serializable {
this.passedUntilStackResolved = player.getPassedUntilStackResolved(); this.passedUntilStackResolved = player.getPassedUntilStackResolved();
this.passedUntilEndStepBeforeMyTurn = player.getPassedUntilEndStepBeforeMyTurn(); this.passedUntilEndStepBeforeMyTurn = player.getPassedUntilEndStepBeforeMyTurn();
this.monarch = player.getId().equals(game.getMonarchId()); this.monarch = player.getId().equals(game.getMonarchId());
this.initiative = player.getId().equals(game.getInitiativeId());
for (Designation designation : player.getDesignations()) { for (Designation designation : player.getDesignations()) {
this.designationNames.add(designation.getName()); this.designationNames.add(designation.getName());
} }
@ -309,6 +311,10 @@ public class PlayerView implements Serializable {
return monarch; return monarch;
} }
public boolean isInitiative() {
return initiative;
}
public List<String> getDesignationNames() { public List<String> getDesignationNames() {
return designationNames; return designationNames;
} }

View file

@ -0,0 +1,108 @@
package mage.cards.w;
import mage.MageInt;
import mage.abilities.Ability;
import mage.abilities.common.BeginningOfUpkeepTriggeredAbility;
import mage.abilities.common.EntersBattlefieldTriggeredAbility;
import mage.abilities.condition.common.CompletedDungeonCondition;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.TakeTheInitiativeEffect;
import mage.cards.CardImpl;
import mage.cards.CardSetInfo;
import mage.constants.CardType;
import mage.constants.Outcome;
import mage.constants.SubType;
import mage.constants.TargetController;
import mage.filter.FilterPermanent;
import mage.filter.StaticFilters;
import mage.filter.common.FilterControlledCreaturePermanent;
import mage.filter.predicate.permanent.TappedPredicate;
import mage.game.Game;
import mage.game.permanent.Permanent;
import mage.players.Player;
import mage.target.TargetPermanent;
import mage.watchers.common.CompletedDungeonWatcher;
import java.util.UUID;
/**
* @author TheElk801
*/
public final class WhitePlumeAdventurer extends CardImpl {
public WhitePlumeAdventurer(UUID ownerId, CardSetInfo setInfo) {
super(ownerId, setInfo, new CardType[]{CardType.CREATURE}, "{2}{W}");
this.subtype.add(SubType.ORC);
this.subtype.add(SubType.CLERIC);
this.power = new MageInt(3);
this.toughness = new MageInt(3);
// When White Plume Adventurer enters battlefield, you take the initiative.
this.addAbility(new EntersBattlefieldTriggeredAbility(new TakeTheInitiativeEffect()));
// At the beginning of each opponent's upkeep, untap a creature you control. If you've completed a dungeon, untap all creatures you control instead.
this.addAbility(new BeginningOfUpkeepTriggeredAbility(
new WhitePlumeAdventurerEffect(), TargetController.OPPONENT, false
).addHint(CompletedDungeonCondition.getHint()), new CompletedDungeonWatcher());
}
private WhitePlumeAdventurer(final WhitePlumeAdventurer card) {
super(card);
}
@Override
public WhitePlumeAdventurer copy() {
return new WhitePlumeAdventurer(this);
}
}
class WhitePlumeAdventurerEffect extends OneShotEffect {
private static final FilterPermanent filter
= new FilterControlledCreaturePermanent("tapped creature you control");
static {
filter.add(TappedPredicate.TAPPED);
}
WhitePlumeAdventurerEffect() {
super(Outcome.Benefit);
staticText = "untap a creature you control. If you've completed a dungeon, " +
"untap all creatures you control instead";
}
private WhitePlumeAdventurerEffect(final WhitePlumeAdventurerEffect effect) {
super(effect);
}
@Override
public WhitePlumeAdventurerEffect copy() {
return new WhitePlumeAdventurerEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
if (!game.getBattlefield().contains(filter, source, game, 1)) {
return false;
}
if (CompletedDungeonWatcher.checkPlayer(source.getControllerId(), game)) {
for (Permanent permanent : game.getBattlefield().getActivePermanents(
StaticFilters.FILTER_CONTROLLED_CREATURE,
source.getControllerId(), source, game
)) {
permanent.untap(game);
}
return true;
}
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
TargetPermanent target = new TargetPermanent(filter);
target.setNotTarget(true);
player.choose(outcome, target, source, game);
Permanent permanent = game.getPermanent(target.getFirstTarget());
return permanent != null && permanent.untap(game);
}
}

View file

@ -34,6 +34,7 @@ public final class CommanderLegendsBattleForBaldursGate extends ExpansionSet {
cards.add(new SetCardInfo("Sea of Clouds", 360, Rarity.RARE, mage.cards.s.SeaOfClouds.class)); cards.add(new SetCardInfo("Sea of Clouds", 360, Rarity.RARE, mage.cards.s.SeaOfClouds.class));
cards.add(new SetCardInfo("Spire Garden", 361, Rarity.RARE, mage.cards.s.SpireGarden.class)); cards.add(new SetCardInfo("Spire Garden", 361, Rarity.RARE, mage.cards.s.SpireGarden.class));
cards.add(new SetCardInfo("Wand of Wonder", 204, Rarity.RARE, mage.cards.w.WandOfWonder.class)); cards.add(new SetCardInfo("Wand of Wonder", 204, Rarity.RARE, mage.cards.w.WandOfWonder.class));
cards.add(new SetCardInfo("White Plume Adventurer", 49, Rarity.RARE, mage.cards.w.WhitePlumeAdventurer.class));
cards.add(new SetCardInfo("Zevlor, Elturel Exile", 296, Rarity.RARE, mage.cards.z.ZevlorElturelExile.class)); cards.add(new SetCardInfo("Zevlor, Elturel Exile", 296, Rarity.RARE, mage.cards.z.ZevlorElturelExile.class));
} }
} }

View file

@ -0,0 +1,32 @@
package mage.abilities.effects.common;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.game.Game;
/**
* @author TheElk801
*/
public class TakeTheInitiativeEffect extends OneShotEffect {
public TakeTheInitiativeEffect() {
super(Outcome.Benefit);
staticText = "you take the initiative";
}
private TakeTheInitiativeEffect(final TakeTheInitiativeEffect effect) {
super(effect);
}
@Override
public TakeTheInitiativeEffect copy() {
return new TakeTheInitiativeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.takeInitiative(source, source.getControllerId());
return true;
}
}

View file

@ -26,7 +26,7 @@ public class VentureIntoTheDungeonEffect extends OneShotEffect {
@Override @Override
public boolean apply(Game game, Ability source) { public boolean apply(Game game, Ability source) {
game.ventureIntoDungeon(source.getControllerId()); game.ventureIntoDungeon(source.getControllerId(), false);
return true; return true;
} }
} }

View file

@ -1,13 +1,12 @@
package mage.designations; package mage.designations;
/** /**
*
* @author LevelX2 * @author LevelX2
*/ */
public enum DesignationType { public enum DesignationType {
THE_MONARCH("The Monarch"), THE_MONARCH("The Monarch"),
CITYS_BLESSING("City's Blessing"); CITYS_BLESSING("City's Blessing"),
THE_INITIATIVE("The Initiative");
private final String text; private final String text;

View file

@ -0,0 +1,179 @@
package mage.designations;
import mage.abilities.Ability;
import mage.abilities.TriggeredAbilityImpl;
import mage.abilities.effects.OneShotEffect;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.game.Controllable;
import mage.game.Game;
import mage.game.events.DamagedPlayerBatchEvent;
import mage.game.events.GameEvent;
import mage.target.targetpointer.FixedTarget;
import java.util.Objects;
import java.util.UUID;
/**
* @author TheElk801
*/
public class Initiative extends Designation {
public Initiative() {
super(DesignationType.THE_INITIATIVE, "CLB");
// Whenever one or more creatures a player controls deals combat damage to you, that player takes the initiative.
this.addAbility(new InitiativeDamageTriggeredAbility());
// Whenever you take the initiative and at the beginning of your upkeep, venture into Undercity.
this.addAbility(new InitiativeVentureTriggeredAbility());
}
private Initiative(final Initiative card) {
super(card);
}
@Override
public Initiative copy() {
return new Initiative(this);
}
}
class InitiativeDamageTriggeredAbility extends TriggeredAbilityImpl {
InitiativeDamageTriggeredAbility() {
super(Zone.ALL, new InitiativeTakeEffect());
}
private InitiativeDamageTriggeredAbility(final InitiativeDamageTriggeredAbility ability) {
super(ability);
}
@Override
public InitiativeDamageTriggeredAbility copy() {
return new InitiativeDamageTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.DAMAGED_PLAYER_BATCH;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
if (!event.getTargetId().equals(game.getInitiativeId())) {
return false;
}
DamagedPlayerBatchEvent dEvent = (DamagedPlayerBatchEvent) event;
UUID playerId = dEvent
.getEvents()
.stream()
.map(GameEvent::getSourceId)
.map(game::getPermanent)
.filter(Objects::nonNull)
.map(Controllable::getControllerId)
.findFirst()
.orElse(null);
if (playerId == null) {
return false;
}
this.getEffects().setTargetPointer(new FixedTarget(playerId));
return true;
}
@Override
public String getRule() {
return "Whenever one or more creatures a player controls deals combat damage to you, that player takes the initiative.";
}
}
class InitiativeTakeEffect extends OneShotEffect {
InitiativeTakeEffect() {
super(Outcome.Benefit);
}
private InitiativeTakeEffect(final InitiativeTakeEffect effect) {
super(effect);
}
@Override
public InitiativeTakeEffect copy() {
return new InitiativeTakeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.takeInitiative(source, getTargetPointer().getFirst(game, source));
return true;
}
}
class InitiativeVentureTriggeredAbility extends TriggeredAbilityImpl {
InitiativeVentureTriggeredAbility() {
super(Zone.ALL, new InitiativeUndercityEffect());
}
private InitiativeVentureTriggeredAbility(final InitiativeVentureTriggeredAbility ability) {
super(ability);
}
@Override
public InitiativeVentureTriggeredAbility copy() {
return new InitiativeVentureTriggeredAbility(this);
}
@Override
public boolean checkEventType(GameEvent event, Game game) {
return event.getType() == GameEvent.EventType.UPKEEP_STEP_PRE
|| event.getType() == GameEvent.EventType.TOOK_INITIATIVE;
}
@Override
public boolean checkTrigger(GameEvent event, Game game) {
UUID playerId;
switch (event.getType()) {
case UPKEEP_STEP_PRE:
if (!game.isActivePlayer(game.getInitiativeId())) {
return false;
}
playerId = game.getActivePlayerId();
break;
case TOOK_INITIATIVE:
playerId = event.getPlayerId();
break;
default:
return false;
}
this.getEffects().setTargetPointer(new FixedTarget(playerId));
return true;
}
@Override
public String getRule() {
return "Whenever you take the initiative and at the beginning of your upkeep, venture into Undercity.";
}
}
class InitiativeUndercityEffect extends OneShotEffect {
InitiativeUndercityEffect() {
super(Outcome.Benefit);
}
private InitiativeUndercityEffect(final InitiativeUndercityEffect effect) {
super(effect);
}
@Override
public InitiativeUndercityEffect copy() {
return new InitiativeUndercityEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
game.ventureIntoDungeon(getTargetPointer().getFirst(game, source), true);
return true;
}
}

View file

@ -386,7 +386,7 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
Dungeon addDungeon(Dungeon dungeon, UUID playerId); Dungeon addDungeon(Dungeon dungeon, UUID playerId);
void ventureIntoDungeon(UUID playerId); void ventureIntoDungeon(UUID playerId, boolean undercity);
/** /**
* Tells whether the current game has day or night, defaults to false * Tells whether the current game has day or night, defaults to false
@ -519,6 +519,10 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
void setMonarchId(Ability source, UUID monarchId); void setMonarchId(Ability source, UUID monarchId);
UUID getInitiativeId();
void takeInitiative(Ability source, UUID initiativeId);
int damagePlayerOrPlaneswalker(UUID playerOrWalker, int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable); int damagePlayerOrPlaneswalker(UUID playerOrWalker, int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable);
int damagePlayerOrPlaneswalker(UUID playerOrWalker, int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable, List<UUID> appliedEffects); int damagePlayerOrPlaneswalker(UUID playerOrWalker, int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable, List<UUID> appliedEffects);

View file

@ -26,6 +26,7 @@ import mage.constants.*;
import mage.counters.CounterType; import mage.counters.CounterType;
import mage.counters.Counters; import mage.counters.Counters;
import mage.designations.Designation; import mage.designations.Designation;
import mage.designations.Initiative;
import mage.designations.Monarch; import mage.designations.Monarch;
import mage.filter.Filter; import mage.filter.Filter;
import mage.filter.FilterCard; import mage.filter.FilterCard;
@ -36,6 +37,7 @@ import mage.filter.predicate.mageobject.NamePredicate;
import mage.filter.predicate.permanent.ControllerIdPredicate; import mage.filter.predicate.permanent.ControllerIdPredicate;
import mage.game.combat.Combat; import mage.game.combat.Combat;
import mage.game.command.*; import mage.game.command.*;
import mage.game.command.dungeons.UndercityDungeon;
import mage.game.events.*; import mage.game.events.*;
import mage.game.events.TableEvent.EventType; import mage.game.events.TableEvent.EventType;
import mage.game.mulligan.Mulligan; import mage.game.mulligan.Mulligan;
@ -536,21 +538,24 @@ public abstract class GameImpl implements Game {
)); ));
} }
private Dungeon getOrCreateDungeon(UUID playerId) { private Dungeon getOrCreateDungeon(UUID playerId, boolean undercity) {
Dungeon dungeon = this.getPlayerDungeon(playerId); Dungeon dungeon = this.getPlayerDungeon(playerId);
if (dungeon != null && dungeon.hasNextRoom()) { if (dungeon != null && dungeon.hasNextRoom()) {
return dungeon; return dungeon;
} }
removeDungeon(dungeon); removeDungeon(dungeon);
return this.addDungeon(Dungeon.selectDungeon(playerId, this), playerId); return this.addDungeon(undercity ? new UndercityDungeon() : Dungeon.selectDungeon(playerId, this), playerId);
} }
@Override @Override
public void ventureIntoDungeon(UUID playerId) { public void ventureIntoDungeon(UUID playerId, boolean undercity) {
if (playerId == null) {
return;
}
if (replaceEvent(GameEvent.getEvent(GameEvent.EventType.VENTURE, playerId, null, playerId))) { if (replaceEvent(GameEvent.getEvent(GameEvent.EventType.VENTURE, playerId, null, playerId))) {
return; return;
} }
this.getOrCreateDungeon(playerId).moveToNextRoom(playerId, this); this.getOrCreateDungeon(playerId, undercity).moveToNextRoom(playerId, this);
fireEvent(GameEvent.getEvent(GameEvent.EventType.VENTURED, playerId, null, playerId)); fireEvent(GameEvent.getEvent(GameEvent.EventType.VENTURED, playerId, null, playerId));
} }
@ -3691,6 +3696,22 @@ public abstract class GameImpl implements Game {
} }
} }
@Override
public UUID getInitiativeId() {
return getState().getInitiativeId();
}
@Override
public void takeInitiative(Ability source, UUID initiativeId) {
if (getInitiativeId() == null) {
getState().addDesignation(new Initiative(), this, initiativeId);
} else if (!getInitiativeId().equals(initiativeId)) {
getState().setInitiativeId(initiativeId);
}
informPlayers(getPlayer(initiativeId).getLogName() + " takes the initiative");
fireEvent(new GameEvent(GameEvent.EventType.TOOK_INITIATIVE, initiativeId, source, initiativeId));
}
@Override @Override
public int damagePlayerOrPlaneswalker(UUID playerOrWalker, int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable) { public int damagePlayerOrPlaneswalker(UUID playerOrWalker, int damage, UUID attackerId, Ability source, Game game, boolean combatDamage, boolean preventable) {
return damagePlayerOrPlaneswalker(playerOrWalker, damage, attackerId, source, game, combatDamage, preventable, null); return damagePlayerOrPlaneswalker(playerOrWalker, damage, attackerId, source, game, combatDamage, preventable, null);

View file

@ -76,6 +76,7 @@ public class GameState implements Serializable, Copyable<GameState> {
private UUID priorityPlayerId; // player that has currently priority private UUID priorityPlayerId; // player that has currently priority
private UUID playerByOrderId; // player that has currently priority private UUID playerByOrderId; // player that has currently priority
private UUID monarchId; // player that is the monarch private UUID monarchId; // player that is the monarch
private UUID initiativeId; // player that has the initiative
private SpellStack stack; private SpellStack stack;
private Command command; private Command command;
private boolean isPlaneChase; private boolean isPlaneChase;
@ -144,6 +145,7 @@ public class GameState implements Serializable, Copyable<GameState> {
this.priorityPlayerId = state.priorityPlayerId; this.priorityPlayerId = state.priorityPlayerId;
this.playerByOrderId = state.playerByOrderId; this.playerByOrderId = state.playerByOrderId;
this.monarchId = state.monarchId; this.monarchId = state.monarchId;
this.initiativeId = state.initiativeId;
this.turn = state.turn.copy(); this.turn = state.turn.copy();
this.stack = state.stack.copy(); this.stack = state.stack.copy();
@ -249,6 +251,7 @@ public class GameState implements Serializable, Copyable<GameState> {
this.playerByOrderId = state.playerByOrderId; this.playerByOrderId = state.playerByOrderId;
this.priorityPlayerId = state.priorityPlayerId; this.priorityPlayerId = state.priorityPlayerId;
this.monarchId = state.monarchId; this.monarchId = state.monarchId;
this.initiativeId = state.initiativeId;
this.stack = state.stack; this.stack = state.stack;
this.command = state.command; this.command = state.command;
this.isPlaneChase = state.isPlaneChase; this.isPlaneChase = state.isPlaneChase;
@ -482,6 +485,14 @@ public class GameState implements Serializable, Copyable<GameState> {
this.monarchId = monarchId; this.monarchId = monarchId;
} }
public UUID getInitiativeId() {
return initiativeId;
}
public void setInitiativeId(UUID initiativeId) {
this.initiativeId = initiativeId;
}
public UUID getChoosingPlayerId() { public UUID getChoosingPlayerId() {
return choosingPlayerId; return choosingPlayerId;
} }

View file

@ -0,0 +1,152 @@
package mage.game.command.dungeons;
import mage.abilities.Ability;
import mage.abilities.effects.OneShotEffect;
import mage.abilities.effects.common.CreateTokenEffect;
import mage.abilities.effects.common.DrawCardSourceControllerEffect;
import mage.abilities.effects.common.LoseLifeTargetEffect;
import mage.abilities.effects.common.combat.GoadTargetEffect;
import mage.abilities.effects.common.continuous.GainAbilityTargetEffect;
import mage.abilities.effects.common.counter.AddCountersTargetEffect;
import mage.abilities.effects.common.search.SearchLibraryPutInHandEffect;
import mage.abilities.effects.keyword.ScryEffect;
import mage.abilities.keyword.HexproofAbility;
import mage.cards.Card;
import mage.cards.Cards;
import mage.cards.CardsImpl;
import mage.constants.Outcome;
import mage.constants.Zone;
import mage.counters.CounterType;
import mage.filter.StaticFilters;
import mage.game.Game;
import mage.game.command.Dungeon;
import mage.game.command.DungeonRoom;
import mage.game.permanent.Permanent;
import mage.game.permanent.token.SkeletonToken;
import mage.game.permanent.token.TreasureToken;
import mage.players.Player;
import mage.target.TargetPlayer;
import mage.target.common.TargetCardInLibrary;
import mage.target.common.TargetCreaturePermanent;
import mage.target.targetpointer.FixedTarget;
import mage.util.RandomUtil;
/**
* @author TheElk801
*/
public class UndercityDungeon extends Dungeon {
public UndercityDungeon() {
super("Undercity", "CLB");
DungeonRoom secretEntrance = new DungeonRoom(
"Secret Entrance",
new SearchLibraryPutInHandEffect(
new TargetCardInLibrary(StaticFilters.FILTER_CARD_BASIC_LAND)
)
);
DungeonRoom forge = new DungeonRoom(
"Forge", new AddCountersTargetEffect(CounterType.P1P1.createInstance())
);
forge.addTarget(new TargetCreaturePermanent());
DungeonRoom lostWell = new DungeonRoom(
"Lost Well", new ScryEffect(2, false)
);
DungeonRoom trap = new DungeonRoom("Trap!", new LoseLifeTargetEffect(5));
trap.addTarget(new TargetPlayer());
DungeonRoom arena = new DungeonRoom("Arena", new GoadTargetEffect());
arena.addTarget(new TargetCreaturePermanent());
DungeonRoom stash = new DungeonRoom("Stash", new CreateTokenEffect(new TreasureToken()));
DungeonRoom archives = new DungeonRoom("Archives", new DrawCardSourceControllerEffect(1));
DungeonRoom catacombs = new DungeonRoom("Catacombs", new CreateTokenEffect(new SkeletonToken()));
DungeonRoom throneOfTheDeadThree = new DungeonRoom("Throne of the Dead Three", new ThroneOfTheDeadThreeEffect());
secretEntrance.addNextRoom(forge);
secretEntrance.addNextRoom(lostWell);
forge.addNextRoom(trap);
forge.addNextRoom(arena);
lostWell.addNextRoom(arena);
lostWell.addNextRoom(stash);
trap.addNextRoom(archives);
arena.addNextRoom(archives);
arena.addNextRoom(catacombs);
archives.addNextRoom(throneOfTheDeadThree);
catacombs.addNextRoom(throneOfTheDeadThree);
this.addRoom(secretEntrance);
this.addRoom(forge);
this.addRoom(lostWell);
this.addRoom(trap);
this.addRoom(arena);
this.addRoom(stash);
this.addRoom(archives);
this.addRoom(catacombs);
this.addRoom(throneOfTheDeadThree);
}
private UndercityDungeon(final UndercityDungeon dungeon) {
super(dungeon);
}
public UndercityDungeon copy() {
return new UndercityDungeon(this);
}
}
class ThroneOfTheDeadThreeEffect extends OneShotEffect {
ThroneOfTheDeadThreeEffect() {
super(Outcome.Benefit);
staticText = "Reveal the top ten cards of your library. Put a creature card from among them onto the " +
"battlefield with three +1/+1 counters on it. It gains hexproof until your next turn. Then shuffle.";
}
private ThroneOfTheDeadThreeEffect(final ThroneOfTheDeadThreeEffect effect) {
super(effect);
}
@Override
public ThroneOfTheDeadThreeEffect copy() {
return new ThroneOfTheDeadThreeEffect(this);
}
@Override
public boolean apply(Game game, Ability source) {
Player player = game.getPlayer(source.getControllerId());
if (player == null) {
return false;
}
Cards cards = new CardsImpl(player.getLibrary().getTopCards(game, 10));
player.revealCards(source, cards, game);
Card card;
switch (cards.count(StaticFilters.FILTER_CARD_CREATURE, game)) {
case 0:
card = null;
break;
case 1:
card = RandomUtil.randomFromCollection(cards.getCards(StaticFilters.FILTER_CARD_CREATURE, game));
break;
default:
TargetCardInLibrary target = new TargetCardInLibrary(StaticFilters.FILTER_CARD_CREATURE);
player.choose(outcome, cards, target, game);
card = cards.get(target.getFirstTarget(), game);
}
if (card != null) {
player.moveCards(card, Zone.BATTLEFIELD, source, game);
Permanent permanent = game.getPermanent(card.getId());
permanent.addCounters(CounterType.P1P1.createInstance(), source, game);
game.addEffect(new GainAbilityTargetEffect(HexproofAbility.getInstance())
.setTargetPointer(new FixedTarget(permanent, game)), source);
}
player.shuffleLibrary(source, game);
return true;
}
}

View file

@ -362,6 +362,7 @@ public class GameEvent implements Serializable {
*/ */
BECOME_MONARCH, BECOME_MONARCH,
BECOMES_MONARCH, BECOMES_MONARCH,
TOOK_INITIATIVE,
BECOMES_DAY_NIGHT, BECOMES_DAY_NIGHT,
MEDITATED, MEDITATED,
PHASE_OUT, PHASED_OUT, PHASE_OUT, PHASED_OUT,

View file

@ -44184,6 +44184,7 @@ Swamp|Streets of New Capenna|266|C||Basic Land - Swamp|||({T}: Add {B}.)|
Mountain|Streets of New Capenna|268|C||Basic Land - Mountain|||({T}: Add {R}.)| Mountain|Streets of New Capenna|268|C||Basic Land - Mountain|||({T}: Add {R}.)|
Forest|Streets of New Capenna|270|C||Basic Land - Forest|||({T}: Add {G}.)| Forest|Streets of New Capenna|270|C||Basic Land - Forest|||({T}: Add {G}.)|
Faceless One|Commander Legends: Battle for Baldur's Gate|1|C|{5}|Legendary Enchantment Creature - Background|3|3|If Faceless One is your commander, choose a color before the game begins. Faceless One is the chosen color.$Choose a Background| Faceless One|Commander Legends: Battle for Baldur's Gate|1|C|{5}|Legendary Enchantment Creature - Background|3|3|If Faceless One is your commander, choose a color before the game begins. Faceless One is the chosen color.$Choose a Background|
White Plume Adventurer|Commander Legends: Battle for Baldur's Gate|49|R|{2}{W}|Creature - Orc Cleric|3|3|When White Plume Adventurer enters battlefield, you take the initiative.$At the beginning of each opponent's upkeep, untap a creature you control. If you've completed a dungeon, untap all creatures you control instead.|
Ancient Brass Dragon|Commander Legends: Battle for Baldur's Gate|111|M|{5}{B}{B}|Creature - Elder Dragon|7|6|Flying$Whenever Ancient Brass Dragon deals combat damage to a player, roll a d20. When you do, put any number of target creature cards with mana value X or less from graveyards onto the battlefield under your control, where X is the result.| Ancient Brass Dragon|Commander Legends: Battle for Baldur's Gate|111|M|{5}{B}{B}|Creature - Elder Dragon|7|6|Flying$Whenever Ancient Brass Dragon deals combat damage to a player, roll a d20. When you do, put any number of target creature cards with mana value X or less from graveyards onto the battlefield under your control, where X is the result.|
Elder Brain|Commander Legends: Battle for Baldur's Gate|125|R|{5}{B}{B}|Creature - Horror|6|6|Menace$Whenever Elder Brain attacks a player, exile all cards from that player's hand, then they draw that many cards. You may play lands and cast spells from among the exiled cards for as long as they remain exiled. If you cast a spell this way, you may spend mana as though it were mana of any color to cast it.| Elder Brain|Commander Legends: Battle for Baldur's Gate|125|R|{5}{B}{B}|Creature - Horror|6|6|Menace$Whenever Elder Brain attacks a player, exile all cards from that player's hand, then they draw that many cards. You may play lands and cast spells from among the exiled cards for as long as they remain exiled. If you cast a spell this way, you may spend mana as though it were mana of any color to cast it.|
Fireball|Commander Legends: Battle for Baldur's Gate|175|U|{X}{R}|Sorcery|||This spell costs {1} more to cast for each target beyond the first.$Fireball deals X damage divided evenly, rounded down, among any number of targets.| Fireball|Commander Legends: Battle for Baldur's Gate|175|U|{X}{R}|Sorcery|||This spell costs {1} more to cast for each target beyond the first.$Fireball deals X damage divided evenly, rounded down, among any number of targets.|