From b34ca7b951a93bbdc66a6419d09223e3942d907a Mon Sep 17 00:00:00 2001 From: drdev Date: Fri, 7 Feb 2014 05:20:08 +0000 Subject: [PATCH] Support canceling when selecting block or custom draft format when setting up a new draft or sealed deck Prevent crash if you select a block that has no sets --- .../gui/home/sanctioned/CSubmenuDraft.java | 9 +- .../gui/home/sanctioned/CSubmenuSealed.java | 10 +- .../main/java/forge/limited/BoosterDraft.java | 171 ++++++++++-------- .../limited/SealedCardPoolGenerator.java | 14 +- .../main/java/forge/model/UnOpenedMeta.java | 30 +-- .../test/java/forge/BoosterDraft1Test.java | 4 +- 6 files changed, 139 insertions(+), 99 deletions(-) diff --git a/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java b/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java index f7a094d5143..a2620861650 100644 --- a/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java +++ b/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuDraft.java @@ -150,11 +150,14 @@ public enum CSubmenuDraft implements ICDoc { final LimitedPoolType poolType = GuiChoose.oneOrNone("Choose Draft Format", LimitedPoolType.values()); if (poolType == null) { return; } - final CEditorDraftingProcess draft = new CEditorDraftingProcess(); - draft.showGui(new BoosterDraft(poolType)); + BoosterDraft draft = BoosterDraft.createDraft(poolType); + if (draft == null) { return; } + + final CEditorDraftingProcess draftController = new CEditorDraftingProcess(); + draftController.showGui(draft); Singletons.getControl().setCurrentScreen(FScreen.DRAFTING_PROCESS); - CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draft); + CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(draftController); } /* (non-Javadoc) diff --git a/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java b/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java index 742d15db2db..d302a52f2fa 100644 --- a/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java +++ b/forge-gui/src/main/java/forge/gui/home/sanctioned/CSubmenuSealed.java @@ -16,6 +16,7 @@ import org.apache.commons.lang3.StringUtils; import forge.Command; import forge.Singletons; import forge.card.MagicColor; +import forge.deck.CardPool; import forge.deck.Deck; import forge.deck.DeckBase; import forge.deck.DeckGroup; @@ -36,7 +37,6 @@ import forge.limited.ReadDraftRankings; import forge.limited.SealedCardPoolGenerator; import forge.limited.SealedDeckBuilder; import forge.properties.ForgePreferences.FPref; -import forge.util.ItemPool; import forge.util.MyRandom; import forge.util.storage.IStorage; @@ -151,7 +151,8 @@ public enum CSubmenuSealed implements ICDoc { SealedCardPoolGenerator sd = new SealedCardPoolGenerator(poolType); if (sd.isEmpty()) { return; } - final ItemPool humanPool = sd.getCardpool(true); + final CardPool humanPool = sd.getCardPool(true); + if (humanPool == null) { return; } // System.out.println(humanPool); @@ -208,7 +209,10 @@ public enum CSubmenuSealed implements ICDoc { sealed.setHumanDeck(deck); for (int i = 0; i < rounds; i++) { // Generate other decks for next N opponents - sealed.addAiDeck(new SealedDeckBuilder(sd.getCardpool(false).toFlatList()).buildDeck()); + final CardPool aiPool = sd.getCardPool(false); + if (aiPool == null) { return; } + + sealed.addAiDeck(new SealedDeckBuilder(aiPool.toFlatList()).buildDeck()); } // Rank the AI decks diff --git a/forge-gui/src/main/java/forge/limited/BoosterDraft.java b/forge-gui/src/main/java/forge/limited/BoosterDraft.java index 12057f0040b..bf263a44a1c 100644 --- a/forge-gui/src/main/java/forge/limited/BoosterDraft.java +++ b/forge-gui/src/main/java/forge/limited/BoosterDraft.java @@ -71,6 +71,95 @@ public final class BoosterDraft implements IBoosterDraft { private final List>> product = new ArrayList>>(); + public static BoosterDraft createDraft(final LimitedPoolType draftType) { + BoosterDraft draft = new BoosterDraft(draftType); + + switch (draftType) { + case Full: // Draft from all cards in Forge + Supplier> s = new UnOpenedProduct(SealedProduct.Template.genericBooster); + + for (int i = 0; i < 3; i++) { + draft.product.add(s); + } + IBoosterDraft.LAND_SET_CODE[0] = CardEdition.Predicates.getRandomSetWithAllBasicLands(Singletons.getMagicDb().getEditions()); + break; + + case Block: // Draft from cards by block or set + case FantasyBlock: + List blocks = new ArrayList(); + IStorage storage = draftType == LimitedPoolType.Block + ? Singletons.getModel().getBlocks() : Singletons.getModel().getFantasyBlocks(); + + for (CardBlock b : storage) { + if (b.getCntBoostersDraft() > 0) { + blocks.add(b); + } + } + + final CardBlock block = GuiChoose.oneOrNone("Choose Block", blocks); + if (block == null) { return null; } + + final CardEdition[] cardSets = block.getSets(); + if (cardSets.length == 0) { + FOptionPane.showErrorDialog(block.toString() + " does not contain any set combinations."); + return null; + } + + final Stack sets = new Stack(); + for (int k = cardSets.length - 1; k >= 0; k--) { + sets.add(cardSets[k].getCode()); + } + + for (String setCode : block.getMetaSetNames()) { + if (block.getMetaSet(setCode).isDraftable()) { + sets.push(setCode); // to the beginning + } + } + + final int nPacks = block.getCntBoostersDraft(); + + if (sets.size() > 1) { + final Object p = GuiChoose.oneOrNone("Choose Set Combination", getSetCombos(sets)); + if (p == null) { return null; } + + final String[] pp = p.toString().split("/"); + for (int i = 0; i < nPacks; i++) { + draft.product.add(block.getBooster(pp[i])); + } + } + else { + IUnOpenedProduct product1 = block.getBooster(sets.get(0)); + + for (int i = 0; i < nPacks; i++) { + draft.product.add(product1); + } + } + + IBoosterDraft.LAND_SET_CODE[0] = block.getLandSet(); + break; + + case Custom: + final List myDrafts = draft.loadCustomDrafts("res/draft/", ".draft"); + + if (myDrafts.isEmpty()) { + FOptionPane.showMessageDialog("No custom draft files found."); + } + else { + final CustomLimited customDraft = GuiChoose.oneOrNone("Choose Custom Draft", myDrafts); + if (customDraft == null) { return null; } + + draft.setupCustomDraft(customDraft); + } + break; + + default: + throw new NoSuchElementException("Draft for mode " + draftType + " has not been set up!"); + } + + draft.pack = draft.get8BoosterPack(); + return draft; + } + /** *

* Constructor for BoosterDraft_1. @@ -79,77 +168,9 @@ public final class BoosterDraft implements IBoosterDraft { * @param draftType * a {@link java.lang.String} object. */ - public BoosterDraft(final LimitedPoolType draftType) { + private BoosterDraft(final LimitedPoolType draftType) { this.draftAI.setBd(this); this.draftFormat = draftType; - - switch (draftType) { - case Full: // Draft from all cards in Forge - Supplier> s = new UnOpenedProduct(SealedProduct.Template.genericBooster); - - for (int i = 0; i < 3; i++) this.product.add(s); - IBoosterDraft.LAND_SET_CODE[0] = CardEdition.Predicates.getRandomSetWithAllBasicLands(Singletons.getMagicDb().getEditions()); - break; - - case Block: case FantasyBlock: // Draft from cards by block or set - - List blocks = new ArrayList(); - IStorage storage = draftType == LimitedPoolType.Block - ? Singletons.getModel().getBlocks() : Singletons.getModel().getFantasyBlocks(); - - for (CardBlock b : storage) { - if( b.getCntBoostersDraft() > 0) - blocks.add(b); - } - - final CardBlock block = GuiChoose.one("Choose Block", blocks); - - final CardEdition[] cardSets = block.getSets(); - final Stack sets = new Stack(); - for (int k = cardSets.length - 1; k >= 0; --k) { - sets.add(cardSets[k].getCode()); - } - - for(String setCode : block.getMetaSetNames() ) { - if ( block.getMetaSet(setCode).isDraftable() ) - sets.push(setCode); // to the beginning - } - - final int nPacks = block.getCntBoostersDraft(); - - if (sets.size() > 1) { - final Object p = GuiChoose.one("Choose Set Combination", getSetCombos(sets)); - final String[] pp = p.toString().split("/"); - for (int i = 0; i < nPacks; i++) { - this.product.add(block.getBooster(pp[i])); - } - } else { - IUnOpenedProduct product1 = block.getBooster(sets.get(0)); - - for (int i = 0; i < nPacks; i++) { - this.product.add(product1); - } - } - - IBoosterDraft.LAND_SET_CODE[0] = block.getLandSet(); - break; - - case Custom: - final List myDrafts = this.loadCustomDrafts("res/draft/", ".draft"); - - if (myDrafts.isEmpty()) { - FOptionPane.showMessageDialog("No custom draft files found."); - } - else { - final CustomLimited draft = GuiChoose.one("Choose Custom Draft", myDrafts); - this.setupCustomDraft(draft); - } - break; - default: - throw new NoSuchElementException("Draft for mode " + draftType + " has not been set up!"); - } - - this.pack = this.get8BoosterPack(); } private void setupCustomDraft(final CustomLimited draft) { @@ -252,11 +273,9 @@ public final class BoosterDraft implements IBoosterDraft { } private void computerChoose() { - final int iHumansBooster = this.getCurrentBoosterIndex(); int iPlayer = 0; for (int i = 1; i < this.pack.size(); i++) { - final List forAi = new ArrayList(); final List booster = this.pack.get((iHumansBooster + i) % this.pack.size()); for (final IPaperCard cr : booster) { @@ -311,13 +330,15 @@ public final class BoosterDraft implements IBoosterDraft { if (cc.equals(c)) { pickValue = thisBooster.size() * (1f - (((float) this.currentBoosterPick / this.currentBoosterSize) * 2f)); - } else { + } + else { pickValue = 0; } if (!this.draftPicks.containsKey(cnBk)) { this.draftPicks.put(cnBk, pickValue); - } else { + } + else { final float curValue = this.draftPicks.get(cnBk); final float newValue = (curValue + pickValue) / 2; this.draftPicks.put(cnBk, newValue); @@ -335,7 +356,7 @@ public final class BoosterDraft implements IBoosterDraft { if (!Preferences.UPLOAD_DRAFT || 1 >= draftPicks.size()) { return; } - + ArrayList outDraftData = new ArrayList(); for (Entry key : draftPicks.entrySet()) { outDraftData.add(key.getValue() + "|" + key.getKey()); @@ -344,7 +365,7 @@ public final class BoosterDraft implements IBoosterDraft { HttpUtil.upload(NewConstants.URL_DRAFT_UPLOAD + "?fmt=" + draftFormat, outDraftData); } - private List getSetCombos(final List setz) { + private static List getSetCombos(final List setz) { String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY); List setCombos = new ArrayList(); if (sets.length >= 2) { diff --git a/forge-gui/src/main/java/forge/limited/SealedCardPoolGenerator.java b/forge-gui/src/main/java/forge/limited/SealedCardPoolGenerator.java index 89cba8c0de0..87cfd2a4034 100644 --- a/forge-gui/src/main/java/forge/limited/SealedCardPoolGenerator.java +++ b/forge-gui/src/main/java/forge/limited/SealedCardPoolGenerator.java @@ -36,7 +36,6 @@ import forge.item.SealedProduct; import forge.model.CardBlock; import forge.model.UnOpenedMeta; import forge.util.FileUtil; -import forge.util.ItemPool; import forge.util.TextUtil; /** @@ -155,7 +154,8 @@ public class SealedCardPoolGenerator { return; } - final CustomLimited draft = GuiChoose.one("Choose Custom Sealed Pool", customs); + final CustomLimited draft = GuiChoose.oneOrNone("Choose Custom Sealed Pool", customs); + if (draft == null) { return; } UnOpenedProduct toAdd = new UnOpenedProduct(draft.getSealedProductTemplate(), draft.getCardPool()); toAdd.setLimitedPool(draft.isSingleton()); @@ -185,7 +185,7 @@ public class SealedCardPoolGenerator { * * @return an ArrayList of the set choices. */ - private ArrayList getSetCombos(final List setz, final int nPacks) { + private static ArrayList getSetCombos(final List setz, final int nPacks) { String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY); ArrayList setCombos = new ArrayList(); @@ -335,12 +335,16 @@ public class SealedCardPoolGenerator { * boolean, get pool for human (possible choices) * @return a {@link forge.CardList} object. */ - public ItemPool getCardpool(final boolean isHuman) { + public CardPool getCardPool(final boolean isHuman) { final CardPool pool = new CardPool(); for (IUnOpenedProduct prod : product) { if (prod instanceof UnOpenedMeta) { - pool.addAllFlat(((UnOpenedMeta) prod).open(isHuman)); + List cards = ((UnOpenedMeta) prod).open(isHuman, true); + if (cards == null) { + return null; //return null if user canceled + } + pool.addAllFlat(cards); } else { pool.addAllFlat(prod.get()); diff --git a/forge-gui/src/main/java/forge/model/UnOpenedMeta.java b/forge-gui/src/main/java/forge/model/UnOpenedMeta.java index 569c5b888a4..43341e24c36 100644 --- a/forge-gui/src/main/java/forge/model/UnOpenedMeta.java +++ b/forge-gui/src/main/java/forge/model/UnOpenedMeta.java @@ -40,7 +40,7 @@ public class UnOpenedMeta implements IUnOpenedProduct { ChooseOne, SelectAll, } - + private final ArrayList metaSets; private final JoinOperation operation; private final Random generator = MyRandom.getRandom(); @@ -56,19 +56,18 @@ public class UnOpenedMeta implements IUnOpenedProduct { metaSets = new ArrayList(); operation = op; - for(String m : TextUtil.splitWithParenthesis(creationString, ';')) { + for (String m : TextUtil.splitWithParenthesis(creationString, ';')) { metaSets.add(new MetaSet(m, true)); } } - /** * Open the booster pack, return contents. * @return List, list of cards. */ @Override public List get() { - return this.open(true); + return this.open(true, false); } /** @@ -79,24 +78,32 @@ public class UnOpenedMeta implements IUnOpenedProduct { * known partialities for the AI. * @return List, list of cards. */ - public List open(final boolean isHuman) { - + public List open(final boolean isHuman, final boolean allowCancel) { if (metaSets.isEmpty()) { throw new RuntimeException("Empty UnOpenedMetaset, cannot generate booster."); } - switch(operation) { + switch (operation) { case ChooseOne: if (isHuman) { - final MetaSet ms = GuiChoose.one("Choose booster:", metaSets); + final MetaSet ms; + if (allowCancel) { + ms = GuiChoose.oneOrNone("Choose Booster", metaSets); + if (ms == null) { + return null; + } + } + else { + ms = GuiChoose.one("Choose Booster", metaSets); + } return ms.getBooster().get(); } - + case RandomOne: // AI should fall though here from the case above int selected = generator.nextInt(metaSets.size()); final IUnOpenedProduct newBooster = metaSets.get(selected).getBooster(); return newBooster.get(); - + case SelectAll: List allCards = new ArrayList(); for (MetaSet ms : metaSets) { @@ -106,7 +113,7 @@ public class UnOpenedMeta implements IUnOpenedProduct { } throw new IllegalStateException("Got wrong operation type in unopenedMeta - execution should never reach this point"); } - + public static UnOpenedMeta choose(String desc) { return new UnOpenedMeta(desc, JoinOperation.ChooseOne); } @@ -116,5 +123,4 @@ public class UnOpenedMeta implements IUnOpenedProduct { public static UnOpenedMeta selectAll(String desc) { return new UnOpenedMeta(desc, JoinOperation.SelectAll); } - } diff --git a/forge-gui/src/test/java/forge/BoosterDraft1Test.java b/forge-gui/src/test/java/forge/BoosterDraft1Test.java index 5e93297561d..d2765a8b056 100644 --- a/forge-gui/src/test/java/forge/BoosterDraft1Test.java +++ b/forge-gui/src/test/java/forge/BoosterDraft1Test.java @@ -20,7 +20,9 @@ public class BoosterDraft1Test { */ @Test(groups = { "UnitTest", "fast" }, timeOut = 1000, enabled = false) public void boosterDraft1Test1() throws Exception { - final BoosterDraft draft = new BoosterDraft(LimitedPoolType.Full); + final BoosterDraft draft = BoosterDraft.createDraft(LimitedPoolType.Full); + if (draft == null) { return; } + while (draft.hasNextChoice()) { final CardPool list = draft.nextChoice(); System.out.println(list.countAll());