Merge branch 'BrawlFormat' into 'master'

Brawl format

See merge request core-developers/forge!324
This commit is contained in:
Michael Kamensky
2018-03-30 06:35:07 +00:00
31 changed files with 458 additions and 81 deletions

View File

@@ -1,5 +1,6 @@
package forge;
import com.google.common.base.Predicate;
import forge.card.CardDb;
import forge.card.CardEdition;
import forge.card.CardRules;
@@ -32,6 +33,9 @@ public class StaticData {
private final TokenDb allTokens;
private final CardEdition.Collection editions;
private Predicate<PaperCard> standardPredicate;
private Predicate<PaperCard> modernPredicate;
// Loaded lazily:
private IStorage<SealedProduct.Template> boosters;
private IStorage<SealedProduct.Template> specialBoosters;
@@ -186,6 +190,18 @@ public class StaticData {
public TokenDb getAllTokens() { return allTokens; }
public Predicate<PaperCard> getStandardPredicate() {
return standardPredicate;
}
public void setStandardPredicate(Predicate<PaperCard> standardPredicate) { this.standardPredicate = standardPredicate; }
public void setModernPredicate(Predicate<PaperCard> modernPredicate) { this.modernPredicate = standardPredicate; }
public Predicate<PaperCard> getModernPredicate() {
return modernPredicate;
}
public PaperCard getCardByEditionDate(PaperCard card, Date editionDate) {
PaperCard c = this.getCommonCards().getCardFromEdition(card.getName(), editionDate, CardDb.SetPreference.LatestCoreExp, card.getArtIndex());

View File

@@ -207,6 +207,11 @@ public final class CardRules implements ICardCharacteristics {
return canBeCommander() && Iterables.contains(mainPart.getKeywords(), "Partner");
}
public boolean canBeBrawlCommander() {
CardType type = mainPart.getType();
return (type.isLegendary() && type.isCreature()) || type.isPlaneswalker();
}
public String getMeldWith() {
return meldWith;
}

View File

@@ -572,6 +572,8 @@ public final class CardRulesPredicates {
public static final Predicate<CardRules> IS_NON_CREATURE_SPELL = Predicates.not(Predicates.or(Presets.IS_CREATURE, Presets.IS_LAND));
public static final Predicate<CardRules> CAN_BE_COMMANDER = Predicates.or(CardRulesPredicates.rules(StringOp.CONTAINS_IC, "can be your commander"),
Predicates.and(Presets.IS_CREATURE, Presets.IS_LEGENDARY));
public static final Predicate<CardRules> CAN_BE_BRAWL_COMMANDER = Predicates.or(Presets.IS_PLANESWALKER,
Predicates.and(Presets.IS_CREATURE, Presets.IS_LEGENDARY));
/** The Constant IS_NONCREATURE_SPELL_FOR_GENERATOR. **/
@SuppressWarnings("unchecked")

View File

@@ -68,6 +68,8 @@ public enum DeckFormat {
return true;
}
}),
Pauper ( Range.is(60), Range.between(0, 10), 1),
Brawl ( Range.is(59), Range.between(0, 15), 1, null, StaticData.instance() == null ? null : StaticData.instance().getStandardPredicate()),
TinyLeaders ( Range.is(49), Range.between(0, 10), 1, new Predicate<CardRules>() {
private final Set<String> bannedCards = new HashSet<String>(Arrays.asList(
"Ancestral Recall", "Balance", "Black Lotus", "Black Vise", "Channel", "Chaos Orb", "Contract From Below", "Counterbalance", "Darkpact", "Demonic Attorney", "Demonic Tutor", "Earthcraft", "Edric, Spymaster of Trest", "Falling Star",
@@ -117,21 +119,36 @@ public enum DeckFormat {
private final Range<Integer> sideRange; // null => no check
private final int maxCardCopies;
private final Predicate<CardRules> cardPoolFilter;
private final Predicate<PaperCard> paperCardPoolFilter;
private final static String ADVPROCLAMATION = "Advantageous Proclamation";
private final static String SOVREALM = "Sovereign's Realm";
private DeckFormat(Range<Integer> mainRange0, Range<Integer> sideRange0, int maxCardCopies0) {
this(mainRange0, sideRange0, maxCardCopies0, null);
}
private DeckFormat(Range<Integer> mainRange0, Range<Integer> sideRange0, int maxCardCopies0, Predicate<CardRules> cardPoolFilter0) {
private DeckFormat(Range<Integer> mainRange0, Range<Integer> sideRange0, int maxCardCopies0, Predicate<CardRules> cardPoolFilter0, Predicate<PaperCard> paperCardPoolFilter0) {
mainRange = mainRange0;
sideRange = sideRange0;
maxCardCopies = maxCardCopies0;
cardPoolFilter = cardPoolFilter0;
paperCardPoolFilter = paperCardPoolFilter0;
}
private DeckFormat(Range<Integer> mainRange0, Range<Integer> sideRange0, int maxCardCopies0, Predicate<CardRules> cardPoolFilter0) {
mainRange = mainRange0;
sideRange = sideRange0;
maxCardCopies = maxCardCopies0;
paperCardPoolFilter = null;
cardPoolFilter = cardPoolFilter0;
}
private DeckFormat(Range<Integer> mainRange0, Range<Integer> sideRange0, int maxCardCopies0) {
mainRange = mainRange0;
sideRange = sideRange0;
maxCardCopies = maxCardCopies0;
paperCardPoolFilter = null;
cardPoolFilter = null;
}
private boolean hasCommander() {
return this == Commander || this == TinyLeaders;
return this == Commander || this == TinyLeaders || this == Brawl;
}
/**
@@ -364,7 +381,16 @@ public enum DeckFormat {
public IDeckGenPool getCardPool(IDeckGenPool basePool) {
if (cardPoolFilter == null) {
return basePool;
if (paperCardPoolFilter == null) {
return basePool;
}
DeckGenPool filteredPool = new DeckGenPool();
for (PaperCard pc : basePool.getAllCards()) {
if (paperCardPoolFilter.apply(pc)) {
filteredPool.add(pc);
}
}
return filteredPool;
}
DeckGenPool filteredPool = new DeckGenPool();
for (PaperCard pc : basePool.getAllCards()) {
@@ -381,7 +407,10 @@ public enum DeckFormat {
public boolean isLegalCard(PaperCard pc) {
if (cardPoolFilter == null) {
return true;
if (paperCardPoolFilter == null) {
return true;
}
return paperCardPoolFilter.apply(pc);
}
return cardPoolFilter.apply(pc.getRules());
}
@@ -390,6 +419,9 @@ public enum DeckFormat {
if (cardPoolFilter != null && !cardPoolFilter.apply(rules)) {
return false;
}
if(this.equals(DeckFormat.Brawl)) {
return rules.canBeBrawlCommander();
}
return rules.canBeCommander();
}
@@ -413,6 +445,13 @@ public enum DeckFormat {
}
}
}
if (paperCardPoolFilter != null) {
for (final Entry<PaperCard, Integer> cp : deck.getAllCardsInASinglePool()) {
if (!paperCardPoolFilter.apply(cp.getKey())) {
return false;
}
}
}
return true;
}
};

View File

@@ -78,7 +78,8 @@ public class GameRules {
}
public boolean hasCommander() {
return appliedVariants.contains(GameType.Commander) || appliedVariants.contains(GameType.TinyLeaders);
return appliedVariants.contains(GameType.Commander) || appliedVariants.contains(GameType.TinyLeaders)
|| appliedVariants.contains(GameType.Brawl);
}
public boolean canCloneUseTargetsImage() {

View File

@@ -23,6 +23,7 @@ public enum GameType {
Vanguard (DeckFormat.Vanguard, true, true, true, "Vanguard", "Each player has a special \"Avatar\" card that affects the game."),
Commander (DeckFormat.Commander, false, false, false, "Commander", "Each player has a legendary \"General\" card which can be cast at any time and determines deck colors."),
TinyLeaders (DeckFormat.TinyLeaders, false, false, false, "Tiny Leaders", "Each player has a legendary \"General\" card which can be cast at any time and determines deck colors. Each card must have CMC less than 4."),
Brawl (DeckFormat.Brawl, false, false, false, "Brawl", "Each player has a legendary \"General\" card which can be cast at any time and determines deck colors. Only cards legal in Standard may be used."),
Planeswalker (DeckFormat.PlanarConquest, false, false, true, "Planeswalker", "Each player has a Planeswalker card which can be cast at any time."),
Planechase (DeckFormat.Planechase, false, false, true, "Planechase", "Plane cards apply global effects. The Plane card changes when a player rolls \"Planeswalk\" on the planar die."),
Archenemy (DeckFormat.Archenemy, false, false, true, "Archenemy", "One player is the Archenemy and fights the other players by playing Scheme cards."),

View File

@@ -2078,7 +2078,7 @@ public class CardFactoryUtil {
" | ValidBlocker$ Creature | Secondary$ True " +
" | TriggerDescription$ Afflict " + n + " (" + inst.getReminderText() + ")";
final String abStringAfflict = "DB$ Loselife | Defined$ TriggeredDefendingPlayer" +
final String abStringAfflict = "DB$ LoseLife | Defined$ TriggeredDefendingPlayer" +
" | LifeAmount$ " + n;
final Trigger afflictTrigger = TriggerHandler.parseTrigger(trigStr.toString(), card, intrinsic);

View File

@@ -550,8 +550,9 @@ public class Player extends GameEntity implements Comparable<Player> {
}
}
//Tiny Leaders ignore commander damage rule.
if (source.isCommander() && isCombat && this.getGame().getRules().getGameType() != GameType.TinyLeaders) {
//Tiny Leaders and Brawl ignore commander damage rule.
if (source.isCommander() && isCombat && this.getGame().getRules().getGameType() != GameType.TinyLeaders
&& this.getGame().getRules().getGameType() != GameType.Brawl) {
commanderDamage.put(source, getCommanderDamage(source) + amount);
view.updateCommanderDamage(this);
}

View File

@@ -124,6 +124,10 @@ public class RegisteredPlayer {
start.commanders = deck.getCommanders();
start.setStartingLife(start.getStartingLife() + 5);
}
if (appliedVariants.contains(GameType.Brawl)) {
start.commanders = deck.getCommanders();
start.setStartingLife(start.getStartingLife() + 10);
}
if (appliedVariants.contains(GameType.Planechase)) {
start.planes = planes;
}

View File

@@ -136,6 +136,8 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
updateDecks(DeckProxy.getAllCommanderDecks(), ItemManagerConfig.COMMANDER_DECKS);
}else if(deckFormat.equals(DeckFormat.TinyLeaders)){
updateDecks(DeckProxy.getAllTinyLeadersDecks(), ItemManagerConfig.COMMANDER_DECKS);
}else if(deckFormat.equals(DeckFormat.Brawl)){
updateDecks(DeckProxy.getAllBrawlDecks(), ItemManagerConfig.COMMANDER_DECKS);
}else {
updateDecks(DeckProxy.getAllConstructedDecks(), ItemManagerConfig.CONSTRUCTED_DECKS);
}
@@ -178,8 +180,9 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
}
private void updateRandomCommander() {
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander)&&
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders)))){
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander))&&
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders))&&
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Brawl))){
return;
}
lstDecks.setAllowMultipleSelections(false);
@@ -200,8 +203,9 @@ public class FDeckChooser extends JPanel implements IDecksComboBoxListener {
}
private void updateRandomCardGenCommander() {
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander)&&
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders)))){
if((!lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Commander))&&
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.TinyLeaders))&&
!(lstDecks.getGameType().getDeckFormat().equals(DeckFormat.Brawl))){
return;
}
lstDecks.setAllowMultipleSelections(false);

View File

@@ -79,6 +79,15 @@ public class FScreen {
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_BRAWL = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,
"Brawl Deck Editor",
FSkin.getImage(FSkinProp.IMG_PACK),
true,
"Close Editor",
ForgeConstants.EDITOR_LAYOUT_FILE,
false);
public static final FScreen DECK_EDITOR_PLANECHASE = new FScreen(
VDeckEditorUI.SINGLETON_INSTANCE,
CDeckEditorUI.SINGLETON_INSTANCE,

View File

@@ -17,9 +17,11 @@
*/
package forge.screens.deckeditor.controllers;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.base.Supplier;
import forge.UiCommand;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.deck.Deck;
import forge.deck.DeckSection;
@@ -65,14 +67,27 @@ public final class CEditorCommander extends ACEditorBase<PaperCard, Deck> {
* all cards are available.
*/
@SuppressWarnings("serial")
public CEditorCommander(final CDetailPicture cDetailPicture, boolean tinyLeaders) {
super(tinyLeaders ? FScreen.DECK_EDITOR_TINY_LEADERS : FScreen.DECK_EDITOR_COMMANDER, cDetailPicture);
public CEditorCommander(final CDetailPicture cDetailPicture, boolean tinyLeaders, boolean brawl) {
super(tinyLeaders ? FScreen.DECK_EDITOR_TINY_LEADERS : brawl ? FScreen.DECK_EDITOR_BRAWL : FScreen.DECK_EDITOR_COMMANDER, cDetailPicture);
allSections.add(DeckSection.Main);
allSections.add(DeckSection.Sideboard);
allSections.add(DeckSection.Commander);
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(CardRulesPredicates.Presets.CAN_BE_COMMANDER, PaperCard.FN_GET_RULES)),PaperCard.class);
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class);
if(brawl){
Predicate<CardRules> commanderFilter = CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER;
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.and(
FModel.getFormats().getStandard().getFilterPrinted(),Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES))),PaperCard.class);
}else{
Predicate<CardRules> commanderFilter = CardRulesPredicates.Presets.CAN_BE_COMMANDER ;
commanderPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(Predicates.compose(commanderFilter, PaperCard.FN_GET_RULES)),PaperCard.class);
}
if(brawl){
normalPool = ItemPool.createFrom(FModel.getFormats().getStandard().getAllCards(), PaperCard.class);
}else {
normalPool = ItemPool.createFrom(FModel.getMagicDb().getCommonCards().getAllCards(), PaperCard.class);
}
CardManager catalogManager = new CardManager(getCDetailPicture(), true, false);
CardManager deckManager = new CardManager(getCDetailPicture(), true, false);
@@ -88,7 +103,7 @@ public final class CEditorCommander extends ACEditorBase<PaperCard, Deck> {
return new Deck();
}
};
this.controller = new DeckController<Deck>(tinyLeaders ? FModel.getDecks().getTinyLeaders() :FModel.getDecks().getCommander(), this, newCreator);
this.controller = new DeckController<Deck>(tinyLeaders ? FModel.getDecks().getTinyLeaders() :brawl ? FModel.getDecks().getBrawl(): FModel.getDecks().getCommander(), this, newCreator);
getBtnAddBasicLands().setCommand(new UiCommand() {
@Override

View File

@@ -95,6 +95,14 @@ public class CLobby {
view.focusOnAvatar();
}
});
final FDeckChooser fdbcom = view.getBrawlDeckChooser(iSlot);
fdbcom.initialize(FPref.BRAWL_DECK_STATES[iSlot], defaultDeckTypeForBrawlSlot(iSlot));
fdbcom.populate();
fdbcom.getDecksComboBox().addListener(new IDecksComboBoxListener() {
@Override public final void deckTypeSelected(final DecksComboBoxEvent ev) {
view.focusOnAvatar();
}
});
}
final ForgePreferences prefs = FModel.getPreferences();
@@ -131,4 +139,8 @@ public class CLobby {
private static DeckType defaultDeckTypeForTinyLeaderSlot(final int iSlot) {
return iSlot == 0 ? DeckType.TINY_LEADERS_DECKS : DeckType.RANDOM_CARDGEN_COMMANDER_DECK;
}
private static DeckType defaultDeckTypeForBrawlSlot(final int iSlot) {
return iSlot == 0 ? DeckType.BRAWL_DECKS : DeckType.CUSTOM_DECK;
}
}

View File

@@ -335,7 +335,8 @@ public class PlayerPanel extends FPanel {
private void updateVariantControlsVisibility() {
final boolean isTinyLeaders = lobby.hasVariant(GameType.TinyLeaders);
final boolean isCommanderApplied = mayEdit && (lobby.hasVariant(GameType.Commander) || isTinyLeaders);
final boolean isBrawl = lobby.hasVariant(GameType.Brawl);
final boolean isCommanderApplied = mayEdit && (lobby.hasVariant(GameType.Commander) || isTinyLeaders || isBrawl);
final boolean isPlanechaseApplied = mayEdit && lobby.hasVariant(GameType.Planechase);
final boolean isVanguardApplied = mayEdit && lobby.hasVariant(GameType.Vanguard);
final boolean isArchenemyApplied = mayEdit && lobby.hasVariant(GameType.Archenemy);
@@ -346,7 +347,7 @@ public class PlayerPanel extends FPanel {
deckLabel.setVisible(isDeckBuildingAllowed);
deckBtn.setVisible(isDeckBuildingAllowed);
cmdDeckSelectorBtn.setVisible(isCommanderApplied);
cmdDeckEditor.setText(isTinyLeaders ? "TL Deck Editor" : "Commander Deck Editor");
cmdDeckEditor.setText(isTinyLeaders ? "TL Deck Editor" : isBrawl ? "Brawl Editor" : "Commander Deck Editor");
cmdDeckEditor.setVisible(isCommanderApplied);
cmdLabel.setVisible(isCommanderApplied);
@@ -508,7 +509,7 @@ public class PlayerPanel extends FPanel {
cmdDeckSelectorBtn.setCommand(new Runnable() {
@Override
public void run() {
lobby.setCurrentGameMode(lobby.hasVariant(GameType.TinyLeaders) ? GameType.TinyLeaders : GameType.Commander);
lobby.setCurrentGameMode(lobby.hasVariant(GameType.TinyLeaders) ? GameType.TinyLeaders : lobby.hasVariant(GameType.Brawl) ? GameType.Brawl : GameType.Commander);
cmdDeckSelectorBtn.requestFocusInWindow();
lobby.changePlayerFocus(index);
}
@@ -520,11 +521,15 @@ public class PlayerPanel extends FPanel {
if (lobby.hasVariant(GameType.TinyLeaders)) {
lobby.setCurrentGameMode(GameType.TinyLeaders);
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_TINY_LEADERS);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorCommander(CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture(), true));
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorCommander(CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture(), true, false));
} else if (lobby.hasVariant(GameType.Brawl)) {
lobby.setCurrentGameMode(GameType.Brawl);
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_BRAWL);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorCommander(CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture(), false, true));
} else {
lobby.setCurrentGameMode(GameType.Commander);
Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_COMMANDER);
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorCommander(CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture(), false));
CDeckEditorUI.SINGLETON_INSTANCE.setEditorController(new CEditorCommander(CDeckEditorUI.SINGLETON_INSTANCE.getCDetailPicture(), false, false));
}
}
});

View File

@@ -91,13 +91,14 @@ public class VLobby implements ILobbyView {
private final VariantCheckBox vntMomirBasic = new VariantCheckBox(GameType.MomirBasic);
private final VariantCheckBox vntCommander = new VariantCheckBox(GameType.Commander);
private final VariantCheckBox vntTinyLeaders = new VariantCheckBox(GameType.TinyLeaders);
private final VariantCheckBox vntBrawl = new VariantCheckBox(GameType.Brawl);
private final VariantCheckBox vntPlanechase = new VariantCheckBox(GameType.Planechase);
private final VariantCheckBox vntArchenemy = new VariantCheckBox(GameType.Archenemy);
private final VariantCheckBox vntArchenemyRumble = new VariantCheckBox(GameType.ArchenemyRumble);
private final ImmutableList<VariantCheckBox> vntBoxesLocal =
ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntPlanechase, vntArchenemy, vntArchenemyRumble);
ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntBrawl, vntPlanechase, vntArchenemy, vntArchenemyRumble);
private final ImmutableList<VariantCheckBox> vntBoxesNetwork =
ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders /*, vntPlanechase, vntArchenemy, vntArchenemyRumble */);
ImmutableList.of(vntVanguard, vntMomirBasic, vntCommander, vntTinyLeaders, vntBrawl /*, vntPlanechase, vntArchenemy, vntArchenemyRumble */);
// Player frame elements
private final JPanel playersFrame = new JPanel(new MigLayout("insets 0, gap 0 5, wrap, hidemode 3"));
@@ -119,8 +120,13 @@ public class VLobby implements ILobbyView {
private final List<FList<Object>> tinyLeadersDeckLists = new ArrayList<FList<Object>>();
private final List<FPanel> tinyLeadersDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
private final List<FList<Object>> brawlDeckLists = new ArrayList<FList<Object>>();
private final List<FPanel> brawlDeckPanels = 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<FDeckChooser> brawlDeckChoosers = Lists.newArrayListWithCapacity(MAX_PLAYERS);
private final List<FList<Object>> schemeDeckLists = new ArrayList<FList<Object>>();
private final List<FPanel> schemeDeckPanels = new ArrayList<FPanel>(MAX_PLAYERS);
@@ -227,6 +233,8 @@ public class VLobby implements ILobbyView {
fdcom.restoreSavedState();
final FDeckChooser fdtl = getTinyLeaderDeckChooser(iPlayer);
fdtl.restoreSavedState();
final FDeckChooser fdbr = getBrawlDeckChooser(iPlayer);
fdbr.restoreSavedState();
}
}
@@ -272,6 +280,17 @@ public class VLobby implements ILobbyView {
default:
break;
}
final FDeckChooser brawlDeckChooser = getBrawlDeckChooser(slot);
brawlDeckChooser.setIsAi(type==LobbySlotType.AI);
selectedDeckType = brawlDeckChooser.getSelectedDeckType();
switch (selectedDeckType){
case RANDOM_CARDGEN_COMMANDER_DECK:
case RANDOM_COMMANDER_DECK:
brawlDeckChooser.refreshDeckListForAI();
break;
default:
break;
}
}
@Override
@@ -299,6 +318,7 @@ public class VLobby implements ILobbyView {
final FDeckChooser deckChooser = getDeckChooser(i);
final FDeckChooser commanderDeckChooser = getCommanderDeckChooser(i);
final FDeckChooser tinyLeaderDeckChooser = getTinyLeaderDeckChooser(i);
final FDeckChooser brawlDeckChooser = getBrawlDeckChooser(i);
final PlayerPanel panel;
final boolean isNewPanel;
if (hasPanel) {
@@ -315,6 +335,7 @@ public class VLobby implements ILobbyView {
deckChooser.restoreSavedState();
commanderDeckChooser.restoreSavedState();
tinyLeaderDeckChooser.restoreSavedState();
brawlDeckChooser.restoreSavedState();
if (i == 0) {
slot.setIsDevMode(prefs.getPrefBoolean(FPref.DEV_MODE_ENABLED));
changePlayerFocus(0);
@@ -341,6 +362,7 @@ public class VLobby implements ILobbyView {
deckChooser.setIsAi(isSlotAI);
commanderDeckChooser.setIsAi(isSlotAI);
tinyLeaderDeckChooser.setIsAi(isSlotAI);
brawlDeckChooser.setIsAi(isSlotAI);
if (fullUpdate && (type == LobbySlotType.LOCAL || isSlotAI)) {
selectDeck(i);
}
@@ -461,6 +483,15 @@ public class VLobby implements ILobbyView {
tinyLeaderChooser.initialize();
tinyLeadersDeckChoosers.add(tinyLeaderChooser);
final FDeckChooser brawlChooser = new FDeckChooser(null, isPlayerAI(playerIndex), GameType.Brawl, true);
brawlChooser.getLstDecks().setSelectCommand(new UiCommand() {
@Override public final void run() {
selectBrawlDeck(playerIndex);
}
});
brawlChooser.initialize();
brawlDeckChoosers.add(brawlChooser);
/* // Tiny Leaders deck list
buildDeckPanel("Tiny Leaders Deck", playerIndex, tinyLeadersDeckLists, tinyLeadersDeckPanels, new ListSelectionListener() {
@@ -523,7 +554,7 @@ public class VLobby implements ILobbyView {
}
private void selectMainDeck(final int playerIndex) {
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders)) {
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders) || hasVariant(GameType.Brawl)) {
// These game types use specific deck panel
return;
}
@@ -573,6 +604,23 @@ public class VLobby implements ILobbyView {
mainChooser.saveState();
}
private void selectBrawlDeck(final int playerIndex) {
if (!hasVariant(GameType.Brawl)) {
// Only these game types use this specific deck panel
return;
}
final FDeckChooser mainChooser = getBrawlDeckChooser(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) {
@@ -712,6 +760,9 @@ public class VLobby implements ILobbyView {
case TinyLeaders:
decksFrame.add(tinyLeadersDeckChoosers.get(playerWithFocus), "grow, push");
break;
case Brawl:
decksFrame.add(brawlDeckChoosers.get(playerWithFocus), "grow, push");
break;
case Planechase:
decksFrame.add(planarDeckPanels.get(playerWithFocus), "grow, push");
break;
@@ -763,6 +814,10 @@ public class VLobby implements ILobbyView {
return tinyLeadersDeckChoosers.get(playernum);
}
public final FDeckChooser getBrawlDeckChooser(final int playernum) {
return brawlDeckChoosers.get(playernum);
}
GameType getCurrentGameMode() {
return lobby.getGameType();
}
@@ -921,6 +976,11 @@ public class VLobby implements ILobbyView {
return tinyLeadersDeckLists;
}
/** Gets the list of tiny leaders deck lists. */
public List<FList<Object>> getBrawlDeckLists() {
return brawlDeckLists;
}
/** Gets the list of scheme deck lists. */
public List<FList<Object>> getSchemeDeckLists() {
return schemeDeckLists;

View File

@@ -183,6 +183,7 @@ public class FDeckChooser extends FScreen {
break; //delay initialize for constructed until saved decks can be reloaded
case Commander:
case TinyLeaders:
case Brawl:
case Gauntlet:
initialize(null, DeckType.CUSTOM_DECK);
break;
@@ -220,6 +221,9 @@ public class FDeckChooser extends FScreen {
case TinyLeaders:
lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck());
break;
case Brawl:
lstDecks.setSelectedString(DeckPreferences.getBrawlDeck());
break;
case Archenemy:
lstDecks.setSelectedString(DeckPreferences.getSchemeDeck());
break;
@@ -234,6 +238,9 @@ public class FDeckChooser extends FScreen {
case TINY_LEADERS_DECKS:
lstDecks.setSelectedString(DeckPreferences.getTinyLeadersDeck());
break;
case BRAWL_DECKS:
lstDecks.setSelectedString(DeckPreferences.getBrawlDeck());
break;
case SCHEME_DECKS:
lstDecks.setSelectedString(DeckPreferences.getSchemeDeck());
break;
@@ -303,6 +310,7 @@ public class FDeckChooser extends FScreen {
switch (selectedDeckType) {
case COMMANDER_DECK:
case TINY_LEADERS_DECKS:
case BRAWL_DECKS:
case SCHEME_DECKS:
case PLANAR_DECKS:
case DRAFT_DECKS:
@@ -331,6 +339,7 @@ public class FDeckChooser extends FScreen {
case CONSTRUCTED_DECK:
case COMMANDER_DECK:
case TINY_LEADERS_DECKS:
case BRAWL_DECKS:
case SCHEME_DECKS:
case PLANAR_DECKS:
case DRAFT_DECKS:
@@ -374,6 +383,8 @@ public class FDeckChooser extends FScreen {
return EditorType.Commander;
case TINY_LEADERS_DECKS:
return EditorType.TinyLeaders;
case BRAWL_DECKS:
return EditorType.Brawl;
case SCHEME_DECKS:
return EditorType.Archenemy;
case PLANAR_DECKS:
@@ -389,6 +400,8 @@ public class FDeckChooser extends FScreen {
return EditorType.Commander;
case TinyLeaders:
return EditorType.TinyLeaders;
case Brawl:
return EditorType.Brawl;
case Archenemy:
return EditorType.Archenemy;
case Planechase:
@@ -454,6 +467,7 @@ public class FDeckChooser extends FScreen {
break;
case Commander:
case TinyLeaders:
case Brawl:
cmbDeckTypes.addItem(DeckType.CUSTOM_DECK);
cmbDeckTypes.addItem(DeckType.RANDOM_DECK);
if(FModel.isdeckGenMatrixLoaded()) {
@@ -466,6 +480,7 @@ public class FDeckChooser extends FScreen {
cmbDeckTypes.addItem(DeckType.CONSTRUCTED_DECK);
cmbDeckTypes.addItem(DeckType.COMMANDER_DECK);
cmbDeckTypes.addItem(DeckType.TINY_LEADERS_DECKS);
cmbDeckTypes.addItem(DeckType.BRAWL_DECKS);
cmbDeckTypes.addItem(DeckType.SCHEME_DECKS);
cmbDeckTypes.addItem(DeckType.PLANAR_DECKS);
cmbDeckTypes.addItem(DeckType.DRAFT_DECKS);
@@ -564,6 +579,10 @@ public class FDeckChooser extends FScreen {
pool = DeckProxy.getAllTinyLeadersDecks();
config = ItemManagerConfig.COMMANDER_DECKS;
break;
case Brawl:
pool = DeckProxy.getAllBrawlDecks();
config = ItemManagerConfig.COMMANDER_DECKS;
break;
case Archenemy:
pool = DeckProxy.getAllSchemeDecks();
config = ItemManagerConfig.SCHEME_DECKS;
@@ -590,6 +609,10 @@ public class FDeckChooser extends FScreen {
pool = DeckProxy.getAllTinyLeadersDecks();
config = ItemManagerConfig.COMMANDER_DECKS;
break;
case BRAWL_DECKS:
pool = DeckProxy.getAllBrawlDecks();
config = ItemManagerConfig.COMMANDER_DECKS;
break;
case RANDOM_COMMANDER_DECK:
pool = CommanderDeckGenerator.getCommanderDecks(lstDecks.getGameType().getDeckFormat(),isAi, false);
config = ItemManagerConfig.STRING_ONLY;
@@ -971,6 +994,12 @@ public class FDeckChooser extends FScreen {
return;
}
if (selectedDeckType == DeckType.BRAWL_DECKS) {
//cannot create gauntlet for tiny leaders decks, so just start single match
testVariantDeck(userDeck, GameType.Brawl);
return;
}
GuiChoose.getInteger("How many opponents are you willing to face?", 1, 50, new Callback<Integer>() {
@Override
public void run(final Integer numOpponents) {

View File

@@ -11,11 +11,9 @@ import forge.Forge;
import forge.Forge.KeyInputAdapter;
import forge.Graphics;
import forge.assets.*;
import forge.card.CardDb;
import forge.card.CardEdition;
import forge.card.CardPreferences;
import forge.card.CardRulesPredicates;
import forge.card.*;
import forge.deck.io.DeckPreferences;
import forge.item.IPaperCard;
import forge.item.PaperCard;
import forge.itemmanager.CardManager;
import forge.itemmanager.ColumnDef;
@@ -83,12 +81,18 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
return new Deck();
}
}), null),
TinyLeaders(new DeckController<Deck>(FModel.getDecks().getCommander(), new Supplier<Deck>() {
TinyLeaders(new DeckController<Deck>(FModel.getDecks().getTinyLeaders(), new Supplier<Deck>() {
@Override
public Deck get() {
return new Deck();
}
}), DeckFormat.TinyLeaders.isLegalCardPredicate()),
Brawl(new DeckController<Deck>(FModel.getDecks().getBrawl(), new Supplier<Deck>() {
@Override
public Deck get() {
return new Deck();
}
}), DeckFormat.Brawl.isLegalCardPredicate()),
Archenemy(new DeckController<Deck>(FModel.getDecks().getScheme(), new Supplier<Deck>() {
@Override
public Deck get() {
@@ -176,6 +180,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
};
case Commander:
case TinyLeaders:
case Brawl:
return new DeckEditorPage[] {
new CatalogPage(ItemManagerConfig.CARD_CATALOG),
new DeckSectionPage(DeckSection.Main),
@@ -507,6 +512,7 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
return CardLimit.None;
case Commander:
case TinyLeaders:
case Brawl:
case PlanarConquest:
return CardLimit.Singleton;
}
@@ -910,15 +916,30 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
break;
case Commander:
case TinyLeaders:
case Brawl:
final List<PaperCard> commanders = parentScreen.getDeck().getCommanders();
if (commanders.isEmpty()) {
//if no commander set for deck, only show valid commanders
additionalFilter = DeckFormat.Commander.isLegalCommanderPredicate();
switch (editorType) {
case TinyLeaders:
case Commander:
additionalFilter = DeckFormat.Commander.isLegalCommanderPredicate();
break;
case Brawl:
additionalFilter = DeckFormat.Brawl.isLegalCommanderPredicate();
}
cardManager.setCaption("Commanders");
}
else {
//if a commander has been set, only show cards that match its color identity
additionalFilter = DeckFormat.Commander.isLegalCardForCommanderOrLegalPartnerPredicate(commanders);
switch (editorType) {
case TinyLeaders:
case Commander:
additionalFilter = DeckFormat.Commander.isLegalCardForCommanderOrLegalPartnerPredicate(commanders);
break;
case Brawl:
additionalFilter = DeckFormat.Brawl.isLegalCardForCommanderOrLegalPartnerPredicate(commanders);
}
cardManager.setCaption("Cards");
}
//fall through to below
@@ -1017,7 +1038,13 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
}
}
if (parentScreen.getCommanderPage() != null) {
if (parentScreen.editorType != EditorType.PlanarConquest && DeckFormat.Commander.isLegalCommander(card.getRules()) && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) {
boolean isLegalCommander;
if(parentScreen.editorType.equals(EditorType.Brawl)){
isLegalCommander = card.getRules().canBeBrawlCommander();
}else{
isLegalCommander = DeckFormat.Commander.isLegalCommander(card.getRules());
}
if (parentScreen.editorType != EditorType.PlanarConquest && isLegalCommander && !parentScreen.getCommanderPage().cardManager.getPool().contains(card)) {
addItem(menu, "Set", "as Commander", parentScreen.getCommanderPage().getIcon(), true, true, new Callback<Integer>() {
@Override
public void run(Integer result) {
@@ -1607,6 +1634,9 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
case TinyLeaders:
DeckPreferences.setTinyLeadersDeck(deckStr);
break;
case Brawl:
DeckPreferences.setBrawlDeck(deckStr);
break;
case Archenemy:
DeckPreferences.setSchemeDeck(deckStr);
break;

View File

@@ -122,6 +122,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
cbVariants.addItem(GameType.MomirBasic);
cbVariants.addItem(GameType.Commander);
cbVariants.addItem(GameType.TinyLeaders);
cbVariants.addItem(GameType.Brawl);
cbVariants.addItem(GameType.Planechase);
cbVariants.addItem(GameType.Archenemy);
cbVariants.addItem(GameType.ArchenemyRumble);
@@ -154,13 +155,13 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
FThreads.invokeInBackgroundThread(new Runnable() {
@Override
public void run() {
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, FPref.COMMANDER_P2_DECK_STATE, FPref.TINY_LEADER_P2_DECK_STATE, DeckType.COLOR_DECK);
playerPanels.get(0).initialize(FPref.CONSTRUCTED_P1_DECK_STATE, FPref.COMMANDER_P1_DECK_STATE, FPref.TINY_LEADER_P1_DECK_STATE, FPref.BRAWL_P1_DECK_STATE, DeckType.PRECONSTRUCTED_DECK);
playerPanels.get(1).initialize(FPref.CONSTRUCTED_P2_DECK_STATE, FPref.COMMANDER_P2_DECK_STATE, FPref.TINY_LEADER_P2_DECK_STATE, FPref.BRAWL_P2_DECK_STATE, DeckType.COLOR_DECK);
if(getNumPlayers()>2) {
playerPanels.get(2).initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, DeckType.COLOR_DECK);
playerPanels.get(2).initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, FPref.BRAWL_P3_DECK_STATE, DeckType.COLOR_DECK);
}
if(getNumPlayers()>3) {
playerPanels.get(3).initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, DeckType.COLOR_DECK);
playerPanels.get(3).initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, FPref.BRAWL_P4_DECK_STATE, DeckType.COLOR_DECK);
}
/*playerPanels.get(4).initialize(FPref.CONSTRUCTED_P5_DECK_STATE, DeckType.COLOR_DECK);
playerPanels.get(5).initialize(FPref.CONSTRUCTED_P6_DECK_STATE, DeckType.COLOR_DECK);
@@ -346,6 +347,7 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
lstVariants.addItem(new Variant(GameType.MomirBasic));
lstVariants.addItem(new Variant(GameType.Commander));
lstVariants.addItem(new Variant(GameType.TinyLeaders));
lstVariants.addItem(new Variant(GameType.Brawl));
lstVariants.addItem(new Variant(GameType.Planechase));
lstVariants.addItem(new Variant(GameType.Archenemy));
lstVariants.addItem(new Variant(GameType.ArchenemyRumble));
@@ -456,6 +458,16 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
default:
break;
}
final FDeckChooser brawlDeckChooser = playerPanels.get(slot).getBrawlDeckChooser();
selectedDeckType = brawlDeckChooser.getSelectedDeckType();
switch (selectedDeckType){
case RANDOM_CARDGEN_COMMANDER_DECK:
case RANDOM_COMMANDER_DECK:
brawlDeckChooser.refreshDeckListForAI();
break;
default:
break;
}
}
@Override
@@ -479,10 +491,10 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
else {
panel = new PlayerPanel(this, allowNetworking, i, slot, lobby.mayEdit(i), lobby.hasControl());
if(i==2) {
panel.initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, DeckType.COLOR_DECK);
panel.initialize(FPref.CONSTRUCTED_P3_DECK_STATE, FPref.COMMANDER_P3_DECK_STATE, FPref.TINY_LEADER_P3_DECK_STATE, FPref.BRAWL_P3_DECK_STATE, DeckType.COLOR_DECK);
}
if(i==3) {
panel.initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, DeckType.COLOR_DECK);
panel.initialize(FPref.CONSTRUCTED_P4_DECK_STATE, FPref.COMMANDER_P4_DECK_STATE, FPref.TINY_LEADER_P4_DECK_STATE, FPref.BRAWL_P4_DECK_STATE, DeckType.COLOR_DECK);
}
playerPanels.add(panel);
playersScroll.add(panel);
@@ -534,7 +546,10 @@ public abstract class LobbyScreen extends LaunchScreen implements ILobbyView {
deck = playerPanel.getTinyLeadersDeck();
playerPanel.getTinyLeadersDeckChooser().saveState();
}
else {
else if (hasVariant(GameType.Brawl)) {
deck = playerPanel.getBrawlDeck();
playerPanel.getBrawlDeckChooser().saveState();
}else {
deck = playerPanel.getDeck();
playerPanel.getDeckChooser().saveState();
}

View File

@@ -71,10 +71,11 @@ public class PlayerPanel extends FContainer {
private final FLabel btnSchemeDeck = new FLabel.ButtonBuilder().text("Scheme Deck: Random Generated Deck").build();
private final FLabel btnCommanderDeck = new FLabel.ButtonBuilder().text("Commander Deck: Random Generated Deck").build();
private final FLabel btnTinyLeadersDeck = new FLabel.ButtonBuilder().text("Tiny Leaders Deck: Random Generated Deck").build();
private final FLabel btnBrawlDeck = new FLabel.ButtonBuilder().text("Brawl Deck: Random Generated Deck").build();
private final FLabel btnPlanarDeck = new FLabel.ButtonBuilder().text("Planar Deck: Random Generated Deck").build();
private final FLabel btnVanguardAvatar = new FLabel.ButtonBuilder().text("Vanguard Avatar: Random").build();
private final FDeckChooser deckChooser, lstSchemeDecks, lstCommanderDecks, lstTinyLeadersDecks, lstPlanarDecks;
private final FDeckChooser deckChooser, lstSchemeDecks, lstCommanderDecks, lstTinyLeadersDecks, lstBrawlDecks, lstPlanarDecks;
private final FVanguardChooser lstVanguardAvatars;
public PlayerPanel(final LobbyScreen screen0, final boolean allowNetworking0, final int index0, final LobbySlot slot, final boolean mayEdit0, final boolean mayControl0) {
@@ -128,6 +129,17 @@ public class PlayerPanel extends FContainer {
}
}
});
lstBrawlDecks = new FDeckChooser(GameType.Brawl, isAi, new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
if( ((DeckManager)e.getSource()).getSelectedItem() != null) {
btnBrawlDeck.setText("Brawl Deck: " + ((DeckManager) e.getSource()).getSelectedItem().getName());
lstBrawlDecks.saveState();
}else{
btnBrawlDeck.setText("Brawl Deck");
}
}
});
lstSchemeDecks = new FDeckChooser(GameType.Archenemy, isAi, new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
@@ -198,6 +210,14 @@ public class PlayerPanel extends FContainer {
Forge.openScreen(lstTinyLeadersDecks);
}
});
add(btnBrawlDeck);
btnBrawlDeck.setCommand(new FEventHandler() {
@Override
public void handleEvent(FEvent e) {
lstBrawlDecks.setHeaderCaption("Select Brawl Deck for " + txtPlayerName.getText());
Forge.openScreen(lstBrawlDecks);
}
});
add(btnSchemeDeck);
btnSchemeDeck.setCommand(new FEventHandler() {
@Override
@@ -235,10 +255,11 @@ public class PlayerPanel extends FContainer {
cbTeam.setEnabled(true);
}
public void initialize(FPref savedStateSetting, FPref savedStateSettingCommander, FPref savedStateSettingTinyLeader, DeckType defaultDeckType) {
public void initialize(FPref savedStateSetting, FPref savedStateSettingCommander, FPref savedStateSettingTinyLeader, FPref savedStateSettingBrawl, DeckType defaultDeckType) {
deckChooser.initialize(savedStateSetting, defaultDeckType);
lstCommanderDecks.initialize(savedStateSettingCommander, DeckType.COMMANDER_DECK);
lstTinyLeadersDecks.initialize(savedStateSettingTinyLeader, DeckType.TINY_LEADERS_DECKS);
lstBrawlDecks.initialize(savedStateSettingBrawl, DeckType.BRAWL_DECKS);
lstPlanarDecks.initialize(null, DeckType.RANDOM_DECK);
lstSchemeDecks.initialize(null, DeckType.RANDOM_DECK);
}
@@ -282,6 +303,10 @@ public class PlayerPanel extends FContainer {
btnTinyLeadersDeck.setBounds(x, y, w, fieldHeight);
y += dy;
}
else if (btnBrawlDeck.isVisible()) {
btnBrawlDeck.setBounds(x, y, w, fieldHeight);
y += dy;
}
else if (btnDeck.isVisible()) {
btnDeck.setBounds(x, y, w, fieldHeight);
y += dy;
@@ -304,7 +329,7 @@ public class PlayerPanel extends FContainer {
if (!btnDeck.isVisible()) {
rows--;
}
if (btnCommanderDeck.isVisible() || btnTinyLeadersDeck.isVisible()) {
if (btnCommanderDeck.isVisible() || btnTinyLeadersDeck.isVisible() || btnBrawlDeck.isVisible()) {
rows++;
}
if (btnSchemeDeck.isVisible()) {
@@ -404,6 +429,7 @@ public class PlayerPanel extends FContainer {
public void updateVariantControlsVisibility() {
boolean isCommanderApplied = false;
boolean isTinyLeadersApplied = false;
boolean isBrawlApplied = false;
boolean isPlanechaseApplied = false;
boolean isVanguardApplied = false;
boolean isArchenemyApplied = false;
@@ -429,6 +455,10 @@ public class PlayerPanel extends FContainer {
isTinyLeadersApplied = true;
isDeckBuildingAllowed = false; //Tiny Leaders deck replaces basic deck, so hide that
break;
case Brawl:
isBrawlApplied = true;
isDeckBuildingAllowed = false; //Tiny Leaders deck replaces basic deck, so hide that
break;
case Planechase:
isPlanechaseApplied = true;
break;
@@ -446,6 +476,7 @@ public class PlayerPanel extends FContainer {
btnDeck.setVisible(isDeckBuildingAllowed);
btnCommanderDeck.setVisible(isCommanderApplied && mayEdit);
btnTinyLeadersDeck.setVisible(isTinyLeadersApplied && mayEdit);
btnBrawlDeck.setVisible(isBrawlApplied && mayEdit);
btnSchemeDeck.setVisible(archenemyVisiblity && mayEdit);
@@ -693,6 +724,10 @@ public class PlayerPanel extends FContainer {
return lstTinyLeadersDecks;
}
public FDeckChooser getBrawlDeckChooser() {
return lstBrawlDecks;
}
public Deck getDeck() {
return deckChooser.getDeck();
@@ -706,6 +741,10 @@ public class PlayerPanel extends FContainer {
return lstTinyLeadersDecks.getDeck();
}
public Deck getBrawlDeck() {
return lstBrawlDecks.getDeck();
}
public Deck getSchemeDeck() {
return lstSchemeDecks.getDeck();
}

View File

@@ -15,6 +15,7 @@ public class ConstructedAchievements extends AchievementCollection {
add(new VariantWins(GameType.MomirBasic, 25, 50, 100));
add(new VariantWins(GameType.Commander, 25, 50, 100));
add(new VariantWins(GameType.TinyLeaders, 25, 50, 100));
add(new VariantWins(GameType.Brawl, 25, 50, 100));
add(new VariantWins(GameType.Planechase, 25, 50, 100));
add(new VariantWins(GameType.Archenemy, 25, 50, 100));
add(new Poisoned(15, 25, 40));

View File

@@ -23,6 +23,9 @@ import java.util.Map;
*/
public class CommanderDeckGenerator extends DeckProxy implements Comparable<CommanderDeckGenerator> {
public static List<DeckProxy> getCommanderDecks(final DeckFormat format, boolean isForAi, boolean isCardGen){
if(format.equals(DeckFormat.Brawl)){
return getBrawlDecks(format, isForAi, isCardGen);
}
ItemPool uniqueCards;
if(isCardGen){
uniqueCards = new ItemPool<PaperCard>(PaperCard.class);
@@ -50,6 +53,31 @@ public class CommanderDeckGenerator extends DeckProxy implements Comparable<Comm
return decks;
}
public static List<DeckProxy> getBrawlDecks(final DeckFormat format, boolean isForAi, boolean isCardGen){
ItemPool uniqueCards;
if(isCardGen){
uniqueCards = new ItemPool<PaperCard>(PaperCard.class);
//TODO: upate to actual Brawl model from real Brawl decks
Iterable<String> legendNames=CardRelationMatrixGenerator.cardPools.get(FModel.getFormats().getStandard().getName()).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.and(format.isLegalCardPredicate(),
Predicates.compose(Predicates.and(
CardRulesPredicates.Presets.CAN_BE_BRAWL_COMMANDER,
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;

View File

@@ -370,6 +370,21 @@ public class DeckProxy implements InventoryItem {
return result;
}
public static Iterable<DeckProxy> getAllBrawlDecks() {
return getAllBrawlDecks(null);
}
public static Iterable<DeckProxy> getAllBrawlDecks(Predicate<Deck> filter) {
final List<DeckProxy> result = new ArrayList<DeckProxy>();
if (filter == null) {
filter = DeckFormat.Brawl.hasLegalCardsPredicate();
}
else {
filter = Predicates.and(DeckFormat.Brawl.hasLegalCardsPredicate(), filter);
}
addDecksRecursivelly("Brawl", GameType.Brawl, result, "", FModel.getDecks().getBrawl(), filter);
return result;
}
public static Iterable<DeckProxy> getAllSchemeDecks() {
return getAllSchemeDecks(null);
}

View File

@@ -10,6 +10,7 @@ public enum DeckType {
RANDOM_COMMANDER_DECK ("Random Commander Decks"),
RANDOM_CARDGEN_COMMANDER_DECK ("Random Commander Card-based Decks"),
TINY_LEADERS_DECKS ("Tiny Leaders Decks"),
BRAWL_DECKS ("Brawl Decks"),
SCHEME_DECKS ("Scheme Decks"),
PLANAR_DECKS ("Planar Decks"),
DRAFT_DECKS ("Draft Decks"),

View File

@@ -498,40 +498,18 @@ public class DeckgenUtil {
final DeckFormat format = gameType.getDeckFormat();
Predicate<CardRules> canPlay = forAi ? DeckGeneratorBase.AI_CAN_PLAY : DeckGeneratorBase.HUMAN_CAN_PLAY;
@SuppressWarnings("unchecked")
Iterable<PaperCard> legends = cardDb.getAllCards(Predicates.compose(Predicates.and(
Iterable<PaperCard> legends = cardDb.getAllCards(Predicates.and(format.isLegalCardPredicate(),
Predicates.compose(Predicates.and(
new Predicate<CardRules>() {
@Override
public boolean apply(CardRules rules) {
return format.isLegalCommander(rules);
}
},
canPlay), PaperCard.FN_GET_RULES));
canPlay), PaperCard.FN_GET_RULES)));
do {
commander = Aggregates.random(legends);
colorID = commander.getRules().getColorIdentity();
} while (colorID.countColors() != 2);
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"); }
DeckGeneratorBase gen = null;
gen = new DeckGenerator2Color(cardDb, format, comColors.get(0), comColors.get(1));
gen.setSingleton(true);
gen.setUseArtifacts(!FModel.getPreferences().getPrefBoolean(FPref.DECKGEN_ARTIFACTS));
CardPool cards = gen.getDeck(gameType.getDeckFormat().getMainRange().getMaximum(), forAi);
// After generating card lists, build deck.
deck = new Deck("Generated " + gameType.toString() + " deck (" + commander.getName() + ")");
deck.setDirectory("generated/commander");
deck.getMain().addAll(cards);
deck.getOrCreate(DeckSection.Commander).add(commander);
return deck;
commander = Aggregates.random(legends);
return generateRandomCommanderDeck(commander, format, forAi, false);
}
/** Generate a ramdom Commander deck. */
@@ -542,7 +520,11 @@ public class DeckgenUtil {
PaperCard selectedPartner=null;
if(isCardGen){
List<Map.Entry<PaperCard,Integer>> potentialCards = new ArrayList<>();
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(DeckFormat.Commander.toString()).get(commander.getName()));
if(format.equals(DeckFormat.Brawl)){//TODO: replace with actual Brawl based data
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(FModel.getFormats().getStandard().getName()).get(commander.getName()));
}else {
potentialCards.addAll(CardRelationMatrixGenerator.cardPools.get(DeckFormat.Commander.toString()).get(commander.getName()));
}
Random r = new Random();
//Collections.shuffle(potentialCards, r);
List<PaperCard> preSelectedCards = new ArrayList<>();
@@ -588,11 +570,21 @@ public class DeckgenUtil {
cardDb = FModel.getMagicDb().getCommonCards();
//shuffle first 400 random cards
Iterable<PaperCard> colorList = Iterables.filter(format.getCardPool(cardDb).getAllCards(),
Predicates.compose(Predicates.or(new CardThemedDeckBuilder.MatchColorIdentity(commander.getRules().getColorIdentity()),
DeckGeneratorBase.COLORLESS_CARDS), PaperCard.FN_GET_RULES));
Predicates.and(format.isLegalCardPredicate(),Predicates.compose(Predicates.or(
new CardThemedDeckBuilder.MatchColorIdentity(commander.getRules().getColorIdentity()),
DeckGeneratorBase.COLORLESS_CARDS), PaperCard.FN_GET_RULES)));
if(format.equals(DeckFormat.Brawl)){//for Brawl - add additional filterprinted rule to remove old reprints for a consistent look
Iterable<PaperCard> colorListFiltered = Iterables.filter(colorList,FModel.getFormats().getStandard().getFilterPrinted());
colorList=colorListFiltered;
}
List<PaperCard> cardList = Lists.newArrayList(colorList);
Collections.shuffle(cardList, new Random());
List<PaperCard> shortList = cardList.subList(1, 400);
int shortlistlength=400;
if(cardList.size()<shortlistlength){
shortlistlength=cardList.size();
}
List<PaperCard> shortList = cardList.subList(1, shortlistlength);
shortList.remove(commander);
gen = new CardThemedCommanderDeckBuilder(commander, selectedPartner,shortList,forAi,format);
}

View File

@@ -80,6 +80,8 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
return DeckgenUtil.generateCommanderDeck(isAi, GameType.Commander);
case TinyLeaders:
return DeckgenUtil.generateCommanderDeck(isAi, GameType.TinyLeaders);
case Brawl:
return DeckgenUtil.generateCommanderDeck(isAi, GameType.Brawl);
case Archenemy:
return DeckgenUtil.generateSchemeDeck();
case Planechase:
@@ -135,6 +137,9 @@ public class RandomDeckGenerator extends DeckProxy implements Comparable<RandomD
case TinyLeaders:
decks = DeckProxy.getAllTinyLeadersDecks(DeckFormat.TinyLeaders.isLegalDeckPredicate());
break;
case Brawl:
decks = DeckProxy.getAllBrawlDecks(DeckFormat.Brawl.isLegalDeckPredicate());
break;
case Archenemy:
decks = DeckProxy.getAllSchemeDecks(DeckFormat.Archenemy.isLegalDeckPredicate());
break;

View File

@@ -21,7 +21,7 @@ import org.w3c.dom.NodeList;
*
*/
public class DeckPreferences {
private static String currentDeck = "", draftDeck = "", sealedDeck = "", commanderDeck = "", tinyLeadersDeck = "", planarDeck = "", schemeDeck = "";
private static String currentDeck = "", draftDeck = "", sealedDeck = "", commanderDeck = "", tinyLeadersDeck = "", brawlDeck = "", planarDeck = "", schemeDeck = "";
private static Map<String, DeckPreferences> allPrefs = new HashMap<String, DeckPreferences>();
public static String getCurrentDeck() {
@@ -69,6 +69,15 @@ public class DeckPreferences {
save();
}
public static String getBrawlDeck() {
return brawlDeck;
}
public static void setBrawlDeck(String brawlDeck0) {
if (brawlDeck.equals(brawlDeck0)) { return; }
brawlDeck = brawlDeck0;
save();
}
public static String getPlanarDeck() {
return planarDeck;
}

View File

@@ -232,10 +232,17 @@ public abstract class GameLobby implements IHasGameType {
break;
case Commander:
data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.MomirBasic);
break;
case TinyLeaders:
data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.MomirBasic);
break;
case Brawl:
data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.MomirBasic);
break;
case Vanguard:
@@ -244,6 +251,7 @@ public abstract class GameLobby implements IHasGameType {
case MomirBasic:
data.appliedVariants.remove(GameType.Commander);
data.appliedVariants.remove(GameType.TinyLeaders);
data.appliedVariants.remove(GameType.Brawl);
data.appliedVariants.remove(GameType.Vanguard);
break;
default:
@@ -263,6 +271,8 @@ public abstract class GameLobby implements IHasGameType {
currentGameType = GameType.Commander;
} else if (hasVariant(GameType.TinyLeaders)) {
currentGameType = GameType.TinyLeaders;
} else if (hasVariant(GameType.Brawl)) {
currentGameType = GameType.Brawl;
} else {
currentGameType = GameType.Constructed;
}
@@ -326,7 +336,7 @@ public abstract class GameLobby implements IHasGameType {
SOptionPane.showMessageDialog(TextUtil.concatNoSpace("Please specify a deck for ", slot.getName()));
return null;
}
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders)) {
if (hasVariant(GameType.Commander) || hasVariant(GameType.TinyLeaders) || hasVariant(GameType.Brawl)) {
if (!slot.getDeck().has(DeckSection.Commander)) {
SOptionPane.showMessageDialog(TextUtil.concatNoSpace(slot.getName(), " doesn't have a commander"));
return null;
@@ -339,9 +349,11 @@ public abstract class GameLobby implements IHasGameType {
GameType autoGenerateVariant = null;
boolean isCommanderMatch = false;
boolean isTinyLeadersMatch = false;
boolean isBrawlMatch = false;
if (!variantTypes.isEmpty()) {
isTinyLeadersMatch = variantTypes.contains(GameType.TinyLeaders);
isCommanderMatch = isTinyLeadersMatch || variantTypes.contains(GameType.Commander);
isBrawlMatch = variantTypes.contains(GameType.Brawl);
isCommanderMatch = isBrawlMatch || isTinyLeadersMatch || variantTypes.contains(GameType.Commander);
if (!isCommanderMatch) {
for (final GameType variant : variantTypes) {
if (variant.isAutoGenerated()) {
@@ -403,7 +415,7 @@ public abstract class GameLobby implements IHasGameType {
else {
PaperCard vanguardAvatar = null;
if (isCommanderMatch) {
final GameType commanderGameType = isTinyLeadersMatch ? GameType.TinyLeaders : GameType.Commander;
final GameType commanderGameType = isTinyLeadersMatch ? GameType.TinyLeaders : isBrawlMatch ? GameType.Brawl : GameType.Commander;
if (checkLegality) {
final String errMsg = commanderGameType.getDeckFormat().getDeckConformanceProblem(deck);
if (errMsg != null) {

View File

@@ -42,6 +42,7 @@ public class CardCollections {
private IStorage<Deck> plane;
private IStorage<Deck> commander;
private IStorage<Deck> tinyLeaders;
private IStorage<Deck> brawl;
public CardCollections() {
}
@@ -118,4 +119,12 @@ public class CardCollections {
}
return tinyLeaders;
}
public IStorage<Deck> getBrawl() {
if (brawl == null) {
brawl = new StorageImmediatelySerialized<Deck>("Brawl decks",
new DeckStorage(new File(ForgeConstants.DECK_BRAWL_DIR), ForgeConstants.DECK_BASE_DIR));
}
return brawl;
}
}

View File

@@ -173,6 +173,9 @@ public final class FModel {
formats.add(format);
}
magicDb.setStandardPredicate(formats.getStandard().getFilterRules());
magicDb.setModernPredicate(formats.getModern().getFilterRules());
blocks = new StorageBase<>("Block definitions", new CardBlock.Reader(ForgeConstants.BLOCK_DATA_DIR + "blocks.txt", magicDb.getEditions()));
questPreferences = new QuestPreferences();
conquestPreferences = new ConquestPreferences();

View File

@@ -219,6 +219,7 @@ public final class ForgeConstants {
public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves" + PATH_SEPARATOR;
public static final String CONQUEST_SAVE_DIR = USER_CONQUEST_DIR + "saves" + PATH_SEPARATOR;
public static final String DECK_TINY_LEADERS_DIR= DECK_BASE_DIR + "tiny_leaders" + PATH_SEPARATOR;
public static final String DECK_BRAWL_DIR = DECK_BASE_DIR + "brawl" + PATH_SEPARATOR;
public static final String MAIN_PREFS_FILE = USER_PREFS_DIR + "forge.preferences";
public static final String CARD_PREFS_FILE = USER_PREFS_DIR + "card.preferences";
public static final String DECK_PREFS_FILE = USER_PREFS_DIR + "deck.preferences";

View File

@@ -50,6 +50,14 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
TINY_LEADER_P6_DECK_STATE(""),
TINY_LEADER_P7_DECK_STATE(""),
TINY_LEADER_P8_DECK_STATE(""),
BRAWL_P1_DECK_STATE(""),
BRAWL_P2_DECK_STATE(""),
BRAWL_P3_DECK_STATE(""),
BRAWL_P4_DECK_STATE(""),
BRAWL_P5_DECK_STATE(""),
BRAWL_P6_DECK_STATE(""),
BRAWL_P7_DECK_STATE(""),
BRAWL_P8_DECK_STATE(""),
UI_LANDSCAPE_MODE ("false"),
UI_COMPACT_MAIN_MENU ("false"),
UI_USE_OLD ("false"),
@@ -240,6 +248,12 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
TINY_LEADER_P5_DECK_STATE, TINY_LEADER_P6_DECK_STATE,
TINY_LEADER_P7_DECK_STATE, TINY_LEADER_P8_DECK_STATE };
public static FPref[] BRAWL_DECK_STATES = {
BRAWL_P1_DECK_STATE, BRAWL_P2_DECK_STATE,
BRAWL_P3_DECK_STATE, BRAWL_P4_DECK_STATE,
BRAWL_P5_DECK_STATE, BRAWL_P6_DECK_STATE,
BRAWL_P7_DECK_STATE, BRAWL_P8_DECK_STATE };
}
/** Instantiates a ForgePreferences object. */