Fix drawn card being revealed during ability resolve

This commit is contained in:
tool4EvEr
2021-08-07 13:17:06 +02:00
parent 058ad2b1dd
commit f78c3ba441
9 changed files with 74 additions and 29 deletions

View File

@@ -119,6 +119,7 @@ public class Game {
private Table<CounterType, Player, List<Pair<Card, Integer>>> countersAddedThisTurn = HashBasedTable.create();
private Map<Player, Card> topLibsCast = Maps.newHashMap();
private Map<Card, Integer> facedownWhileCasting = Maps.newHashMap();
private Player monarch = null;
private Player monarchBeginTurn = null;
@@ -1113,7 +1114,29 @@ public class Game {
topLibsCast.put(p, p.getTopXCardsFromLibrary(1).isEmpty() ? null : p.getTopXCardsFromLibrary(1).get(0));
}
}
public void clearTopLibsCast() {
topLibsCast.clear();
public void clearTopLibsCast(SpellAbility sa) {
// if nothing left to pay
if (sa.getActivatingPlayer().getPaidForSA() == null) {
topLibsCast.clear();
for (Card c : facedownWhileCasting.keySet()) {
// maybe it was discarded as payment?
if (c.isInZone(ZoneType.Hand)) {
c.forceTurnFaceUp();
// run triggers for cards that need reveal
final Map<AbilityKey, Object> runParams = Maps.newHashMap();
runParams.put(AbilityKey.Card, c);
runParams.put(AbilityKey.Number, facedownWhileCasting.get(c));
runParams.put(AbilityKey.Player, this);
runParams.put(AbilityKey.CanReveal, true);
// need to hold trigger to clear list first
getTriggerHandler().runTrigger(TriggerType.Drawn, runParams, true);
}
}
facedownWhileCasting.clear();
}
}
public void addFacedownWhileCasting(Card c, int numDrawn) {
facedownWhileCasting.put(c, Integer.valueOf(numDrawn));
}
}

View File

@@ -25,6 +25,7 @@ public enum AbilityKey {
AttackedTarget("AttackedTarget"),
Blocker("Blocker"),
Blockers("Blockers"),
CanReveal("CanReveal"),
CastSA("CastSA"),
CastSACMC("CastSACMC"),
Card("Card"),

View File

@@ -1219,20 +1219,6 @@ public class Player extends GameEntity implements Comparable<Player> {
return false;
}
public final boolean canDraw() {
if (hasKeyword("You can't draw cards.")) {
return false;
}
if (hasKeyword("You can't draw more than one card each turn.")) {
return numDrawnThisTurn < 1;
}
return true;
}
public final CardCollectionView drawCard() {
return drawCards(1, null);
}
public void surveil(int num, SpellAbility cause, CardZoneTable table) {
final Map<AbilityKey, Object> repParams = AbilityKey.mapFromAffected(this);
repParams.put(AbilityKey.Source, cause);
@@ -1300,12 +1286,25 @@ public class Player extends GameEntity implements Comparable<Player> {
return !getZone(ZoneType.Hand).isEmpty();
}
public final boolean canDraw() {
if (hasKeyword("You can't draw cards.")) {
return false;
}
if (hasKeyword("You can't draw more than one card each turn.")) {
return numDrawnThisTurn < 1;
}
return true;
}
public final CardCollectionView drawCard() {
return drawCards(1, null);
}
public final CardCollectionView drawCards(final int n) {
return drawCards(n, null);
}
public final CardCollectionView drawCards(final int n, SpellAbility cause) {
final CardCollection drawn = new CardCollection();
final Map<Player, CardCollection> toReveal = Maps.newHashMap();
// Replacement effects
final Map<AbilityKey, Object> repRunParams = AbilityKey.mapFromAffected(this);
@@ -1317,6 +1316,7 @@ public class Player extends GameEntity implements Comparable<Player> {
// always allow drawing cards before the game actually starts (e.g. Maralen of the Mornsong Avatar)
final boolean gameStarted = game.getAge().ordinal() > GameStage.Mulligan.ordinal();
final Map<Player, CardCollection> toReveal = Maps.newHashMap();
for (int i = 0; i < n; i++) {
if (gameStarted && !canDraw()) {
@@ -1358,7 +1358,6 @@ public class Player extends GameEntity implements Comparable<Player> {
}
List<Player> pList = Lists.newArrayList();
for (Player p : getAllOtherPlayers()) {
if (c.mayPlayerLook(p)) {
pList.add(p);
@@ -1385,8 +1384,16 @@ public class Player extends GameEntity implements Comparable<Player> {
}
view.updateNumDrawnThisTurn(this);
// Run triggers
final Map<AbilityKey, Object> runParams = Maps.newHashMap();
// CR 121.8 card was drawn as part of another sa (e.g. paying with Chromantic Sphere), hide it temporarily
if (game.getTopLibForPlayer(this) != null && getPaidForSA() != null && cause != null && getPaidForSA() != cause.getRootAbility()) {
c.turnFaceDown();
game.addFacedownWhileCasting(c, numDrawnThisTurn);
runParams.put(AbilityKey.CanReveal, false);
}
// Run triggers
runParams.put(AbilityKey.Card, c);
runParams.put(AbilityKey.Number, numDrawnThisTurn);
runParams.put(AbilityKey.Player, this);
@@ -3167,6 +3174,9 @@ public class Player extends GameEntity implements Comparable<Player> {
// it could be empty if spell couldn't be cast
paidForStack.poll();
}
public void clearPaidForSA() {
paidForStack.clear();
}
public boolean isMonarch() {
return equals(game.getMonarch());

View File

@@ -86,6 +86,18 @@ public class TriggerDrawn extends Trigger {
return false;
}
if (runParams.containsKey(AbilityKey.CanReveal)) {
// while drawing this is only set if false
boolean canReveal = (boolean) runParams.get(AbilityKey.CanReveal);
if (hasParam("ForReveal")) {
if (!canReveal) {
return false;
}
} else if (canReveal) {
return false;
}
}
return true;
}