From 88f3db03c4ac3e575e51c3f3be8654bd78edf4c9 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Wed, 3 Oct 2018 17:38:30 -0700 Subject: [PATCH 1/5] Both players' decks show up at the same time, but hangs if you don't select in the correct order --- .../mage/cards/j/JaceArchitectOfThought.java | 68 +++++++++++++++---- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 09ebb7644e..1caa13f393 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -1,6 +1,8 @@ package mage.cards.j; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Set; import java.util.UUID; @@ -34,10 +36,13 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInExile; import mage.target.common.TargetCardInLibrary; +import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; +import javax.swing.*; + /** * * @@ -239,23 +244,21 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } + ArrayList threads = new ArrayList<>(); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - Player player = game.getPlayer(playerId); - String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); - if (source.isControlledBy(player.getId())) { - playerName = "your"; - } - TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); - if (controller.searchLibrary(target, game, playerId)) { - UUID targetId = target.getFirstTarget(); - Card card = player.getLibrary().remove(targetId, game); - if (card != null) { - controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); + JaceArchitectOfThoughtEffect3Helper thread = new JaceArchitectOfThoughtEffect3Helper(playerId, game, source, sourcePermanent, controller); + thread.execute(); + thread.addPropertyChangeListener(new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + if("state".equals(evt.getPropertyName()) && SwingWorker.StateValue.DONE.equals(evt.getNewValue())){ + threads.remove(evt.getSource()); + } } - } - player.shuffleLibrary(source, game); + }); + threads.add(thread); } - + while(threads.size() > 0) {} ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); if (jaceExileZone == null) { return true; @@ -274,3 +277,40 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { return true; } } + +class JaceArchitectOfThoughtEffect3Helper extends SwingWorker { + + UUID playerId; + Game game; + Ability source; + Permanent sourcePermanent; + Player controller; + + public JaceArchitectOfThoughtEffect3Helper (UUID playerId, Game game, Ability source, Permanent sourcePermanent, Player controller) { + this.playerId = playerId; + this.game = game; + this.source = source; + this.sourcePermanent = sourcePermanent; + this.controller = controller; + } + + @Override + protected Boolean doInBackground() throws Exception { + Player player = this.game.getPlayer(this.playerId); + String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); + if (this.source.isControlledBy(player.getId())) { + playerName = "your"; + } + TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); + if (this.controller.searchLibrary(target, this.game, this.playerId)) { + UUID targetId = target.getFirstTarget(); + Card card = player.getLibrary().remove(targetId, this.game); + if (card != null) { + this.controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(this.game, this.source), this.sourcePermanent.getIdName(), this.source.getSourceId(), this.game, Zone.LIBRARY, true); + } + player.shuffleLibrary(this.source, this.game); + } + return true; + } + +} From 02d9287cfae35c50956ec2b81971fc32ede28956 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 11:19:40 -0700 Subject: [PATCH 2/5] Reverting concurrent code to start fresh --- .../mage/cards/j/JaceArchitectOfThought.java | 68 ++++--------------- 1 file changed, 14 insertions(+), 54 deletions(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 1caa13f393..09ebb7644e 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -1,8 +1,6 @@ package mage.cards.j; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.Set; import java.util.UUID; @@ -36,13 +34,10 @@ import mage.players.Player; import mage.target.TargetCard; import mage.target.common.TargetCardInExile; import mage.target.common.TargetCardInLibrary; -import mage.target.common.TargetCardInLibrary; import mage.target.common.TargetOpponent; import mage.target.targetpointer.FixedTarget; import mage.util.CardUtil; -import javax.swing.*; - /** * * @@ -244,21 +239,23 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } - ArrayList threads = new ArrayList<>(); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { - JaceArchitectOfThoughtEffect3Helper thread = new JaceArchitectOfThoughtEffect3Helper(playerId, game, source, sourcePermanent, controller); - thread.execute(); - thread.addPropertyChangeListener(new PropertyChangeListener() { - @Override - public void propertyChange(PropertyChangeEvent evt) { - if("state".equals(evt.getPropertyName()) && SwingWorker.StateValue.DONE.equals(evt.getNewValue())){ - threads.remove(evt.getSource()); - } + Player player = game.getPlayer(playerId); + String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); + if (source.isControlledBy(player.getId())) { + playerName = "your"; + } + TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); + if (controller.searchLibrary(target, game, playerId)) { + UUID targetId = target.getFirstTarget(); + Card card = player.getLibrary().remove(targetId, game); + if (card != null) { + controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(game, source), sourcePermanent.getIdName(), source.getSourceId(), game, Zone.LIBRARY, true); } - }); - threads.add(thread); + } + player.shuffleLibrary(source, game); } - while(threads.size() > 0) {} + ExileZone jaceExileZone = game.getExile().getExileZone(CardUtil.getCardExileZoneId(game, source)); if (jaceExileZone == null) { return true; @@ -277,40 +274,3 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { return true; } } - -class JaceArchitectOfThoughtEffect3Helper extends SwingWorker { - - UUID playerId; - Game game; - Ability source; - Permanent sourcePermanent; - Player controller; - - public JaceArchitectOfThoughtEffect3Helper (UUID playerId, Game game, Ability source, Permanent sourcePermanent, Player controller) { - this.playerId = playerId; - this.game = game; - this.source = source; - this.sourcePermanent = sourcePermanent; - this.controller = controller; - } - - @Override - protected Boolean doInBackground() throws Exception { - Player player = this.game.getPlayer(this.playerId); - String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); - if (this.source.isControlledBy(player.getId())) { - playerName = "your"; - } - TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); - if (this.controller.searchLibrary(target, this.game, this.playerId)) { - UUID targetId = target.getFirstTarget(); - Card card = player.getLibrary().remove(targetId, this.game); - if (card != null) { - this.controller.moveCardToExileWithInfo(card, CardUtil.getCardExileZoneId(this.game, this.source), this.sourcePermanent.getIdName(), this.source.getSourceId(), this.game, Zone.LIBRARY, true); - } - player.shuffleLibrary(this.source, this.game); - } - return true; - } - -} From c5cedc2abacbe2fff2e2564d8663244824df8e78 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 13:45:44 -0700 Subject: [PATCH 3/5] Adding lookAtAllLibraries to Player/PlayerImpl and using that method during JAOT's -8 resolution --- .../src/mage/cards/j/JaceArchitectOfThought.java | 2 ++ Mage/src/main/java/mage/players/Player.java | 9 +++++++++ Mage/src/main/java/mage/players/PlayerImpl.java | 12 ++++++++++++ 3 files changed, 23 insertions(+) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 09ebb7644e..8a5c9342e1 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -239,12 +239,14 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } + controller.lookAtAllLibraries(source, game); for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); if (source.isControlledBy(player.getId())) { playerName = "your"; } + TargetCardInLibrary target = new TargetCardInLibrary(new FilterNonlandCard(new StringBuilder("nonland card from ").append(playerName).append(" library").toString())); if (controller.searchLibrary(target, game, playerId)) { UUID targetId = target.getFirstTarget(); diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index a730164f73..f6f30cf08e 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -350,6 +350,15 @@ public interface Player extends MageItem, Copyable { */ boolean searchLibrary(TargetCardInLibrary target, Game game, UUID targetPlayerId, boolean triggerEvents); + /** + * Reveals all players' libraries. Useful for abilities like Jace, Architect of Thought's -8 + * that have effects that require information from all libraries. + * @param source + * @param game + * @return + */ + boolean lookAtAllLibraries(Ability source, Game game); + boolean canPlayLand(); /** diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 2659dfd145..9b202e4466 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -2477,6 +2477,18 @@ public abstract class PlayerImpl implements Player, Serializable { return false; } + @Override + public boolean lookAtAllLibraries(Ability source, Game game) { + for(UUID playerId : game.getState().getPlayersInRange(this.getId(), game)){ + Player player = game.getPlayer(playerId); + String playerName = this.getName().equals(player.getName()) ? "Your " : player.getName() + "'s "; + playerName += "library"; + Cards cardsInLibrary = new CardsImpl(player.getLibrary().getTopCards(game, player.getLibrary().size())); + lookAtCards(playerName, cardsInLibrary, game); + } + return true; + } + private boolean handleLibraryCastableCards(Library library, Game game, UUID targetPlayerId) { // for handling Panglacial Wurm boolean alreadyChosenUse = false; From 4057cc2859b0e448b72fd6845daa529ec0ff3a0b Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 14:16:52 -0700 Subject: [PATCH 4/5] Implementing new function in all classes implementing Player --- Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java | 4 ++++ Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java | 3 +++ Mage/src/main/java/mage/players/Player.java | 2 +- Mage/src/main/java/mage/players/PlayerImpl.java | 3 +-- 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 0fa4a84a09..05837e862f 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -2072,6 +2072,10 @@ public class TestPlayer implements Player { return computerPlayer.searchLibrary(target, game, targetPlayerId, triggerEvents); } + public void lookAtAllLibraries(Ability source, Game game) { + computerPlayer.lookAtAllLibraries(source, game); + } + @Override public boolean flipCoin(Game game) { return computerPlayer.flipCoin(game); diff --git a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java index 810c068ccf..360bd94251 100644 --- a/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java +++ b/Mage.Tests/src/test/java/org/mage/test/stub/PlayerStub.java @@ -597,6 +597,9 @@ public class PlayerStub implements Player { return false; } + @Override + public void lookAtAllLibraries(Ability source, Game game) {} + @Override public boolean canPlayLand() { return false; diff --git a/Mage/src/main/java/mage/players/Player.java b/Mage/src/main/java/mage/players/Player.java index f6f30cf08e..ec86ad550c 100644 --- a/Mage/src/main/java/mage/players/Player.java +++ b/Mage/src/main/java/mage/players/Player.java @@ -357,7 +357,7 @@ public interface Player extends MageItem, Copyable { * @param game * @return */ - boolean lookAtAllLibraries(Ability source, Game game); + void lookAtAllLibraries(Ability source, Game game); boolean canPlayLand(); diff --git a/Mage/src/main/java/mage/players/PlayerImpl.java b/Mage/src/main/java/mage/players/PlayerImpl.java index 9b202e4466..53053fb046 100644 --- a/Mage/src/main/java/mage/players/PlayerImpl.java +++ b/Mage/src/main/java/mage/players/PlayerImpl.java @@ -2478,7 +2478,7 @@ public abstract class PlayerImpl implements Player, Serializable { } @Override - public boolean lookAtAllLibraries(Ability source, Game game) { + public void lookAtAllLibraries(Ability source, Game game) { for(UUID playerId : game.getState().getPlayersInRange(this.getId(), game)){ Player player = game.getPlayer(playerId); String playerName = this.getName().equals(player.getName()) ? "Your " : player.getName() + "'s "; @@ -2486,7 +2486,6 @@ public abstract class PlayerImpl implements Player, Serializable { Cards cardsInLibrary = new CardsImpl(player.getLibrary().getTopCards(game, player.getLibrary().size())); lookAtCards(playerName, cardsInLibrary, game); } - return true; } private boolean handleLibraryCastableCards(Library library, Game game, UUID targetPlayerId) { From 2ed63a7184cc29bb163ad17fb702a1f28395d915 Mon Sep 17 00:00:00 2001 From: Tyler Moore Date: Thu, 4 Oct 2018 15:14:43 -0700 Subject: [PATCH 5/5] Notifying players of library search, and giving controller choice to search --- Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java | 5 ++++- .../src/test/java/org/mage/test/player/TestPlayer.java | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java index 8a5c9342e1..125d144b15 100644 --- a/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java +++ b/Mage.Sets/src/mage/cards/j/JaceArchitectOfThought.java @@ -239,7 +239,10 @@ class JaceArchitectOfThoughtEffect3 extends OneShotEffect { if (controller == null || sourcePermanent == null) { return false; } - controller.lookAtAllLibraries(source, game); + if(controller.chooseUse(Outcome.Benefit, "Look at all players' libraries before card select?", null, game)) { + game.informPlayers(controller.getLogName() + " is looking at all players' libraries."); + controller.lookAtAllLibraries(source, game); + } for (UUID playerId : game.getState().getPlayersInRange(controller.getId(), game)) { Player player = game.getPlayer(playerId); String playerName = new StringBuilder(player.getLogName()).append("'s").toString(); diff --git a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java index 05837e862f..8c22e36169 100644 --- a/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java +++ b/Mage.Tests/src/test/java/org/mage/test/player/TestPlayer.java @@ -2072,6 +2072,7 @@ public class TestPlayer implements Player { return computerPlayer.searchLibrary(target, game, targetPlayerId, triggerEvents); } + @Override public void lookAtAllLibraries(Ability source, Game game) { computerPlayer.lookAtAllLibraries(source, game); }