mirror of
https://github.com/magefree/mage.git
synced 2025-12-25 04:52:07 -08:00
[LCC] Implement Topography Tracker (#11504)
* Refactor replacement effects on ExploreEvent by using a queue of events
This commit is contained in:
parent
15fcc22bb3
commit
5c83818cba
6 changed files with 289 additions and 37 deletions
|
|
@ -10,6 +10,7 @@ import mage.constants.Outcome;
|
|||
import mage.constants.Zone;
|
||||
import mage.counters.CounterType;
|
||||
import mage.game.Game;
|
||||
import mage.game.events.ExploreEvent;
|
||||
import mage.game.events.ExploredEvent;
|
||||
import mage.game.events.GameEvent;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
|
@ -70,41 +71,57 @@ public class ExploreSourceEffect extends OneShotEffect {
|
|||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
GameEvent event = new GameEvent(GameEvent.EventType.EXPLORE, permanentId, source, permanent.getControllerId());
|
||||
if (game.replaceEvent(event)) {
|
||||
continue;
|
||||
// Because of Topography Tracker and Twists and Turns, we need to be able to have a mix of Explores and Scry 1s
|
||||
// The ExploreEvent generates with a queue of EventType.EXPLORE equal to amount, the replacement effects
|
||||
// can then replace each EXPLORE with either two EXPLOREs or a SCRY and an EXPLORE.
|
||||
ExploreEvent event = new ExploreEvent(permanent, source, amount);
|
||||
if (game.replaceEvent(event)) {
|
||||
return false;
|
||||
}
|
||||
for (GameEvent.EventType eventType : event.getEventQueue()) {
|
||||
switch (eventType) {
|
||||
case SCRY:
|
||||
controller.scry(1, source, game);
|
||||
break;
|
||||
case EXPLORE:
|
||||
doOneExplore(game, permanent, source, controller);
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Wrong code usage: unrecognized event type in explore event");
|
||||
}
|
||||
// 701.40a Certain abilities instruct a permanent to explore. To do so, that permanent’s controller reveals
|
||||
// the top card of their library. If a land card is revealed this way, that player puts that card into their
|
||||
// hand. Otherwise, that player puts a +1/+1 counter on the exploring permanent and may put the revealed
|
||||
// card into their graveyard.
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
controller.revealCards("Explored card", new CardsImpl(card), game);
|
||||
if (card.isLand(game)) {
|
||||
controller.moveCards(card, Zone.HAND, source, game);
|
||||
} else {
|
||||
addCounter(game, permanent, source);
|
||||
if (controller.chooseUse(Outcome.Neutral, "Put " + card.getLogName() + " in your graveyard?", source, game)) {
|
||||
controller.moveCards(card, Zone.GRAVEYARD, source, game);
|
||||
} else {
|
||||
game.informPlayers(controller.getLogName() + " leaves " + card.getLogName() + " on top of their library.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If no card is revealed, most likely because that player's library is empty,
|
||||
// the exploring creature receives a +1/+1 counter.
|
||||
addCounter(game, permanent, source);
|
||||
}
|
||||
game.getState().processAction(game);
|
||||
// 701.40b A permanent “explores” after the process described in rule 701.40a is complete, even if some or all of
|
||||
// those actions were impossible.
|
||||
game.fireEvent(new ExploredEvent(permanent, source, card));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static void doOneExplore(Game game, Permanent permanent, Ability source, Player controller) {
|
||||
// 701.40a Certain abilities instruct a permanent to explore. To do so, that permanent’s controller reveals
|
||||
// the top card of their library. If a land card is revealed this way, that player puts that card into their
|
||||
// hand. Otherwise, that player puts a +1/+1 counter on the exploring permanent and may put the revealed
|
||||
// card into their graveyard.
|
||||
Card card = controller.getLibrary().getFromTop(game);
|
||||
if (card != null) {
|
||||
controller.revealCards("Explored card", new CardsImpl(card), game);
|
||||
if (card.isLand(game)) {
|
||||
controller.moveCards(card, Zone.HAND, source, game);
|
||||
} else {
|
||||
addCounter(game, permanent, source);
|
||||
if (controller.chooseUse(Outcome.Neutral, "Put " + card.getLogName() + " in your graveyard?", source, game)) {
|
||||
controller.moveCards(card, Zone.GRAVEYARD, source, game);
|
||||
} else {
|
||||
game.informPlayers(controller.getLogName() + " leaves " + card.getLogName() + " on top of their library.");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// If no card is revealed, most likely because that player's library is empty,
|
||||
// the exploring creature receives a +1/+1 counter.
|
||||
addCounter(game, permanent, source);
|
||||
}
|
||||
game.getState().processAction(game);
|
||||
// 701.40b A permanent “explores” after the process described in rule 701.40a is complete, even if some or all of
|
||||
// those actions were impossible.
|
||||
game.fireEvent(new ExploredEvent(permanent, source, card));
|
||||
}
|
||||
|
||||
private static void addCounter(Game game, Permanent permanent, Ability source) {
|
||||
if (game.getState().getZone(permanent.getId()) == Zone.BATTLEFIELD) { // needed in case LKI object is used
|
||||
permanent.addCounters(CounterType.P1P1.createInstance(), source.getControllerId(), source, game);
|
||||
|
|
|
|||
51
Mage/src/main/java/mage/game/events/ExploreEvent.java
Normal file
51
Mage/src/main/java/mage/game/events/ExploreEvent.java
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
package mage.game.events;
|
||||
|
||||
import mage.abilities.Ability;
|
||||
import mage.game.permanent.Permanent;
|
||||
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.Queue;
|
||||
|
||||
/**
|
||||
* @author Grath
|
||||
*/
|
||||
public class ExploreEvent extends GameEvent {
|
||||
|
||||
private Queue<EventType> eventQueue = new ArrayDeque<>();
|
||||
|
||||
public ExploreEvent(Permanent permanent, Ability source, int amount) {
|
||||
super(EventType.EXPLORE, permanent.getId(), source, permanent.getControllerId(), amount, false);
|
||||
// Populate the queue with a number of EXPLOREs equal to the initial number of EXPLOREs.
|
||||
for (int i = 0; i < amount; ++i) {
|
||||
eventQueue.add(EventType.EXPLORE);
|
||||
}
|
||||
}
|
||||
|
||||
public void doubleExplores() {
|
||||
// Process through the Queue, when we find an EXPLORE add another EXPLORE.
|
||||
Queue<EventType> newQueue = new ArrayDeque<>();
|
||||
for (EventType eventType : eventQueue) {
|
||||
if (eventType == EventType.EXPLORE) {
|
||||
newQueue.add(EventType.EXPLORE);
|
||||
}
|
||||
newQueue.add(eventType);
|
||||
}
|
||||
eventQueue = newQueue;
|
||||
}
|
||||
|
||||
public void addScry() {
|
||||
// Process through the Queue, when we find an EXPLORE add a SCRY before it.
|
||||
Queue<EventType> newQueue = new ArrayDeque<>();
|
||||
for (EventType eventType : eventQueue) {
|
||||
if (eventType == EventType.EXPLORE) {
|
||||
newQueue.add(EventType.SCRY);
|
||||
}
|
||||
newQueue.add(eventType);
|
||||
}
|
||||
eventQueue = newQueue;
|
||||
}
|
||||
|
||||
public Queue<EventType> getEventQueue() {
|
||||
return eventQueue;
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue