mirror of
https://github.com/correl/mage.git
synced 2024-12-25 03:00:15 +00:00
[CLB] Implemented White Plume Adventurer
This commit is contained in:
parent
4777466b50
commit
86dad5e54f
13 changed files with 524 additions and 9 deletions
|
@ -54,6 +54,7 @@ public class PlayerView implements Serializable {
|
|||
private final boolean passedAllTurns; // F9
|
||||
private final boolean passedUntilEndStepBeforeMyTurn; // F11
|
||||
private final boolean monarch;
|
||||
private final boolean initiative;
|
||||
private final List<String> designationNames = new ArrayList<>();
|
||||
|
||||
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.passedUntilEndStepBeforeMyTurn = player.getPassedUntilEndStepBeforeMyTurn();
|
||||
this.monarch = player.getId().equals(game.getMonarchId());
|
||||
this.initiative = player.getId().equals(game.getInitiativeId());
|
||||
for (Designation designation : player.getDesignations()) {
|
||||
this.designationNames.add(designation.getName());
|
||||
}
|
||||
|
@ -309,6 +311,10 @@ public class PlayerView implements Serializable {
|
|||
return monarch;
|
||||
}
|
||||
|
||||
public boolean isInitiative() {
|
||||
return initiative;
|
||||
}
|
||||
|
||||
public List<String> getDesignationNames() {
|
||||
return designationNames;
|
||||
}
|
||||
|
|
108
Mage.Sets/src/mage/cards/w/WhitePlumeAdventurer.java
Normal file
108
Mage.Sets/src/mage/cards/w/WhitePlumeAdventurer.java
Normal 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);
|
||||
}
|
||||
}
|
|
@ -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("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("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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -26,7 +26,7 @@ public class VentureIntoTheDungeonEffect extends OneShotEffect {
|
|||
|
||||
@Override
|
||||
public boolean apply(Game game, Ability source) {
|
||||
game.ventureIntoDungeon(source.getControllerId());
|
||||
game.ventureIntoDungeon(source.getControllerId(), false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
|
||||
package mage.designations;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author LevelX2
|
||||
*/
|
||||
public enum DesignationType {
|
||||
THE_MONARCH("The Monarch"),
|
||||
CITYS_BLESSING("City's Blessing");
|
||||
CITYS_BLESSING("City's Blessing"),
|
||||
THE_INITIATIVE("The Initiative");
|
||||
|
||||
private final String text;
|
||||
|
||||
|
|
179
Mage/src/main/java/mage/designations/Initiative.java
Normal file
179
Mage/src/main/java/mage/designations/Initiative.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -386,7 +386,7 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
|
|||
|
||||
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
|
||||
|
@ -519,6 +519,10 @@ public interface Game extends MageItem, Serializable, Copyable<Game> {
|
|||
|
||||
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, List<UUID> appliedEffects);
|
||||
|
|
|
@ -26,6 +26,7 @@ import mage.constants.*;
|
|||
import mage.counters.CounterType;
|
||||
import mage.counters.Counters;
|
||||
import mage.designations.Designation;
|
||||
import mage.designations.Initiative;
|
||||
import mage.designations.Monarch;
|
||||
import mage.filter.Filter;
|
||||
import mage.filter.FilterCard;
|
||||
|
@ -36,6 +37,7 @@ import mage.filter.predicate.mageobject.NamePredicate;
|
|||
import mage.filter.predicate.permanent.ControllerIdPredicate;
|
||||
import mage.game.combat.Combat;
|
||||
import mage.game.command.*;
|
||||
import mage.game.command.dungeons.UndercityDungeon;
|
||||
import mage.game.events.*;
|
||||
import mage.game.events.TableEvent.EventType;
|
||||
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);
|
||||
if (dungeon != null && dungeon.hasNextRoom()) {
|
||||
return dungeon;
|
||||
}
|
||||
removeDungeon(dungeon);
|
||||
return this.addDungeon(Dungeon.selectDungeon(playerId, this), playerId);
|
||||
return this.addDungeon(undercity ? new UndercityDungeon() : Dungeon.selectDungeon(playerId, this), playerId);
|
||||
}
|
||||
|
||||
@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))) {
|
||||
return;
|
||||
}
|
||||
this.getOrCreateDungeon(playerId).moveToNextRoom(playerId, this);
|
||||
this.getOrCreateDungeon(playerId, undercity).moveToNextRoom(playerId, this);
|
||||
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
|
||||
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);
|
||||
|
|
|
@ -76,6 +76,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
private UUID priorityPlayerId; // player that has currently priority
|
||||
private UUID playerByOrderId; // player that has currently priority
|
||||
private UUID monarchId; // player that is the monarch
|
||||
private UUID initiativeId; // player that has the initiative
|
||||
private SpellStack stack;
|
||||
private Command command;
|
||||
private boolean isPlaneChase;
|
||||
|
@ -144,6 +145,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.priorityPlayerId = state.priorityPlayerId;
|
||||
this.playerByOrderId = state.playerByOrderId;
|
||||
this.monarchId = state.monarchId;
|
||||
this.initiativeId = state.initiativeId;
|
||||
this.turn = state.turn.copy();
|
||||
|
||||
this.stack = state.stack.copy();
|
||||
|
@ -249,6 +251,7 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.playerByOrderId = state.playerByOrderId;
|
||||
this.priorityPlayerId = state.priorityPlayerId;
|
||||
this.monarchId = state.monarchId;
|
||||
this.initiativeId = state.initiativeId;
|
||||
this.stack = state.stack;
|
||||
this.command = state.command;
|
||||
this.isPlaneChase = state.isPlaneChase;
|
||||
|
@ -482,6 +485,14 @@ public class GameState implements Serializable, Copyable<GameState> {
|
|||
this.monarchId = monarchId;
|
||||
}
|
||||
|
||||
public UUID getInitiativeId() {
|
||||
return initiativeId;
|
||||
}
|
||||
|
||||
public void setInitiativeId(UUID initiativeId) {
|
||||
this.initiativeId = initiativeId;
|
||||
}
|
||||
|
||||
public UUID getChoosingPlayerId() {
|
||||
return choosingPlayerId;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -362,6 +362,7 @@ public class GameEvent implements Serializable {
|
|||
*/
|
||||
BECOME_MONARCH,
|
||||
BECOMES_MONARCH,
|
||||
TOOK_INITIATIVE,
|
||||
BECOMES_DAY_NIGHT,
|
||||
MEDITATED,
|
||||
PHASE_OUT, PHASED_OUT,
|
||||
|
|
|
@ -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}.)|
|
||||
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|
|
||||
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.|
|
||||
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.|
|
||||
|
|
Loading…
Reference in a new issue