From 50c460d4467fcb904e12003c5c35738b3e4169b2 Mon Sep 17 00:00:00 2001 From: Hans Mackowiak Date: Wed, 11 Nov 2020 13:12:59 +0100 Subject: [PATCH] ReplaceScry: RE for Eligeth --- .../src/main/java/forge/game/GameAction.java | 59 +++++++++++++------ .../forge/game/replacement/ReplaceScry.java | 51 ++++++++++++++++ .../game/replacement/ReplacementType.java | 1 + .../upcoming/eligeth_crossroads_augur.txt | 11 ++++ 4 files changed, 105 insertions(+), 17 deletions(-) create mode 100644 forge-game/src/main/java/forge/game/replacement/ReplaceScry.java create mode 100644 forge-gui/res/cardsfolder/upcoming/eligeth_crossroads_augur.txt diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index b628d2a3f97..f94e9458882 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1796,25 +1796,50 @@ public class GameAction { // 701.17c If multiple players scry at once, each of those players looks at the top cards of their library // at the same time. Those players decide in APNAP order (see rule 101.4) where to put those // cards, then those cards move at the same time. - public void scry(List players, int numScry, SpellAbility cause) { - if (numScry == 0) { + public void scry(final List players, int numScry, SpellAbility cause) { + if (numScry <= 0) { return; } - // reveal the top N library cards to the player (only) - // no real need to separate out the look if - // there is only one player scrying - if (players.size() > 1) { - for (final Player p : players) { - final CardCollection topN = new CardCollection(p.getCardsIn(ZoneType.Library, numScry)); - revealTo(topN, p); + + // in case something alters the scry amount + Map actualPlayers = Maps.newLinkedHashMap(); + + for (final Player p : players) { + int playerScry = numScry; + final Map repParams = AbilityKey.mapFromAffected(p); + repParams.put(AbilityKey.Source, cause); + repParams.put(AbilityKey.Num, playerScry); + + switch (game.getReplacementHandler().run(ReplacementType.Scry, repParams)) { + case NotReplaced: + break; + case Updated: { + playerScry = (int) repParams.get(AbilityKey.Num); + break; + } + default: + continue; + } + if (playerScry > 0) { + actualPlayers.put(p, playerScry); + + // reveal the top N library cards to the player (only) + // no real need to separate out the look if + // there is only one player scrying + if (players.size() > 1) { + final CardCollection topN = new CardCollection(p.getCardsIn(ZoneType.Library, playerScry)); + revealTo(topN, p); + } } } + // make the decisions - List> decisions = Lists.newArrayList(); - for (final Player p : players) { - final CardCollection topN = new CardCollection(p.getCardsIn(ZoneType.Library, numScry)); + Map> decisions = Maps.newLinkedHashMap(); + for (final Map.Entry e : actualPlayers.entrySet()) { + final Player p = e.getKey(); + final CardCollection topN = new CardCollection(p.getCardsIn(ZoneType.Library, e.getValue())); ImmutablePair decision = p.getController().arrangeForScry(topN); - decisions.add(decision); + decisions.put(p, decision); int numToTop = decision.getLeft() == null ? 0 : decision.getLeft().size(); int numToBottom = decision.getRight() == null ? 0 : decision.getRight().size(); @@ -1823,11 +1848,11 @@ public class GameAction { } // do the moves after all the decisions (maybe not necesssary, but let's // do it the official way) - for (int i = 0; i < players.size(); i++) { + for (Map.Entry> e : decisions.entrySet()) { // no good iterate simultaneously in Java - final Player p = players.get(i); - final CardCollection toTop = decisions.get(i).getLeft(); - final CardCollection toBottom = decisions.get(i).getRight(); + final Player p = e.getKey(); + final CardCollection toTop = e.getValue().getLeft(); + final CardCollection toBottom = e.getValue().getRight(); if (toTop != null) { Collections.reverse(toTop); // reverse to get the correct order for (Card c : toTop) { diff --git a/forge-game/src/main/java/forge/game/replacement/ReplaceScry.java b/forge-game/src/main/java/forge/game/replacement/ReplaceScry.java new file mode 100644 index 00000000000..5338d7b22fa --- /dev/null +++ b/forge-game/src/main/java/forge/game/replacement/ReplaceScry.java @@ -0,0 +1,51 @@ +package forge.game.replacement; + +import forge.game.ability.AbilityKey; +import forge.game.card.Card; +import forge.game.spellability.SpellAbility; + +import java.util.Map; + +/** + * TODO: Write javadoc for this type. + * + */ +public class ReplaceScry extends ReplacementEffect { + + /** + * + * @param mapParams   HashMap + * @param host   Card + */ + public ReplaceScry(final Map mapParams, final Card host, final boolean intrinsic) { + super(mapParams, host, intrinsic); + } + + /* (non-Javadoc) + * @see forge.card.replacement.ReplacementEffect#canReplace(java.util.Map) + */ + @Override + public boolean canReplace(Map runParams) { + if (((int) runParams.get(AbilityKey.Num)) <= 0) { + return false; + } + + if (hasParam("ValidPlayer")) { + if (!matchesValid(runParams.get(AbilityKey.Affected), getParam("ValidPlayer").split(","), getHostCard())) { + return false; + } + } + + return true; + } + + /* (non-Javadoc) + * @see forge.card.replacement.ReplacementEffect#setReplacingObjects(java.util.Map, forge.card.spellability.SpellAbility) + */ + @Override + public void setReplacingObjects(Map runParams, SpellAbility sa) { + sa.setReplacingObject(AbilityKey.Player, runParams.get(AbilityKey.Affected)); + sa.setReplacingObject(AbilityKey.Num, runParams.get(AbilityKey.Num)); + } + +} diff --git a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java index 88f55ebe554..fc29a485edc 100644 --- a/forge-game/src/main/java/forge/game/replacement/ReplacementType.java +++ b/forge-game/src/main/java/forge/game/replacement/ReplacementType.java @@ -26,6 +26,7 @@ public enum ReplacementType { Mill(ReplaceMill.class), Moved(ReplaceMoved.class), ProduceMana(ReplaceProduceMana.class), + Scry(ReplaceScry.class), SetInMotion(ReplaceSetInMotion.class), Surveil(ReplaceSurveil.class), TurnFaceUp(ReplaceTurnFaceUp.class), diff --git a/forge-gui/res/cardsfolder/upcoming/eligeth_crossroads_augur.txt b/forge-gui/res/cardsfolder/upcoming/eligeth_crossroads_augur.txt new file mode 100644 index 00000000000..bc0ed7f5adb --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/eligeth_crossroads_augur.txt @@ -0,0 +1,11 @@ +Name:Eligeth, Crossroads Augur +ManaCost:4 U U +Types:Legendary Creature Sphinx +PT:5/6 +K:Flying +K:Partner +R:Event$ Scry | ActiveZones$ Battlefield | ValidPlayer$ You | ReplaceWith$ Draw | Description$ If you would scry a number of cards, draw that many cards instead. +SVar:Draw:DB$ Draw | Defined$ You | NumCards$ X | References$ X +SVar:X:ReplaceCount$Num +Oracle:Flying\nIf you would scry a number of cards, draw that many cards instead.\nPartner (You can have two commanders if both have partner.) +