mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 12:18:00 +00:00
Merge branch 'commanderDeckGenerator' into 'master'
Commander deck generator See merge request core-developers/forge!249
This commit is contained in:
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Forge Team
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.deck.generation;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import forge.card.ColorSet;
|
||||||
|
import forge.card.MagicColor;
|
||||||
|
import forge.deck.CardPool;
|
||||||
|
import forge.deck.DeckFormat;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
import org.apache.commons.lang3.tuple.ImmutablePair;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Generate3ColorDeck class.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Forge
|
||||||
|
* @version $Id$
|
||||||
|
*/
|
||||||
|
public class DeckGenerator4Color extends DeckGeneratorBase {
|
||||||
|
@Override
|
||||||
|
protected final float getLandPercentage() {
|
||||||
|
return 0.44f;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected final float getCreaturePercentage() {
|
||||||
|
return 0.33f;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected final float getSpellPercentage() {
|
||||||
|
return 0.23f;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
final List<ImmutablePair<FilterCMC, Integer>> cmcLevels = Lists.newArrayList(
|
||||||
|
ImmutablePair.of(new FilterCMC(0, 2), 12),
|
||||||
|
ImmutablePair.of(new FilterCMC(3, 5), 9),
|
||||||
|
ImmutablePair.of(new FilterCMC(6, 20), 3)
|
||||||
|
);
|
||||||
|
|
||||||
|
public DeckGenerator4Color(IDeckGenPool pool0, DeckFormat format0, Predicate<PaperCard> formatFilter0, final String clr1, final String clr2, final String clr3, final String clr4) {
|
||||||
|
super(pool0, format0, formatFilter0);
|
||||||
|
initialize(format0,clr1,clr2,clr3,clr4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DeckGenerator4Color(IDeckGenPool pool0, DeckFormat format0, final String clr1, final String clr2, final String clr3, final String clr4) {
|
||||||
|
super(pool0, format0);
|
||||||
|
initialize(format0,clr1,clr2,clr3,clr4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initialize(DeckFormat format0, final String clr1, final String clr2, final String clr3, final String clr4){
|
||||||
|
format0.adjustCMCLevels(cmcLevels);
|
||||||
|
|
||||||
|
int c1 = MagicColor.fromName(clr1);
|
||||||
|
int c2 = MagicColor.fromName(clr2);
|
||||||
|
int c3 = MagicColor.fromName(clr3);
|
||||||
|
int c4 = MagicColor.fromName(clr4);
|
||||||
|
|
||||||
|
int rc = 0;
|
||||||
|
int combo = c1 | c2 | c3 | c4;
|
||||||
|
|
||||||
|
ColorSet param = ColorSet.fromMask(combo);
|
||||||
|
switch(param.countColors()) {
|
||||||
|
case 3:
|
||||||
|
colors = param;
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
int color1 = r.nextInt(5);
|
||||||
|
int color2 = (color1 + 1 + r.nextInt(4)) % 5;
|
||||||
|
colors = ColorSet.fromMask(MagicColor.WHITE << color1 | MagicColor.WHITE << color2).inverse();
|
||||||
|
return;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
do {
|
||||||
|
rc = MagicColor.WHITE << MyRandom.getRandom().nextInt(5);
|
||||||
|
} while ( rc == combo );
|
||||||
|
combo |= rc;
|
||||||
|
|
||||||
|
//$FALL-THROUGH$
|
||||||
|
case 2:
|
||||||
|
do {
|
||||||
|
rc = MagicColor.WHITE << MyRandom.getRandom().nextInt(5);
|
||||||
|
} while ( (rc & combo) != 0 );
|
||||||
|
combo |= rc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
colors = ColorSet.fromMask(combo);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final CardPool getDeck(final int size, final boolean forAi) {
|
||||||
|
addCreaturesAndSpells(size, cmcLevels, forAi);
|
||||||
|
|
||||||
|
// Add lands
|
||||||
|
int numLands = Math.round(size * getLandPercentage());
|
||||||
|
adjustDeckSize(size - numLands);
|
||||||
|
trace.append("numLands:").append(numLands).append("\n");
|
||||||
|
|
||||||
|
// Add dual lands
|
||||||
|
List<String> duals = getDualLandList();
|
||||||
|
for (String s : duals) {
|
||||||
|
this.cardCounts.put(s, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int dblsAdded = addSomeStr((numLands / 4), duals);
|
||||||
|
numLands -= dblsAdded;
|
||||||
|
|
||||||
|
addBasicLand(numLands);
|
||||||
|
adjustDeckSize(size);
|
||||||
|
trace.append("DeckSize:").append(tDeck.countAll()).append("\n");
|
||||||
|
return tDeck;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,8 +25,12 @@ public class DecksComboBox extends FComboBoxWrapper<DeckType> {
|
|||||||
addActionListener(getDeckTypeComboListener());
|
addActionListener(getDeckTypeComboListener());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void refresh(final DeckType deckType) {
|
public void refresh(final DeckType deckType, final boolean isForCommander) {
|
||||||
setModel(new DefaultComboBoxModel<DeckType>(DeckType.ConstructedOptions));
|
if(isForCommander){
|
||||||
|
setModel(new DefaultComboBoxModel<DeckType>(DeckType.CommanderOptions));
|
||||||
|
}else {
|
||||||
|
setModel(new DefaultComboBoxModel<DeckType>(DeckType.ConstructedOptions));
|
||||||
|
}
|
||||||
setSelectedItem(deckType);
|
setSelectedItem(deckType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -43,6 +43,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
private ItemManagerContainer lstDecksContainer;
|
private ItemManagerContainer lstDecksContainer;
|
||||||
private NetDeckCategory netDeckCategory;
|
private NetDeckCategory netDeckCategory;
|
||||||
private boolean refreshingDeckType;
|
private boolean refreshingDeckType;
|
||||||
|
private boolean isForCommander;
|
||||||
|
|
||||||
private final DeckManager lstDecks;
|
private final DeckManager lstDecks;
|
||||||
private final FLabel btnViewDeck = new FLabel.ButtonBuilder().text("View Deck").fontSize(14).build();
|
private final FLabel btnViewDeck = new FLabel.ButtonBuilder().text("View Deck").fontSize(14).build();
|
||||||
@@ -56,7 +57,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
//Show dialog to select a deck
|
//Show dialog to select a deck
|
||||||
public static Deck promptForDeck(final CDetailPicture cDetailPicture, final String title, final DeckType defaultDeckType, final boolean forAi) {
|
public static Deck promptForDeck(final CDetailPicture cDetailPicture, final String title, final DeckType defaultDeckType, final boolean forAi) {
|
||||||
FThreads.assertExecutedByEdt(true);
|
FThreads.assertExecutedByEdt(true);
|
||||||
final FDeckChooser chooser = new FDeckChooser(cDetailPicture, forAi);
|
final FDeckChooser chooser = new FDeckChooser(cDetailPicture, forAi, GameType.Constructed, false);
|
||||||
chooser.initialize(defaultDeckType);
|
chooser.initialize(defaultDeckType);
|
||||||
chooser.populate();
|
chooser.populate();
|
||||||
final Dimension parentSize = JOptionPane.getRootFrame().getSize();
|
final Dimension parentSize = JOptionPane.getRootFrame().getSize();
|
||||||
@@ -78,10 +79,11 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public FDeckChooser(final CDetailPicture cDetailPicture, final boolean forAi) {
|
public FDeckChooser(final CDetailPicture cDetailPicture, final boolean forAi, GameType gameType, boolean forCommander) {
|
||||||
lstDecks = new DeckManager(GameType.Constructed, cDetailPicture);
|
lstDecks = new DeckManager(gameType, cDetailPicture);
|
||||||
setOpaque(false);
|
setOpaque(false);
|
||||||
isAi = forAi;
|
isAi = forAi;
|
||||||
|
isForCommander = forCommander;
|
||||||
final UiCommand cmdViewDeck = new UiCommand() {
|
final UiCommand cmdViewDeck = new UiCommand() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
if (selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK) {
|
if (selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK) {
|
||||||
@@ -129,7 +131,14 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateCustom() {
|
private void updateCustom() {
|
||||||
updateDecks(DeckProxy.getAllConstructedDecks(), ItemManagerConfig.CONSTRUCTED_DECKS);
|
DeckFormat deckFormat = lstDecks.getGameType().getDeckFormat();
|
||||||
|
if(deckFormat.equals(DeckFormat.Commander)){
|
||||||
|
updateDecks(DeckProxy.getAllCommanderDecks(), ItemManagerConfig.COMMANDER_DECKS);
|
||||||
|
}else if(deckFormat.equals(DeckFormat.TinyLeaders)){
|
||||||
|
updateDecks(DeckProxy.getAllTinyLeadersDecks(), ItemManagerConfig.COMMANDER_DECKS);
|
||||||
|
}else {
|
||||||
|
updateDecks(DeckProxy.getAllConstructedDecks(), ItemManagerConfig.CONSTRUCTED_DECKS);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateColors(Predicate<PaperCard> formatFilter) {
|
private void updateColors(Predicate<PaperCard> formatFilter) {
|
||||||
@@ -168,6 +177,49 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
lstDecks.setSelectedIndices(new Integer[]{0});
|
lstDecks.setSelectedIndices(new Integer[]{0});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateRandomCommander() {
|
||||||
|
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander)&&
|
||||||
|
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders)))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lstDecks.setAllowMultipleSelections(false);
|
||||||
|
|
||||||
|
lstDecks.setPool(CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(), isAi, false));
|
||||||
|
lstDecks.setup(ItemManagerConfig.STRING_ONLY);
|
||||||
|
|
||||||
|
btnRandom.setText("Random");
|
||||||
|
btnRandom.setCommand(new UiCommand() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DeckgenUtil.randomSelect(lstDecks);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// default selection = basic two color deck
|
||||||
|
lstDecks.setSelectedIndices(new Integer[]{0});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateRandomCardGenCommander() {
|
||||||
|
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander)&&
|
||||||
|
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders)))){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
lstDecks.setAllowMultipleSelections(false);
|
||||||
|
lstDecks.setPool(CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(), isAi, true));
|
||||||
|
lstDecks.setup(ItemManagerConfig.STRING_ONLY);
|
||||||
|
|
||||||
|
btnRandom.setText("Random");
|
||||||
|
btnRandom.setCommand(new UiCommand() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
DeckgenUtil.randomSelect(lstDecks);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// default selection = basic two color deck
|
||||||
|
lstDecks.setSelectedIndices(new Integer[]{0});
|
||||||
|
}
|
||||||
|
|
||||||
private void updateThemes() {
|
private void updateThemes() {
|
||||||
updateDecks(DeckProxy.getAllThemeDecks(), ItemManagerConfig.STRING_ONLY);
|
updateDecks(DeckProxy.getAllThemeDecks(), ItemManagerConfig.STRING_ONLY);
|
||||||
}
|
}
|
||||||
@@ -192,9 +244,6 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Deck getDeck() {
|
public Deck getDeck() {
|
||||||
/*if(selectedDeckType.equals(DeckType.STANDARD_CARDGEN_DECK)){
|
|
||||||
return DeckgenUtil.buildCardGenDeck(lstDecks.getSelectedItem().getName(),Predicate<PaperCard> formatFilter);
|
|
||||||
}*/
|
|
||||||
final DeckProxy proxy = lstDecks.getSelectedItem();
|
final DeckProxy proxy = lstDecks.getSelectedItem();
|
||||||
if (proxy == null) {
|
if (proxy == null) {
|
||||||
return null;
|
return null;
|
||||||
@@ -250,7 +299,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deckTypeSelected(final DecksComboBoxEvent ev) {
|
public void deckTypeSelected(final DecksComboBoxEvent ev) {
|
||||||
if (ev.getDeckType() == DeckType.NET_DECK && !refreshingDeckType) {
|
if ((ev.getDeckType() == DeckType.NET_DECK || ev.getDeckType() == DeckType.NET_COMMANDER_DECK) && !refreshingDeckType) {
|
||||||
FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks
|
FThreads.invokeInBackgroundThread(new Runnable() { //needed for loading net decks
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
@@ -268,7 +317,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
netDeckCategory = category;
|
netDeckCategory = category;
|
||||||
refreshDecksList(DeckType.NET_DECK, true, ev);
|
refreshDecksList(ev.getDeckType(), true, ev);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -285,7 +334,7 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
|
|
||||||
if (ev == null) {
|
if (ev == null) {
|
||||||
refreshingDeckType = true;
|
refreshingDeckType = true;
|
||||||
decksComboBox.refresh(deckType);
|
decksComboBox.refresh(deckType, isForCommander);
|
||||||
refreshingDeckType = false;
|
refreshingDeckType = false;
|
||||||
}
|
}
|
||||||
lstDecks.setCaption(deckType.toString());
|
lstDecks.setCaption(deckType.toString());
|
||||||
@@ -294,6 +343,9 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
case CUSTOM_DECK:
|
case CUSTOM_DECK:
|
||||||
updateCustom();
|
updateCustom();
|
||||||
break;
|
break;
|
||||||
|
case COMMANDER_DECK:
|
||||||
|
updateCustom();
|
||||||
|
break;
|
||||||
case COLOR_DECK:
|
case COLOR_DECK:
|
||||||
updateColors(null);
|
updateColors(null);
|
||||||
break;
|
break;
|
||||||
@@ -304,10 +356,22 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
updateColors(FModel.getFormats().getModern().getFilterPrinted());
|
updateColors(FModel.getFormats().getModern().getFilterPrinted());
|
||||||
break;
|
break;
|
||||||
case STANDARD_CARDGEN_DECK:
|
case STANDARD_CARDGEN_DECK:
|
||||||
updateMatrix(FModel.getFormats().getStandard());
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
updateMatrix(FModel.getFormats().getStandard());
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case MODERN_CARDGEN_DECK:
|
case MODERN_CARDGEN_DECK:
|
||||||
updateMatrix(FModel.getFormats().getModern());
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
updateMatrix(FModel.getFormats().getModern());
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RANDOM_COMMANDER_DECK:
|
||||||
|
updateRandomCommander();
|
||||||
|
break;
|
||||||
|
case RANDOM_CARDGEN_COMMANDER_DECK:
|
||||||
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
updateRandomCardGenCommander();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case THEME_DECK:
|
case THEME_DECK:
|
||||||
updateThemes();
|
updateThemes();
|
||||||
@@ -324,6 +388,9 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
|
|||||||
case NET_DECK:
|
case NET_DECK:
|
||||||
updateNetDecks();
|
updateNetDecks();
|
||||||
break;
|
break;
|
||||||
|
case NET_COMMANDER_DECK:
|
||||||
|
updateNetDecks();
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break; //other deck types not currently supported here
|
break; //other deck types not currently supported here
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import javax.swing.SwingUtilities;
|
|||||||
|
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
|
||||||
|
import forge.deck.CommanderDeckGenerator;
|
||||||
import forge.deck.DeckProxy;
|
import forge.deck.DeckProxy;
|
||||||
import forge.deck.DeckType;
|
import forge.deck.DeckType;
|
||||||
import forge.deckchooser.DecksComboBoxEvent;
|
import forge.deckchooser.DecksComboBoxEvent;
|
||||||
@@ -23,6 +24,7 @@ public class CLobby {
|
|||||||
private final VLobby view;
|
private final VLobby view;
|
||||||
public CLobby(final VLobby view) {
|
public CLobby(final VLobby view) {
|
||||||
this.view = view;
|
this.view = view;
|
||||||
|
this.view.setForCommander(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDecks(final Iterable<DeckProxy> commanderDecks, FList<Object> deckList, String... initialItems) {
|
private void addDecks(final Iterable<DeckProxy> commanderDecks, FList<Object> deckList, String... initialItems) {
|
||||||
@@ -50,14 +52,10 @@ public class CLobby {
|
|||||||
public void update() {
|
public void update() {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override public final void run() {
|
@Override public final void run() {
|
||||||
final Iterable<DeckProxy> commanderDecks = DeckProxy.getAllCommanderDecks();
|
|
||||||
final Iterable<DeckProxy> tinyLeadersDecks = DeckProxy.getAllTinyLeadersDecks();
|
|
||||||
final Iterable<DeckProxy> schemeDecks = DeckProxy.getAllSchemeDecks();
|
final Iterable<DeckProxy> schemeDecks = DeckProxy.getAllSchemeDecks();
|
||||||
final Iterable<DeckProxy> planarDecks = DeckProxy.getAllPlanarDecks();
|
final Iterable<DeckProxy> planarDecks = DeckProxy.getAllPlanarDecks();
|
||||||
|
|
||||||
for (int i = 0; i < VLobby.MAX_PLAYERS; i++) {
|
for (int i = 0; i < VLobby.MAX_PLAYERS; i++) {
|
||||||
addDecks(commanderDecks, view.getCommanderDeckLists().get(i));
|
|
||||||
addDecks(tinyLeadersDecks, view.getTinyLeadersDeckLists().get(i));
|
|
||||||
addDecks(schemeDecks, view.getSchemeDeckLists().get(i),
|
addDecks(schemeDecks, view.getSchemeDeckLists().get(i),
|
||||||
"Use deck's scheme section (random if unavailable)");
|
"Use deck's scheme section (random if unavailable)");
|
||||||
addDecks(planarDecks, view.getPlanarDeckLists().get(i),
|
addDecks(planarDecks, view.getPlanarDeckLists().get(i),
|
||||||
@@ -76,7 +74,23 @@ public class CLobby {
|
|||||||
final FDeckChooser fdc = view.getDeckChooser(iSlot);
|
final FDeckChooser fdc = view.getDeckChooser(iSlot);
|
||||||
fdc.initialize(FPref.CONSTRUCTED_DECK_STATES[iSlot], defaultDeckTypeForSlot(iSlot));
|
fdc.initialize(FPref.CONSTRUCTED_DECK_STATES[iSlot], defaultDeckTypeForSlot(iSlot));
|
||||||
fdc.populate();
|
fdc.populate();
|
||||||
fdc.getDecksComboBox().addListener(new IDecksComboBoxListener() {
|
/*fdc.getDecksComboBox().addListener(new IDecksComboBoxListener() {
|
||||||
|
@Override public final void deckTypeSelected(final DecksComboBoxEvent ev) {
|
||||||
|
view.focusOnAvatar();
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
final FDeckChooser fdccom = view.getCommanderDeckChooser(iSlot);
|
||||||
|
fdccom.initialize(FPref.COMMANDER_DECK_STATES[iSlot], defaultDeckTypeForCommanderSlot(iSlot));
|
||||||
|
fdccom.populate();
|
||||||
|
fdccom.getDecksComboBox().addListener(new IDecksComboBoxListener() {
|
||||||
|
@Override public final void deckTypeSelected(final DecksComboBoxEvent ev) {
|
||||||
|
view.focusOnAvatar();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final FDeckChooser fdtlcom = view.getTinyLeaderDeckChooser(iSlot);
|
||||||
|
fdtlcom.initialize(FPref.TINY_LEADER_DECK_STATES[iSlot], defaultDeckTypeForTinyLeaderSlot(iSlot));
|
||||||
|
fdtlcom.populate();
|
||||||
|
fdtlcom.getDecksComboBox().addListener(new IDecksComboBoxListener() {
|
||||||
@Override public final void deckTypeSelected(final DecksComboBoxEvent ev) {
|
@Override public final void deckTypeSelected(final DecksComboBoxEvent ev) {
|
||||||
view.focusOnAvatar();
|
view.focusOnAvatar();
|
||||||
}
|
}
|
||||||
@@ -109,4 +123,12 @@ public class CLobby {
|
|||||||
private static DeckType defaultDeckTypeForSlot(final int iSlot) {
|
private static DeckType defaultDeckTypeForSlot(final int iSlot) {
|
||||||
return iSlot == 0 ? DeckType.PRECONSTRUCTED_DECK : DeckType.COLOR_DECK;
|
return iSlot == 0 ? DeckType.PRECONSTRUCTED_DECK : DeckType.COLOR_DECK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DeckType defaultDeckTypeForCommanderSlot(final int iSlot) {
|
||||||
|
return iSlot == 0 ? DeckType.COMMANDER_DECK : DeckType.RANDOM_CARDGEN_COMMANDER_DECK;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DeckType defaultDeckTypeForTinyLeaderSlot(final int iSlot) {
|
||||||
|
return iSlot == 0 ? DeckType.TINY_LEADERS_DECKS : DeckType.RANDOM_CARDGEN_COMMANDER_DECK;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -116,6 +116,8 @@ public class VLobby implements ILobbyView {
|
|||||||
|
|
||||||
private final List<FList<Object>> tinyLeadersDeckLists = new ArrayList<FList<Object>>();
|
private final List<FList<Object>> tinyLeadersDeckLists = new ArrayList<FList<Object>>();
|
||||||
private final List<FPanel> tinyLeadersDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
|
private final List<FPanel> tinyLeadersDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
|
||||||
|
private final List<FDeckChooser> commanderDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
|
||||||
|
private final List<FDeckChooser> tinyLeadersDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
|
||||||
|
|
||||||
private final List<FList<Object>> schemeDeckLists = new ArrayList<FList<Object>>();
|
private final List<FList<Object>> schemeDeckLists = new ArrayList<FList<Object>>();
|
||||||
private final List<FPanel> schemeDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
|
private final List<FPanel> schemeDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
|
||||||
@@ -133,6 +135,16 @@ public class VLobby implements ILobbyView {
|
|||||||
private final Vector<Object> humanListData = new Vector<Object>();
|
private final Vector<Object> humanListData = new Vector<Object>();
|
||||||
private final Vector<Object> aiListData = new Vector<Object>();
|
private final Vector<Object> aiListData = new Vector<Object>();
|
||||||
|
|
||||||
|
public boolean isForCommander() {
|
||||||
|
return isForCommander;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setForCommander(boolean forCommander) {
|
||||||
|
isForCommander = forCommander;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isForCommander = false;
|
||||||
|
|
||||||
// CTR
|
// CTR
|
||||||
public VLobby(final GameLobby lobby) {
|
public VLobby(final GameLobby lobby) {
|
||||||
this.lobby = lobby;
|
this.lobby = lobby;
|
||||||
@@ -202,6 +214,10 @@ public class VLobby implements ILobbyView {
|
|||||||
for (int iPlayer = 0; iPlayer < activePlayersNum; iPlayer++) {
|
for (int iPlayer = 0; iPlayer < activePlayersNum; iPlayer++) {
|
||||||
final FDeckChooser fdc = getDeckChooser(iPlayer);
|
final FDeckChooser fdc = getDeckChooser(iPlayer);
|
||||||
fdc.restoreSavedState();
|
fdc.restoreSavedState();
|
||||||
|
final FDeckChooser fdcom = getCommanderDeckChooser(iPlayer);
|
||||||
|
fdcom.restoreSavedState();
|
||||||
|
final FDeckChooser fdtl = getTinyLeaderDeckChooser(iPlayer);
|
||||||
|
fdtl.restoreSavedState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -226,6 +242,7 @@ public class VLobby implements ILobbyView {
|
|||||||
// visible panels
|
// visible panels
|
||||||
final LobbySlot slot = lobby.getSlot(i);
|
final LobbySlot slot = lobby.getSlot(i);
|
||||||
final FDeckChooser deckChooser = getDeckChooser(i);
|
final FDeckChooser deckChooser = getDeckChooser(i);
|
||||||
|
final FDeckChooser commanderDeckChooser = getCommanderDeckChooser(i);
|
||||||
final PlayerPanel panel;
|
final PlayerPanel panel;
|
||||||
final boolean isNewPanel;
|
final boolean isNewPanel;
|
||||||
if (hasPanel) {
|
if (hasPanel) {
|
||||||
@@ -240,6 +257,7 @@ public class VLobby implements ILobbyView {
|
|||||||
}
|
}
|
||||||
playersScroll.add(panel, constraints);
|
playersScroll.add(panel, constraints);
|
||||||
deckChooser.restoreSavedState();
|
deckChooser.restoreSavedState();
|
||||||
|
commanderDeckChooser.restoreSavedState();
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
changePlayerFocus(0);
|
changePlayerFocus(0);
|
||||||
}
|
}
|
||||||
@@ -331,7 +349,7 @@ public class VLobby implements ILobbyView {
|
|||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
private void buildDeckPanels(final int playerIndex) {
|
private void buildDeckPanels(final int playerIndex) {
|
||||||
// Main deck
|
// Main deck
|
||||||
final FDeckChooser mainChooser = new FDeckChooser(null, false);
|
final FDeckChooser mainChooser = new FDeckChooser(null, false, GameType.Constructed, false);
|
||||||
mainChooser.getLstDecks().setSelectCommand(new UiCommand() {
|
mainChooser.getLstDecks().setSelectCommand(new UiCommand() {
|
||||||
@Override public final void run() {
|
@Override public final void run() {
|
||||||
selectMainDeck(playerIndex);
|
selectMainDeck(playerIndex);
|
||||||
@@ -348,19 +366,36 @@ public class VLobby implements ILobbyView {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Commander deck list
|
// Commander deck list
|
||||||
buildDeckPanel("Commander Deck", playerIndex, commanderDeckLists, commanderDeckPanels, new ListSelectionListener() {
|
/*buildDeckPanel("Commander Deck", playerIndex, commanderDeckLists, commanderDeckPanels, new ListSelectionListener() {
|
||||||
@Override public final void valueChanged(final ListSelectionEvent e) {
|
@Override public final void valueChanged(final ListSelectionEvent e) {
|
||||||
selectCommanderDeck(playerIndex);
|
selectCommanderDeck(playerIndex);
|
||||||
}
|
}
|
||||||
|
});*/
|
||||||
|
final FDeckChooser commanderChooser = new FDeckChooser(null, false, GameType.Commander, true);
|
||||||
|
commanderChooser.getLstDecks().setSelectCommand(new UiCommand() {
|
||||||
|
@Override public final void run() {
|
||||||
|
selectCommanderDeck(playerIndex);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
commanderChooser.initialize();
|
||||||
|
commanderDeckChoosers.add(commanderChooser);
|
||||||
|
|
||||||
|
final FDeckChooser tinyLeaderChooser = new FDeckChooser(null, false, GameType.TinyLeaders, true);
|
||||||
|
tinyLeaderChooser.getLstDecks().setSelectCommand(new UiCommand() {
|
||||||
|
@Override public final void run() {
|
||||||
|
selectTinyLeadersDeck(playerIndex);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tinyLeaderChooser.initialize();
|
||||||
|
tinyLeadersDeckChoosers.add(tinyLeaderChooser);
|
||||||
|
|
||||||
|
|
||||||
// Tiny Leaders deck list
|
/* // Tiny Leaders deck list
|
||||||
buildDeckPanel("Tiny Leaders Deck", playerIndex, tinyLeadersDeckLists, tinyLeadersDeckPanels, new ListSelectionListener() {
|
buildDeckPanel("Tiny Leaders Deck", playerIndex, tinyLeadersDeckLists, tinyLeadersDeckPanels, new ListSelectionListener() {
|
||||||
@Override public final void valueChanged(final ListSelectionEvent e) {
|
@Override public final void valueChanged(final ListSelectionEvent e) {
|
||||||
selectTinyLeadersDeck(playerIndex);
|
selectTinyLeadersDeck(playerIndex);
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
|
||||||
// Planar deck list
|
// Planar deck list
|
||||||
buildDeckPanel("Planar Deck", playerIndex, planarDeckLists, planarDeckPanels, new ListSelectionListener() {
|
buildDeckPanel("Planar Deck", playerIndex, planarDeckLists, planarDeckPanels, new ListSelectionListener() {
|
||||||
@@ -432,6 +467,42 @@ public class VLobby implements ILobbyView {
|
|||||||
mainChooser.saveState();
|
mainChooser.saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void selectCommanderDeck(final int playerIndex) {
|
||||||
|
if (!hasVariant(GameType.Commander)) {
|
||||||
|
// Only these game types use this specific deck panel
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final FDeckChooser mainChooser = getCommanderDeckChooser(playerIndex);
|
||||||
|
final DeckType type = mainChooser.getSelectedDeckType();
|
||||||
|
final Deck deck = mainChooser.getDeck();
|
||||||
|
final Collection<DeckProxy> selectedDecks = mainChooser.getLstDecks().getSelectedItems();
|
||||||
|
if (playerIndex < activePlayersNum && lobby.mayEdit(playerIndex)) {
|
||||||
|
final String text = type.toString() + ": " + Lang.joinHomogenous(selectedDecks, DeckProxy.FN_GET_NAME);
|
||||||
|
playerPanels.get(playerIndex).setCommanderDeckSelectorButtonText(text);
|
||||||
|
fireDeckChangeListener(playerIndex, deck);
|
||||||
|
}
|
||||||
|
mainChooser.saveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void selectTinyLeadersDeck(final int playerIndex) {
|
||||||
|
if (!hasVariant(GameType.TinyLeaders)) {
|
||||||
|
// Only these game types use this specific deck panel
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
final FDeckChooser mainChooser = getTinyLeaderDeckChooser(playerIndex);
|
||||||
|
final DeckType type = mainChooser.getSelectedDeckType();
|
||||||
|
final Deck deck = mainChooser.getDeck();
|
||||||
|
final Collection<DeckProxy> selectedDecks = mainChooser.getLstDecks().getSelectedItems();
|
||||||
|
if (playerIndex < activePlayersNum && lobby.mayEdit(playerIndex)) {
|
||||||
|
final String text = type.toString() + ": " + Lang.joinHomogenous(selectedDecks, DeckProxy.FN_GET_NAME);
|
||||||
|
playerPanels.get(playerIndex).setCommanderDeckSelectorButtonText(text);
|
||||||
|
fireDeckChangeListener(playerIndex, deck);
|
||||||
|
}
|
||||||
|
mainChooser.saveState();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void selectSchemeDeck(final int playerIndex) {
|
private void selectSchemeDeck(final int playerIndex) {
|
||||||
if (playerIndex >= activePlayersNum || !(hasVariant(GameType.Archenemy) || hasVariant(GameType.ArchenemyRumble))) {
|
if (playerIndex >= activePlayersNum || !(hasVariant(GameType.Archenemy) || hasVariant(GameType.ArchenemyRumble))) {
|
||||||
return;
|
return;
|
||||||
@@ -463,36 +534,6 @@ public class VLobby implements ILobbyView {
|
|||||||
getDeckChooser(playerIndex).saveState();
|
getDeckChooser(playerIndex).saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectCommanderDeck(final int playerIndex) {
|
|
||||||
selectCommanderOrTinyLeadersDeck(playerIndex, GameType.Commander, getCommanderDeckLists());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectTinyLeadersDeck(final int playerIndex) {
|
|
||||||
selectCommanderOrTinyLeadersDeck(playerIndex, GameType.TinyLeaders, getTinyLeadersDeckLists());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectCommanderOrTinyLeadersDeck(final int playerIndex, final GameType gameType, final List<FList<Object>> deckLists) {
|
|
||||||
if (playerIndex >= activePlayersNum || !hasVariant(gameType)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final Object selected = deckLists.get(playerIndex).getSelectedValue();
|
|
||||||
Deck deck = null;
|
|
||||||
if (selected instanceof String) {
|
|
||||||
if (selected.equals("Random")) {
|
|
||||||
deck = RandomDeckGenerator.getRandomUserDeck(lobby, playerPanels.get(playerIndex).isAi());
|
|
||||||
}
|
|
||||||
} else if (selected instanceof Deck) {
|
|
||||||
deck = (Deck) selected;
|
|
||||||
}
|
|
||||||
if (deck == null) { //Can be null if player deselects the list selection or chose Generate
|
|
||||||
deck = DeckgenUtil.generateCommanderDeck(isPlayerAI(playerIndex), gameType);
|
|
||||||
}
|
|
||||||
playerPanels.get(playerIndex).setCommanderDeckSelectorButtonText(deck.getName());
|
|
||||||
fireDeckChangeListener(playerIndex, deck);
|
|
||||||
getDeckChooser(playerIndex).saveState();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void selectPlanarDeck(final int playerIndex) {
|
private void selectPlanarDeck(final int playerIndex) {
|
||||||
if (playerIndex >= activePlayersNum || !hasVariant(GameType.Planechase)) {
|
if (playerIndex >= activePlayersNum || !hasVariant(GameType.Planechase)) {
|
||||||
return;
|
return;
|
||||||
@@ -594,10 +635,10 @@ public class VLobby implements ILobbyView {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Commander:
|
case Commander:
|
||||||
decksFrame.add(commanderDeckPanels.get(playerWithFocus), "grow, push");
|
decksFrame.add(commanderDeckChoosers.get(playerWithFocus), "grow, push");
|
||||||
break;
|
break;
|
||||||
case TinyLeaders:
|
case TinyLeaders:
|
||||||
decksFrame.add(tinyLeadersDeckPanels.get(playerWithFocus), "grow, push");
|
decksFrame.add(tinyLeadersDeckChoosers.get(playerWithFocus), "grow, push");
|
||||||
break;
|
break;
|
||||||
case Planechase:
|
case Planechase:
|
||||||
decksFrame.add(planarDeckPanels.get(playerWithFocus), "grow, push");
|
decksFrame.add(planarDeckPanels.get(playerWithFocus), "grow, push");
|
||||||
@@ -642,6 +683,14 @@ public class VLobby implements ILobbyView {
|
|||||||
return deckChoosers.get(playernum);
|
return deckChoosers.get(playernum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final FDeckChooser getCommanderDeckChooser(final int playernum) {
|
||||||
|
return commanderDeckChoosers.get(playernum);
|
||||||
|
}
|
||||||
|
|
||||||
|
public final FDeckChooser getTinyLeaderDeckChooser(final int playernum) {
|
||||||
|
return tinyLeadersDeckChoosers.get(playernum);
|
||||||
|
}
|
||||||
|
|
||||||
GameType getCurrentGameMode() {
|
GameType getCurrentGameMode() {
|
||||||
return lobby.getGameType();
|
return lobby.getGameType();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.screens.home.gauntlet;
|
|||||||
|
|
||||||
import forge.assets.FSkinProp;
|
import forge.assets.FSkinProp;
|
||||||
import forge.deckchooser.FDeckChooser;
|
import forge.deckchooser.FDeckChooser;
|
||||||
|
import forge.game.GameType;
|
||||||
import forge.gauntlet.GauntletIO;
|
import forge.gauntlet.GauntletIO;
|
||||||
import forge.gui.framework.DragCell;
|
import forge.gui.framework.DragCell;
|
||||||
import forge.gui.framework.DragTab;
|
import forge.gui.framework.DragTab;
|
||||||
@@ -40,7 +41,7 @@ public enum VSubmenuGauntletBuild implements IVSubmenu<CSubmenuGauntletBuild> {
|
|||||||
private final JPanel pnlStrut = new JPanel();
|
private final JPanel pnlStrut = new JPanel();
|
||||||
private final JPanel pnlDirections = new JPanel();
|
private final JPanel pnlDirections = new JPanel();
|
||||||
|
|
||||||
private final FDeckChooser lstLeft = new FDeckChooser(null, false);
|
private final FDeckChooser lstLeft = new FDeckChooser(null, false, GameType.Constructed, false);
|
||||||
private final JList<String> lstRight = new FList<String>();
|
private final JList<String> lstRight = new FList<String>();
|
||||||
|
|
||||||
private final FScrollPane scrRight = new FScrollPane(lstRight, true,
|
private final FScrollPane scrRight = new FScrollPane(lstRight, true,
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package forge.screens.home.gauntlet;
|
package forge.screens.home.gauntlet;
|
||||||
|
|
||||||
import forge.deckchooser.FDeckChooser;
|
import forge.deckchooser.FDeckChooser;
|
||||||
|
import forge.game.GameType;
|
||||||
import forge.gui.framework.DragCell;
|
import forge.gui.framework.DragCell;
|
||||||
import forge.gui.framework.DragTab;
|
import forge.gui.framework.DragTab;
|
||||||
import forge.gui.framework.EDocID;
|
import forge.gui.framework.EDocID;
|
||||||
@@ -42,7 +43,7 @@ public enum VSubmenuGauntletContests implements IVSubmenu<CSubmenuGauntletContes
|
|||||||
private final SkinnedPanel pnlLoad = new SkinnedPanel(new MigLayout("insets 0, gap 0, wrap"));
|
private final SkinnedPanel pnlLoad = new SkinnedPanel(new MigLayout("insets 0, gap 0, wrap"));
|
||||||
|
|
||||||
private final ContestGauntletLister gauntletList = new ContestGauntletLister();
|
private final ContestGauntletLister gauntletList = new ContestGauntletLister();
|
||||||
private final FDeckChooser lstDecks = new FDeckChooser(null, false);
|
private final FDeckChooser lstDecks = new FDeckChooser(null, false, GameType.Constructed, false);
|
||||||
|
|
||||||
private final FScrollPane scrLeft = new FScrollPane(gauntletList, false,
|
private final FScrollPane scrLeft = new FScrollPane(gauntletList, false,
|
||||||
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package forge.screens.home.gauntlet;
|
|||||||
|
|
||||||
import forge.deck.DeckType;
|
import forge.deck.DeckType;
|
||||||
import forge.deckchooser.FDeckChooser;
|
import forge.deckchooser.FDeckChooser;
|
||||||
|
import forge.game.GameType;
|
||||||
import forge.gui.framework.DragCell;
|
import forge.gui.framework.DragCell;
|
||||||
import forge.gui.framework.DragTab;
|
import forge.gui.framework.DragTab;
|
||||||
import forge.gui.framework.EDocID;
|
import forge.gui.framework.EDocID;
|
||||||
@@ -59,7 +60,7 @@ public enum VSubmenuGauntletQuick implements IVSubmenu<CSubmenuGauntletQuick> {
|
|||||||
private final JCheckBox boxModernColorDecks = new FCheckBox(DeckType.MODERN_COLOR_DECK.toString());
|
private final JCheckBox boxModernColorDecks = new FCheckBox(DeckType.MODERN_COLOR_DECK.toString());
|
||||||
private final JCheckBox boxThemeDecks = new FCheckBox(DeckType.THEME_DECK.toString());
|
private final JCheckBox boxThemeDecks = new FCheckBox(DeckType.THEME_DECK.toString());
|
||||||
|
|
||||||
private final FDeckChooser lstDecks = new FDeckChooser(null, false);
|
private final FDeckChooser lstDecks = new FDeckChooser(null, false, GameType.Constructed, false);
|
||||||
|
|
||||||
private final FLabel lblOptions = new FLabel.Builder().fontSize(16)
|
private final FLabel lblOptions = new FLabel.Builder().fontSize(16)
|
||||||
.fontStyle(Font.BOLD).text("OPTIONS").fontAlign(SwingConstants.CENTER).build();
|
.fontStyle(Font.BOLD).text("OPTIONS").fontAlign(SwingConstants.CENTER).build();
|
||||||
@@ -85,7 +86,7 @@ public enum VSubmenuGauntletQuick implements IVSubmenu<CSubmenuGauntletQuick> {
|
|||||||
boxThemeDecks.setSelected(true);
|
boxThemeDecks.setSelected(true);
|
||||||
boxColorDecks.setSelected(true);
|
boxColorDecks.setSelected(true);
|
||||||
boxStandardColorDecks.setSelected(true);
|
boxStandardColorDecks.setSelected(true);
|
||||||
if(!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.LOAD_CARD_SCRIPTS_LAZILY)) {
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
boxStandardCardgenDecks.setSelected(true);
|
boxStandardCardgenDecks.setSelected(true);
|
||||||
boxModernCardgenDecks.setSelected(true);
|
boxModernCardgenDecks.setSelected(true);
|
||||||
}else{
|
}else{
|
||||||
@@ -114,7 +115,7 @@ public enum VSubmenuGauntletQuick implements IVSubmenu<CSubmenuGauntletQuick> {
|
|||||||
pnlOptions.add(boxQuestDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
pnlOptions.add(boxQuestDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
||||||
pnlOptions.add(boxThemeDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
pnlOptions.add(boxThemeDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
||||||
pnlOptions.add(boxColorDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
pnlOptions.add(boxColorDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
||||||
if(!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.LOAD_CARD_SCRIPTS_LAZILY)) {
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
pnlOptions.add(boxStandardCardgenDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
pnlOptions.add(boxStandardCardgenDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
||||||
pnlOptions.add(boxModernCardgenDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
pnlOptions.add(boxModernCardgenDecks, "w 96%!, h 30px!, gap 2% 0 0 5px");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ public enum CSubmenuPreferences implements ICDoc {
|
|||||||
lstControls.add(Pair.of(view.getCbEnforceDeckLegality(), FPref.ENFORCE_DECK_LEGALITY));
|
lstControls.add(Pair.of(view.getCbEnforceDeckLegality(), FPref.ENFORCE_DECK_LEGALITY));
|
||||||
lstControls.add(Pair.of(view.getCbCloneImgSource(), FPref.UI_CLONE_MODE_SOURCE));
|
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.getCbRemoveSmall(), FPref.DECKGEN_NOSMALL));
|
||||||
|
lstControls.add(Pair.of(view.getCbCardBased(), FPref.DECKGEN_CARDBASED));
|
||||||
lstControls.add(Pair.of(view.getCbRemoveArtifacts(), FPref.DECKGEN_ARTIFACTS));
|
lstControls.add(Pair.of(view.getCbRemoveArtifacts(), FPref.DECKGEN_ARTIFACTS));
|
||||||
lstControls.add(Pair.of(view.getCbSingletons(), FPref.DECKGEN_SINGLETONS));
|
lstControls.add(Pair.of(view.getCbSingletons(), FPref.DECKGEN_SINGLETONS));
|
||||||
lstControls.add(Pair.of(view.getCbEnableAICheats(), FPref.UI_ENABLE_AI_CHEATS));
|
lstControls.add(Pair.of(view.getCbEnableAICheats(), FPref.UI_ENABLE_AI_CHEATS));
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
|||||||
private final FLabel btnPlayerName = new FLabel.Builder().opaque(true).hoverable(true).text("").build();
|
private final FLabel btnPlayerName = new FLabel.Builder().opaque(true).hoverable(true).text("").build();
|
||||||
|
|
||||||
private final JCheckBox cbRemoveSmall = new OptionsCheckBox("Remove Small Creatures");
|
private final JCheckBox cbRemoveSmall = new OptionsCheckBox("Remove Small Creatures");
|
||||||
|
private final JCheckBox cbCardBased = new OptionsCheckBox("Include Card-based Deck Generation");
|
||||||
private final JCheckBox cbSingletons = new OptionsCheckBox("Singleton Mode");
|
private final JCheckBox cbSingletons = new OptionsCheckBox("Singleton Mode");
|
||||||
private final JCheckBox cbRemoveArtifacts = new OptionsCheckBox("Remove Artifacts");
|
private final JCheckBox cbRemoveArtifacts = new OptionsCheckBox("Remove Artifacts");
|
||||||
private final JCheckBox cbAnte = new OptionsCheckBox("Play for Ante");
|
private final JCheckBox cbAnte = new OptionsCheckBox("Play for Ante");
|
||||||
@@ -211,6 +212,9 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
|||||||
pnlPrefs.add(cbRemoveArtifacts, titleConstraints);
|
pnlPrefs.add(cbRemoveArtifacts, titleConstraints);
|
||||||
pnlPrefs.add(new NoteLabel("Disables artifact cards in generated decks."), descriptionConstraints);
|
pnlPrefs.add(new NoteLabel("Disables artifact cards in generated decks."), descriptionConstraints);
|
||||||
|
|
||||||
|
pnlPrefs.add(cbCardBased, titleConstraints);
|
||||||
|
pnlPrefs.add(new NoteLabel("Builds more synergistic random decks (requires restart)."), descriptionConstraints);
|
||||||
|
|
||||||
// Deck building options
|
// Deck building options
|
||||||
pnlPrefs.add(new SectionLabel("Deck Editor Options"), sectionConstraints);
|
pnlPrefs.add(new SectionLabel("Deck Editor Options"), sectionConstraints);
|
||||||
|
|
||||||
@@ -492,6 +496,11 @@ public enum VSubmenuPreferences implements IVSubmenu<CSubmenuPreferences> {
|
|||||||
return cbRemoveSmall;
|
return cbRemoveSmall;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return {@link javax.swing.JCheckBox} */
|
||||||
|
public final JCheckBox getCbCardBased() {
|
||||||
|
return cbCardBased;
|
||||||
|
}
|
||||||
|
|
||||||
/** @return {@link javax.swing.JCheckBox} */
|
/** @return {@link javax.swing.JCheckBox} */
|
||||||
public final JCheckBox getCbSingletons() {
|
public final JCheckBox getCbSingletons() {
|
||||||
return cbSingletons;
|
return cbSingletons;
|
||||||
|
|||||||
@@ -3,9 +3,12 @@ package forge.view;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
|
||||||
import forge.LobbyPlayer;
|
import forge.LobbyPlayer;
|
||||||
import forge.deck.DeckGroup;
|
import forge.deck.DeckGroup;
|
||||||
|
import forge.game.*;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
import forge.tournament.system.*;
|
import forge.tournament.system.*;
|
||||||
import forge.util.TextUtil;
|
import forge.util.TextUtil;
|
||||||
@@ -15,12 +18,6 @@ import org.apache.commons.lang3.time.StopWatch;
|
|||||||
|
|
||||||
import forge.deck.Deck;
|
import forge.deck.Deck;
|
||||||
import forge.deck.io.DeckSerializer;
|
import forge.deck.io.DeckSerializer;
|
||||||
import forge.game.Game;
|
|
||||||
import forge.game.GameLogEntry;
|
|
||||||
import forge.game.GameRules;
|
|
||||||
import forge.game.GameType;
|
|
||||||
import forge.game.GameLogEntryType;
|
|
||||||
import forge.game.Match;
|
|
||||||
import forge.game.player.RegisteredPlayer;
|
import forge.game.player.RegisteredPlayer;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.player.GamePlayerUtil;
|
import forge.player.GamePlayerUtil;
|
||||||
@@ -161,14 +158,38 @@ public class SimulateMatch {
|
|||||||
System.out.println("\tq - Quiet flag. Output just the game result, not the entire game log.");
|
System.out.println("\tq - Quiet flag. Output just the game result, not the entire game log.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private static void simulateSingleMatch(Match mc, int iGame, boolean outputGamelog) {
|
private static void simulateSingleMatch(Match mc, int iGame, boolean outputGamelog) {
|
||||||
StopWatch sw = new StopWatch();
|
StopWatch sw = new StopWatch();
|
||||||
sw.start();
|
sw.start();
|
||||||
|
|
||||||
Game g1 = mc.createGame();
|
Game g1 = mc.createGame();
|
||||||
// will run match in the same thread
|
// will run match in the same thread
|
||||||
mc.startGame(g1);
|
|
||||||
sw.stop();
|
long startTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
TimeLimitedCodeBlock.runWithTimeout(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
mc.startGame(g1);
|
||||||
|
sw.stop();
|
||||||
|
}
|
||||||
|
}, 120, TimeUnit.SECONDS);
|
||||||
|
}
|
||||||
|
catch (TimeoutException e) {
|
||||||
|
System.out.println("Stopping slow match as draw");
|
||||||
|
g1.setGameOver(GameEndReason.Draw);
|
||||||
|
sw.stop();
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
g1.setGameOver(GameEndReason.Draw);
|
||||||
|
sw.stop();
|
||||||
|
}catch(StackOverflowError e){
|
||||||
|
g1.setGameOver(GameEndReason.Draw);
|
||||||
|
sw.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
List<GameLogEntry> log;
|
List<GameLogEntry> log;
|
||||||
if (outputGamelog) {
|
if (outputGamelog) {
|
||||||
|
|||||||
@@ -0,0 +1,46 @@
|
|||||||
|
package forge.view;
|
||||||
|
|
||||||
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by maustin on 08/02/2018.
|
||||||
|
*/
|
||||||
|
public class TimeLimitedCodeBlock {
|
||||||
|
|
||||||
|
public static void runWithTimeout(final Runnable runnable, long timeout, TimeUnit timeUnit) throws Exception {
|
||||||
|
runWithTimeout(new Callable<Object>() {
|
||||||
|
@Override
|
||||||
|
public Object call() throws Exception {
|
||||||
|
runnable.run();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}, timeout, timeUnit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> T runWithTimeout(Callable<T> callable, long timeout, TimeUnit timeUnit) throws Exception {
|
||||||
|
final ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||||
|
final Future<T> future = executor.submit(callable);
|
||||||
|
executor.shutdown(); // This does not cancel the already-scheduled task.
|
||||||
|
try {
|
||||||
|
return future.get(timeout, timeUnit);
|
||||||
|
}
|
||||||
|
catch (TimeoutException e) {
|
||||||
|
//remove this if you do not want to cancel the job in progress
|
||||||
|
//or set the argument to 'false' if you do not want to interrupt the thread
|
||||||
|
future.cancel(true);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
catch (ExecutionException e) {
|
||||||
|
//unwrap the root cause
|
||||||
|
Throwable t = e.getCause();
|
||||||
|
if (t instanceof Error) {
|
||||||
|
throw (Error) t;
|
||||||
|
} else if (t instanceof Exception) {
|
||||||
|
throw (Exception) t;
|
||||||
|
} else {
|
||||||
|
throw new IllegalStateException(t);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,6 +10,10 @@ import com.badlogic.gdx.math.Rectangle;
|
|||||||
import forge.Forge;
|
import forge.Forge;
|
||||||
import forge.Graphics;
|
import forge.Graphics;
|
||||||
import forge.assets.FSkinImage;
|
import forge.assets.FSkinImage;
|
||||||
|
import forge.deck.CardThemedDeckGenerator;
|
||||||
|
import forge.deck.CommanderDeckGenerator;
|
||||||
|
import forge.deck.DeckProxy;
|
||||||
|
import forge.deck.FDeckViewer;
|
||||||
import forge.game.GameView;
|
import forge.game.GameView;
|
||||||
import forge.game.card.CardView;
|
import forge.game.card.CardView;
|
||||||
import forge.item.IPaperCard;
|
import forge.item.IPaperCard;
|
||||||
@@ -123,6 +127,17 @@ public class CardZoom extends FOverlay {
|
|||||||
if (item instanceof CardView) {
|
if (item instanceof CardView) {
|
||||||
return (CardView)item;
|
return (CardView)item;
|
||||||
}
|
}
|
||||||
|
if (item instanceof DeckProxy) {
|
||||||
|
if (item instanceof CardThemedDeckGenerator){
|
||||||
|
return CardView.getCardForUi(((CardThemedDeckGenerator)item).getPaperCard());
|
||||||
|
}else if (item instanceof CommanderDeckGenerator){
|
||||||
|
return CardView.getCardForUi(((CommanderDeckGenerator)item).getPaperCard());
|
||||||
|
}else{
|
||||||
|
DeckProxy deck = ((DeckProxy)item);
|
||||||
|
return new CardView(-1, null, deck.getName(), null, deck.getImageKey(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
if (item instanceof IPaperCard) {
|
if (item instanceof IPaperCard) {
|
||||||
return CardView.getCardForUi((IPaperCard)item);
|
return CardView.getCardForUi((IPaperCard)item);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,8 @@ public class FDeckChooser extends FScreen {
|
|||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
if (selectedDeckType != DeckType.STANDARD_COLOR_DECK && selectedDeckType != DeckType.STANDARD_CARDGEN_DECK
|
if (selectedDeckType != DeckType.STANDARD_COLOR_DECK && selectedDeckType != DeckType.STANDARD_CARDGEN_DECK
|
||||||
&& selectedDeckType != DeckType.MODERN_CARDGEN_DECK && selectedDeckType != DeckType.MODERN_COLOR_DECK &&
|
&& selectedDeckType != DeckType.MODERN_CARDGEN_DECK && selectedDeckType != DeckType.MODERN_COLOR_DECK &&
|
||||||
selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK) {
|
selectedDeckType != DeckType.COLOR_DECK && selectedDeckType != DeckType.THEME_DECK
|
||||||
|
&& selectedDeckType != DeckType.RANDOM_COMMANDER_DECK && selectedDeckType != DeckType.RANDOM_CARDGEN_COMMANDER_DECK) {
|
||||||
FDeckViewer.show(getDeck());
|
FDeckViewer.show(getDeck());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -269,6 +270,8 @@ public class FDeckChooser extends FScreen {
|
|||||||
case COLOR_DECK:
|
case COLOR_DECK:
|
||||||
case STANDARD_COLOR_DECK:
|
case STANDARD_COLOR_DECK:
|
||||||
case STANDARD_CARDGEN_DECK:
|
case STANDARD_CARDGEN_DECK:
|
||||||
|
case RANDOM_CARDGEN_COMMANDER_DECK:
|
||||||
|
case RANDOM_COMMANDER_DECK:
|
||||||
case MODERN_CARDGEN_DECK:
|
case MODERN_CARDGEN_DECK:
|
||||||
case MODERN_COLOR_DECK:
|
case MODERN_COLOR_DECK:
|
||||||
case THEME_DECK:
|
case THEME_DECK:
|
||||||
@@ -440,7 +443,7 @@ public class FDeckChooser extends FScreen {
|
|||||||
cmbDeckTypes.addItem(DeckType.QUEST_OPPONENT_DECK);
|
cmbDeckTypes.addItem(DeckType.QUEST_OPPONENT_DECK);
|
||||||
cmbDeckTypes.addItem(DeckType.COLOR_DECK);
|
cmbDeckTypes.addItem(DeckType.COLOR_DECK);
|
||||||
cmbDeckTypes.addItem(DeckType.STANDARD_COLOR_DECK);
|
cmbDeckTypes.addItem(DeckType.STANDARD_COLOR_DECK);
|
||||||
if(!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.LOAD_CARD_SCRIPTS_LAZILY)) {
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
cmbDeckTypes.addItem(DeckType.STANDARD_CARDGEN_DECK);
|
cmbDeckTypes.addItem(DeckType.STANDARD_CARDGEN_DECK);
|
||||||
cmbDeckTypes.addItem(DeckType.MODERN_CARDGEN_DECK);
|
cmbDeckTypes.addItem(DeckType.MODERN_CARDGEN_DECK);
|
||||||
}
|
}
|
||||||
@@ -453,6 +456,10 @@ public class FDeckChooser extends FScreen {
|
|||||||
case TinyLeaders:
|
case TinyLeaders:
|
||||||
cmbDeckTypes.addItem(DeckType.CUSTOM_DECK);
|
cmbDeckTypes.addItem(DeckType.CUSTOM_DECK);
|
||||||
cmbDeckTypes.addItem(DeckType.RANDOM_DECK);
|
cmbDeckTypes.addItem(DeckType.RANDOM_DECK);
|
||||||
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
cmbDeckTypes.addItem(DeckType.RANDOM_CARDGEN_COMMANDER_DECK);
|
||||||
|
}
|
||||||
|
cmbDeckTypes.addItem(DeckType.RANDOM_COMMANDER_DECK);
|
||||||
cmbDeckTypes.addItem(DeckType.NET_DECK);
|
cmbDeckTypes.addItem(DeckType.NET_DECK);
|
||||||
break;
|
break;
|
||||||
case DeckManager:
|
case DeckManager:
|
||||||
@@ -575,6 +582,17 @@ public class FDeckChooser extends FScreen {
|
|||||||
pool = DeckProxy.getAllTinyLeadersDecks();
|
pool = DeckProxy.getAllTinyLeadersDecks();
|
||||||
config = ItemManagerConfig.COMMANDER_DECKS;
|
config = ItemManagerConfig.COMMANDER_DECKS;
|
||||||
break;
|
break;
|
||||||
|
case RANDOM_COMMANDER_DECK:
|
||||||
|
pool = CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(),isAi, false);
|
||||||
|
config = ItemManagerConfig.STRING_ONLY;
|
||||||
|
break;
|
||||||
|
case RANDOM_CARDGEN_COMMANDER_DECK:
|
||||||
|
pool= new ArrayList<>();
|
||||||
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
pool = CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(), isAi, true);
|
||||||
|
}
|
||||||
|
config = ItemManagerConfig.STRING_ONLY;
|
||||||
|
break;
|
||||||
case SCHEME_DECKS:
|
case SCHEME_DECKS:
|
||||||
pool = DeckProxy.getAllSchemeDecks();
|
pool = DeckProxy.getAllSchemeDecks();
|
||||||
config = ItemManagerConfig.SCHEME_DECKS;
|
config = ItemManagerConfig.SCHEME_DECKS;
|
||||||
@@ -603,12 +621,18 @@ public class FDeckChooser extends FScreen {
|
|||||||
break;
|
break;
|
||||||
case STANDARD_CARDGEN_DECK:
|
case STANDARD_CARDGEN_DECK:
|
||||||
maxSelections = 1;
|
maxSelections = 1;
|
||||||
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi);
|
pool= new ArrayList<>();
|
||||||
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getStandard(), isAi);
|
||||||
|
}
|
||||||
config = ItemManagerConfig.STRING_ONLY;
|
config = ItemManagerConfig.STRING_ONLY;
|
||||||
break;
|
break;
|
||||||
case MODERN_CARDGEN_DECK:
|
case MODERN_CARDGEN_DECK:
|
||||||
maxSelections = 1;
|
maxSelections = 1;
|
||||||
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi);
|
pool= new ArrayList<>();
|
||||||
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
pool = CardThemedDeckGenerator.getMatrixDecks(FModel.getFormats().getModern(), isAi);
|
||||||
|
}
|
||||||
config = ItemManagerConfig.STRING_ONLY;
|
config = ItemManagerConfig.STRING_ONLY;
|
||||||
break;
|
break;
|
||||||
case MODERN_COLOR_DECK:
|
case MODERN_COLOR_DECK:
|
||||||
@@ -940,7 +964,7 @@ public class FDeckChooser extends FScreen {
|
|||||||
public void run(final Integer numOpponents) {
|
public void run(final Integer numOpponents) {
|
||||||
if (numOpponents == null) { return; }
|
if (numOpponents == null) { return; }
|
||||||
List<DeckType> deckTypes=null;
|
List<DeckType> deckTypes=null;
|
||||||
if(!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.LOAD_CARD_SCRIPTS_LAZILY)) {
|
if(FModel.isdeckGenMatrixLoaded()) {
|
||||||
deckTypes=Arrays.asList(new DeckType[] {
|
deckTypes=Arrays.asList(new DeckType[] {
|
||||||
DeckType.CUSTOM_DECK,
|
DeckType.CUSTOM_DECK,
|
||||||
DeckType.PRECONSTRUCTED_DECK,
|
DeckType.PRECONSTRUCTED_DECK,
|
||||||
|
|||||||
@@ -5,9 +5,6 @@ import forge.assets.FImage;
|
|||||||
import forge.assets.FSkin;
|
import forge.assets.FSkin;
|
||||||
import forge.assets.FSkinImage;
|
import forge.assets.FSkinImage;
|
||||||
import forge.assets.FTextureRegionImage;
|
import forge.assets.FTextureRegionImage;
|
||||||
import forge.deck.CardPool;
|
|
||||||
import forge.deck.Deck;
|
|
||||||
import forge.deck.DeckSection;
|
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.itemmanager.CardManager;
|
import forge.itemmanager.CardManager;
|
||||||
import forge.itemmanager.ItemManagerConfig;
|
import forge.itemmanager.ItemManagerConfig;
|
||||||
|
|||||||
@@ -983,6 +983,9 @@ public abstract class ItemManager<T extends InventoryItem> extends FContainer im
|
|||||||
if (cbxSortOptions != null) {
|
if (cbxSortOptions != null) {
|
||||||
return cbxSortOptions.getWidth();
|
return cbxSortOptions.getWidth();
|
||||||
}
|
}
|
||||||
|
if(filters.isEmpty()){
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
return filters.get(filters.size() - 1).getWidget().getWidth();
|
return filters.get(filters.size() - 1).getWidget().getWidth();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,10 @@ import forge.assets.ImageCache;
|
|||||||
import forge.card.CardRenderer;
|
import forge.card.CardRenderer;
|
||||||
import forge.card.CardRenderer.CardStackPosition;
|
import forge.card.CardRenderer.CardStackPosition;
|
||||||
import forge.card.CardZoom;
|
import forge.card.CardZoom;
|
||||||
|
import forge.deck.CardThemedDeckGenerator;
|
||||||
|
import forge.deck.CommanderDeckGenerator;
|
||||||
import forge.deck.DeckProxy;
|
import forge.deck.DeckProxy;
|
||||||
|
import forge.deck.FDeckViewer;
|
||||||
import forge.item.InventoryItem;
|
import forge.item.InventoryItem;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.itemmanager.ColumnDef;
|
import forge.itemmanager.ColumnDef;
|
||||||
@@ -861,6 +864,10 @@ public class ImageView<T extends InventoryItem> extends ItemView<T> {
|
|||||||
public boolean longPress(float x, float y) {
|
public boolean longPress(float x, float y) {
|
||||||
ItemInfo item = getItemAtPoint(x + getLeft(), y + getTop());
|
ItemInfo item = getItemAtPoint(x + getLeft(), y + getTop());
|
||||||
if (item != null) {
|
if (item != null) {
|
||||||
|
if(item.getKey() instanceof CardThemedDeckGenerator || item.getKey() instanceof CommanderDeckGenerator){
|
||||||
|
FDeckViewer.show(((DeckProxy)item.getKey()).getDeck());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
CardZoom.show(orderedItems, orderedItems.indexOf(item), itemManager);
|
CardZoom.show(orderedItems, orderedItems.indexOf(item), itemManager);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,8 +149,8 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
|
|||||||
FThreads.invokeInBackgroundThread(new Runnable() {
|
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
playerPanels.get(0).initialize(FPref.CONSTRUCTED_P1_DECK_STATE, DeckType.PRECONSTRUCTED_DECK);
|
playerPanels.get(0).initialize(FPref.CONSTRUCTED_P1_DECK_STATE, FPref.COMMANDER_P1_DECK_STATE, FPref.TINY_LEADER_P1_DECK_STATE, DeckType.PRECONSTRUCTED_DECK);
|
||||||
playerPanels.get(1).initialize(FPref.CONSTRUCTED_P2_DECK_STATE, DeckType.COLOR_DECK);
|
playerPanels.get(1).initialize(FPref.CONSTRUCTED_P2_DECK_STATE, FPref.COMMANDER_P2_DECK_STATE, FPref.TINY_LEADER_P2_DECK_STATE, DeckType.COLOR_DECK);
|
||||||
/*playerPanels.get(2).initialize(FPref.CONSTRUCTED_P3_DECK_STATE, DeckType.COLOR_DECK);
|
/*playerPanels.get(2).initialize(FPref.CONSTRUCTED_P3_DECK_STATE, DeckType.COLOR_DECK);
|
||||||
playerPanels.get(3).initialize(FPref.CONSTRUCTED_P4_DECK_STATE, DeckType.COLOR_DECK);
|
playerPanels.get(3).initialize(FPref.CONSTRUCTED_P4_DECK_STATE, DeckType.COLOR_DECK);
|
||||||
playerPanels.get(4).initialize(FPref.CONSTRUCTED_P5_DECK_STATE, DeckType.COLOR_DECK);
|
playerPanels.get(4).initialize(FPref.CONSTRUCTED_P5_DECK_STATE, DeckType.COLOR_DECK);
|
||||||
@@ -475,12 +475,15 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
|
|||||||
Deck deck;
|
Deck deck;
|
||||||
if (hasVariant(GameType.Commander)) {
|
if (hasVariant(GameType.Commander)) {
|
||||||
deck = playerPanel.getCommanderDeck();
|
deck = playerPanel.getCommanderDeck();
|
||||||
|
playerPanel.getCommanderDeckChooser().saveState();
|
||||||
}
|
}
|
||||||
else if (hasVariant(GameType.TinyLeaders)) {
|
else if (hasVariant(GameType.TinyLeaders)) {
|
||||||
deck = playerPanel.getTinyLeadersDeck();
|
deck = playerPanel.getTinyLeadersDeck();
|
||||||
|
playerPanel.getTinyLeadersDeckChooser().saveState();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
deck = playerPanel.getDeck();
|
deck = playerPanel.getDeck();
|
||||||
|
playerPanel.getDeckChooser().saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Deck playerDeck = deck;
|
Deck playerDeck = deck;
|
||||||
@@ -505,8 +508,6 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
|
|||||||
playerDeck.putSection(DeckSection.Avatar, avatarPool);
|
playerDeck.putSection(DeckSection.Avatar, avatarPool);
|
||||||
}
|
}
|
||||||
|
|
||||||
playerPanel.getDeckChooser().saveState();
|
|
||||||
|
|
||||||
decks[playerIndex] = playerDeck;
|
decks[playerIndex] = playerDeck;
|
||||||
if (playerChangeListener != null) {
|
if (playerChangeListener != null) {
|
||||||
playerChangeListener.update(playerIndex, UpdateLobbyPlayerEvent.deckUpdate(playerDeck));
|
playerChangeListener.update(playerIndex, UpdateLobbyPlayerEvent.deckUpdate(playerDeck));
|
||||||
|
|||||||
@@ -109,25 +109,43 @@ public class PlayerPanel extends FContainer {
|
|||||||
lstCommanderDecks = new FDeckChooser(GameType.Commander, isAi, new FEventHandler() {
|
lstCommanderDecks = new FDeckChooser(GameType.Commander, isAi, new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
btnCommanderDeck.setText("Commander Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName());
|
if( ((DeckManager)e.getSource()).getSelectedItem() != null) {
|
||||||
|
btnCommanderDeck.setText("Commander Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName());
|
||||||
|
lstCommanderDecks.saveState();
|
||||||
|
}else{
|
||||||
|
btnCommanderDeck.setText("Commander Deck");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lstTinyLeadersDecks = new FDeckChooser(GameType.TinyLeaders, isAi, new FEventHandler() {
|
lstTinyLeadersDecks = new FDeckChooser(GameType.TinyLeaders, isAi, new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
btnTinyLeadersDeck.setText("Tiny Leaders Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName());
|
if( ((DeckManager)e.getSource()).getSelectedItem() != null) {
|
||||||
|
btnTinyLeadersDeck.setText("Tiny Leaders Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName());
|
||||||
|
lstTinyLeadersDecks.saveState();
|
||||||
|
}else{
|
||||||
|
btnTinyLeadersDeck.setText("Tiny Leaders Deck");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lstSchemeDecks = new FDeckChooser(GameType.Archenemy, isAi, new FEventHandler() {
|
lstSchemeDecks = new FDeckChooser(GameType.Archenemy, isAi, new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
btnSchemeDeck.setText("Scheme Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName());
|
if( ((DeckManager)e.getSource()).getSelectedItem() != null){
|
||||||
|
btnSchemeDeck.setText("Scheme Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName());
|
||||||
|
}else{
|
||||||
|
btnSchemeDeck.setText("Scheme Deck");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lstPlanarDecks = new FDeckChooser(GameType.Planechase, isAi, new FEventHandler() {
|
lstPlanarDecks = new FDeckChooser(GameType.Planechase, isAi, new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
btnPlanarDeck.setText("Planar Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName());
|
if( ((DeckManager)e.getSource()).getSelectedItem() != null){
|
||||||
|
btnPlanarDeck.setText("Planar Deck: " + ((DeckManager)e.getSource()).getSelectedItem().getName());
|
||||||
|
}else{
|
||||||
|
btnPlanarDeck.setText("Planar Deck");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lstVanguardAvatars = new FVanguardChooser(isAi, new FEventHandler() {
|
lstVanguardAvatars = new FVanguardChooser(isAi, new FEventHandler() {
|
||||||
@@ -217,10 +235,10 @@ public class PlayerPanel extends FContainer {
|
|||||||
cbTeam.setEnabled(false);
|
cbTeam.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initialize(FPref savedStateSetting, DeckType defaultDeckType) {
|
public void initialize(FPref savedStateSetting, FPref savedStateSettingCommander, FPref savedStateSettingTinyLeader, DeckType defaultDeckType) {
|
||||||
deckChooser.initialize(savedStateSetting, defaultDeckType);
|
deckChooser.initialize(savedStateSetting, defaultDeckType);
|
||||||
lstCommanderDecks.initialize(null, DeckType.RANDOM_DECK);
|
lstCommanderDecks.initialize(savedStateSettingCommander, DeckType.COMMANDER_DECK);
|
||||||
lstTinyLeadersDecks.initialize(null, DeckType.RANDOM_DECK);
|
lstTinyLeadersDecks.initialize(savedStateSettingTinyLeader, DeckType.TINY_LEADERS_DECKS);
|
||||||
lstPlanarDecks.initialize(null, DeckType.RANDOM_DECK);
|
lstPlanarDecks.initialize(null, DeckType.RANDOM_DECK);
|
||||||
lstSchemeDecks.initialize(null, DeckType.RANDOM_DECK);
|
lstSchemeDecks.initialize(null, DeckType.RANDOM_DECK);
|
||||||
}
|
}
|
||||||
@@ -666,6 +684,15 @@ public class PlayerPanel extends FContainer {
|
|||||||
return deckChooser;
|
return deckChooser;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FDeckChooser getCommanderDeckChooser() {
|
||||||
|
return lstCommanderDecks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FDeckChooser getTinyLeadersDeckChooser() {
|
||||||
|
return lstTinyLeadersDecks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public Deck getDeck() {
|
public Deck getDeck() {
|
||||||
return deckChooser.getDeck();
|
return deckChooser.getDeck();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class NewGauntletScreen extends LaunchScreen {
|
|||||||
if (numOpponents == null) { return; }
|
if (numOpponents == null) { return; }
|
||||||
|
|
||||||
ListChooser<DeckType> chooser = new ListChooser<DeckType>(
|
ListChooser<DeckType> chooser = new ListChooser<DeckType>(
|
||||||
"Choose allowed deck types for opponents", 0, 7, Arrays.asList(new DeckType[] {
|
"Choose allowed deck types for opponents", 0, 9, Arrays.asList(new DeckType[] {
|
||||||
DeckType.CUSTOM_DECK,
|
DeckType.CUSTOM_DECK,
|
||||||
DeckType.PRECONSTRUCTED_DECK,
|
DeckType.PRECONSTRUCTED_DECK,
|
||||||
DeckType.QUEST_OPPONENT_DECK,
|
DeckType.QUEST_OPPONENT_DECK,
|
||||||
|
|||||||
@@ -155,6 +155,10 @@ public class SettingsPage extends TabPage<SettingsScreen> {
|
|||||||
"Remove Small Creatures",
|
"Remove Small Creatures",
|
||||||
"Disables 1/1 and 0/X creatures in generated decks."),
|
"Disables 1/1 and 0/X creatures in generated decks."),
|
||||||
2);
|
2);
|
||||||
|
lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_CARDBASED,
|
||||||
|
"Include Card-based Deck Generation",
|
||||||
|
"Builds more synergistic random decks"),
|
||||||
|
2);
|
||||||
lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_SINGLETONS,
|
lstSettings.addItem(new BooleanSetting(FPref.DECKGEN_SINGLETONS,
|
||||||
"Singleton Mode",
|
"Singleton Mode",
|
||||||
"Disables non-land duplicates in generated decks."),
|
"Disables non-land duplicates in generated decks."),
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
This file is automatically updated by our release bot on Discord, Blacksmith. It is created from the files present in the 'release-files' directory. Please do not hand-edit this file if using the bot to perform a release, as your changes will be overwritten.
|
This file is automatically updated by our release bot on Discord, Blacksmith. It is created from the files present in the 'release-files' directory. Please do not hand-edit this file if using the bot to perform a release, as your changes will be overwritten.
|
||||||
|
|||||||
BIN
forge-gui/res/deckgendecks/Commander.dat
Normal file
BIN
forge-gui/res/deckgendecks/Commander.dat
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,9 +1,12 @@
|
|||||||
package forge.deck;
|
package forge.deck;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
import com.google.common.base.Predicates;
|
import com.google.common.base.Predicates;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import forge.card.CardRules;
|
||||||
import forge.card.CardRulesPredicates;
|
import forge.card.CardRulesPredicates;
|
||||||
|
import forge.deck.generation.DeckGeneratorBase;
|
||||||
import forge.deck.io.CardThemedMatrixIO;
|
import forge.deck.io.CardThemedMatrixIO;
|
||||||
import forge.deck.io.DeckStorage;
|
import forge.deck.io.DeckStorage;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
@@ -22,27 +25,42 @@ import java.util.*;
|
|||||||
*/
|
*/
|
||||||
public final class CardRelationMatrixGenerator {
|
public final class CardRelationMatrixGenerator {
|
||||||
|
|
||||||
public static HashMap<GameFormat,HashMap<String,List<Map.Entry<PaperCard,Integer>>>> cardPools = new HashMap<>();
|
public static HashMap<String,HashMap<String,List<Map.Entry<PaperCard,Integer>>>> cardPools = new HashMap<>();
|
||||||
|
|
||||||
|
public static boolean initialize(){
|
||||||
|
List<String> formatStrings = new ArrayList<>();
|
||||||
|
formatStrings.add(FModel.getFormats().getStandard().getName());
|
||||||
|
formatStrings.add(FModel.getFormats().getModern().getName());
|
||||||
|
formatStrings.add(DeckFormat.Commander.toString());
|
||||||
|
|
||||||
public static void initialize(){
|
for (String formatString : formatStrings){
|
||||||
HashMap<String,List<Map.Entry<PaperCard,Integer>>> standardMap = CardThemedMatrixIO.loadMatrix(FModel.getFormats().getStandard());
|
if(!initializeFormat(formatString)){
|
||||||
HashMap<String,List<Map.Entry<PaperCard,Integer>>> modernMap = CardThemedMatrixIO.loadMatrix(FModel.getFormats().getModern());
|
return false;
|
||||||
if(standardMap==null || modernMap==null){
|
}
|
||||||
reInitialize();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
cardPools.put(FModel.getFormats().getStandard(),standardMap);
|
|
||||||
cardPools.put(FModel.getFormats().getModern(),modernMap);
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void reInitialize(){
|
/** Try to load matrix .dat files, otherwise check for deck folders and build .dat, otherwise return false **/
|
||||||
cardPools.put(FModel.getFormats().getStandard(),initializeFormat(FModel.getFormats().getStandard()));
|
public static boolean initializeFormat(String format){
|
||||||
cardPools.put(FModel.getFormats().getModern(),initializeFormat(FModel.getFormats().getModern()));
|
HashMap<String,List<Map.Entry<PaperCard,Integer>>> formatMap = CardThemedMatrixIO.loadMatrix(format);
|
||||||
for(GameFormat format:cardPools.keySet()){
|
if(formatMap==null) {
|
||||||
HashMap<String,List<Map.Entry<PaperCard,Integer>>> map = cardPools.get(format);
|
if (CardThemedMatrixIO.getMatrixFolder(format).exists()) {
|
||||||
CardThemedMatrixIO.saveMatrix(format,map);
|
if(format.equals(FModel.getFormats().getStandard().getName())){
|
||||||
|
formatMap=initializeFormat(FModel.getFormats().getStandard());
|
||||||
|
}else if(format.equals(FModel.getFormats().getModern().getName())){
|
||||||
|
formatMap=initializeFormat(FModel.getFormats().getModern());
|
||||||
|
}else{
|
||||||
|
formatMap=initializeCommanderFormat();
|
||||||
|
}
|
||||||
|
CardThemedMatrixIO.saveMatrix(format, formatMap);
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
cardPools.put(format, formatMap);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeFormat(GameFormat format){
|
public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeFormat(GameFormat format){
|
||||||
@@ -58,8 +76,8 @@ public final class CardRelationMatrixGenerator {
|
|||||||
Map<String, Integer> cardIntegerMap = new HashMap<>();
|
Map<String, Integer> cardIntegerMap = new HashMap<>();
|
||||||
Map<Integer, PaperCard> integerCardMap = new HashMap<>();
|
Map<Integer, PaperCard> integerCardMap = new HashMap<>();
|
||||||
for (int i=0; i<cardList.size(); ++i){
|
for (int i=0; i<cardList.size(); ++i){
|
||||||
cardIntegerMap.put(cardList.get(i).getName(),i);
|
cardIntegerMap.put(cardList.get(i).getName(), i);
|
||||||
integerCardMap.put(i,cardList.get(i));
|
integerCardMap.put(i, cardList.get(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
int[][] matrix = new int[cardList.size()][cardList.size()];
|
int[][] matrix = new int[cardList.size()][cardList.size()];
|
||||||
@@ -71,7 +89,6 @@ public final class CardRelationMatrixGenerator {
|
|||||||
Predicates.compose(Predicates.not(CardRulesPredicates.Presets.IS_BASIC_LAND_NOT_WASTES), PaperCard.FN_GET_RULES))){
|
Predicates.compose(Predicates.not(CardRulesPredicates.Presets.IS_BASIC_LAND_NOT_WASTES), PaperCard.FN_GET_RULES))){
|
||||||
if (!pairCard.getName().equals(card.getName())){
|
if (!pairCard.getName().equals(card.getName())){
|
||||||
try {
|
try {
|
||||||
|
|
||||||
int old = matrix[cardIntegerMap.get(card.getName())][cardIntegerMap.get(pairCard.getName())];
|
int old = matrix[cardIntegerMap.get(card.getName())][cardIntegerMap.get(pairCard.getName())];
|
||||||
matrix[cardIntegerMap.get(card.getName())][cardIntegerMap.get(pairCard.getName())] = old + 1;
|
matrix[cardIntegerMap.get(card.getName())][cardIntegerMap.get(pairCard.getName())] = old + 1;
|
||||||
}catch (NullPointerException ne){
|
}catch (NullPointerException ne){
|
||||||
@@ -109,12 +126,107 @@ public final class CardRelationMatrixGenerator {
|
|||||||
if(excludeThisCard){
|
if(excludeThisCard){
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
cardPools.put(card.getName(),deckPool);
|
cardPools.put(card.getName(), deckPool);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return cardPools;
|
return cardPools;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> initializeCommanderFormat(){
|
||||||
|
|
||||||
|
IStorage<Deck> decks = new StorageImmediatelySerialized<Deck>("Generator",
|
||||||
|
new DeckStorage(new File(ForgeConstants.DECK_GEN_DIR,DeckFormat.Commander.toString()),
|
||||||
|
ForgeConstants.DECK_GEN_DIR, false),
|
||||||
|
true);
|
||||||
|
|
||||||
|
//get all cards
|
||||||
|
final Iterable<PaperCard> cards = Iterables.filter(FModel.getMagicDb().getCommonCards().getUniqueCards()
|
||||||
|
, Predicates.compose(Predicates.not(CardRulesPredicates.Presets.IS_BASIC_LAND_NOT_WASTES), PaperCard.FN_GET_RULES));
|
||||||
|
List<PaperCard> cardList = Lists.newArrayList(cards);
|
||||||
|
cardList.add(FModel.getMagicDb().getCommonCards().getCard("Wastes"));
|
||||||
|
Map<String, Integer> cardIntegerMap = new HashMap<>();
|
||||||
|
Map<Integer, PaperCard> integerCardMap = new HashMap<>();
|
||||||
|
Map<String, Integer> legendIntegerMap = new HashMap<>();
|
||||||
|
Map<Integer, PaperCard> integerLegendMap = new HashMap<>();
|
||||||
|
//generate lookups for cards to link card names to matrix columns
|
||||||
|
for (int i=0; i<cardList.size(); ++i){
|
||||||
|
cardIntegerMap.put(cardList.get(i).getName(), i);
|
||||||
|
integerCardMap.put(i, cardList.get(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
//filter to just legal commanders
|
||||||
|
List<PaperCard> legends = Lists.newArrayList(Iterables.filter(cardList,Predicates.compose(
|
||||||
|
new Predicate<CardRules>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CardRules rules) {
|
||||||
|
return DeckFormat.Commander.isLegalCommander(rules);
|
||||||
|
}
|
||||||
|
}, PaperCard.FN_GET_RULES)));
|
||||||
|
|
||||||
|
//generate lookups for legends to link commander names to matrix rows
|
||||||
|
for (int i=0; i<legends.size(); ++i){
|
||||||
|
legendIntegerMap.put(legends.get(i).getName(), i);
|
||||||
|
integerLegendMap.put(i, legends.get(i));
|
||||||
|
}
|
||||||
|
int[][] matrix = new int[legends.size()][cardList.size()];
|
||||||
|
|
||||||
|
//loop through commanders and decks
|
||||||
|
for (PaperCard legend:legends){
|
||||||
|
for (Deck deck:decks){
|
||||||
|
//if the deck has the commander
|
||||||
|
if (deck.getCommanders().contains(legend)){
|
||||||
|
//update the matrix by incrementing the connectivity count for each card in the deck
|
||||||
|
updateLegendMatrix(deck, legend, cardIntegerMap, legendIntegerMap, matrix);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//convert the matrix into a map of pools for each commander
|
||||||
|
HashMap<String,List<Map.Entry<PaperCard,Integer>>> cardPools = new HashMap<>();
|
||||||
|
for (PaperCard card:legends){
|
||||||
|
int col=legendIntegerMap.get(card.getName());
|
||||||
|
int[] distances = matrix[col];
|
||||||
|
int max = (Integer) Collections.max(Arrays.asList(ArrayUtils.toObject(distances)));
|
||||||
|
if (max>0) {
|
||||||
|
List<Map.Entry<PaperCard,Integer>> deckPool=new ArrayList<>();
|
||||||
|
for(int k=0;k<cardList.size(); k++){
|
||||||
|
if(matrix[col][k]>0){
|
||||||
|
deckPool.add(new AbstractMap.SimpleEntry<PaperCard, Integer>(integerCardMap.get(k),matrix[col][k]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cardPools.put(card.getName(), deckPool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return cardPools;
|
||||||
|
}
|
||||||
|
|
||||||
|
//update the matrix by incrementing the connectivity count for each card in the deck
|
||||||
|
public static void updateLegendMatrix(Deck deck, PaperCard legend, Map<String, Integer> cardIntegerMap,
|
||||||
|
Map<String, Integer> legendIntegerMap, int[][] matrix){
|
||||||
|
for (PaperCard pairCard:Iterables.filter(deck.getMain().toFlatList(),
|
||||||
|
Predicates.compose(Predicates.not(CardRulesPredicates.Presets.IS_BASIC_LAND_NOT_WASTES), PaperCard.FN_GET_RULES))){
|
||||||
|
if (!pairCard.getName().equals(legend.getName())){
|
||||||
|
try {
|
||||||
|
int old = matrix[legendIntegerMap.get(legend.getName())][cardIntegerMap.get(pairCard.getName())];
|
||||||
|
matrix[legendIntegerMap.get(legend.getName())][cardIntegerMap.get(pairCard.getName())] = old + 1;
|
||||||
|
}catch (NullPointerException ne){
|
||||||
|
//Todo: Not sure what was failing here
|
||||||
|
ne.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
//add partner commanders to matrix
|
||||||
|
if(deck.getCommanders().size()>1){
|
||||||
|
for(PaperCard partner:deck.getCommanders()){
|
||||||
|
if(!partner.equals(legend)){
|
||||||
|
int old = matrix[legendIntegerMap.get(legend.getName())][cardIntegerMap.get(partner.getName())];
|
||||||
|
matrix[legendIntegerMap.get(legend.getName())][cardIntegerMap.get(partner.getName())] = old + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class ArrayIndexComparator implements Comparator<Integer>
|
public static class ArrayIndexComparator implements Comparator<Integer>
|
||||||
{
|
{
|
||||||
private final Integer[] array;
|
private final Integer[] array;
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
package forge.deck;
|
package forge.deck;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
import forge.card.CardEdition;
|
import forge.card.CardEdition;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.model.FModel;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -12,7 +16,7 @@ import java.util.List;
|
|||||||
public class CardThemedDeckGenerator extends DeckProxy implements Comparable<CardThemedDeckGenerator> {
|
public class CardThemedDeckGenerator extends DeckProxy implements Comparable<CardThemedDeckGenerator> {
|
||||||
public static List<DeckProxy> getMatrixDecks(GameFormat format, boolean isForAi){
|
public static List<DeckProxy> getMatrixDecks(GameFormat format, boolean isForAi){
|
||||||
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||||
for(String card: CardRelationMatrixGenerator.cardPools.get(format).keySet()) {
|
for(String card: CardRelationMatrixGenerator.cardPools.get(format.getName()).keySet()) {
|
||||||
decks.add(new CardThemedDeckGenerator(card, format, isForAi));
|
decks.add(new CardThemedDeckGenerator(card, format, isForAi));
|
||||||
}
|
}
|
||||||
return decks;
|
return decks;
|
||||||
@@ -61,4 +65,15 @@ public class CardThemedDeckGenerator extends DeckProxy implements Comparable<Car
|
|||||||
public boolean isGeneratedDeck() {
|
public boolean isGeneratedDeck() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getImageKey(boolean altState) {
|
||||||
|
/* Predicate<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(name));
|
||||||
|
List<PaperCard> cards=FModel.getMagicDb().getCommonCards().getAllCards(cardFilter);
|
||||||
|
return cards.get(cards.size()-1).getImageKey(altState);*/
|
||||||
|
return FModel.getMagicDb().getCommonCards().getUniqueByName(name).getImageKey(altState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaperCard getPaperCard(){
|
||||||
|
return FModel.getMagicDb().getCommonCards().getUniqueByName(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
107
forge-gui/src/main/java/forge/deck/CommanderDeckGenerator.java
Normal file
107
forge-gui/src/main/java/forge/deck/CommanderDeckGenerator.java
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
package forge.deck;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import forge.card.CardEdition;
|
||||||
|
import forge.card.CardRules;
|
||||||
|
import forge.card.CardRulesPredicates;
|
||||||
|
import forge.deck.generation.DeckGeneratorBase;
|
||||||
|
import forge.deck.generation.IDeckGenPool;
|
||||||
|
import forge.game.GameFormat;
|
||||||
|
import forge.game.GameType;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.util.ItemPool;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by maustin on 09/05/2017.
|
||||||
|
*/
|
||||||
|
public class CommanderDeckGenerator extends DeckProxy implements Comparable<CommanderDeckGenerator> {
|
||||||
|
public static List<DeckProxy> getCommanderDecks(DeckFormat format, boolean isForAi, boolean isCardGen){
|
||||||
|
ItemPool uniqueCards;
|
||||||
|
if(isCardGen){
|
||||||
|
uniqueCards = new ItemPool<PaperCard>(PaperCard.class);
|
||||||
|
Iterable<String> legendNames=CardRelationMatrixGenerator.cardPools.get(DeckFormat.Commander.toString()).keySet();
|
||||||
|
for(String legendName:legendNames) {
|
||||||
|
uniqueCards.add(FModel.getMagicDb().getCommonCards().getUniqueByName(legendName));
|
||||||
|
}
|
||||||
|
}else {
|
||||||
|
uniqueCards = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getUniqueCards(), PaperCard.class);
|
||||||
|
}
|
||||||
|
Predicate<CardRules> canPlay = isForAi ? DeckGeneratorBase.AI_CAN_PLAY : DeckGeneratorBase.HUMAN_CAN_PLAY;
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
Iterable<PaperCard> legends = Iterables.filter(uniqueCards.toFlatList(), Predicates.compose(Predicates.and(
|
||||||
|
new Predicate<CardRules>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CardRules rules) {
|
||||||
|
return format.isLegalCommander(rules);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
canPlay), PaperCard.FN_GET_RULES));
|
||||||
|
final List<DeckProxy> decks = new ArrayList<DeckProxy>();
|
||||||
|
for(PaperCard legend: legends) {
|
||||||
|
decks.add(new CommanderDeckGenerator(legend, format, isForAi, isCardGen));
|
||||||
|
}
|
||||||
|
return decks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final PaperCard legend;
|
||||||
|
private final int index;
|
||||||
|
private final DeckFormat format;
|
||||||
|
private final boolean isForAi;
|
||||||
|
private final boolean isCardgen;
|
||||||
|
|
||||||
|
|
||||||
|
private CommanderDeckGenerator(PaperCard legend0, DeckFormat format0, boolean isForAi0, boolean isCardgen0) {
|
||||||
|
super();
|
||||||
|
legend = legend0;
|
||||||
|
index = 0;
|
||||||
|
isForAi=isForAi0;
|
||||||
|
format=format0;
|
||||||
|
isCardgen=isCardgen0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardEdition getEdition() {
|
||||||
|
return CardEdition.UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return legend.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return legend.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final CommanderDeckGenerator d) {
|
||||||
|
return this.getName().compareTo(d.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Deck getDeck() {
|
||||||
|
|
||||||
|
return DeckgenUtil.generateRandomCommanderDeck(legend, format,isForAi, isCardgen);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGeneratedDeck() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getImageKey(boolean altState) {
|
||||||
|
return legend.getImageKey(altState);
|
||||||
|
}
|
||||||
|
|
||||||
|
public PaperCard getPaperCard(){
|
||||||
|
return legend;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -7,6 +7,8 @@ public enum DeckType {
|
|||||||
CUSTOM_DECK ("Custom User Decks"),
|
CUSTOM_DECK ("Custom User Decks"),
|
||||||
CONSTRUCTED_DECK ("Constructed Decks"),
|
CONSTRUCTED_DECK ("Constructed Decks"),
|
||||||
COMMANDER_DECK ("Commander Decks"),
|
COMMANDER_DECK ("Commander Decks"),
|
||||||
|
RANDOM_COMMANDER_DECK ("Random Commander Decks"),
|
||||||
|
RANDOM_CARDGEN_COMMANDER_DECK ("Random Commander Card-based Decks"),
|
||||||
TINY_LEADERS_DECKS ("Tiny Leaders Decks"),
|
TINY_LEADERS_DECKS ("Tiny Leaders Decks"),
|
||||||
SCHEME_DECKS ("Scheme Decks"),
|
SCHEME_DECKS ("Scheme Decks"),
|
||||||
PLANAR_DECKS ("Planar Decks"),
|
PLANAR_DECKS ("Planar Decks"),
|
||||||
@@ -25,9 +27,10 @@ public enum DeckType {
|
|||||||
NET_COMMANDER_DECK ("Net Commander Decks");
|
NET_COMMANDER_DECK ("Net Commander Decks");
|
||||||
|
|
||||||
public static DeckType[] ConstructedOptions;
|
public static DeckType[] ConstructedOptions;
|
||||||
|
public static DeckType[] CommanderOptions;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (!FModel.getPreferences().getPrefBoolean(ForgePreferences.FPref.LOAD_CARD_SCRIPTS_LAZILY)) {
|
if (FModel.isdeckGenMatrixLoaded()) {
|
||||||
ConstructedOptions = new DeckType[]{
|
ConstructedOptions = new DeckType[]{
|
||||||
DeckType.CUSTOM_DECK,
|
DeckType.CUSTOM_DECK,
|
||||||
DeckType.PRECONSTRUCTED_DECK,
|
DeckType.PRECONSTRUCTED_DECK,
|
||||||
@@ -55,6 +58,25 @@ public enum DeckType {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
static {
|
||||||
|
if (FModel.isdeckGenMatrixLoaded()) {
|
||||||
|
CommanderOptions = new DeckType[]{
|
||||||
|
DeckType.COMMANDER_DECK,
|
||||||
|
DeckType.RANDOM_COMMANDER_DECK,
|
||||||
|
DeckType.RANDOM_CARDGEN_COMMANDER_DECK,
|
||||||
|
DeckType.RANDOM_DECK,
|
||||||
|
DeckType.NET_COMMANDER_DECK
|
||||||
|
};
|
||||||
|
}else{
|
||||||
|
CommanderOptions = new DeckType[]{
|
||||||
|
DeckType.COMMANDER_DECK,
|
||||||
|
DeckType.RANDOM_COMMANDER_DECK,
|
||||||
|
DeckType.RANDOM_DECK,
|
||||||
|
DeckType.NET_COMMANDER_DECK
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private String value;
|
private String value;
|
||||||
private DeckType(final String value) {
|
private DeckType(final String value) {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import forge.game.GameFormat;
|
|||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
import forge.item.PaperCard;
|
import forge.item.PaperCard;
|
||||||
import forge.itemmanager.IItemManager;
|
import forge.itemmanager.IItemManager;
|
||||||
|
import forge.limited.CardThemedCommanderDeckBuilder;
|
||||||
import forge.limited.CardThemedDeckBuilder;
|
import forge.limited.CardThemedDeckBuilder;
|
||||||
import forge.model.FModel;
|
import forge.model.FModel;
|
||||||
import forge.properties.ForgePreferences.FPref;
|
import forge.properties.ForgePreferences.FPref;
|
||||||
@@ -44,7 +45,7 @@ public class DeckgenUtil {
|
|||||||
public static Deck buildCardGenDeck(GameFormat format, boolean isForAI){
|
public static Deck buildCardGenDeck(GameFormat format, boolean isForAI){
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
try {
|
try {
|
||||||
List<String> keys = new ArrayList<>(CardRelationMatrixGenerator.cardPools.get(format).keySet());
|
List<String> keys = new ArrayList<>(CardRelationMatrixGenerator.cardPools.get(format.getName()).keySet());
|
||||||
String randomKey = keys.get( random.nextInt(keys.size()) );
|
String randomKey = keys.get( random.nextInt(keys.size()) );
|
||||||
Predicate<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(randomKey));
|
Predicate<PaperCard> cardFilter = Predicates.and(format.getFilterPrinted(),PaperCard.Predicates.name(randomKey));
|
||||||
PaperCard keyCard = FModel.getMagicDb().getCommonCards().getAllCards(cardFilter).get(0);
|
PaperCard keyCard = FModel.getMagicDb().getCommonCards().getAllCards(cardFilter).get(0);
|
||||||
@@ -119,7 +120,7 @@ public class DeckgenUtil {
|
|||||||
*/
|
*/
|
||||||
public static Deck buildCardGenDeck(PaperCard card, GameFormat format, boolean isForAI){
|
public static Deck buildCardGenDeck(PaperCard card, GameFormat format, boolean isForAI){
|
||||||
List<Map.Entry<PaperCard,Integer>> potentialCards = new ArrayList<>();
|
List<Map.Entry<PaperCard,Integer>> potentialCards = new ArrayList<>();
|
||||||
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(format).get(card.getName()));
|
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(format.getName()).get(card.getName()));
|
||||||
Collections.sort(potentialCards,new CardDistanceComparator());
|
Collections.sort(potentialCards,new CardDistanceComparator());
|
||||||
Collections.reverse(potentialCards);
|
Collections.reverse(potentialCards);
|
||||||
//get second keycard
|
//get second keycard
|
||||||
@@ -146,7 +147,7 @@ public class DeckgenUtil {
|
|||||||
randMax=preSelectedCards.size();
|
randMax=preSelectedCards.size();
|
||||||
}
|
}
|
||||||
PaperCard secondKeycard = preSelectedCards.get(r.nextInt(randMax));
|
PaperCard secondKeycard = preSelectedCards.get(r.nextInt(randMax));
|
||||||
List<Map.Entry<PaperCard,Integer>> potentialSecondCards = CardRelationMatrixGenerator.cardPools.get(format).get(secondKeycard.getName());
|
List<Map.Entry<PaperCard,Integer>> potentialSecondCards = CardRelationMatrixGenerator.cardPools.get(format.getName()).get(secondKeycard.getName());
|
||||||
|
|
||||||
//combine card distances from second key card and re-sort
|
//combine card distances from second key card and re-sort
|
||||||
if(potentialSecondCards !=null && potentialSecondCards.size()>0) {
|
if(potentialSecondCards !=null && potentialSecondCards.size()>0) {
|
||||||
@@ -486,7 +487,7 @@ public class DeckgenUtil {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Generate a 2-color Commander deck. */
|
/** Generate a 2-5-color Commander deck. */
|
||||||
public static Deck generateCommanderDeck(boolean forAi, GameType gameType) {
|
public static Deck generateCommanderDeck(boolean forAi, GameType gameType) {
|
||||||
final Deck deck;
|
final Deck deck;
|
||||||
IDeckGenPool cardDb = FModel.getMagicDb().getCommonCards();
|
IDeckGenPool cardDb = FModel.getMagicDb().getCommonCards();
|
||||||
@@ -504,7 +505,6 @@ public class DeckgenUtil {
|
|||||||
return format.isLegalCommander(rules);
|
return format.isLegalCommander(rules);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
CardRulesPredicates.Presets.IS_MULTICOLOR,
|
|
||||||
canPlay), PaperCard.FN_GET_RULES));
|
canPlay), PaperCard.FN_GET_RULES));
|
||||||
|
|
||||||
do {
|
do {
|
||||||
@@ -534,6 +534,104 @@ public class DeckgenUtil {
|
|||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Generate a ramdom Commander deck. */
|
||||||
|
public static Deck generateRandomCommanderDeck(PaperCard commander, DeckFormat format, boolean forAi, boolean isCardGen) {
|
||||||
|
final Deck deck;
|
||||||
|
IDeckGenPool cardDb;
|
||||||
|
DeckGeneratorBase gen = null;
|
||||||
|
PaperCard selectedPartner=null;
|
||||||
|
if(isCardGen){
|
||||||
|
List<Map.Entry<PaperCard,Integer>> potentialCards = new ArrayList<>();
|
||||||
|
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(DeckFormat.Commander.toString()).get(commander.getName()));
|
||||||
|
Random r = new Random();
|
||||||
|
//Collections.shuffle(potentialCards, r);
|
||||||
|
List<PaperCard> preSelectedCards = new ArrayList<>();
|
||||||
|
for(Map.Entry<PaperCard,Integer> pair:potentialCards){
|
||||||
|
if(format.isLegalCard(pair.getKey())) {
|
||||||
|
preSelectedCards.add(pair.getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//check for partner commanders
|
||||||
|
List<PaperCard> partners=new ArrayList<>();
|
||||||
|
for(PaperCard c:preSelectedCards){
|
||||||
|
if(c.getRules().canBePartnerCommander()){
|
||||||
|
partners.add(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(partners.size()>0&&commander.getRules().canBePartnerCommander()){
|
||||||
|
selectedPartner=partners.get(MyRandom.getRandom().nextInt(partners.size()));
|
||||||
|
preSelectedCards.remove(selectedPartner);
|
||||||
|
}
|
||||||
|
//randomly remove cards
|
||||||
|
int removeCount=0;
|
||||||
|
int i=0;
|
||||||
|
List<PaperCard> toRemove = new ArrayList<>();
|
||||||
|
for(PaperCard c:preSelectedCards){
|
||||||
|
if(!format.isLegalCard(c)){
|
||||||
|
toRemove.add(c);
|
||||||
|
removeCount++;
|
||||||
|
}
|
||||||
|
if(preSelectedCards.size()<75){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if(r.nextInt(100)>60+(15-(i/preSelectedCards.size())*preSelectedCards.size()) && removeCount<4 //randomly remove some cards - more likely as distance increases
|
||||||
|
&&!c.getName().contains("Urza")&&!c.getName().contains("Wastes")){ //avoid breaking Tron decks
|
||||||
|
toRemove.add(c);
|
||||||
|
removeCount++;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
preSelectedCards.removeAll(toRemove);
|
||||||
|
gen = new CardThemedCommanderDeckBuilder(commander, selectedPartner,preSelectedCards,forAi,format);
|
||||||
|
}else{
|
||||||
|
cardDb = FModel.getMagicDb().getCommonCards();
|
||||||
|
ColorSet colorID;
|
||||||
|
colorID = commander.getRules().getColorIdentity();
|
||||||
|
List<String> comColors = new ArrayList<String>(2);
|
||||||
|
if (colorID.hasWhite()) { comColors.add("White"); }
|
||||||
|
if (colorID.hasBlue()) { comColors.add("Blue"); }
|
||||||
|
if (colorID.hasBlack()) { comColors.add("Black"); }
|
||||||
|
if (colorID.hasRed()) { comColors.add("Red"); }
|
||||||
|
if (colorID.hasGreen()) { comColors.add("Green"); }
|
||||||
|
|
||||||
|
if(comColors.size()==1){
|
||||||
|
gen = new DeckGeneratorMonoColor(cardDb, format, comColors.get(0));
|
||||||
|
}else if(comColors.size()==2){
|
||||||
|
gen = new DeckGenerator2Color(cardDb, format, comColors.get(0), comColors.get(1));
|
||||||
|
}else if(comColors.size()==3){
|
||||||
|
gen = new DeckGenerator3Color(cardDb, format, comColors.get(0), comColors.get(1), comColors.get(2));
|
||||||
|
}else if(comColors.size()==4){
|
||||||
|
gen = new DeckGenerator4Color(cardDb, format, comColors.get(0), comColors.get(1), comColors.get(2), comColors.get(3));
|
||||||
|
}else if(comColors.size()==5){
|
||||||
|
gen = new DeckGenerator5Color(cardDb, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
gen.setSingleton(true);
|
||||||
|
gen.setUseArtifacts(!FModel.getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS));
|
||||||
|
CardPool cards = gen.getDeck(format.getMainRange().getMaximum(), forAi);
|
||||||
|
|
||||||
|
// After generating card lists, build deck.
|
||||||
|
if(selectedPartner!=null){
|
||||||
|
deck = new Deck("Generated " + format.toString() + " deck (" + commander.getName() +
|
||||||
|
"--" + selectedPartner.getName() + ")");
|
||||||
|
}else{
|
||||||
|
deck = new Deck("Generated " + format.toString() + " deck (" + commander.getName() + ")");
|
||||||
|
}
|
||||||
|
deck.setDirectory("generated/commander");
|
||||||
|
deck.getMain().addAll(cards);
|
||||||
|
deck.getOrCreate(DeckSection.Commander).add(commander);
|
||||||
|
if(selectedPartner!=null){
|
||||||
|
deck.getOrCreate(DeckSection.Commander).add(selectedPartner);
|
||||||
|
}
|
||||||
|
|
||||||
|
return deck;
|
||||||
|
}
|
||||||
|
|
||||||
public static Map<ManaCostShard, Integer> suggestBasicLandCount(Deck d) {
|
public static Map<ManaCostShard, Integer> suggestBasicLandCount(Deck d) {
|
||||||
int W=0, U=0, R=0, B=0, G=0, total=0;
|
int W=0, U=0, R=0, B=0, G=0, total=0;
|
||||||
List<PaperCard> cards = d.getOrCreate(DeckSection.Main).toFlatList();
|
List<PaperCard> cards = d.getOrCreate(DeckSection.Main).toFlatList();
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public class CardThemedMatrixIO {
|
|||||||
/** suffix for all gauntlet data files */
|
/** suffix for all gauntlet data files */
|
||||||
public static final String SUFFIX_DATA = ".dat";
|
public static final String SUFFIX_DATA = ".dat";
|
||||||
|
|
||||||
public static void saveMatrix(GameFormat format, HashMap<String,List<Map.Entry<PaperCard,Integer>>> map){
|
public static void saveMatrix(String format, HashMap<String,List<Map.Entry<PaperCard,Integer>>> map){
|
||||||
File file = getMatrixFile(format);
|
File file = getMatrixFile(format);
|
||||||
ObjectOutputStream s = null;
|
ObjectOutputStream s = null;
|
||||||
try {
|
try {
|
||||||
@@ -43,7 +43,7 @@ public class CardThemedMatrixIO {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> loadMatrix(GameFormat format){
|
public static HashMap<String,List<Map.Entry<PaperCard,Integer>>> loadMatrix(String format){
|
||||||
try {
|
try {
|
||||||
FileInputStream fin = new FileInputStream(getMatrixFile(format));
|
FileInputStream fin = new FileInputStream(getMatrixFile(format));
|
||||||
ObjectInputStream s = new ObjectInputStream(fin);
|
ObjectInputStream s = new ObjectInputStream(fin);
|
||||||
@@ -61,6 +61,10 @@ public class CardThemedMatrixIO {
|
|||||||
return new File(ForgeConstants.DECK_GEN_DIR, name + SUFFIX_DATA);
|
return new File(ForgeConstants.DECK_GEN_DIR, name + SUFFIX_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static File getMatrixFolder(final String name) {
|
||||||
|
return new File(ForgeConstants.DECK_GEN_DIR, name);
|
||||||
|
}
|
||||||
|
|
||||||
public static File getMatrixFile(final GameFormat gf) {
|
public static File getMatrixFile(final GameFormat gf) {
|
||||||
return getMatrixFile(gf.getName());
|
return getMatrixFile(gf.getName());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,781 @@
|
|||||||
|
package forge.limited;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import forge.card.*;
|
||||||
|
import forge.card.mana.ManaCost;
|
||||||
|
import forge.card.mana.ManaCostShard;
|
||||||
|
import forge.deck.CardPool;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.deck.DeckFormat;
|
||||||
|
import forge.deck.DeckSection;
|
||||||
|
import forge.deck.generation.DeckGenPool;
|
||||||
|
import forge.deck.generation.DeckGeneratorBase;
|
||||||
|
import forge.item.IPaperCard;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.util.MyRandom;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limited format deck.
|
||||||
|
*/
|
||||||
|
public class CardThemedCommanderDeckBuilder extends DeckGeneratorBase {
|
||||||
|
@Override
|
||||||
|
protected final float getLandPercentage() {
|
||||||
|
return 0.44f;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected final float getCreaturePercentage() {
|
||||||
|
return 0.33f;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
protected final float getSpellPercentage() {
|
||||||
|
return 0.23f;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int targetSize;
|
||||||
|
protected int numSpellsNeeded;
|
||||||
|
protected int numCreaturesToStart;
|
||||||
|
protected int landsNeeded;
|
||||||
|
|
||||||
|
protected final PaperCard commanderCard;
|
||||||
|
protected final PaperCard partnerCard;
|
||||||
|
|
||||||
|
protected Predicate<CardRules> hasColor;
|
||||||
|
protected final List<PaperCard> availableList;
|
||||||
|
protected final List<PaperCard> aiPlayables;
|
||||||
|
protected final List<PaperCard> deckList = new ArrayList<>();
|
||||||
|
protected final List<String> setsWithBasicLands = new ArrayList<>();
|
||||||
|
protected List<PaperCard> rankedColorList;
|
||||||
|
|
||||||
|
// Views for aiPlayable
|
||||||
|
protected Iterable<PaperCard> onColorCreatures;
|
||||||
|
protected Iterable<PaperCard> onColorNonCreatures;
|
||||||
|
|
||||||
|
protected static final boolean logToConsole = false;
|
||||||
|
protected static final boolean logColorsToConsole = false;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param dList
|
||||||
|
* Cards to build the deck from.
|
||||||
|
*/
|
||||||
|
public CardThemedCommanderDeckBuilder(PaperCard commanderCard0,PaperCard partner0, final List<PaperCard> dList, boolean isForAI, DeckFormat format) {
|
||||||
|
super(FModel.getMagicDb().getCommonCards(), format);
|
||||||
|
this.availableList = dList;
|
||||||
|
commanderCard = commanderCard0;
|
||||||
|
partnerCard = partner0;
|
||||||
|
// remove Unplayables
|
||||||
|
if(isForAI) {
|
||||||
|
final Iterable<PaperCard> playables = Iterables.filter(availableList,
|
||||||
|
Predicates.compose(CardRulesPredicates.IS_KEPT_IN_AI_DECKS, PaperCard.FN_GET_RULES));
|
||||||
|
this.aiPlayables = Lists.newArrayList(playables);
|
||||||
|
}else{
|
||||||
|
this.aiPlayables = Lists.newArrayList(availableList);
|
||||||
|
}
|
||||||
|
this.availableList.removeAll(aiPlayables);
|
||||||
|
targetSize=format.getMainRange().getMinimum();
|
||||||
|
colors = commanderCard.getRules().getColorIdentity();
|
||||||
|
colors = ColorSet.fromMask(colors.getColor() | commanderCard.getRules().getColorIdentity().getColor());
|
||||||
|
if(partnerCard!=null) {
|
||||||
|
colors = ColorSet.fromMask(colors.getColor() | partnerCard.getRules().getColorIdentity().getColor());
|
||||||
|
targetSize--;
|
||||||
|
}
|
||||||
|
numSpellsNeeded = ((Double)Math.floor(targetSize*(getCreaturePercentage()+getSpellPercentage()))).intValue();
|
||||||
|
numCreaturesToStart = ((Double)Math.ceil(targetSize*(getCreaturePercentage()))).intValue();
|
||||||
|
landsNeeded = ((Double)Math.ceil(targetSize*(getLandPercentage()))).intValue();;
|
||||||
|
if (logColorsToConsole) {
|
||||||
|
System.out.println(commanderCard.getName());
|
||||||
|
System.out.println("Pre Colors: " + colors.toEnumSet().toString());
|
||||||
|
}
|
||||||
|
findBasicLandSets();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CardPool getDeck(final int size, final boolean forAi) {
|
||||||
|
return buildDeck().getMain();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* buildDeck.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return the new Deck.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public Deck buildDeck() {
|
||||||
|
// 1. Prepare
|
||||||
|
hasColor = Predicates.or(new MatchColorIdentity(colors), COLORLESS_CARDS);
|
||||||
|
if (logColorsToConsole) {
|
||||||
|
System.out.println(commanderCard.getName());
|
||||||
|
System.out.println("Colors: " + colors.toEnumSet().toString());
|
||||||
|
}
|
||||||
|
Iterable<PaperCard> colorList = Iterables.filter(aiPlayables,
|
||||||
|
Predicates.compose(hasColor, PaperCard.FN_GET_RULES));
|
||||||
|
rankedColorList = Lists.newArrayList(colorList);
|
||||||
|
onColorCreatures = Iterables.filter(rankedColorList,
|
||||||
|
Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE, PaperCard.FN_GET_RULES));
|
||||||
|
onColorNonCreatures = Iterables.filter(rankedColorList,
|
||||||
|
Predicates.compose(CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, PaperCard.FN_GET_RULES));
|
||||||
|
// Guava iterables do not copy the collection contents, instead they act
|
||||||
|
// as filters and iterate over _source_ collection each time. So even if
|
||||||
|
// aiPlayable has changed, there is no need to create a new iterable.
|
||||||
|
|
||||||
|
// 2. Add any planeswalkers - removed - treat as non-creature
|
||||||
|
|
||||||
|
// 3. Add creatures, trying to follow mana curve
|
||||||
|
|
||||||
|
addManaCurveCards(onColorCreatures, numCreaturesToStart, "Creatures");
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post Creatures : " + deckList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4.Try to fill up to num needed with on-color non-creature cards
|
||||||
|
addManaCurveCards(onColorNonCreatures, numSpellsNeeded - deckList.size(), "Spells");
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post Spells : " + deckList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5.If we couldn't get enough, try to fill up with on-color cards
|
||||||
|
addCards(rankedColorList, numSpellsNeeded - deckList.size());
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post more creatures : " + deckList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. If there are still on-color cards, and the average cmc is low, add
|
||||||
|
// extras.
|
||||||
|
double avCMC=getAverageCMC(deckList);
|
||||||
|
int maxCMC=getMaxCMC(deckList);
|
||||||
|
if (deckList.size() == numSpellsNeeded && avCMC < 4) {
|
||||||
|
addLowCMCCard();
|
||||||
|
if(targetSize>60){
|
||||||
|
addLowCMCCard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (deckList.size() >= numSpellsNeeded && avCMC < 3 && maxCMC<6) {
|
||||||
|
addLowCMCCard();
|
||||||
|
}
|
||||||
|
if (deckList.size() >= numSpellsNeeded && avCMC < 2.5 && maxCMC<5) {
|
||||||
|
addLowCMCCard();
|
||||||
|
if(targetSize>60){
|
||||||
|
addLowCMCCard();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post lowcoc : " + deckList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* // 7. If not enough cards yet, try to add a third color,
|
||||||
|
// to try and avoid adding purely random cards.
|
||||||
|
addThirdColorCards(numSpellsNeeded - deckList.size());
|
||||||
|
if (logColorsToConsole) {
|
||||||
|
System.out.println("Post 3rd colour : " + deckList.size());
|
||||||
|
System.out.println("Colors: " + colors.toEnumSet().toString());
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// 8. Check for DeckNeeds cards.
|
||||||
|
//checkRemRandomDeckCards(); - no need
|
||||||
|
|
||||||
|
// 9. If there are still less than 22 non-land cards add off-color
|
||||||
|
// cards. This should be avoided.
|
||||||
|
addRandomCards(numSpellsNeeded - deckList.size());
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post Randoms : " + deckList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> duals = getDualLandList();
|
||||||
|
addNonBasicLands();
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post Nonbasic lands : " + deckList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
checkEvolvingWilds();
|
||||||
|
|
||||||
|
// 11. Fill up with basic lands.
|
||||||
|
final int[] clrCnts = calculateLandNeeds();
|
||||||
|
|
||||||
|
// Add dual lands
|
||||||
|
if (clrCnts.length>1) {
|
||||||
|
|
||||||
|
for (String s : duals) {
|
||||||
|
this.cardCounts.put(s, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (landsNeeded > 0) {
|
||||||
|
addLands(clrCnts);
|
||||||
|
}
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post Lands : " + deckList.size());
|
||||||
|
}
|
||||||
|
if (commanderCard.getRules().getColorIdentity().isColorless()&&landsNeeded>0){
|
||||||
|
// 10. Add non-basic lands that were drafted.
|
||||||
|
addWastesIfRequired();
|
||||||
|
}
|
||||||
|
fixDeckSize();
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Post Size fix : " + deckList.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
//Create Deck
|
||||||
|
final Deck result = new Deck(generateName());
|
||||||
|
result.getMain().add(deckList);
|
||||||
|
|
||||||
|
//Add remaining non-land colour matching cards to sideboard
|
||||||
|
final CardPool cp = result.getOrCreate(DeckSection.Sideboard);
|
||||||
|
Iterable<PaperCard> potentialSideboard = Iterables.filter(aiPlayables,
|
||||||
|
Predicates.and(Predicates.compose(hasColor, PaperCard.FN_GET_RULES),
|
||||||
|
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES)));
|
||||||
|
int i=0;
|
||||||
|
while(i<15 && potentialSideboard.iterator().hasNext()){
|
||||||
|
PaperCard sbCard = potentialSideboard.iterator().next();
|
||||||
|
cp.add(sbCard);
|
||||||
|
aiPlayables.remove(sbCard);
|
||||||
|
rankedColorList.remove(sbCard);
|
||||||
|
|
||||||
|
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
if (logToConsole) {
|
||||||
|
debugFinalDeck();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If evolving wilds is in the deck and there are fewer than 4 spaces for basic lands - remove evolving wilds
|
||||||
|
*/
|
||||||
|
protected void checkEvolvingWilds(){
|
||||||
|
List<PaperCard> evolvingWilds = Lists.newArrayList(Iterables.filter(deckList,PaperCard.Predicates.name("Evolving Wilds")));
|
||||||
|
if((evolvingWilds.size()>0 && landsNeeded<4 ) || colors.countColors()<2){
|
||||||
|
deckList.removeAll(evolvingWilds);
|
||||||
|
landsNeeded=landsNeeded+evolvingWilds.size();
|
||||||
|
aiPlayables.addAll(evolvingWilds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected void addLowCMCCard(){
|
||||||
|
final Iterable<PaperCard> nonLands = Iterables.filter(aiPlayables,
|
||||||
|
Predicates.compose(CardRulesPredicates.Presets.IS_NON_LAND, PaperCard.FN_GET_RULES));
|
||||||
|
final PaperCard card = Iterables.getFirst(nonLands, null);
|
||||||
|
if (card != null) {
|
||||||
|
deckList.add(card);
|
||||||
|
aiPlayables.remove(card);
|
||||||
|
rankedColorList.remove(card);
|
||||||
|
|
||||||
|
landsNeeded--;
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Low CMC: " + card.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the basic land pool
|
||||||
|
* @param edition
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
protected boolean setBasicLandPool(String edition){
|
||||||
|
Predicate<PaperCard> isSetBasicLand;
|
||||||
|
if (edition !=null){
|
||||||
|
isSetBasicLand = Predicates.and(IPaperCard.Predicates.printedInSet(edition),
|
||||||
|
Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, PaperCard.FN_GET_RULES));
|
||||||
|
}else{
|
||||||
|
isSetBasicLand = Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, PaperCard.FN_GET_RULES);
|
||||||
|
}
|
||||||
|
|
||||||
|
landPool = new DeckGenPool(format.getCardPool(fullCardDB).getAllCards(isSetBasicLand));
|
||||||
|
return landPool.contains("Plains");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a descriptive name.
|
||||||
|
*
|
||||||
|
* @return name
|
||||||
|
*/
|
||||||
|
private String generateName() {
|
||||||
|
return commanderCard.getName() +" based commander deck";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Print out listing of all cards for debugging.
|
||||||
|
*/
|
||||||
|
private void debugFinalDeck() {
|
||||||
|
int i = 0;
|
||||||
|
System.out.println("DECK");
|
||||||
|
for (final PaperCard c : deckList) {
|
||||||
|
i++;
|
||||||
|
System.out.println(i + ". " + c.toString() + ": " + c.getRules().getManaCost().toString());
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
System.out.println("NOT PLAYABLE");
|
||||||
|
for (final PaperCard c : availableList) {
|
||||||
|
i++;
|
||||||
|
System.out.println(i + ". " + c.toString() + ": " + c.getRules().getManaCost().toString());
|
||||||
|
}
|
||||||
|
i = 0;
|
||||||
|
System.out.println("NOT PICKED");
|
||||||
|
for (final PaperCard c : aiPlayables) {
|
||||||
|
i++;
|
||||||
|
System.out.println(i + ". " + c.toString() + ": " + c.getRules().getManaCost().toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the deck does not have 40 cards, fix it. This method should not be
|
||||||
|
* called if the stuff above it is working correctly.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private void fixDeckSize() {
|
||||||
|
while (deckList.size() > targetSize) {
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("WARNING: Fixing deck size, currently " + deckList.size() + " cards.");
|
||||||
|
}
|
||||||
|
final PaperCard c = deckList.get(MyRandom.getRandom().nextInt(deckList.size() - 1));
|
||||||
|
deckList.remove(c);
|
||||||
|
aiPlayables.add(c);
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println(" - Removed " + c.getName() + " randomly.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(deckList.size()==targetSize){
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Predicate<PaperCard> possibleFromFullPool = new Predicate<PaperCard>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(PaperCard card) {
|
||||||
|
return format.isLegalCard(card)
|
||||||
|
&&!card.getRules().getManaCost().isPureGeneric()
|
||||||
|
&& colors.containsAllColorsFrom(card.getRules().getColorIdentity().getColor())
|
||||||
|
&& !deckList.contains(card)
|
||||||
|
&&!card.getRules().getAiHints().getRemAIDecks()
|
||||||
|
&&!card.getRules().getAiHints().getRemRandomDecks()
|
||||||
|
&&!card.getRules().getMainPart().getType().isLand();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
List<PaperCard> randomPool = Lists.newArrayList(pool.getAllCards(possibleFromFullPool));
|
||||||
|
Collections.shuffle(randomPool,new Random());
|
||||||
|
Iterator<PaperCard> iRandomPool=randomPool.iterator();
|
||||||
|
while (deckList.size() < targetSize) {
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("WARNING: Fixing deck size, currently " + deckList.size() + " cards.");
|
||||||
|
}
|
||||||
|
PaperCard randomCard = iRandomPool.next();
|
||||||
|
deckList.add(randomCard);
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println(" - Added " + randomCard.getName() + " randomly.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the sets that have basic lands for the available cards.
|
||||||
|
*/
|
||||||
|
private void findBasicLandSets() {
|
||||||
|
final Set<String> sets = new HashSet<>();
|
||||||
|
for (final PaperCard cp : aiPlayables) {
|
||||||
|
final CardEdition ee = FModel.getMagicDb().getEditions().get(cp.getEdition());
|
||||||
|
if( !sets.contains(cp.getEdition()) && CardEdition.Predicates.hasBasicLands.apply(ee)) {
|
||||||
|
sets.add(cp.getEdition());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setsWithBasicLands.addAll(sets);
|
||||||
|
if (setsWithBasicLands.isEmpty()) {
|
||||||
|
setsWithBasicLands.add("BFZ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add lands to fulfill the given color counts.
|
||||||
|
*
|
||||||
|
* @param clrCnts
|
||||||
|
* counts of lands needed, by color
|
||||||
|
*/
|
||||||
|
private void addLands(final int[] clrCnts) {
|
||||||
|
// basic lands that are available in the deck
|
||||||
|
final Iterable<PaperCard> basicLands = Iterables.filter(aiPlayables, Predicates.compose(CardRulesPredicates.Presets.IS_BASIC_LAND, PaperCard.FN_GET_RULES));
|
||||||
|
final Set<PaperCard> snowLands = new HashSet<PaperCard>();
|
||||||
|
|
||||||
|
// total of all ClrCnts
|
||||||
|
int totalColor = 0;
|
||||||
|
int numColors = 0;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
totalColor += clrCnts[i];
|
||||||
|
if (clrCnts[i] > 0) {
|
||||||
|
numColors++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*if (totalColor == 0) {
|
||||||
|
for (int j = 0; j < nLand; j++) {
|
||||||
|
deckList.add(getBasicLand(i));
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// do not update landsNeeded until after the loop, because the
|
||||||
|
// calculation involves landsNeeded
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
if (clrCnts[i] > 0) {
|
||||||
|
// calculate number of lands for each color
|
||||||
|
float p = (float) clrCnts[i] / (float) totalColor;
|
||||||
|
if (numColors == 2) {
|
||||||
|
// In the normal two-color case, constrain to within 40% and 60% so that the AI
|
||||||
|
// doesn't put too few lands of the lesser color, risking getting screwed on that color.
|
||||||
|
// Don't do this for the odd case where a third color had to be added to the deck.
|
||||||
|
p = Math.min(Math.max(p, 0.4f), 0.6f);
|
||||||
|
}
|
||||||
|
int nLand = Math.round(landsNeeded * p); // desired truncation to int
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.printf("Basics[%s]: %d/%d = %f%% = %d cards%n", MagicColor.Constant.BASIC_LANDS.get(i), clrCnts[i], totalColor, 100*p, nLand);
|
||||||
|
}
|
||||||
|
|
||||||
|
// if appropriate snow-covered lands are available, add them
|
||||||
|
for (final PaperCard cp : basicLands) {
|
||||||
|
if (cp.getName().equals(MagicColor.Constant.SNOW_LANDS.get(i))) {
|
||||||
|
snowLands.add(cp);
|
||||||
|
nLand--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j = 0; j < nLand; j++) {
|
||||||
|
deckList.add(getBasicLand(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// A common problem at this point is that p in the above loop was exactly 1/2,
|
||||||
|
// and nLand rounded up for both colors, so that one too many lands was added.
|
||||||
|
// So if the deck size is > 60, remove the last land added.
|
||||||
|
// Otherwise, the fixDeckSize() method would remove random cards.
|
||||||
|
while (deckList.size() > targetSize) {
|
||||||
|
deckList.remove(deckList.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
deckList.addAll(snowLands);
|
||||||
|
aiPlayables.removeAll(snowLands);
|
||||||
|
rankedColorList.remove(snowLands);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get basic land.
|
||||||
|
*
|
||||||
|
* @param basicLand
|
||||||
|
* the set to take basic lands from (pass 'null' for random).
|
||||||
|
* @return card
|
||||||
|
*/
|
||||||
|
private PaperCard getBasicLand(final int basicLand) {
|
||||||
|
String set;
|
||||||
|
if (setsWithBasicLands.size() > 1) {
|
||||||
|
set = setsWithBasicLands.get(MyRandom.getRandom().nextInt(setsWithBasicLands.size() - 1));
|
||||||
|
} else {
|
||||||
|
set = setsWithBasicLands.get(0);
|
||||||
|
}
|
||||||
|
return FModel.getMagicDb().getCommonCards().getCard(MagicColor.Constant.BASIC_LANDS.get(basicLand), set);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only adds wastes if present in the card pool but if present adds them all
|
||||||
|
*/
|
||||||
|
private void addWastesIfRequired(){
|
||||||
|
Iterable<PaperCard> wastes = Iterables.filter(aiPlayables,PaperCard.Predicates.name("Wastes"));
|
||||||
|
if(wastes.iterator().hasNext()){
|
||||||
|
PaperCard waste = wastes.iterator().next();
|
||||||
|
while(landsNeeded>0) {
|
||||||
|
deckList.add(waste);
|
||||||
|
landsNeeded--;
|
||||||
|
}
|
||||||
|
aiPlayables.remove(waste);
|
||||||
|
rankedColorList.remove(waste);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attempt to optimize basic land counts according to color representation.
|
||||||
|
* Only consider colors that are supposed to be in the deck. It's not worth
|
||||||
|
* putting one land in for that random off-color card we had to stick in at
|
||||||
|
* the end...
|
||||||
|
*
|
||||||
|
* @return CCnt
|
||||||
|
*/
|
||||||
|
private int[] calculateLandNeeds() {
|
||||||
|
final int[] clrCnts = { 0,0,0,0,0 };
|
||||||
|
// count each card color using mana costs
|
||||||
|
for (final PaperCard cp : deckList) {
|
||||||
|
final ManaCost mc = cp.getRules().getManaCost();
|
||||||
|
|
||||||
|
// count each mana symbol in the mana cost
|
||||||
|
for (final ManaCostShard shard : mc) {
|
||||||
|
for ( int i = 0 ; i < MagicColor.WUBRG.length; i++ ) {
|
||||||
|
final byte c = MagicColor.WUBRG[i];
|
||||||
|
|
||||||
|
if ( shard.canBePaidWithManaOfColor(c) && colors.hasAnyColor(c)) {
|
||||||
|
clrCnts[i]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clrCnts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add non-basic lands to the deck.
|
||||||
|
*/
|
||||||
|
private void addNonBasicLands() {
|
||||||
|
final Iterable<PaperCard> lands = Iterables.filter(aiPlayables,
|
||||||
|
Predicates.compose(CardRulesPredicates.Presets.IS_NONBASIC_LAND, PaperCard.FN_GET_RULES));
|
||||||
|
List<PaperCard> landsToAdd = new ArrayList<>();
|
||||||
|
int minBasics;//Keep a minimum number of basics to ensure playable decks
|
||||||
|
if(colors.isMonoColor()){
|
||||||
|
minBasics=Math.round((r.nextInt(15)+6)*targetSize/60);
|
||||||
|
}else{
|
||||||
|
minBasics=Math.round((r.nextInt(8)+6)*targetSize/60);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
for (final PaperCard card : lands) {
|
||||||
|
if (landsNeeded > minBasics) {
|
||||||
|
// Throw out any dual-lands for the wrong colors. Assume
|
||||||
|
// everything else is either
|
||||||
|
// (a) dual-land of the correct two colors, or
|
||||||
|
// (b) a land that generates colorless mana and has some other
|
||||||
|
// beneficial effect.
|
||||||
|
if (!card.getRules().getColorIdentity().isColorless() && card.getRules().getColorIdentity().getSharedColors(colors).countColors()==0){
|
||||||
|
//skip as does not match colours
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Excluding NonBasicLand: " + card.getName());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!inverseDLands.contains(card.getName())&&!dLands.contains(card.getName())&&r.nextInt(100)<90) {
|
||||||
|
landsToAdd.add(card);
|
||||||
|
landsNeeded--;
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("NonBasicLand[" + landsNeeded + "]:" + card.getName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deckList.addAll(landsToAdd);
|
||||||
|
aiPlayables.removeAll(landsToAdd);
|
||||||
|
rankedColorList.removeAll(landsToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add random cards to the deck.
|
||||||
|
*
|
||||||
|
* @param num
|
||||||
|
* number to add
|
||||||
|
*/
|
||||||
|
private void addRandomCards(int num) {
|
||||||
|
Predicate<PaperCard> possibleFromFullPool = new Predicate<PaperCard>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(PaperCard card) {
|
||||||
|
return format.isLegalCard(card)
|
||||||
|
&&!card.getRules().getManaCost().isPureGeneric()
|
||||||
|
&& colors.containsAllColorsFrom(card.getRules().getColorIdentity().getColor())
|
||||||
|
&& !deckList.contains(card)
|
||||||
|
&&!card.getRules().getAiHints().getRemAIDecks()
|
||||||
|
&&!card.getRules().getAiHints().getRemRandomDecks()
|
||||||
|
&&!card.getRules().getMainPart().getType().isLand();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
List<PaperCard> randomPool = Lists.newArrayList(pool.getAllCards(possibleFromFullPool));
|
||||||
|
Collections.shuffle(randomPool,new Random());
|
||||||
|
Iterator<PaperCard> iRandomPool=randomPool.iterator();
|
||||||
|
for(int i=0;i<num;++i){
|
||||||
|
PaperCard randomCard=iRandomPool.next();
|
||||||
|
deckList.add(randomCard);
|
||||||
|
if(logToConsole) {
|
||||||
|
System.out.println("Random Card[" + i + "]:" + randomCard.getName() + " (" + randomCard.getRules().getManaCost() + ")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add creatures to the deck.
|
||||||
|
*
|
||||||
|
* @param cards
|
||||||
|
* cards to choose from
|
||||||
|
* @param num
|
||||||
|
* number to add
|
||||||
|
*/
|
||||||
|
private void addCards(final Iterable<PaperCard> cards, int num) {
|
||||||
|
List<PaperCard> cardsToAdd = new ArrayList<>();
|
||||||
|
for (final PaperCard card : cards) {
|
||||||
|
if(card.getRules().getMainPart().getType().isLand()){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (num +1 > 0) {
|
||||||
|
cardsToAdd.add(card);
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println("Extra needed[" + num + "]:" + card.getName() + " (" + card.getRules().getManaCost() + ")");
|
||||||
|
}
|
||||||
|
num--;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deckList.addAll(cardsToAdd);
|
||||||
|
aiPlayables.removeAll(cardsToAdd);
|
||||||
|
rankedColorList.removeAll(cardsToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add cards to the deck, trying to follow some mana curve. Trying to
|
||||||
|
* have generous limits at each cost, but perhaps still too strict. But
|
||||||
|
* we're trying to prevent the AI from adding everything at a single cost.
|
||||||
|
*
|
||||||
|
* @param creatures
|
||||||
|
* cards to choose from
|
||||||
|
* @param num
|
||||||
|
* number to add
|
||||||
|
*/
|
||||||
|
private void addManaCurveCards(final Iterable<PaperCard> creatures, int num, String nameForLog) {
|
||||||
|
/* // Add the deck card
|
||||||
|
if(commanderCard.getRules().getMainPart().getType().isCreature()) {
|
||||||
|
keyCards = Iterables.filter(aiPlayables,PaperCard.Predicates.name(commanderCard.getName()));
|
||||||
|
final List<PaperCard> keyCardList = Lists.newArrayList(keyCards);
|
||||||
|
deckList.addAll(keyCardList);
|
||||||
|
aiPlayables.removeAll(keyCardList);
|
||||||
|
rankedColorList.removeAll(keyCardList);
|
||||||
|
}*/
|
||||||
|
final Map<Integer,Integer> targetCMCs = new HashMap<>();
|
||||||
|
targetCMCs.put(1,Math.round((r.nextInt(4)+2)*targetSize/60));//2
|
||||||
|
targetCMCs.put(2,Math.round((r.nextInt(5)+5)*targetSize/60));//6
|
||||||
|
targetCMCs.put(3,Math.round((r.nextInt(5)+6)*targetSize/60));//7
|
||||||
|
targetCMCs.put(4,Math.round((r.nextInt(3)+3)*targetSize/60));//4
|
||||||
|
targetCMCs.put(5,Math.round((r.nextInt(3)+3)*targetSize/60));//3
|
||||||
|
targetCMCs.put(6,Math.round((r.nextInt(3)+1)*targetSize/60));//2
|
||||||
|
|
||||||
|
|
||||||
|
final Map<Integer, Integer> creatureCosts = new HashMap<Integer, Integer>();
|
||||||
|
for (int i = 1; i < 7; i++) {
|
||||||
|
creatureCosts.put(i, 0);
|
||||||
|
}
|
||||||
|
final Predicate<PaperCard> filter = Predicates.compose(CardRulesPredicates.Presets.IS_CREATURE,
|
||||||
|
PaperCard.FN_GET_RULES);
|
||||||
|
for (final IPaperCard creature : Iterables.filter(deckList, filter)) {
|
||||||
|
int cmc = creature.getRules().getManaCost().getCMC();
|
||||||
|
if (cmc < 1) {
|
||||||
|
cmc = 1;
|
||||||
|
} else if (cmc > 6) {
|
||||||
|
cmc = 6;
|
||||||
|
}
|
||||||
|
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<PaperCard> creaturesToAdd = new ArrayList<>();
|
||||||
|
for (final PaperCard card : creatures) {
|
||||||
|
int cmc = card.getRules().getManaCost().getCMC();
|
||||||
|
if (cmc < 1) {
|
||||||
|
cmc = 1;
|
||||||
|
} else if (cmc > 6) {
|
||||||
|
cmc = 6;
|
||||||
|
}
|
||||||
|
final Integer currentAtCmc = creatureCosts.get(cmc);
|
||||||
|
boolean willAddCreature = false;
|
||||||
|
if (cmc <= 1 && currentAtCmc < targetCMCs.get(1)) {
|
||||||
|
willAddCreature = true;
|
||||||
|
} else if (cmc == 2 && currentAtCmc < targetCMCs.get(2)) {
|
||||||
|
willAddCreature = true;
|
||||||
|
} else if (cmc == 3 && currentAtCmc < targetCMCs.get(3)) {
|
||||||
|
willAddCreature = true;
|
||||||
|
} else if (cmc == 4 && currentAtCmc < targetCMCs.get(4)) {
|
||||||
|
willAddCreature = true;
|
||||||
|
} else if (cmc == 5 && currentAtCmc < targetCMCs.get(5)) {
|
||||||
|
willAddCreature = true;
|
||||||
|
} else if (cmc >= 6 && currentAtCmc < targetCMCs.get(6)) {
|
||||||
|
willAddCreature = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (willAddCreature) {
|
||||||
|
creaturesToAdd.add(card);
|
||||||
|
num--;
|
||||||
|
creatureCosts.put(cmc, creatureCosts.get(cmc) + 1);
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println(nameForLog+"[" + num + "]:" + card.getName() + " (" + card.getRules().getManaCost() + ")");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (logToConsole) {
|
||||||
|
System.out.println(card.getName() + " not added because CMC " + card.getRules().getManaCost().getCMC()
|
||||||
|
+ " has " + currentAtCmc + " already.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (num <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
deckList.addAll(creaturesToAdd);
|
||||||
|
aiPlayables.removeAll(creaturesToAdd);
|
||||||
|
rankedColorList.removeAll(creaturesToAdd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate average CMC.
|
||||||
|
*
|
||||||
|
* @param cards
|
||||||
|
* cards to choose from
|
||||||
|
* @return the average
|
||||||
|
*/
|
||||||
|
private static double getAverageCMC(final List<PaperCard> cards) {
|
||||||
|
double sum = 0.0;
|
||||||
|
for (final IPaperCard cardPrinted : cards) {
|
||||||
|
sum += cardPrinted.getRules().getManaCost().getCMC();
|
||||||
|
}
|
||||||
|
return sum / cards.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate max CMC.
|
||||||
|
*
|
||||||
|
* @param cards
|
||||||
|
* cards to choose from
|
||||||
|
* @return the average
|
||||||
|
*/
|
||||||
|
private static int getMaxCMC(final List<PaperCard> cards) {
|
||||||
|
int max = 0;
|
||||||
|
for (final IPaperCard cardPrinted : cards) {
|
||||||
|
if(cardPrinted.getRules().getManaCost().getCMC()>max) {
|
||||||
|
max = cardPrinted.getRules().getManaCost().getCMC();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the colors
|
||||||
|
*/
|
||||||
|
public ColorSet getColors() {
|
||||||
|
return colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param colors0
|
||||||
|
* the colors to set
|
||||||
|
*/
|
||||||
|
public void setColors(final ColorSet colors0) {
|
||||||
|
colors = colors0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the aiPlayables
|
||||||
|
*/
|
||||||
|
public List<PaperCard> getAiPlayables() {
|
||||||
|
return aiPlayables;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -190,7 +190,7 @@ public class CardThemedDeckBuilder extends DeckGeneratorBase {
|
|||||||
// extras.
|
// extras.
|
||||||
double avCMC=getAverageCMC(deckList);
|
double avCMC=getAverageCMC(deckList);
|
||||||
int maxCMC=getMaxCMC(deckList);
|
int maxCMC=getMaxCMC(deckList);
|
||||||
if (deckList.size() == numSpellsNeeded && avCMC < 4) {
|
if (deckList.size() >= numSpellsNeeded && avCMC < 4) {
|
||||||
addLowCMCCard();
|
addLowCMCCard();
|
||||||
}
|
}
|
||||||
if (deckList.size() >= numSpellsNeeded && avCMC < 3 && maxCMC<6) {
|
if (deckList.size() >= numSpellsNeeded && avCMC < 3 && maxCMC<6) {
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ import forge.ai.AiProfileUtil;
|
|||||||
import forge.card.CardPreferences;
|
import forge.card.CardPreferences;
|
||||||
import forge.card.CardType;
|
import forge.card.CardType;
|
||||||
import forge.deck.CardRelationMatrixGenerator;
|
import forge.deck.CardRelationMatrixGenerator;
|
||||||
|
import forge.deck.DeckFormat;
|
||||||
|
import forge.deck.io.CardThemedMatrixIO;
|
||||||
import forge.deck.io.DeckPreferences;
|
import forge.deck.io.DeckPreferences;
|
||||||
import forge.game.GameFormat;
|
import forge.game.GameFormat;
|
||||||
import forge.game.GameType;
|
import forge.game.GameType;
|
||||||
@@ -218,11 +220,18 @@ public final class FModel {
|
|||||||
AiProfileUtil.loadAllProfiles(ForgeConstants.AI_PROFILE_DIR);
|
AiProfileUtil.loadAllProfiles(ForgeConstants.AI_PROFILE_DIR);
|
||||||
|
|
||||||
//generate Deck Gen matrix
|
//generate Deck Gen matrix
|
||||||
if(!FModel.getPreferences().getPrefBoolean(FPref.LOAD_CARD_SCRIPTS_LAZILY)) {
|
if(!FModel.getPreferences().getPrefBoolean(FPref.LOAD_CARD_SCRIPTS_LAZILY)
|
||||||
CardRelationMatrixGenerator.initialize();
|
&&FModel.getPreferences().getPrefBoolean(FPref.DECKGEN_CARDBASED)) {
|
||||||
|
deckGenMatrixLoaded=CardRelationMatrixGenerator.initialize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean deckGenMatrixLoaded=false;
|
||||||
|
|
||||||
|
public static boolean isdeckGenMatrixLoaded(){
|
||||||
|
return deckGenMatrixLoaded;
|
||||||
|
}
|
||||||
|
|
||||||
public static QuestController getQuest() {
|
public static QuestController getQuest() {
|
||||||
return quest;
|
return quest;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -34,6 +34,22 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
|||||||
CONSTRUCTED_P6_DECK_STATE(""),
|
CONSTRUCTED_P6_DECK_STATE(""),
|
||||||
CONSTRUCTED_P7_DECK_STATE(""),
|
CONSTRUCTED_P7_DECK_STATE(""),
|
||||||
CONSTRUCTED_P8_DECK_STATE(""),
|
CONSTRUCTED_P8_DECK_STATE(""),
|
||||||
|
COMMANDER_P1_DECK_STATE(""),
|
||||||
|
COMMANDER_P2_DECK_STATE(""),
|
||||||
|
COMMANDER_P3_DECK_STATE(""),
|
||||||
|
COMMANDER_P4_DECK_STATE(""),
|
||||||
|
COMMANDER_P5_DECK_STATE(""),
|
||||||
|
COMMANDER_P6_DECK_STATE(""),
|
||||||
|
COMMANDER_P7_DECK_STATE(""),
|
||||||
|
COMMANDER_P8_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P1_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P2_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P3_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P4_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P5_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P6_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P7_DECK_STATE(""),
|
||||||
|
TINY_LEADER_P8_DECK_STATE(""),
|
||||||
UI_LANDSCAPE_MODE ("false"),
|
UI_LANDSCAPE_MODE ("false"),
|
||||||
UI_COMPACT_MAIN_MENU ("false"),
|
UI_COMPACT_MAIN_MENU ("false"),
|
||||||
UI_USE_OLD ("false"),
|
UI_USE_OLD ("false"),
|
||||||
@@ -140,6 +156,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
|||||||
DECKGEN_SINGLETONS ("false"),
|
DECKGEN_SINGLETONS ("false"),
|
||||||
DECKGEN_ARTIFACTS ("false"),
|
DECKGEN_ARTIFACTS ("false"),
|
||||||
DECKGEN_NOSMALL ("false"),
|
DECKGEN_NOSMALL ("false"),
|
||||||
|
DECKGEN_CARDBASED ("true"),
|
||||||
|
|
||||||
PHASE_AI_UPKEEP ("false"),
|
PHASE_AI_UPKEEP ("false"),
|
||||||
PHASE_AI_DRAW ("false"),
|
PHASE_AI_DRAW ("false"),
|
||||||
@@ -210,6 +227,19 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
|||||||
CONSTRUCTED_P3_DECK_STATE, CONSTRUCTED_P4_DECK_STATE,
|
CONSTRUCTED_P3_DECK_STATE, CONSTRUCTED_P4_DECK_STATE,
|
||||||
CONSTRUCTED_P5_DECK_STATE, CONSTRUCTED_P6_DECK_STATE,
|
CONSTRUCTED_P5_DECK_STATE, CONSTRUCTED_P6_DECK_STATE,
|
||||||
CONSTRUCTED_P7_DECK_STATE, CONSTRUCTED_P8_DECK_STATE };
|
CONSTRUCTED_P7_DECK_STATE, CONSTRUCTED_P8_DECK_STATE };
|
||||||
|
|
||||||
|
public static FPref[] COMMANDER_DECK_STATES = {
|
||||||
|
COMMANDER_P1_DECK_STATE, COMMANDER_P2_DECK_STATE,
|
||||||
|
COMMANDER_P3_DECK_STATE, COMMANDER_P4_DECK_STATE,
|
||||||
|
COMMANDER_P5_DECK_STATE, COMMANDER_P6_DECK_STATE,
|
||||||
|
COMMANDER_P7_DECK_STATE, COMMANDER_P8_DECK_STATE };
|
||||||
|
|
||||||
|
public static FPref[] TINY_LEADER_DECK_STATES = {
|
||||||
|
TINY_LEADER_P1_DECK_STATE, TINY_LEADER_P2_DECK_STATE,
|
||||||
|
TINY_LEADER_P3_DECK_STATE, TINY_LEADER_P4_DECK_STATE,
|
||||||
|
TINY_LEADER_P5_DECK_STATE, TINY_LEADER_P6_DECK_STATE,
|
||||||
|
TINY_LEADER_P7_DECK_STATE, TINY_LEADER_P8_DECK_STATE };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Instantiates a ForgePreferences object. */
|
/** Instantiates a ForgePreferences object. */
|
||||||
|
|||||||
Reference in New Issue
Block a user