From c9a0058042da04e4dc664f4c53a2e43a6bb820b2 Mon Sep 17 00:00:00 2001 From: austinio7116 Date: Wed, 23 May 2018 21:35:33 +0100 Subject: [PATCH 01/11] Experimental MTG Arena style double hand filtering --- .../src/main/java/forge/game/GameAction.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 70645eaf92a..3fd7da8757b 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1620,6 +1620,51 @@ public class GameAction { } } + private void drawStartingHand(Player p1){ + + //copy starting hand/lib + List lib = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + + //draw initial hand + p1.drawCards(p1.getMaxHandSize()); + List lib1 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand1 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + System.out.println("Hand 1: " + hand1.toString()); + + //reset, shuffle + p1.getZone(ZoneType.Library).setCards(lib); + p1.getZone(ZoneType.Hand).setCards(hand); + List shuffledCards = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + Collections.shuffle(shuffledCards); + p1.getZone(ZoneType.Library).setCards(shuffledCards); + + //draw a second hand + p1.drawCards(p1.getMaxHandSize()); + List lib2 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand2 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + System.out.println("Hand 2: " + hand2.toString()); + + //choose better hand according to land count + if(getHandScore(hand1)<=getHandScore(hand2)){ + p1.getZone(ZoneType.Library).setCards(lib1); + p1.getZone(ZoneType.Hand).setCards(hand1); + }else{ + p1.getZone(ZoneType.Library).setCards(lib2); + p1.getZone(ZoneType.Hand).setCards(hand2); + } + } + + private int getHandScore(List hand){ + int landCount = 0; + for(Card c:hand){ + if(c.isLand()){ + landCount++; + } + } + return Math.abs(3-landCount); + } + public void startGame(GameOutcome lastGameOutcome) { startGame(lastGameOutcome, null); } @@ -1640,7 +1685,8 @@ public class GameAction { game.setAge(GameStage.Mulligan); for (final Player p1 : game.getPlayers()) { - p1.drawCards(p1.getMaxHandSize()); + + drawStartingHand(p1); // If pl has Backup Plan as a Conspiracy draw that many extra hands From d52deee44eaa574c12ffe6e6d5939bd02edceb92 Mon Sep 17 00:00:00 2001 From: austinio7116 Date: Wed, 23 May 2018 21:35:33 +0100 Subject: [PATCH 02/11] Experimental MTG Arena style double hand filtering --- .../src/main/java/forge/game/GameAction.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 3bf8a391842..d9c834a35c5 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1562,6 +1562,51 @@ public class GameAction { } } + private void drawStartingHand(Player p1){ + + //copy starting hand/lib + List lib = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + + //draw initial hand + p1.drawCards(p1.getMaxHandSize()); + List lib1 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand1 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + System.out.println("Hand 1: " + hand1.toString()); + + //reset, shuffle + p1.getZone(ZoneType.Library).setCards(lib); + p1.getZone(ZoneType.Hand).setCards(hand); + List shuffledCards = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + Collections.shuffle(shuffledCards); + p1.getZone(ZoneType.Library).setCards(shuffledCards); + + //draw a second hand + p1.drawCards(p1.getMaxHandSize()); + List lib2 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand2 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + System.out.println("Hand 2: " + hand2.toString()); + + //choose better hand according to land count + if(getHandScore(hand1)<=getHandScore(hand2)){ + p1.getZone(ZoneType.Library).setCards(lib1); + p1.getZone(ZoneType.Hand).setCards(hand1); + }else{ + p1.getZone(ZoneType.Library).setCards(lib2); + p1.getZone(ZoneType.Hand).setCards(hand2); + } + } + + private int getHandScore(List hand){ + int landCount = 0; + for(Card c:hand){ + if(c.isLand()){ + landCount++; + } + } + return Math.abs(3-landCount); + } + public void startGame(GameOutcome lastGameOutcome) { startGame(lastGameOutcome, null); } @@ -1582,7 +1627,8 @@ public class GameAction { game.setAge(GameStage.Mulligan); for (final Player p1 : game.getPlayers()) { - p1.drawCards(p1.getMaxHandSize()); + + drawStartingHand(p1); // If pl has Backup Plan as a Conspiracy draw that many extra hands From 70a82fbc4528bb00307c3ebdc624b3c0b1bf2b2e Mon Sep 17 00:00:00 2001 From: austinio7116 Date: Sat, 26 May 2018 13:53:17 +0100 Subject: [PATCH 03/11] Removed flicker when filtering starting hand --- .../src/main/java/forge/game/GameAction.java | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index d9c834a35c5..36b446dff47 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1563,38 +1563,23 @@ public class GameAction { } private void drawStartingHand(Player p1){ - - //copy starting hand/lib - List lib = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); - List hand = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); - //draw initial hand - p1.drawCards(p1.getMaxHandSize()); + //check initial hand List lib1 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); - List hand1 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); - System.out.println("Hand 1: " + hand1.toString()); + List hand1 = lib1.subList(0,p1.getMaxHandSize()); - //reset, shuffle - p1.getZone(ZoneType.Library).setCards(lib); - p1.getZone(ZoneType.Hand).setCards(hand); + //shuffle List shuffledCards = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); Collections.shuffle(shuffledCards); - p1.getZone(ZoneType.Library).setCards(shuffledCards); - //draw a second hand - p1.drawCards(p1.getMaxHandSize()); - List lib2 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); - List hand2 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); - System.out.println("Hand 2: " + hand2.toString()); + //check a second hand + List hand2 = shuffledCards.subList(0,p1.getMaxHandSize()); //choose better hand according to land count - if(getHandScore(hand1)<=getHandScore(hand2)){ - p1.getZone(ZoneType.Library).setCards(lib1); - p1.getZone(ZoneType.Hand).setCards(hand1); - }else{ - p1.getZone(ZoneType.Library).setCards(lib2); - p1.getZone(ZoneType.Hand).setCards(hand2); + if(getHandScore(hand1)>getHandScore(hand2)){ + p1.getZone(ZoneType.Library).setCards(shuffledCards); } + p1.drawCards(p1.getMaxHandSize()); } private int getHandScore(List hand){ From 18e2d127be6ee31a965470b822cf3bf8a9b802b5 Mon Sep 17 00:00:00 2001 From: austinio7116 Date: Wed, 23 May 2018 21:35:33 +0100 Subject: [PATCH 04/11] Experimental MTG Arena style double hand filtering --- .../src/main/java/forge/game/GameAction.java | 48 ++++++++++++++++++- 1 file changed, 47 insertions(+), 1 deletion(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 3bf8a391842..d9c834a35c5 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1562,6 +1562,51 @@ public class GameAction { } } + private void drawStartingHand(Player p1){ + + //copy starting hand/lib + List lib = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + + //draw initial hand + p1.drawCards(p1.getMaxHandSize()); + List lib1 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand1 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + System.out.println("Hand 1: " + hand1.toString()); + + //reset, shuffle + p1.getZone(ZoneType.Library).setCards(lib); + p1.getZone(ZoneType.Hand).setCards(hand); + List shuffledCards = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + Collections.shuffle(shuffledCards); + p1.getZone(ZoneType.Library).setCards(shuffledCards); + + //draw a second hand + p1.drawCards(p1.getMaxHandSize()); + List lib2 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); + List hand2 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); + System.out.println("Hand 2: " + hand2.toString()); + + //choose better hand according to land count + if(getHandScore(hand1)<=getHandScore(hand2)){ + p1.getZone(ZoneType.Library).setCards(lib1); + p1.getZone(ZoneType.Hand).setCards(hand1); + }else{ + p1.getZone(ZoneType.Library).setCards(lib2); + p1.getZone(ZoneType.Hand).setCards(hand2); + } + } + + private int getHandScore(List hand){ + int landCount = 0; + for(Card c:hand){ + if(c.isLand()){ + landCount++; + } + } + return Math.abs(3-landCount); + } + public void startGame(GameOutcome lastGameOutcome) { startGame(lastGameOutcome, null); } @@ -1582,7 +1627,8 @@ public class GameAction { game.setAge(GameStage.Mulligan); for (final Player p1 : game.getPlayers()) { - p1.drawCards(p1.getMaxHandSize()); + + drawStartingHand(p1); // If pl has Backup Plan as a Conspiracy draw that many extra hands From 14ba4e6894e661b155bfb5be329eaaf6386a837e Mon Sep 17 00:00:00 2001 From: austinio7116 Date: Sat, 26 May 2018 13:53:17 +0100 Subject: [PATCH 05/11] Removed flicker when filtering starting hand --- .../src/main/java/forge/game/GameAction.java | 31 +++++-------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index d9c834a35c5..36b446dff47 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -1563,38 +1563,23 @@ public class GameAction { } private void drawStartingHand(Player p1){ - - //copy starting hand/lib - List lib = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); - List hand = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); - //draw initial hand - p1.drawCards(p1.getMaxHandSize()); + //check initial hand List lib1 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); - List hand1 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); - System.out.println("Hand 1: " + hand1.toString()); + List hand1 = lib1.subList(0,p1.getMaxHandSize()); - //reset, shuffle - p1.getZone(ZoneType.Library).setCards(lib); - p1.getZone(ZoneType.Hand).setCards(hand); + //shuffle List shuffledCards = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); Collections.shuffle(shuffledCards); - p1.getZone(ZoneType.Library).setCards(shuffledCards); - //draw a second hand - p1.drawCards(p1.getMaxHandSize()); - List lib2 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); - List hand2 = Lists.newArrayList(p1.getZone(ZoneType.Hand).getCards().threadSafeIterable()); - System.out.println("Hand 2: " + hand2.toString()); + //check a second hand + List hand2 = shuffledCards.subList(0,p1.getMaxHandSize()); //choose better hand according to land count - if(getHandScore(hand1)<=getHandScore(hand2)){ - p1.getZone(ZoneType.Library).setCards(lib1); - p1.getZone(ZoneType.Hand).setCards(hand1); - }else{ - p1.getZone(ZoneType.Library).setCards(lib2); - p1.getZone(ZoneType.Hand).setCards(hand2); + if(getHandScore(hand1)>getHandScore(hand2)){ + p1.getZone(ZoneType.Library).setCards(shuffledCards); } + p1.drawCards(p1.getMaxHandSize()); } private int getHandScore(List hand){ From e6af43b060a7dd53116546f49ab67a3f8820068e Mon Sep 17 00:00:00 2001 From: austinio7116 Date: Wed, 30 May 2018 07:19:54 +0100 Subject: [PATCH 06/11] Implemented hand filtering properly using deck land ratio Made hand filtering optional and disabled by default --- .../src/main/java/forge/StaticData.java | 10 ++++++ .../src/main/java/forge/game/GameAction.java | 31 ++++++++++++++++--- .../home/settings/CSubmenuPreferences.java | 1 + .../home/settings/VSubmenuPreferences.java | 9 ++++++ .../forge/screens/settings/SettingsPage.java | 4 +++ .../src/main/java/forge/model/FModel.java | 2 ++ .../forge/properties/ForgePreferences.java | 1 + 7 files changed, 53 insertions(+), 5 deletions(-) diff --git a/forge-core/src/main/java/forge/StaticData.java b/forge-core/src/main/java/forge/StaticData.java index 6c7d931d7b3..9e8629baf20 100644 --- a/forge-core/src/main/java/forge/StaticData.java +++ b/forge-core/src/main/java/forge/StaticData.java @@ -37,6 +37,8 @@ public class StaticData { private Predicate brawlPredicate; private Predicate modernPredicate; + private boolean filteredHandsEnabled = false; + // Loaded lazily: private IStorage boosters; private IStorage specialBoosters; @@ -209,6 +211,14 @@ public class StaticData { return brawlPredicate; } + public void setFilteredHandsEnabled(boolean filteredHandsEnabled){ + this.filteredHandsEnabled = filteredHandsEnabled; + } + + public boolean getFilteredHandsEnabled(){ + return filteredHandsEnabled; + } + public PaperCard getCardByEditionDate(PaperCard card, Date editionDate) { PaperCard c = this.getCommonCards().getCardFromEdition(card.getName(), editionDate, CardDb.SetPreference.LatestCoreExp, card.getArtIndex()); diff --git a/forge-game/src/main/java/forge/game/GameAction.java b/forge-game/src/main/java/forge/game/GameAction.java index 36b446dff47..ad4e4f6dc0a 100644 --- a/forge-game/src/main/java/forge/game/GameAction.java +++ b/forge-game/src/main/java/forge/game/GameAction.java @@ -20,6 +20,7 @@ package forge.game; import com.google.common.base.Predicate; import com.google.common.collect.*; import forge.GameCommand; +import forge.StaticData; import forge.card.CardStateName; import forge.game.ability.AbilityFactory; import forge.game.ability.AbilityUtils; @@ -1567,6 +1568,7 @@ public class GameAction { //check initial hand List lib1 = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); List hand1 = lib1.subList(0,p1.getMaxHandSize()); + System.out.println(hand1.toString()); //shuffle List shuffledCards = Lists.newArrayList(p1.getZone(ZoneType.Library).getCards().threadSafeIterable()); @@ -1574,22 +1576,38 @@ public class GameAction { //check a second hand List hand2 = shuffledCards.subList(0,p1.getMaxHandSize()); + System.out.println(hand2.toString()); //choose better hand according to land count - if(getHandScore(hand1)>getHandScore(hand2)){ + float averageLandRatio = getLandRatio(lib1); + if(getHandScore(hand1, averageLandRatio)>getHandScore(hand2, averageLandRatio)){ p1.getZone(ZoneType.Library).setCards(shuffledCards); } p1.drawCards(p1.getMaxHandSize()); } - private int getHandScore(List hand){ + private float getLandRatio(List deck){ + int landCount = 0; + for(Card c:deck){ + if(c.isLand()){ + landCount++; + } + } + if (landCount == 0 ){ + return 0; + } + return new Float(landCount)/new Float(deck.size()); + } + + private float getHandScore(List hand, float landRatio){ int landCount = 0; for(Card c:hand){ if(c.isLand()){ landCount++; } } - return Math.abs(3-landCount); + float averageCount = landRatio * hand.size(); + return Math.abs(averageCount-landCount); } public void startGame(GameOutcome lastGameOutcome) { @@ -1612,8 +1630,11 @@ public class GameAction { game.setAge(GameStage.Mulligan); for (final Player p1 : game.getPlayers()) { - - drawStartingHand(p1); + if (StaticData.instance().getFilteredHandsEnabled() ) { + drawStartingHand(p1); + } else { + p1.drawCards(p1.getStartingHandSize()); + } // If pl has Backup Plan as a Conspiracy draw that many extra hands diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java index ef7276a47b3..d7efbea3719 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/CSubmenuPreferences.java @@ -101,6 +101,7 @@ public enum CSubmenuPreferences implements ICDoc { lstControls.add(Pair.of(view.getCbRandomArtInPools(), FPref.UI_RANDOM_ART_IN_POOLS)); lstControls.add(Pair.of(view.getCbEnforceDeckLegality(), FPref.ENFORCE_DECK_LEGALITY)); lstControls.add(Pair.of(view.getCbPerformanceMode(), FPref.PERFORMANCE_MODE)); + lstControls.add(Pair.of(view.getCbFilteredHands(), FPref.FILTERED_HANDS)); lstControls.add(Pair.of(view.getCbCloneImgSource(), FPref.UI_CLONE_MODE_SOURCE)); lstControls.add(Pair.of(view.getCbRemoveSmall(), FPref.DECKGEN_NOSMALL)); lstControls.add(Pair.of(view.getCbCardBased(), FPref.DECKGEN_CARDBASED)); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java index 3c3c2b37d65..6486d73aac3 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/settings/VSubmenuPreferences.java @@ -69,6 +69,7 @@ public enum VSubmenuPreferences implements IVSubmenu { private final JCheckBox cbWorkshopSyntax = new OptionsCheckBox("Workshop Syntax Checker"); private final JCheckBox cbEnforceDeckLegality = new OptionsCheckBox("Deck Conformance"); private final JCheckBox cbPerformanceMode = new OptionsCheckBox("Performance Mode"); + private final JCheckBox cbFilteredHands = new OptionsCheckBox("Filtered Hands"); private final JCheckBox cbImageFetcher = new OptionsCheckBox("Automatically Download Missing Card Art"); private final JCheckBox cbCloneImgSource = new OptionsCheckBox("Clones Use Original Card Art"); private final JCheckBox cbScaleLarger = new OptionsCheckBox("Scale Image Larger"); @@ -175,6 +176,9 @@ public enum VSubmenuPreferences implements IVSubmenu { pnlPrefs.add(cbPerformanceMode, titleConstraints); pnlPrefs.add(new NoteLabel("Disables additional static abilities checks to speed up the game engine. (Warning: breaks some 'as if had flash' scenarios when casting cards owned by opponents)."), descriptionConstraints); + pnlPrefs.add(cbFilteredHands, titleConstraints); + pnlPrefs.add(new NoteLabel("Generates two starting hands and keeps the one with the closest to average land count for the deck. (Requires restart)"), descriptionConstraints); + pnlPrefs.add(cbCloneImgSource, titleConstraints); pnlPrefs.add(new NoteLabel("When enabled clones will use their original art instead of the cloned card's art."), descriptionConstraints); @@ -641,6 +645,11 @@ public enum VSubmenuPreferences implements IVSubmenu { return cbPerformanceMode; } + /** @return {@link javax.swing.JCheckBox} */ + public JCheckBox getCbFilteredHands() { + return cbFilteredHands; + } + /** @return {@link javax.swing.JCheckBox} */ public JCheckBox getCbCloneImgSource() { return cbCloneImgSource; diff --git a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java index 5204f333eed..7d76e3f190d 100644 --- a/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java +++ b/forge-gui-mobile/src/forge/screens/settings/SettingsPage.java @@ -117,6 +117,10 @@ public class SettingsPage extends TabPage { "Performance Mode", "Disables additional static abilities checks to speed up the game engine. (Warning: breaks some 'as if had flash' scenarios when casting cards owned by opponents)."), 1); + lstSettings.addItem(new BooleanSetting(FPref.FILTERED_HANDS, + "Filtered Hands", + "Generates two starting hands and keeps the one with the closest to average land count for the deck. (Requires restart)"), + 1); lstSettings.addItem(new BooleanSetting(FPref.UI_CLONE_MODE_SOURCE, "Clones Use Original Card Art", "When enabled clones will use their original art instead of the cloned card's art."), diff --git a/forge-gui/src/main/java/forge/model/FModel.java b/forge-gui/src/main/java/forge/model/FModel.java index 782fd3ac175..3528ed4d14e 100644 --- a/forge-gui/src/main/java/forge/model/FModel.java +++ b/forge-gui/src/main/java/forge/model/FModel.java @@ -173,6 +173,8 @@ public final class FModel { magicDb.setBrawlPredicate(formats.get("Brawl").getFilterRules()); magicDb.setModernPredicate(formats.getModern().getFilterRules()); + magicDb.setFilteredHandsEnabled(preferences.getPrefBoolean(FPref.FILTERED_HANDS)); + blocks = new StorageBase<>("Block definitions", new CardBlock.Reader(ForgeConstants.BLOCK_DATA_DIR + "blocks.txt", magicDb.getEditions())); questPreferences = new QuestPreferences(); conquestPreferences = new ConquestPreferences(); diff --git a/forge-gui/src/main/java/forge/properties/ForgePreferences.java b/forge-gui/src/main/java/forge/properties/ForgePreferences.java index 96add1638de..7e2c7096384 100644 --- a/forge-gui/src/main/java/forge/properties/ForgePreferences.java +++ b/forge-gui/src/main/java/forge/properties/ForgePreferences.java @@ -154,6 +154,7 @@ public class ForgePreferences extends PreferencesStore { ENFORCE_DECK_LEGALITY ("true"), PERFORMANCE_MODE ("false"), + FILTERED_HANDS ("false"), DEV_MODE_ENABLED ("false"), DEV_WORKSHOP_SYNTAX ("false"), From 8448148f971bc2a218108eb72d78f5341d7f449b Mon Sep 17 00:00:00 2001 From: Rob Schnautz Date: Sat, 9 Jun 2018 06:07:05 +0000 Subject: [PATCH 07/11] typo --- forge-gui/res/editions/Battlebond.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/forge-gui/res/editions/Battlebond.txt b/forge-gui/res/editions/Battlebond.txt index 42852f9b214..d216d495893 100644 --- a/forge-gui/res/editions/Battlebond.txt +++ b/forge-gui/res/editions/Battlebond.txt @@ -225,7 +225,7 @@ Booster=10 Common, 3 Uncommon, 1 RareMythic:!fromSheet("BBD RareMythic"), 1 Basi 215 R Vigor 216 C Wandering Wolf 217 R Apocalypse Hydra -218 C Augur Spree +218 C Auger Spree 219 C Centaur Healer 220 U Dinrova Horror 221 U Enduring Scalelord From a551612b894fef8e14a421a1398c14401dc37f6c Mon Sep 17 00:00:00 2001 From: Hanmac Date: Fri, 8 Jun 2018 23:04:35 +0200 Subject: [PATCH 08/11] cards: added blaring partner --- forge-gui/res/cardsfolder/upcoming/blaring_captain.txt | 10 ++++++++++ .../res/cardsfolder/upcoming/blaring_recruiter.txt | 10 ++++++++++ 2 files changed, 20 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/blaring_captain.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/blaring_recruiter.txt diff --git a/forge-gui/res/cardsfolder/upcoming/blaring_captain.txt b/forge-gui/res/cardsfolder/upcoming/blaring_captain.txt new file mode 100644 index 00000000000..78354ca731e --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/blaring_captain.txt @@ -0,0 +1,10 @@ +Name:Blaring Captain +ManaCost:3 B +Types:Creature Azra Warrior +PT:2/2 +K:Partner:Blaring Recruiter +T:Mode$ Attacks | ValidCard$ Card.Self | TriggerZones$ Battlefield | Execute$ TrigPumpAttack | TriggerDescription$ Whenever CARDNAME attacks, attacking Warriors get +1/+1 until end of turn. +SVar:TrigPumpAttack:DB$ PumpAll | ValidCards$ Warrior.attacking | NumAtt$ 1 | NumDef$ 1 +DeckHints:Name$Blaring Recruiter & Type$Warrior +SVar:Picture:http://www.wizards.com/global/images/magic/general/blaring_captain.jpg +Oracle:Partner with Blaring Recruiter (When this creature enters the battlefield, target player may put Blaring Recruiter into their hand from their library, then shuffle.)\nWhenever Blaring Captain attacks, attacking Warriors get +1/+1 until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/blaring_recruiter.txt b/forge-gui/res/cardsfolder/upcoming/blaring_recruiter.txt new file mode 100644 index 00000000000..a1d3c98b5da --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/blaring_recruiter.txt @@ -0,0 +1,10 @@ +Name:Blaring Recruiter +ManaCost:3 W +Types:Creature Elf Warrior +PT:2/2 +K:Partner:Blaring Captain +A:AB$ Token | Cost$ 2 W | TokenAmount$ 1 | TokenName$ Warrior | TokenTypes$ Creature,Warrior | TokenOwner$ You | TokenColors$ White | TokenPower$ 1 | TokenToughness$ 1 | TokenImage$ w 1 1 warrior BBD | SpellDescription$ Create a 1/1 white Warrior creature tokens. +DeckHints:Name$Blaring Captain +DeckHas:Ability$Token +SVar:Picture:http://www.wizards.com/global/images/magic/general/blaring_recruiter.jpg +Oracle:Partner with Blaring Captain (When this creature enters the battlefield, target player may put Blaring Captain into their hand from their library, then shuffle.)\n{2}{W}: Create a 1/1 white Warrior creature token. From bfd667de00c8cea0e61dc32d5e647b1bc410e4bc Mon Sep 17 00:00:00 2001 From: Hanmac Date: Fri, 8 Jun 2018 23:05:25 +0200 Subject: [PATCH 09/11] cards: add chakram partner --- .../res/cardsfolder/upcoming/chakram_retriever.txt | 10 ++++++++++ forge-gui/res/cardsfolder/upcoming/chakram_slinger.txt | 9 +++++++++ 2 files changed, 19 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/chakram_retriever.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/chakram_slinger.txt diff --git a/forge-gui/res/cardsfolder/upcoming/chakram_retriever.txt b/forge-gui/res/cardsfolder/upcoming/chakram_retriever.txt new file mode 100644 index 00000000000..26361572ba2 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/chakram_retriever.txt @@ -0,0 +1,10 @@ +Name:Chakram Retriever +ManaCost:4 U +Types:Creature Elemental Hound +PT:2/4 +K:Partner:Chakram Slinger +T:Mode$ SpellCast | ValidCard$ Card | ValidActivatingPlayer$ You | TriggerZones$ Battlefield | PlayerTurn$ True | Execute$ TrigUntap | TriggerDescription$ Whenever you cast a spell during your turn, untap target creature. +SVar:TrigUntap:DB$ Untap | ValidTgts$ Creature | TgtPrompt$ Select target creature +DeckHints:Name$Chakram Slinger +SVar:Picture:http://www.wizards.com/global/images/magic/general/chakram_retriever.jpg +Oracle:Partner with Chakram Slinger (When this creature enters the battlefield, target player may put Chakram Slinger into their hand from their library, then shuffle.)\nWhenever you cast a spell during your turn, untap target creature. diff --git a/forge-gui/res/cardsfolder/upcoming/chakram_slinger.txt b/forge-gui/res/cardsfolder/upcoming/chakram_slinger.txt new file mode 100644 index 00000000000..1976e7e47cc --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/chakram_slinger.txt @@ -0,0 +1,9 @@ +Name:Chakram Slinger +ManaCost:4 R +Types:Creature Human Warrior +PT:2/4 +K:Partner:Chakram Retriever +A:AB$ DealDamage | Cost$ R T | ValidTgts$ Player,Planeswalker | TgtPrompt$ Select target player or planeswalker | NumDmg$ 2 | SpellDescription$ CARDNAME deals 2 damage to target player or planeswalker. +DeckHints:Name$Chakram Retriever +SVar:Picture:http://www.wizards.com/global/images/magic/general/chakram_slinger.jpg +Oracle:Partner with Chakram Retriever (When this creature enters the battlefield, target player may put Chakram Retriever into their hand from their library, then shuffle.)\n{R}, {T}: Chakram Slinger deals 2 damage to target player or planeswalker. From 20b28e3d06d8a831d69d896d24e5f614dc8e0e9e Mon Sep 17 00:00:00 2001 From: Hanmac Date: Fri, 8 Jun 2018 23:09:34 +0200 Subject: [PATCH 10/11] cards: add soulblade partner --- .../res/cardsfolder/upcoming/soulblade_corrupter.txt | 11 +++++++++++ .../res/cardsfolder/upcoming/soulblade_renewer.txt | 11 +++++++++++ 2 files changed, 22 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/soulblade_corrupter.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/soulblade_renewer.txt diff --git a/forge-gui/res/cardsfolder/upcoming/soulblade_corrupter.txt b/forge-gui/res/cardsfolder/upcoming/soulblade_corrupter.txt new file mode 100644 index 00000000000..18840ab2910 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/soulblade_corrupter.txt @@ -0,0 +1,11 @@ +Name:Soulblade Corrupter +ManaCost:4 B +Types:Creature Human Warrior +PT:3/3 +K:Partner:Soulblade Renewer +K:Deathtouch +T:Mode$ Attacks | ValidCard$ Creature.counters_GE1_P1P1 | Attacked$ Player.Opponent | TriggerZones$ Battlefield | Execute$ TrigPump | TriggerDescription$ Whenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn. +SVar:TrigPump:DB$Pump | Defined$ TriggeredAttacker | KW$ Deathtouch +DeckHints:Name$Soulblade Renewer & Ability$Counters +SVar:Picture:http://www.wizards.com/global/images/magic/general/soulblade_corrupter.jpg +Oracle:Partner with Soulblade Renewer (When this creature enters the battlefield, target player may put Soulblade Renewer into their hand from their library, then shuffle.)\nDeathtouch\nWhenever a creature with a +1/+1 counter on it attacks one of your opponents, that creature gains deathtouch until end of turn. diff --git a/forge-gui/res/cardsfolder/upcoming/soulblade_renewer.txt b/forge-gui/res/cardsfolder/upcoming/soulblade_renewer.txt new file mode 100644 index 00000000000..85400543572 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/soulblade_renewer.txt @@ -0,0 +1,11 @@ +Name:Soulblade Renewer +ManaCost:4 G +Types:Creature Elf Warrior +PT:2/2 +K:Partner:Soulblade Corrupter +T:Mode$ ChangesZone | Origin$ Any | Destination$ Battlefield | ValidCard$ Card.Self | Execute$ TrigPut | TriggerDescription$ When CARDNAME enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.) +SVar:TrigPut:DB$PutCounter | ValidTgts$ Creature.Other | TgtPrompt$ Select target creature other than CARDNAME | TargetMin$ 0 | TargetMax$ 2 | CounterType$ P1P1 | CounterNum$ 1 +DeckHas:Ability$Counters +DeckHints:Name$Soulblade Renewer +SVar:Picture:http://www.wizards.com/global/images/magic/general/soulblade_renewer.jpg +Oracle:Partner with Soulblade Corrupter (When this creature enters the battlefield, target player may put Soulblade Corrupter into their hand from their library, then shuffle.)\nWhen Soulblade Renewer enters the battlefield, support 2. (Put a +1/+1 counter on each of up to two other target creatures.) From ed612574bc780af873b85240cb3480bd30266aac Mon Sep 17 00:00:00 2001 From: Hanmac Date: Fri, 8 Jun 2018 23:28:40 +0200 Subject: [PATCH 11/11] cards: add mentor and protege partner --- .../res/cardsfolder/upcoming/impetuous_protege.txt | 11 +++++++++++ forge-gui/res/cardsfolder/upcoming/proud_mentor.txt | 9 +++++++++ 2 files changed, 20 insertions(+) create mode 100644 forge-gui/res/cardsfolder/upcoming/impetuous_protege.txt create mode 100644 forge-gui/res/cardsfolder/upcoming/proud_mentor.txt diff --git a/forge-gui/res/cardsfolder/upcoming/impetuous_protege.txt b/forge-gui/res/cardsfolder/upcoming/impetuous_protege.txt new file mode 100644 index 00000000000..1d953e979ad --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/impetuous_protege.txt @@ -0,0 +1,11 @@ +Name:Impetuous Protege +ManaCost:2 R +Types:Creature Human Warrior +PT:0/4 +K:Partner:Proud Mentor +T:Mode$ Attacks | ValidCard$ Card.Self | Execute$ TrigPump | TriggerDescription$ Whenever CARDNAME attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control. +SVar:TrigPump:DB$ Pump | Defined$ Self | NumAtt$ X | References$ X +SVar:X:Count$GreatestPower_Creature.tapped+OppCtrl +DeckHints:Name$Proud Mentor +SVar:Picture:http://www.wizards.com/global/images/magic/general/impetuous_protege.jpg +Oracle:Partner with Proud Mentor (When this creature enters the battlefield, target player may put Proud Mentor into their hand from their library, then shuffle.)\nWhenever Impetuous Protege attacks, it gets +X/+0 until end of turn, where X is the greatest power among tapped creatures your opponents control. diff --git a/forge-gui/res/cardsfolder/upcoming/proud_mentor.txt b/forge-gui/res/cardsfolder/upcoming/proud_mentor.txt new file mode 100644 index 00000000000..035d5287494 --- /dev/null +++ b/forge-gui/res/cardsfolder/upcoming/proud_mentor.txt @@ -0,0 +1,9 @@ +Name:Proud Mentor +ManaCost:2 W +Types:Creature Human Warrior +PT:1/1 +K:Partner:Impetuous Protege +A:AB$ Tap | Cost$ W T | ValidTgts$ Creature | TgtPrompt$ Select target creature | SpellDescription$ Tap target creature. +DeckHints:Name$Impetuous Protege +SVar:Picture:http://www.wizards.com/global/images/magic/general/proud_mentor.jpg +Oracle:Partner with Impetuous Protege (When this creature enters the battlefield, target player may put Impetuous Protege into their hand from their library, then shuffle.)\n{W}, {T}: Tap target creature.