mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
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
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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<PaperCard> 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
|
||||
|
||||
@@ -71,6 +71,95 @@ public final class BoosterDraft implements IBoosterDraft {
|
||||
|
||||
private final List<Supplier<List<PaperCard>>> product = new ArrayList<Supplier<List<PaperCard>>>();
|
||||
|
||||
public static BoosterDraft createDraft(final LimitedPoolType draftType) {
|
||||
BoosterDraft draft = new BoosterDraft(draftType);
|
||||
|
||||
switch (draftType) {
|
||||
case Full: // Draft from all cards in Forge
|
||||
Supplier<List<PaperCard>> 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<CardBlock> blocks = new ArrayList<CardBlock>();
|
||||
IStorage<CardBlock> 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<String> sets = new Stack<String>();
|
||||
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<CustomLimited> 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 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<List<PaperCard>> 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<CardBlock> blocks = new ArrayList<CardBlock>();
|
||||
IStorage<CardBlock> 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<String> sets = new Stack<String>();
|
||||
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<CustomLimited> 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<Card> forAi = new ArrayList<Card>();
|
||||
final List<PaperCard> 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<String> outDraftData = new ArrayList<String>();
|
||||
for (Entry<String, Float> 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<String> getSetCombos(final List<String> setz) {
|
||||
private static List<String> getSetCombos(final List<String> setz) {
|
||||
String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
|
||||
List<String> setCombos = new ArrayList<String>();
|
||||
if (sets.length >= 2) {
|
||||
|
||||
@@ -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<String> getSetCombos(final List<String> setz, final int nPacks) {
|
||||
private static ArrayList<String> getSetCombos(final List<String> setz, final int nPacks) {
|
||||
String[] sets = setz.toArray(ArrayUtils.EMPTY_STRING_ARRAY);
|
||||
ArrayList<String> setCombos = new ArrayList<String>();
|
||||
|
||||
@@ -335,12 +335,16 @@ public class SealedCardPoolGenerator {
|
||||
* boolean, get pool for human (possible choices)
|
||||
* @return a {@link forge.CardList} object.
|
||||
*/
|
||||
public ItemPool<PaperCard> 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<PaperCard> cards = ((UnOpenedMeta) prod).open(isHuman, true);
|
||||
if (cards == null) {
|
||||
return null; //return null if user canceled
|
||||
}
|
||||
pool.addAllFlat(cards);
|
||||
}
|
||||
else {
|
||||
pool.addAllFlat(prod.get());
|
||||
|
||||
@@ -40,7 +40,7 @@ public class UnOpenedMeta implements IUnOpenedProduct {
|
||||
ChooseOne,
|
||||
SelectAll,
|
||||
}
|
||||
|
||||
|
||||
private final ArrayList<MetaSet> metaSets;
|
||||
private final JoinOperation operation;
|
||||
private final Random generator = MyRandom.getRandom();
|
||||
@@ -56,19 +56,18 @@ public class UnOpenedMeta implements IUnOpenedProduct {
|
||||
metaSets = new ArrayList<MetaSet>();
|
||||
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<PaperCard> 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<PaperCard> open(final boolean isHuman) {
|
||||
|
||||
public List<PaperCard> 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<PaperCard> allCards = new ArrayList<PaperCard>();
|
||||
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);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user