diff --git a/.gitattributes b/.gitattributes index ee3c75b8843..f42632bb168 100644 --- a/.gitattributes +++ b/.gitattributes @@ -871,13 +871,10 @@ forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestPrefs.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/DialogChooseSets.java -text -forge-gui-desktop/src/main/java/forge/screens/home/quest/IVQuestStats.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlDraftEvent.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlEvent.java -text -forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestDraftUtils.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestFileLister.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestPreferencesHandler.java -text -forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuChallenges.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuDuels.java -text forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuQuestData.java -text @@ -1202,7 +1199,7 @@ forge-gui-mobile/src/forge/screens/match/winlose/GauntletWinLose.java -text forge-gui-mobile/src/forge/screens/match/winlose/LimitedWinLose.java -text forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java -text forge-gui-mobile/src/forge/screens/quest/QuestDuelsScreen.java -text -forge-gui-mobile/src/forge/screens/quest/QuestScreen.java -text +forge-gui-mobile/src/forge/screens/quest/QuestMenu.java -text forge-gui-mobile/src/forge/screens/sealed/SealedScreen.java -text forge-gui-mobile/src/forge/screens/settings/FilesPage.java -text forge-gui-mobile/src/forge/screens/settings/GuiDownloader.java -text @@ -16454,6 +16451,8 @@ forge-gui/src/main/java/forge/events/UiEventBlockerAssigned.java -text forge-gui/src/main/java/forge/gauntlet/GauntletData.java -text forge-gui/src/main/java/forge/gauntlet/GauntletIO.java -text forge-gui/src/main/java/forge/interfaces/IButton.java -text +forge-gui/src/main/java/forge/interfaces/ICheckBox.java -text +forge-gui/src/main/java/forge/interfaces/IComboBox.java -text forge-gui/src/main/java/forge/interfaces/IGuiBase.java -text forge-gui/src/main/java/forge/interfaces/IProgressBar.java -text forge-gui/src/main/java/forge/interfaces/ITextField.java -text @@ -16534,9 +16533,11 @@ forge-gui/src/main/java/forge/properties/SavePreferencesListener.java svneol=nat forge-gui/src/main/java/forge/properties/package-info.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/BoosterUtils.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/IQuestRewardCard.java -text +forge-gui/src/main/java/forge/quest/IVQuestStats.java -text forge-gui/src/main/java/forge/quest/QuestController.java -text forge-gui/src/main/java/forge/quest/QuestDeckGroupMap.java -text forge-gui/src/main/java/forge/quest/QuestDeckMap.java -text +forge-gui/src/main/java/forge/quest/QuestDraftUtils.java -text forge-gui/src/main/java/forge/quest/QuestEvent.java -text forge-gui/src/main/java/forge/quest/QuestEventChallenge.java svneol=native#text/plain forge-gui/src/main/java/forge/quest/QuestEventDifficulty.java -text diff --git a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java index 19ebbc04aca..62a4bbae539 100644 --- a/forge-gui-desktop/src/main/java/forge/GuiDesktop.java +++ b/forge-gui-desktop/src/main/java/forge/GuiDesktop.java @@ -33,6 +33,7 @@ import forge.events.UiEvent; import forge.game.Game; import forge.game.GameEntity; import forge.game.GameType; +import forge.game.Match; import forge.game.card.Card; import forge.game.combat.Combat; import forge.game.event.GameEventTurnBegan; @@ -47,12 +48,16 @@ import forge.gui.FNetOverlay; import forge.gui.GuiChoose; import forge.gui.GuiUtils; import forge.gui.SOverlayUtils; +import forge.gui.framework.FScreen; import forge.gui.framework.SDisplayUtil; import forge.gui.framework.SLayoutIO; import forge.interfaces.IButton; import forge.interfaces.IGuiBase; import forge.item.PaperCard; import forge.match.input.InputQueue; +import forge.model.FModel; +import forge.screens.deckeditor.CDeckEditorUI; +import forge.screens.deckeditor.controllers.CEditorQuestCardShop; import forge.screens.match.CMatchUI; import forge.screens.match.VMatchUI; import forge.screens.match.ViewWinLose; @@ -450,6 +455,11 @@ public class GuiDesktop implements IGuiBase { return FControl.instance.getGuiPlayer(); } + @Override + public LobbyPlayer getAiPlayer(String name) { + return FControl.instance.getAiPlayer(name); + } + @Override public LobbyPlayer createAiPlayer() { return FControl.instance.getAiPlayer(); @@ -484,4 +494,40 @@ public class GuiDesktop implements IGuiBase { public void clearImageCache() { ImageCache.clear(); } + + @Override + public void startGame(Match match) { + SOverlayUtils.startGameOverlay(); + SOverlayUtils.showOverlay(); + Singletons.getControl().startGameWithUi(match); + } + + @Override + public void continueMatch(Match match) { + Singletons.getControl().endCurrentGame(); + if (match == null) { + Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN); + } + else { + Singletons.getControl().startGameWithUi(match); + } + } + + @Override + public void showSpellShop() { + Singletons.getControl().setCurrentScreen(FScreen.QUEST_CARD_SHOP); + CDeckEditorUI.SINGLETON_INSTANCE.setEditorController( + new CEditorQuestCardShop(FModel.getQuest())); + } + + @Override + public void showBazaar() { + Singletons.getControl().setCurrentScreen(FScreen.QUEST_BAZAAR); + Singletons.getView().getFrame().validate(); + } + + @Override + public void setPlayerAvatar(LobbyPlayer player, String iconImageKey) { + CMatchUI.SINGLETON_INSTANCE.avatarImages.put(player, iconImageKey); + } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java index a9f5f809a38..2a12e6bf0a3 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuChallenges.java @@ -7,6 +7,7 @@ import forge.gui.framework.ICDoc; import forge.model.FModel; import forge.quest.QuestController; import forge.quest.QuestEventChallenge; +import forge.quest.QuestUtil; import forge.quest.bazaar.QuestItemType; import forge.quest.bazaar.QuestPetController; import forge.screens.home.CHomeUI; @@ -41,29 +42,29 @@ public enum CSubmenuChallenges implements ICDoc { view.getBtnSpellShop().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.showSpellShop(); } }); + public void run() { QuestUtil.showSpellShop(); } }); view.getBtnBazaar().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.showBazaar(); } }); + public void run() { QuestUtil.showBazaar(); } }); view.getBtnUnlock().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.chooseAndUnlockEdition(); CSubmenuChallenges.this.update(); } }); + public void run() { QuestUtil.chooseAndUnlockEdition(); CSubmenuChallenges.this.update(); } }); view.getBtnTravel().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.travelWorld(); CSubmenuChallenges.this.update(); } }); + public void run() { QuestUtil.travelWorld(); CSubmenuChallenges.this.update(); } }); view.getBtnStart().addActionListener( new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); + public void actionPerformed(final ActionEvent e) { QuestUtil.startGame(); } }); ((FLabel) view.getLblZep()).setCommand( new UiCommand() { @Override public void run() { - if (!SSubmenuQuestUtil.checkActiveQuest("Launch a Zeppelin.")) { + if (!QuestUtil.checkActiveQuest("Launch a Zeppelin.")) { return; } FModel.getQuest().getAchievements().setCurrentChallenges(null); @@ -124,7 +125,7 @@ public enum CSubmenuChallenges implements ICDoc { */ @Override public void update() { - SSubmenuQuestUtil.updateQuestView(VSubmenuChallenges.SINGLETON_INSTANCE); + QuestUtil.updateQuestView(VSubmenuChallenges.SINGLETON_INSTANCE); final VSubmenuChallenges view = VSubmenuChallenges.SINGLETON_INSTANCE; final QuestController qCtrl = FModel.getQuest(); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java index eb5188506d6..d62ba3cb3d1 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuDuels.java @@ -6,6 +6,7 @@ import forge.gui.framework.ICDoc; import forge.model.FModel; import forge.quest.QuestController; import forge.quest.QuestEventDuel; +import forge.quest.QuestUtil; import forge.quest.bazaar.QuestPetController; import forge.screens.home.CHomeUI; import forge.toolbox.JXButtonPanel; @@ -35,23 +36,23 @@ public enum CSubmenuDuels implements ICDoc { view.getBtnSpellShop().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.showSpellShop(); } }); + public void run() { QuestUtil.showSpellShop(); } }); view.getBtnBazaar().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.showBazaar(); } }); + public void run() { QuestUtil.showBazaar(); } }); view.getBtnTravel().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.travelWorld(); CSubmenuDuels.this.update(); } }); + public void run() { QuestUtil.travelWorld(); CSubmenuDuels.this.update(); } }); view.getBtnUnlock().setCommand( new UiCommand() { @Override - public void run() { SSubmenuQuestUtil.chooseAndUnlockEdition(); CSubmenuDuels.this.update(); } }); + public void run() { QuestUtil.chooseAndUnlockEdition(); CSubmenuDuels.this.update(); } }); view.getBtnStart().addActionListener( new ActionListener() { @Override - public void actionPerformed(final ActionEvent e) { SSubmenuQuestUtil.startGame(); } }); + public void actionPerformed(final ActionEvent e) { QuestUtil.startGame(); } }); final QuestController quest = FModel.getQuest(); view.getCbPlant().addActionListener(new ActionListener() { @@ -85,11 +86,11 @@ public enum CSubmenuDuels implements ICDoc { view.getBtnRandomOpponent().setCommand(new UiCommand() { @Override public void run() { - if (SSubmenuQuestUtil.canStartGame()) { + if (QuestUtil.canStartGame()) { FModel.getQuest().getDuelsManager().randomizeOpponents(); final List duels = FModel.getQuest().getDuelsManager().generateDuels(); - SSubmenuQuestUtil.setEvent(duels.get((int) (Math.random() * duels.size()))); - SSubmenuQuestUtil.startGame(); + QuestUtil.setEvent(duels.get((int) (Math.random() * duels.size()))); + QuestUtil.startGame(); } } }); @@ -118,7 +119,7 @@ public enum CSubmenuDuels implements ICDoc { */ @Override public void update() { - SSubmenuQuestUtil.updateQuestView(VSubmenuDuels.SINGLETON_INSTANCE); + QuestUtil.updateQuestView(VSubmenuDuels.SINGLETON_INSTANCE); final VSubmenuDuels view = VSubmenuDuels.SINGLETON_INSTANCE; diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java index d16ec33a6be..65cc830bcd6 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestData.java @@ -242,7 +242,7 @@ public enum CSubmenuQuestData implements ICDoc { questName = FOptionPane.showInputDialog("Poets will remember your quest as:", "Quest Name"); if (questName == null) { return; } - questName = SSubmenuQuestUtil.cleanString(questName); + questName = QuestUtil.cleanString(questName); if (questName.isEmpty()) { FOptionPane.showMessageDialog("Please specify a quest name."); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java index 96540c3f755..0716077c3f1 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDecks.java @@ -9,6 +9,7 @@ import forge.gui.framework.ICDoc; import forge.itemmanager.ItemManagerConfig; import forge.model.FModel; import forge.quest.QuestController; +import forge.quest.QuestUtil; import forge.quest.data.QuestPreferences.QPref; import forge.screens.deckeditor.CDeckEditorUI; import forge.screens.deckeditor.controllers.CEditorQuest; @@ -55,7 +56,7 @@ public enum CSubmenuQuestDecks implements ICDoc { VSubmenuQuestDecks.SINGLETON_INSTANCE.getBtnNewDeck().setCommand(new UiCommand() { @Override public void run() { - if (!SSubmenuQuestUtil.checkActiveQuest("Create a Deck.")) { + if (!QuestUtil.checkActiveQuest("Create a Deck.")) { return; } Singletons.getControl().setCurrentScreen(FScreen.DECK_EDITOR_QUEST); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java index 3c603c3d800..e57c38cdd94 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/CSubmenuQuestDraft.java @@ -37,7 +37,9 @@ import forge.limited.LimitedPoolType; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; import forge.quest.QuestController; +import forge.quest.QuestDraftUtils; import forge.quest.QuestEventDraft; +import forge.quest.QuestUtil; import forge.quest.data.QuestAchievements; import forge.screens.deckeditor.CDeckEditorUI; import forge.screens.deckeditor.controllers.CEditorQuestDraftingProcess; @@ -531,7 +533,7 @@ public enum CSubmenuQuestDraft implements ICDoc { return; } - QuestEventDraft draftEvent = SSubmenuQuestUtil.getDraftEvent(); + QuestEventDraft draftEvent = QuestUtil.getDraftEvent(); long creditsAvailable = FModel.getQuest().getAssets().getCredits(); if (creditsAvailable < draftEvent.getEntryFee()) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/IVQuestStats.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/IVQuestStats.java deleted file mode 100644 index 638452b24aa..00000000000 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/IVQuestStats.java +++ /dev/null @@ -1,61 +0,0 @@ -package forge.screens.home.quest; - -import forge.toolbox.FCheckBox; -import forge.toolbox.FComboBoxWrapper; -import forge.toolbox.FLabel; - -/** Dictates methods required for a panel with stats/pet display. */ - -public interface IVQuestStats { - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getBtnRandomOpponent(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getBtnBazaar(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getBtnSpellShop(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getBtnUnlock(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getBtnTravel(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblCredits(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblLife(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblWorld(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblWins(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblLosses(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblNextChallengeInWins(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblCurrentDeck(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblWinStreak(); - - /** @return {@link javax.swing.FComboBoxWrapper} */ - FComboBoxWrapper getCbxPet(); - - /** @return {@link forge.toolbox.FCheckBox} */ - FCheckBox getCbPlant(); - - /** @return {@link forge.toolbox.FCheckBox} */ - FCheckBox getCbCharm(); - - /** @return {@link forge.toolbox.FLabel} */ - FLabel getLblZep(); -} diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlDraftEvent.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlDraftEvent.java index b089b244eeb..61c9cd41e25 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlDraftEvent.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlDraftEvent.java @@ -12,6 +12,7 @@ import javax.swing.event.ChangeListener; import net.miginfocom.swing.MigLayout; import forge.model.FModel; import forge.quest.QuestEventDraft; +import forge.quest.QuestUtil; import forge.toolbox.FRadioButton; import forge.toolbox.FSkin; import forge.toolbox.FSkin.SkinColor; @@ -56,7 +57,7 @@ public class PnlDraftEvent extends JPanel { @Override public void stateChanged(ChangeEvent arg0) { if (radButton.isSelected()) { - SSubmenuQuestUtil.setDraftEvent(event); + QuestUtil.setDraftEvent(event); } } }); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlEvent.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlEvent.java index 835fcaf79bd..0759281043e 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlEvent.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/PnlEvent.java @@ -2,6 +2,7 @@ package forge.screens.home.quest; import forge.ImageCache; import forge.quest.QuestEvent; +import forge.quest.QuestUtil; import forge.toolbox.FRadioButton; import forge.toolbox.FSkin; import forge.toolbox.FTextArea; @@ -60,7 +61,7 @@ class PnlEvent extends JPanel { @Override public void stateChanged(ChangeEvent arg0) { if (rad.isSelected()) { - SSubmenuQuestUtil.setEvent(event); + QuestUtil.setEvent(event); } } }); diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestFileLister.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestFileLister.java index f2756ae77c3..c84dfcb440c 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestFileLister.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestFileLister.java @@ -3,6 +3,7 @@ package forge.screens.home.quest; import forge.UiCommand; import forge.assets.FSkinProp; import forge.properties.ForgeConstants; +import forge.quest.QuestUtil; import forge.quest.data.QuestData; import forge.toolbox.FLabel; import forge.toolbox.FMouseAdapter; @@ -307,7 +308,7 @@ public class QuestFileLister extends JPanel { questName = FOptionPane.showInputDialog("Rename quest to:", "Quest Rename", null, oldQuestName); if (questName == null) { return; } - questName = SSubmenuQuestUtil.cleanString(questName); + questName = QuestUtil.cleanString(questName); if (questName.equals(oldQuestName)) { return; } //quit if chose same name if (questName.isEmpty()) { diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java deleted file mode 100644 index 5add06eb023..00000000000 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/SSubmenuQuestUtil.java +++ /dev/null @@ -1,544 +0,0 @@ -package forge.screens.home.quest; - -import forge.FThreads; -import forge.GuiBase; -import forge.LobbyPlayer; -import forge.Singletons; -import forge.card.CardEdition; -import forge.control.FControl; -import forge.deck.Deck; -import forge.game.GameRules; -import forge.game.GameType; -import forge.game.Match; -import forge.game.player.RegisteredPlayer; -import forge.gui.GuiChoose; -import forge.gui.SOverlayUtils; -import forge.gui.framework.FScreen; -import forge.model.FModel; -import forge.properties.ForgePreferences.FPref; -import forge.quest.*; -import forge.quest.bazaar.QuestItemType; -import forge.quest.bazaar.QuestPetController; -import forge.quest.data.QuestAchievements; -import forge.quest.data.QuestAssets; -import forge.quest.data.QuestPreferences.QPref; -import forge.screens.deckeditor.CDeckEditorUI; -import forge.screens.deckeditor.controllers.CEditorQuestCardShop; -import forge.screens.match.CMatchUI; -import forge.toolbox.FOptionPane; -import forge.toolbox.FSkin; -import forge.toolbox.FSkin.SkinnedLabel; - -import org.apache.commons.lang3.tuple.ImmutablePair; - -import javax.swing.*; - -import java.awt.*; -import java.util.ArrayList; -import java.util.List; - -/** - * Utilities for the quest submenu, all over the MVC spectrum. - * If a piece of code can be reused, it's dumped here. - * - *

(S at beginning of class name denotes a static factory.) - */ -public class SSubmenuQuestUtil { - private static QuestEvent event; - private static QuestEventDraft draftEvent; - - /** - *

- * nextChallengeInWins. - *

- * - * @return a int. - */ - public static int nextChallengeInWins() { - final QuestController qData = FModel.getQuest(); - final int challengesPlayed = qData.getAchievements().getChallengesPlayed(); - - final int wins = qData.getAchievements().getWin(); - final int turnsToUnlock = FModel.getQuest().getTurnsToUnlockChallenge(); - final int delta; - - // First challenge unlocks after minimum wins reached. - if (wins < 2 * turnsToUnlock) { - delta = 2 * turnsToUnlock - wins; - } - else { - // More than enough wins - if (wins / turnsToUnlock > challengesPlayed) { - delta = 0; - } - // This part takes the "unlimited challenge" bug into account; - // a player could have an inflated challengesPlayed value. - // Added 09-2012, can be removed after a while. - else if (wins < challengesPlayed * turnsToUnlock) { - delta = (challengesPlayed * turnsToUnlock - wins) + turnsToUnlock; - } - // Data OK, but not enough wins yet (default). - else { - delta = turnsToUnlock - wins % turnsToUnlock; - } - } - - return (delta > 0) ? delta : 0; - } - - private static void updatePlantAndPetForView(final IVQuestStats view, final QuestController qCtrl) { - for (int iSlot = 0; iSlot < QuestController.MAX_PET_SLOTS; iSlot++) { - final List petList = qCtrl.getPetsStorage().getAvaliablePets(iSlot, qCtrl.getAssets()); - final String currentPetName = qCtrl.getSelectedPet(iSlot); - - if (iSlot == 0) { // Plant visiblity - if (petList.isEmpty()) { - view.getCbPlant().setVisible(false); - } - else { - view.getCbPlant().setVisible(true); - view.getCbPlant().setSelected(currentPetName != null); - } - } - if (iSlot == 1) { - view.getCbxPet().removeAllItems(); - - // Pet list visibility - if (petList.size() > 0) { - view.getCbxPet().setVisible(true); - view.getCbxPet().addItem("Don't summon a pet"); - - for (final QuestPetController pet : petList) { - String name = "Summon " + pet.getName(); - view.getCbxPet().addItem(name); - if (pet.getName().equals(currentPetName)) { - view.getCbxPet().setSelectedItem(name); - } - } - } else { - view.getCbxPet().setVisible(false); - } - } - } - - if(qCtrl.getAssets().hasItem(QuestItemType.CHARM)) { - view.getCbCharm().setVisible(true); - } else { - view.getCbCharm().setVisible(false); - } - - if (view.equals(VSubmenuChallenges.SINGLETON_INSTANCE)) { - view.getLblZep().setVisible(qCtrl.getAssets().hasItem(QuestItemType.ZEPPELIN)); - if (qCtrl.getAssets().getItemLevel(QuestItemType.ZEPPELIN) == 2) { - view.getLblZep().setEnabled(false); - view.getLblZep().setForeground(Color.gray); - } - else { - view.getLblZep().setEnabled(true); - view.getLblZep().setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); - } - } - else { - view.getLblZep().setVisible(false); - } - } - - /** - * Updates all quest info in a view, using - * retrieval methods dictated in IVQuestStats.
- * - Stats
- * - Pets
- * - Current deck info
- * - "Challenge In" info
- * - * @param view0 {@link forge.screens.home.quest.IVQuestStats} - */ - public static void updateQuestView(final IVQuestStats view0) { - final QuestController qCtrl = FModel.getQuest(); - final QuestAchievements qA = qCtrl.getAchievements(); - final QuestAssets qS = qCtrl.getAssets(); - - if (qA == null) { return; } - - // Fantasy UI display - view0.getLblNextChallengeInWins().setVisible(true); - view0.getBtnBazaar().setVisible(true); - view0.getLblLife().setVisible(true); - - // Stats panel - view0.getLblCredits().setText("Credits: " + qS.getCredits()); - view0.getLblLife().setText("Life: " + qS.getLife(qCtrl.getMode())); - view0.getLblWins().setText("Wins: " + qA.getWin()); - view0.getLblLosses().setText("Losses: " + qA.getLost()); - view0.getLblWorld().setText("World: " + (qCtrl.getWorld() == null ? "(none)" : qCtrl.getWorld())); - - // Show or hide the set unlocking button - - view0.getBtnUnlock().setVisible(qCtrl.getUnlocksTokens() > 0 && qCtrl.getWorldFormat() == null); - - // Challenge in wins - final int num = SSubmenuQuestUtil.nextChallengeInWins(); - final String str; - if (num == 0) { - str = "Your exploits have been noticed. An opponent has challenged you."; - } - else if (num == 1) { - str = "A new challenge will be available after 1 more win."; - } - else { - str = "A new challenge will be available in " + num + " wins."; - } - - view0.getLblNextChallengeInWins().setText(str); - - view0.getLblWinStreak().setText( - "Win streak: " + qA.getWinStreakCurrent() - + "
  (Best: " + qA.getWinStreakBest() + ")"); - - // Current deck message - final SkinnedLabel lblCurrentDeck = view0.getLblCurrentDeck(); - if (SSubmenuQuestUtil.getCurrentDeck() == null) { - lblCurrentDeck.setForeground(Color.red.darker()); - lblCurrentDeck.setText("Build, then select a deck in the \"Quest Decks\" submenu."); - } - else { - lblCurrentDeck.setForeground(FSkin.getColor(FSkin.Colors.CLR_TEXT)); - lblCurrentDeck.setText("Your current deck is \"" - + SSubmenuQuestUtil.getCurrentDeck().getName() + "\"."); - } - - // Start panel: pet, plant, zep. - if (qCtrl.getMode() == QuestMode.Fantasy) { - updatePlantAndPetForView(view0, qCtrl); - } - else { - // Classic mode display changes - view0.getCbxPet().setVisible(false); - view0.getCbPlant().setVisible(false); - view0.getCbCharm().setVisible(false); - view0.getLblZep().setVisible(false); - view0.getLblNextChallengeInWins().setVisible(false); - view0.getBtnBazaar().setVisible(false); - view0.getLblLife().setVisible(false); - } - } - - /** @return {@link forge.deck.Deck} */ - public static Deck getCurrentDeck() { - Deck d = null; - - if (FModel.getQuest().getAssets() != null) { - d = FModel.getQuest().getMyDecks().get( - FModel.getQuestPreferences().getPref(QPref.CURRENT_DECK)); - } - - return d; - } - - /** Updates the current selected quest event, used when game is started. - * @param event0 {@link forge.quest.QuestEvent} - */ - public static void setEvent(final QuestEvent event0) { - SSubmenuQuestUtil.event = event0; - } - - public static void setDraftEvent(final QuestEventDraft event0) { - SSubmenuQuestUtil.draftEvent = event0; - } - - public static QuestEventDraft getDraftEvent() { - return draftEvent; - } - - public static boolean checkActiveQuest(String location) { - QuestController qc = FModel.getQuest(); - if (qc == null || qc.getAssets() == null) { - String msg = "Please create a Quest before attempting to " + location; - FOptionPane.showErrorDialog(msg, "No Quest"); - System.out.println(msg); - return false; - } - return true; - } - - /** */ - public static void showSpellShop() { - if (!checkActiveQuest("Visit the Spell Shop.")) { - return; - } - Singletons.getControl().setCurrentScreen(FScreen.QUEST_CARD_SHOP); - CDeckEditorUI.SINGLETON_INSTANCE.setEditorController( - new CEditorQuestCardShop(FModel.getQuest())); - } - - /** */ - public static void showBazaar() { - if (!checkActiveQuest("Visit the Bazaar.")) { - return; - } - Singletons.getControl().setCurrentScreen(FScreen.QUEST_BAZAAR); - Singletons.getView().getFrame().validate(); - } - - /** */ - public static void chooseAndUnlockEdition() { - if (!checkActiveQuest("Unlock Editions.")) { - return; - } - final QuestController qData = FModel.getQuest(); - ImmutablePair toUnlock = QuestUtilUnlockSets.chooseSetToUnlock(qData, false, null); - if (toUnlock == null) { - return; - } - - CardEdition unlocked = toUnlock.left; - qData.getAssets().subtractCredits(toUnlock.right); - FOptionPane.showMessageDialog("You have successfully unlocked " + unlocked.getName() + "!", - unlocked.getName() + " unlocked!", null); - - QuestUtilUnlockSets.doUnlock(qData, unlocked); - } - - /** */ - public static void travelWorld() { - if (!checkActiveQuest("Travel between worlds.")) { - return; - } - List worlds = new ArrayList(); - final QuestController qCtrl = FModel.getQuest(); - - for (QuestWorld qw : FModel.getWorlds()) { - if (qCtrl.getWorld() != qw) { - worlds.add(qw); - } - } - - if (worlds.size() < 1) { - FOptionPane.showErrorDialog("There are currently no worlds you can travel to\nin this version of Forge.", "No Worlds"); - return; - } - - final String setPrompt = "Where do you wish to travel?"; - final QuestWorld newWorld = GuiChoose.oneOrNone(setPrompt, worlds); - - if (worlds.indexOf(newWorld) < 0) { - return; - } - - if (qCtrl.getWorld() != newWorld) { - boolean needRemove = false; - if (nextChallengeInWins() < 1 && qCtrl.getAchievements().getCurrentChallenges().size() > 0) { - needRemove = true; - - if (!FOptionPane.showConfirmDialog( - "You have uncompleted challenges in your current world. If you travel now, they will be LOST!" - + "\nAre you sure you wish to travel anyway?\n" - + "(Click \"No\" to go back and complete your current challenges first.)", - "WARNING: Uncompleted challenges")) { - return; - } - } - - if (needRemove) { - // Remove current challenges. - while (nextChallengeInWins() == 0) { - qCtrl.getAchievements().addChallengesPlayed(); - } - - qCtrl.getAchievements().getCurrentChallenges().clear(); - } - - qCtrl.setWorld(newWorld); - qCtrl.resetDuelsManager(); - qCtrl.resetChallengesManager(); - // Note that the following can be (ab)used to re-randomize your opponents by travelling to a different - // world and back. To prevent this, simply delete the following line that randomizes DuelsManager. - // (OTOH, you can 'swap' opponents even more easily by simply selecting a different quest data file and - // then re-selecting your current quest data file.) - qCtrl.getDuelsManager().randomizeOpponents(); - qCtrl.getCards().clearShopList(); - qCtrl.save(); - } - } - - /** */ - public static void startGame() { - if (!checkActiveQuest("Start a duel.") || null == event) { - return; - } - final QuestController qData = FModel.getQuest(); - - Deck deck = null; - if (event instanceof QuestEventChallenge) { - // Predefined HumanDeck - deck = ((QuestEventChallenge) event).getHumanDeck(); - } - if (deck == null) { - // If no predefined Deck, use the Player's Deck - deck = SSubmenuQuestUtil.getCurrentDeck(); - } - if (deck == null) { - String msg = "Please select a Quest Deck."; - FOptionPane.showErrorDialog(msg, "No Deck"); - System.out.println(msg); - return; - } - - if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { - String errorMessage = GameType.Quest.getDecksFormat().getDeckConformanceProblem(deck); - if (null != errorMessage) { - FOptionPane.showErrorDialog("Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck"); - return; - } - } - - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - SOverlayUtils.startGameOverlay(); - SOverlayUtils.showOverlay(); - } - }); - - final SwingWorker worker = new SwingWorker() { - @Override - public Object doInBackground() { - qData.getDuelsManager().randomizeOpponents(); - qData.setCurrentEvent(event); - qData.save(); - - return null; - } - - @Override - public void done() { - SOverlayUtils.hideOverlay(); - } - }; - worker.execute(); - - int extraLifeHuman = 0; - Integer lifeHuman = null; - boolean useBazaar = true; - Boolean forceAnte = null; - int lifeAI = 20; - if (event instanceof QuestEventChallenge) { - QuestEventChallenge qc = ((QuestEventChallenge) event); - lifeAI = qc.getAILife(); - lifeHuman = qc.getHumanLife(); - - if (qData.getAssets().hasItem(QuestItemType.ZEPPELIN)) { - extraLifeHuman = 3; - } - - useBazaar = qc.isUseBazaar(); - forceAnte = qc.isForceAnte(); - } - - RegisteredPlayer humanStart = new RegisteredPlayer(deck); - RegisteredPlayer aiStart = new RegisteredPlayer(event.getEventDeck()); - - if (lifeHuman != null) { - humanStart.setStartingLife(lifeHuman); - } else { - humanStart.setStartingLife(qData.getAssets().getLife(qData.getMode()) + extraLifeHuman); - } - - if (useBazaar) { - humanStart.setCardsOnBattlefield(QuestUtil.getHumanStartingCards(qData, event)); - aiStart.setStartingLife(lifeAI); - aiStart.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event)); - } - - List starter = new ArrayList(); - starter.add(humanStart.setPlayer(GuiBase.getInterface().getQuestPlayer())); - - LobbyPlayer aiPlayer = FControl.instance.getAiPlayer(event.getOpponent() == null ? event.getTitle() : event.getOpponent()); - CMatchUI.SINGLETON_INSTANCE.avatarImages.put(aiPlayer, event.getIconImageKey()); - starter.add(aiStart.setPlayer(aiPlayer)); - - boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); - for(RegisteredPlayer rp : starter) { - rp.setRandomFoil(useRandomFoil); - } - boolean useAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE); - boolean matchAnteRarity = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE_MATCH_RARITY); - if(forceAnte != null) - useAnte = forceAnte.booleanValue(); - GameRules rules = new GameRules(GameType.Quest); - rules.setPlayForAnte(useAnte); - rules.setMatchAnteRarity(matchAnteRarity); - rules.setGamesPerMatch(qData.getCharmState() ? 5 : 3); - rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); - rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE); - final Match mc = new Match(rules, starter); - FThreads.invokeInEdtLater(new Runnable(){ - @Override - public void run() { - Singletons.getControl().startGameWithUi(mc); - // no overlays here? - } - }); - } - - /** - * Checks to see if a game can be started and displays relevant dialogues. - * @return - */ - public static boolean canStartGame() { - - if (!checkActiveQuest("Start a duel.") || null == event) { - return false; - } - - Deck deck = null; - if (event instanceof QuestEventChallenge) { - // Predefined HumanDeck - deck = ((QuestEventChallenge) event).getHumanDeck(); - } - - if (deck == null) { - // If no predefined Deck, use the Player's Deck - deck = SSubmenuQuestUtil.getCurrentDeck(); - } - - if (deck == null) { - String msg = "Please select a Quest Deck."; - FOptionPane.showErrorDialog(msg, "No Deck"); - System.out.println(msg); - return false; - } - - if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { - String errorMessage = GameType.Quest.getDecksFormat().getDeckConformanceProblem(deck); - if (null != errorMessage) { - FOptionPane.showErrorDialog("Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck"); - return false; - } - } - - return true; - - } - - /** Duplicate in DeckEditorQuestMenu and - * probably elsewhere...can streamline at some point - * (probably shouldn't be here). - * - * @param in   {@link java.lang.String} - * @return {@link java.lang.String} - */ - public static String cleanString(final String in) { - final StringBuffer out = new StringBuffer(); - final char[] c = in.toCharArray(); - - for (int i = 0; (i < c.length) && (i < 20); i++) { - if (Character.isLetterOrDigit(c[i]) || (c[i] == '-') || (c[i] == '_') || (c[i] == ' ')) { - out.append(c[i]); - } - } - - return out.toString(); - } -} - diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuChallenges.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuChallenges.java index 7aabe70f626..97e0aed2517 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuChallenges.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuChallenges.java @@ -4,6 +4,7 @@ import forge.assets.FSkinProp; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; +import forge.quest.IVQuestStats; import forge.screens.home.*; import forge.toolbox.*; import net.miginfocom.swing.MigLayout; @@ -290,5 +291,9 @@ public enum VSubmenuChallenges implements IVSubmenu, IVQuest public FLabel getBtnRandomOpponent() { return null; } - + + @Override + public boolean isChallengesView() { + return true; + } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuDuels.java b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuDuels.java index 42ec60833b2..7ead79b11d4 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuDuels.java +++ b/forge-gui-desktop/src/main/java/forge/screens/home/quest/VSubmenuDuels.java @@ -4,6 +4,8 @@ import forge.assets.FSkinProp; import forge.gui.framework.DragCell; import forge.gui.framework.DragTab; import forge.gui.framework.EDocID; +import forge.interfaces.IButton; +import forge.quest.IVQuestStats; import forge.screens.home.*; import forge.toolbox.*; import net.miginfocom.swing.MigLayout; @@ -178,7 +180,7 @@ public enum VSubmenuDuels implements IVSubmenu, IVQuestStats { } @Override - public FLabel getLblLosses() { + public IButton getLblLosses() { return lblLosses; } @@ -290,4 +292,9 @@ public enum VSubmenuDuels implements IVSubmenu, IVQuestStats { public FCheckBox getCbCharm() { return cbCharm; } + + @Override + public boolean isChallengesView() { + return false; + } } diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java index b7892752d01..d1eeb8611e2 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/CMatchUI.java @@ -42,7 +42,7 @@ import forge.item.InventoryItem; import forge.menus.IMenuProvider; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; -import forge.screens.home.quest.QuestDraftUtils; +import forge.quest.QuestDraftUtils; import forge.screens.match.controllers.*; import forge.screens.match.menus.CMatchUIMenus; import forge.screens.match.views.*; diff --git a/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java index 993e0047721..f67d21b8fdd 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java +++ b/forge-gui-desktop/src/main/java/forge/screens/match/QuestDraftWinLose.java @@ -30,10 +30,10 @@ import forge.gui.SOverlayUtils; import forge.gui.framework.FScreen; import forge.model.FModel; import forge.quest.QuestController; +import forge.quest.QuestDraftUtils; import forge.screens.home.quest.CSubmenuChallenges; import forge.screens.home.quest.CSubmenuDuels; import forge.screens.home.quest.CSubmenuQuestDraft; -import forge.screens.home.quest.QuestDraftUtils; import forge.screens.home.quest.VSubmenuQuestDraft; import forge.toolbox.FOptionPane; import forge.toolbox.FSkin; diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FButton.java b/forge-gui-desktop/src/main/java/forge/toolbox/FButton.java index 3bd164a97d0..2389a05db53 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FButton.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FButton.java @@ -21,6 +21,7 @@ import forge.UiCommand; import forge.assets.FSkinProp; import forge.gui.framework.ILocalRepaint; import forge.interfaces.IButton; +import forge.toolbox.FSkin.Colors; import forge.toolbox.FSkin.SkinImage; import forge.toolbox.FSkin.SkinnedButton; @@ -248,4 +249,14 @@ public class FButton extends SkinnedButton implements ILocalRepaint, IButton { } }); } + + @Override + public void setTextColor(FSkinProp color) { + setForeground(FSkin.getColor(Colors.fromSkinProp(color))); + } + + @Override + public void setTextColor(int r, int g, int b) { + setForeground(new Color(r, g, b)); + } } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FCheckBox.java b/forge-gui-desktop/src/main/java/forge/toolbox/FCheckBox.java index bd566bd9c22..97d8ab545eb 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FCheckBox.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FCheckBox.java @@ -1,12 +1,13 @@ package forge.toolbox; +import forge.interfaces.ICheckBox; import forge.toolbox.FSkin.SkinnedCheckBox; /** * A custom instance of JCheckBox using Forge skin properties. */ @SuppressWarnings("serial") -public class FCheckBox extends SkinnedCheckBox { +public class FCheckBox extends SkinnedCheckBox implements ICheckBox { public FCheckBox() { this(""); } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FComboBox.java b/forge-gui-desktop/src/main/java/forge/toolbox/FComboBox.java index b4113a0ae8a..24522ccbdab 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FComboBox.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FComboBox.java @@ -1,5 +1,6 @@ package forge.toolbox; +import forge.interfaces.IComboBox; import forge.toolbox.FSkin.SkinFont; import forge.toolbox.FSkin.SkinnedComboBox; @@ -13,7 +14,7 @@ import java.awt.*; import java.util.Vector; @SuppressWarnings("serial") -public class FComboBox extends SkinnedComboBox { +public class FComboBox extends SkinnedComboBox implements IComboBox { public enum TextAlignment { LEFT (SwingConstants.LEFT), RIGHT (SwingConstants.RIGHT), diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FComboBoxWrapper.java b/forge-gui-desktop/src/main/java/forge/toolbox/FComboBoxWrapper.java index 2e47f3c82c2..4d6bb332579 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FComboBoxWrapper.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FComboBoxWrapper.java @@ -1,5 +1,6 @@ package forge.toolbox; +import forge.interfaces.IComboBox; import forge.toolbox.FComboBox.TextAlignment; import forge.toolbox.FSkin.SkinFont; @@ -16,7 +17,7 @@ import java.util.Vector; * Wrapper for combo box with extra logic (either FComboBoxWrapper or FComboBoxPanel should be used instead of FComboBox so skinning works) * */ -public class FComboBoxWrapper { +public class FComboBoxWrapper implements IComboBox { private static final ArrayList> allWrappers = new ArrayList>(); @@ -123,10 +124,22 @@ public class FComboBoxWrapper { this.comboBox.setSkinFont(skinFont); } + @Override + public boolean isVisible() { + return this.comboBox.isVisible(); + } + + @Override public void setVisible(boolean aFlag) { this.comboBox.setVisible(aFlag); } + @Override + public boolean isEnabled() { + return this.comboBox.isEnabled(); + } + + @Override public void setEnabled(boolean aFlag) { this.comboBox.setEnabled(aFlag); } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java b/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java index 5857359e3c9..a2055153046 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FLabel.java @@ -1,8 +1,10 @@ package forge.toolbox; import forge.UiCommand; +import forge.assets.FSkinProp; import forge.gui.framework.ILocalRepaint; import forge.interfaces.IButton; +import forge.toolbox.FSkin.Colors; import forge.toolbox.FSkin.SkinColor; import forge.toolbox.FSkin.SkinImage; import forge.toolbox.FSkin.SkinnedLabel; @@ -632,4 +634,14 @@ public class FLabel extends SkinnedLabel implements ILocalRepaint, IButton { public void setCommand(UiCommand command0) { cmdClick = command0; } + + @Override + public void setTextColor(FSkinProp color) { + setForeground(FSkin.getColor(Colors.fromSkinProp(color))); + } + + @Override + public void setTextColor(int r, int g, int b) { + setForeground(new Color(r, g, b)); + } } diff --git a/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java b/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java index 8164af169ec..df0b132819e 100644 --- a/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java +++ b/forge-gui-desktop/src/main/java/forge/toolbox/FSkin.java @@ -363,6 +363,15 @@ public class FSkin { skinProp = skinProp0; } + public static Colors fromSkinProp(FSkinProp skinProp) { + for (final Colors c : Colors.values()) { + if (c.skinProp == skinProp) { + return c; + } + } + return null; + } + public static void updateAll() { for (final Colors c : Colors.values()) { c.updateColor(); diff --git a/forge-gui-mobile/src/forge/GuiMobile.java b/forge-gui-mobile/src/forge/GuiMobile.java index d1e7bcee2d3..f434f633888 100644 --- a/forge-gui-mobile/src/forge/GuiMobile.java +++ b/forge-gui-mobile/src/forge/GuiMobile.java @@ -25,6 +25,7 @@ import forge.events.UiEvent; import forge.game.Game; import forge.game.GameEntity; import forge.game.GameType; +import forge.game.Match; import forge.game.card.Card; import forge.game.combat.Combat; import forge.game.event.GameEventTurnBegan; @@ -369,6 +370,11 @@ public class GuiMobile implements IGuiBase { return FControl.getGuiPlayer(); } + @Override + public LobbyPlayer getAiPlayer(String name) { + return FControl.getAiPlayer(name); + } + @Override public LobbyPlayer createAiPlayer() { return FControl.getAiPlayer(); @@ -403,4 +409,35 @@ public class GuiMobile implements IGuiBase { public void clearImageCache() { ImageCache.clear(); } + + @Override + public void startGame(Match match) { + FControl.startGame(match); + } + + @Override + public void continueMatch(Match match) { + FControl.endCurrentGame(); + if (match == null) { + Forge.back(); + } + else { + FControl.startGame(match); + } + } + + @Override + public void showSpellShop() { + + } + + @Override + public void showBazaar() { + + } + + @Override + public void setPlayerAvatar(LobbyPlayer player, String iconImageKey) { + //Not needed for mobile game + } } diff --git a/forge-gui-mobile/src/forge/screens/LaunchScreen.java b/forge-gui-mobile/src/forge/screens/LaunchScreen.java index 589524ca557..6e1c4f34963 100644 --- a/forge-gui-mobile/src/forge/screens/LaunchScreen.java +++ b/forge-gui-mobile/src/forge/screens/LaunchScreen.java @@ -7,6 +7,7 @@ import java.util.Set; import com.badlogic.gdx.Input.Keys; +import forge.menu.FPopupMenu; import forge.screens.FScreen; import forge.screens.match.FControl; import forge.Graphics; @@ -21,12 +22,14 @@ public abstract class LaunchScreen extends FScreen { private static final float IMAGE_WIDTH = FSkinImage.BTN_START_UP.getWidth() * IMAGE_HEIGHT / FSkinImage.BTN_START_UP.getHeight(); private static final float PADDING = IMAGE_HEIGHT * 0.025f; - protected final StartButton btnStart; + protected final StartButton btnStart = add(new StartButton()); private boolean creatingMatch; public LaunchScreen(String headerCaption) { super(headerCaption); - btnStart = add(new StartButton()); + } + public LaunchScreen(String headerCaption, FPopupMenu menu) { + super(headerCaption, menu); } @Override diff --git a/forge-gui-mobile/src/forge/screens/quest/QuestDuelsScreen.java b/forge-gui-mobile/src/forge/screens/quest/QuestDuelsScreen.java index 99afbdc00ee..52f8953388c 100644 --- a/forge-gui-mobile/src/forge/screens/quest/QuestDuelsScreen.java +++ b/forge-gui-mobile/src/forge/screens/quest/QuestDuelsScreen.java @@ -1,13 +1,21 @@ package forge.screens.quest; -public class QuestDuelsScreen extends QuestScreen { +import forge.screens.LaunchScreen; +public class QuestDuelsScreen extends LaunchScreen { public QuestDuelsScreen() { - super("Quest Duels"); + super("Quest Duels", new QuestMenu()); } @Override - protected void doLayout(float startY, float width, float height) { + protected void doLayoutAboveBtnStart(float startY, float width, float height) { + // TODO Auto-generated method stub } + + @Override + protected boolean buildLaunchParams(LaunchParams launchParams) { + // TODO Auto-generated method stub + return false; + } } diff --git a/forge-gui-mobile/src/forge/screens/quest/QuestMenu.java b/forge-gui-mobile/src/forge/screens/quest/QuestMenu.java new file mode 100644 index 00000000000..eef8c7d6733 --- /dev/null +++ b/forge-gui-mobile/src/forge/screens/quest/QuestMenu.java @@ -0,0 +1,68 @@ +package forge.screens.quest; + +import forge.assets.FSkinImage; +import forge.menu.FMenuItem; +import forge.menu.FPopupMenu; +import forge.toolbox.FEvent; +import forge.toolbox.FEvent.FEventHandler; + +public class QuestMenu extends FPopupMenu { + @Override + protected void buildMenu() { + addItem(new FMenuItem("Duels", FSkinImage.QUEST_GEAR, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Challenges", FSkinImage.QUEST_HEART, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Tournaments", FSkinImage.PACK, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Travel", FSkinImage.QUEST_MAP, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Spell Shop", FSkinImage.QUEST_BOOK, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Bazaar", FSkinImage.QUEST_BOTTLES, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Statistics", FSkinImage.MULTI, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Change Deck", FSkinImage.DECKLIST, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("New Quest", FSkinImage.NEW, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Load Quest", FSkinImage.OPEN, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + addItem(new FMenuItem("Preferences", FSkinImage.SETTINGS, new FEventHandler() { + @Override + public void handleEvent(FEvent e) { + } + })); + } +} diff --git a/forge-gui-mobile/src/forge/screens/quest/QuestScreen.java b/forge-gui-mobile/src/forge/screens/quest/QuestScreen.java deleted file mode 100644 index 6129619b777..00000000000 --- a/forge-gui-mobile/src/forge/screens/quest/QuestScreen.java +++ /dev/null @@ -1,68 +0,0 @@ -package forge.screens.quest; - -import forge.assets.FSkinImage; -import forge.menu.FMenuItem; -import forge.menu.FPopupMenu; -import forge.screens.FScreen; -import forge.toolbox.FEvent; -import forge.toolbox.FEvent.FEventHandler; - -public abstract class QuestScreen extends FScreen { - protected QuestScreen(String headerCaption) { - super(headerCaption, new FPopupMenu() { - @Override - protected void buildMenu() { - addItem(new FMenuItem("Duels", FSkinImage.QUEST_GEAR, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Challenges", FSkinImage.QUEST_HEART, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Tournaments", FSkinImage.PACK, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Travel", FSkinImage.QUEST_MAP, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Spell Shop", FSkinImage.QUEST_BOOK, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Bazaar", FSkinImage.QUEST_BOTTLES, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Change Deck", FSkinImage.DECKLIST, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("New Quest", FSkinImage.NEW, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Load Quest", FSkinImage.OPEN, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - addItem(new FMenuItem("Preferences", FSkinImage.SETTINGS, new FEventHandler() { - @Override - public void handleEvent(FEvent e) { - } - })); - } - }); - } -} diff --git a/forge-gui-mobile/src/forge/toolbox/FCheckBox.java b/forge-gui-mobile/src/forge/toolbox/FCheckBox.java index af238c19208..ab5be4c4f99 100644 --- a/forge-gui-mobile/src/forge/toolbox/FCheckBox.java +++ b/forge-gui-mobile/src/forge/toolbox/FCheckBox.java @@ -6,9 +6,10 @@ import forge.Graphics; import forge.assets.FImage; import forge.assets.FSkinColor; import forge.assets.FSkinColor.Colors; +import forge.interfaces.ICheckBox; import forge.util.Utils; -public class FCheckBox extends FLabel { +public class FCheckBox extends FLabel implements ICheckBox { private static final FSkinColor CHECK_COLOR = FSkinColor.get(Colors.CLR_TEXT); private static final FSkinColor BOX_COLOR = CHECK_COLOR.alphaColor(0.5f); diff --git a/forge-gui/src/main/java/forge/interfaces/IButton.java b/forge-gui/src/main/java/forge/interfaces/IButton.java index dc710354d1a..b249c5bbbec 100644 --- a/forge-gui/src/main/java/forge/interfaces/IButton.java +++ b/forge-gui/src/main/java/forge/interfaces/IButton.java @@ -1,6 +1,7 @@ package forge.interfaces; import forge.UiCommand; +import forge.assets.FSkinProp; public interface IButton { boolean isEnabled(); @@ -13,4 +14,6 @@ public interface IButton { void setSelected(boolean b0); boolean requestFocusInWindow(); void setCommand(UiCommand command0); + void setTextColor(FSkinProp color); + void setTextColor(int r, int g, int b); } diff --git a/forge-gui/src/main/java/forge/interfaces/ICheckBox.java b/forge-gui/src/main/java/forge/interfaces/ICheckBox.java new file mode 100644 index 00000000000..392a0740e98 --- /dev/null +++ b/forge-gui/src/main/java/forge/interfaces/ICheckBox.java @@ -0,0 +1,10 @@ +package forge.interfaces; + +public interface ICheckBox { + boolean isEnabled(); + void setEnabled(boolean b0); + boolean isVisible(); + void setVisible(boolean b0); + boolean isSelected(); + void setSelected(boolean b0); +} diff --git a/forge-gui/src/main/java/forge/interfaces/IComboBox.java b/forge-gui/src/main/java/forge/interfaces/IComboBox.java new file mode 100644 index 00000000000..3d84c43d8db --- /dev/null +++ b/forge-gui/src/main/java/forge/interfaces/IComboBox.java @@ -0,0 +1,11 @@ +package forge.interfaces; + +public interface IComboBox { + boolean isEnabled(); + void setEnabled(boolean b0); + boolean isVisible(); + void setVisible(boolean b0); + void setSelectedItem(E item); + void addItem(E item); + void removeAllItems(); +} diff --git a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java index 3d09ab89ee4..6bdd64b7859 100644 --- a/forge-gui/src/main/java/forge/interfaces/IGuiBase.java +++ b/forge-gui/src/main/java/forge/interfaces/IGuiBase.java @@ -17,6 +17,7 @@ import forge.events.UiEvent; import forge.game.Game; import forge.game.GameEntity; import forge.game.GameType; +import forge.game.Match; import forge.game.card.Card; import forge.game.combat.Combat; import forge.game.event.GameEventTurnBegan; @@ -86,6 +87,7 @@ public interface IGuiBase { void copyToClipboard(String text); void browseToUrl(String url) throws Exception; LobbyPlayer getGuiPlayer(); + LobbyPlayer getAiPlayer(String name); LobbyPlayer createAiPlayer(); LobbyPlayer createAiPlayer(String name, int avatarIndex); LobbyPlayer getQuestPlayer(); @@ -93,4 +95,9 @@ public interface IGuiBase { IAudioMusic createAudioMusic(String filename); void startAltSoundSystem(String filename, boolean isSynchronized); void clearImageCache(); + void startGame(Match match); + void continueMatch(Match match); + void showSpellShop(); + void showBazaar(); + void setPlayerAvatar(LobbyPlayer player, String iconImageKey); } \ No newline at end of file diff --git a/forge-gui/src/main/java/forge/quest/IVQuestStats.java b/forge-gui/src/main/java/forge/quest/IVQuestStats.java new file mode 100644 index 00000000000..a4b6babd660 --- /dev/null +++ b/forge-gui/src/main/java/forge/quest/IVQuestStats.java @@ -0,0 +1,32 @@ +package forge.quest; + +import forge.interfaces.IButton; +import forge.interfaces.ICheckBox; +import forge.interfaces.IComboBox; + +/** Dictates methods required for a panel with stats/pet display. */ + +public interface IVQuestStats { + + IButton getBtnRandomOpponent(); + IButton getBtnBazaar(); + IButton getBtnSpellShop(); + IButton getBtnUnlock(); + IButton getBtnTravel(); + IButton getLblCredits(); + IButton getLblLife(); + IButton getLblWorld(); + IButton getLblWins(); + IButton getLblLosses(); + IButton getLblNextChallengeInWins(); + IButton getLblCurrentDeck(); + IButton getLblWinStreak(); + + IComboBox getCbxPet(); + ICheckBox getCbPlant(); + ICheckBox getCbCharm(); + + IButton getLblZep(); + + boolean isChallengesView(); +} diff --git a/forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestDraftUtils.java b/forge-gui/src/main/java/forge/quest/QuestDraftUtils.java similarity index 85% rename from forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestDraftUtils.java rename to forge-gui/src/main/java/forge/quest/QuestDraftUtils.java index 7c4fc10f8d4..0b95499f359 100644 --- a/forge-gui-desktop/src/main/java/forge/screens/home/quest/QuestDraftUtils.java +++ b/forge-gui/src/main/java/forge/quest/QuestDraftUtils.java @@ -1,47 +1,32 @@ -package forge.screens.home.quest; +package forge.quest; import java.util.ArrayList; import java.util.List; -import javax.swing.SwingUtilities; - import forge.FThreads; import forge.GuiBase; -import forge.Singletons; import forge.deck.DeckGroup; import forge.game.Game; import forge.game.GameRules; import forge.game.GameType; import forge.game.Match; import forge.game.player.RegisteredPlayer; -import forge.gui.SOverlayUtils; -import forge.gui.framework.FScreen; import forge.model.FModel; import forge.properties.ForgePreferences.FPref; import forge.quest.QuestEventDraft; public class QuestDraftUtils { - private static List matchups = new ArrayList(); public static boolean matchInProgress = false; public static boolean aiMatchInProgress = false; private static boolean waitForUserInput = false; - + public static void continueMatch(Game lastGame) { - if (lastGame.getMatch().isMatchOver()) { matchInProgress = false; } - - if (!matchInProgress) { - Singletons.getControl().endCurrentGame(); - Singletons.getControl().setCurrentScreen(FScreen.HOME_SCREEN); - } else { - Singletons.getControl().endCurrentGame(); - Singletons.getControl().startGameWithUi(lastGame.getMatch()); - } - + GuiBase.getInterface().continueMatch(matchInProgress ? lastGame.getMatch() : null); } public static void startNextMatch() { @@ -151,11 +136,9 @@ public class QuestDraftUtils { } matchups.add(matchup); - } - + public static void update() { - if (matchups.isEmpty()) { if (!matchInProgress) { aiMatchInProgress = false; @@ -177,19 +160,12 @@ public class QuestDraftUtils { matchInProgress = true; - SwingUtilities.invokeLater(new Runnable() { - @Override - public void run() { - SOverlayUtils.startGameOverlay(); - SOverlayUtils.showOverlay(); - } - }); - if (!nextMatch.hasHumanPlayer) { GuiBase.getInterface().disableOverlay(); waitForUserInput = false; aiMatchInProgress = true; - } else { + } + else { waitForUserInput = true; aiMatchInProgress = false; } @@ -205,10 +181,9 @@ public class QuestDraftUtils { FThreads.invokeInEdtLater(new Runnable(){ @Override public void run() { - Singletons.getControl().startGameWithUi(match); + GuiBase.getInterface().startGame(match); } }); - } public static void continueMatches() { @@ -222,5 +197,4 @@ public class QuestDraftUtils { private boolean hasHumanPlayer = false; } - } diff --git a/forge-gui/src/main/java/forge/quest/QuestUtil.java b/forge-gui/src/main/java/forge/quest/QuestUtil.java index 734e80961a4..89b963a4f75 100644 --- a/forge-gui/src/main/java/forge/quest/QuestUtil.java +++ b/forge-gui/src/main/java/forge/quest/QuestUtil.java @@ -17,18 +17,37 @@ */ package forge.quest; +import forge.FThreads; +import forge.GuiBase; +import forge.LobbyPlayer; +import forge.assets.FSkinProp; import forge.card.CardDb.SetPreference; import forge.card.CardEdition; import forge.card.CardRules; +import forge.deck.Deck; +import forge.game.GameRules; +import forge.game.GameType; +import forge.game.Match; import forge.game.card.Card; +import forge.game.player.RegisteredPlayer; +import forge.interfaces.IButton; import forge.item.IPaperCard; import forge.item.PaperToken; import forge.model.FModel; +import forge.properties.ForgePreferences.FPref; +import forge.quest.bazaar.QuestItemType; import forge.quest.bazaar.QuestPetController; +import forge.quest.data.QuestAchievements; +import forge.quest.data.QuestAssets; +import forge.quest.data.QuestPreferences.QPref; +import forge.util.gui.SGuiChoose; +import forge.util.gui.SOptionPane; import java.util.ArrayList; import java.util.List; +import org.apache.commons.lang3.tuple.ImmutablePair; + /** *

* QuestUtil class. @@ -170,5 +189,480 @@ public class QuestUtil { // Standard card creation return FModel.getMagicDb().getCommonCards().getCardFromEdition(name, SetPreference.Latest); } + + public static void travelWorld() { + if (!checkActiveQuest("Travel between worlds.")) { + return; + } + List worlds = new ArrayList(); + final QuestController qCtrl = FModel.getQuest(); + + for (QuestWorld qw : FModel.getWorlds()) { + if (qCtrl.getWorld() != qw) { + worlds.add(qw); + } + } + + if (worlds.size() < 1) { + SOptionPane.showErrorDialog("There are currently no worlds you can travel to\nin this version of Forge.", "No Worlds"); + return; + } + + final String setPrompt = "Where do you wish to travel?"; + final QuestWorld newWorld = SGuiChoose.oneOrNone(setPrompt, worlds); + + if (worlds.indexOf(newWorld) < 0) { + return; + } + + if (qCtrl.getWorld() != newWorld) { + boolean needRemove = false; + if (nextChallengeInWins() < 1 && qCtrl.getAchievements().getCurrentChallenges().size() > 0) { + needRemove = true; + + if (!SOptionPane.showConfirmDialog( + "You have uncompleted challenges in your current world. If you travel now, they will be LOST!" + + "\nAre you sure you wish to travel anyway?\n" + + "(Click \"No\" to go back and complete your current challenges first.)", + "WARNING: Uncompleted challenges")) { + return; + } + } + + if (needRemove) { + // Remove current challenges. + while (nextChallengeInWins() == 0) { + qCtrl.getAchievements().addChallengesPlayed(); + } + + qCtrl.getAchievements().getCurrentChallenges().clear(); + } + + qCtrl.setWorld(newWorld); + qCtrl.resetDuelsManager(); + qCtrl.resetChallengesManager(); + // Note that the following can be (ab)used to re-randomize your opponents by travelling to a different + // world and back. To prevent this, simply delete the following line that randomizes DuelsManager. + // (OTOH, you can 'swap' opponents even more easily by simply selecting a different quest data file and + // then re-selecting your current quest data file.) + qCtrl.getDuelsManager().randomizeOpponents(); + qCtrl.getCards().clearShopList(); + qCtrl.save(); + } + } + + private static QuestEvent event; + private static QuestEventDraft draftEvent; + + /** + *

+ * nextChallengeInWins. + *

+ * + * @return a int. + */ + public static int nextChallengeInWins() { + final QuestController qData = FModel.getQuest(); + final int challengesPlayed = qData.getAchievements().getChallengesPlayed(); + + final int wins = qData.getAchievements().getWin(); + final int turnsToUnlock = FModel.getQuest().getTurnsToUnlockChallenge(); + final int delta; + + // First challenge unlocks after minimum wins reached. + if (wins < 2 * turnsToUnlock) { + delta = 2 * turnsToUnlock - wins; + } + else { + // More than enough wins + if (wins / turnsToUnlock > challengesPlayed) { + delta = 0; + } + // This part takes the "unlimited challenge" bug into account; + // a player could have an inflated challengesPlayed value. + // Added 09-2012, can be removed after a while. + else if (wins < challengesPlayed * turnsToUnlock) { + delta = (challengesPlayed * turnsToUnlock - wins) + turnsToUnlock; + } + // Data OK, but not enough wins yet (default). + else { + delta = turnsToUnlock - wins % turnsToUnlock; + } + } + + return (delta > 0) ? delta : 0; + } + + private static void updatePlantAndPetForView(final IVQuestStats view, final QuestController qCtrl) { + for (int iSlot = 0; iSlot < QuestController.MAX_PET_SLOTS; iSlot++) { + final List petList = qCtrl.getPetsStorage().getAvaliablePets(iSlot, qCtrl.getAssets()); + final String currentPetName = qCtrl.getSelectedPet(iSlot); + + if (iSlot == 0) { // Plant visiblity + if (petList.isEmpty()) { + view.getCbPlant().setVisible(false); + } + else { + view.getCbPlant().setVisible(true); + view.getCbPlant().setSelected(currentPetName != null); + } + } + if (iSlot == 1) { + view.getCbxPet().removeAllItems(); + + // Pet list visibility + if (petList.size() > 0) { + view.getCbxPet().setVisible(true); + view.getCbxPet().addItem("Don't summon a pet"); + + for (final QuestPetController pet : petList) { + String name = "Summon " + pet.getName(); + view.getCbxPet().addItem(name); + if (pet.getName().equals(currentPetName)) { + view.getCbxPet().setSelectedItem(name); + } + } + } else { + view.getCbxPet().setVisible(false); + } + } + } + + if (qCtrl.getAssets().hasItem(QuestItemType.CHARM)) { + view.getCbCharm().setVisible(true); + } + else { + view.getCbCharm().setVisible(false); + } + + if (view.isChallengesView()) { + view.getLblZep().setVisible(qCtrl.getAssets().hasItem(QuestItemType.ZEPPELIN)); + if (qCtrl.getAssets().getItemLevel(QuestItemType.ZEPPELIN) == 2) { + view.getLblZep().setEnabled(false); + view.getLblZep().setTextColor(128, 128, 128); + } + else { + view.getLblZep().setEnabled(true); + view.getLblZep().setTextColor(FSkinProp.CLR_TEXT); + } + } + else { + view.getLblZep().setVisible(false); + } + } + + /** + * Updates all quest info in a view, using + * retrieval methods dictated in IVQuestStats.
+ * - Stats
+ * - Pets
+ * - Current deck info
+ * - "Challenge In" info
+ * + * @param view0 {@link forge.screens.home.quest.IVQuestStats} + */ + public static void updateQuestView(final IVQuestStats view0) { + final QuestController qCtrl = FModel.getQuest(); + final QuestAchievements qA = qCtrl.getAchievements(); + final QuestAssets qS = qCtrl.getAssets(); + + if (qA == null) { return; } + + // Fantasy UI display + view0.getLblNextChallengeInWins().setVisible(true); + view0.getBtnBazaar().setVisible(true); + view0.getLblLife().setVisible(true); + + // Stats panel + view0.getLblCredits().setText("Credits: " + qS.getCredits()); + view0.getLblLife().setText("Life: " + qS.getLife(qCtrl.getMode())); + view0.getLblWins().setText("Wins: " + qA.getWin()); + view0.getLblLosses().setText("Losses: " + qA.getLost()); + view0.getLblWorld().setText("World: " + (qCtrl.getWorld() == null ? "(none)" : qCtrl.getWorld())); + + // Show or hide the set unlocking button + + view0.getBtnUnlock().setVisible(qCtrl.getUnlocksTokens() > 0 && qCtrl.getWorldFormat() == null); + + // Challenge in wins + final int num = nextChallengeInWins(); + final String str; + if (num == 0) { + str = "Your exploits have been noticed. An opponent has challenged you."; + } + else if (num == 1) { + str = "A new challenge will be available after 1 more win."; + } + else { + str = "A new challenge will be available in " + num + " wins."; + } + + view0.getLblNextChallengeInWins().setText(str); + + view0.getLblWinStreak().setText( + "Win streak: " + qA.getWinStreakCurrent() + + "
  (Best: " + qA.getWinStreakBest() + ")"); + + // Current deck message + final IButton lblCurrentDeck = view0.getLblCurrentDeck(); + if (getCurrentDeck() == null) { + lblCurrentDeck.setTextColor(204, 0, 0); + lblCurrentDeck.setText("Build, then select a deck in the \"Quest Decks\" submenu."); + } + else { + lblCurrentDeck.setTextColor(FSkinProp.CLR_TEXT); + lblCurrentDeck.setText("Your current deck is \"" + + getCurrentDeck().getName() + "\"."); + } + + // Start panel: pet, plant, zep. + if (qCtrl.getMode() == QuestMode.Fantasy) { + updatePlantAndPetForView(view0, qCtrl); + } + else { + // Classic mode display changes + view0.getCbxPet().setVisible(false); + view0.getCbPlant().setVisible(false); + view0.getCbCharm().setVisible(false); + view0.getLblZep().setVisible(false); + view0.getLblNextChallengeInWins().setVisible(false); + view0.getBtnBazaar().setVisible(false); + view0.getLblLife().setVisible(false); + } + } + + /** @return {@link forge.deck.Deck} */ + public static Deck getCurrentDeck() { + Deck d = null; + + if (FModel.getQuest().getAssets() != null) { + d = FModel.getQuest().getMyDecks().get( + FModel.getQuestPreferences().getPref(QPref.CURRENT_DECK)); + } + + return d; + } + + /** Updates the current selected quest event, used when game is started. + * @param event0 {@link forge.quest.QuestEvent} + */ + public static void setEvent(final QuestEvent event0) { + event = event0; + } + + public static void setDraftEvent(final QuestEventDraft event0) { + draftEvent = event0; + } + + public static QuestEventDraft getDraftEvent() { + return draftEvent; + } + + public static boolean checkActiveQuest(String location) { + QuestController qc = FModel.getQuest(); + if (qc == null || qc.getAssets() == null) { + String msg = "Please create a Quest before attempting to " + location; + SOptionPane.showErrorDialog(msg, "No Quest"); + System.out.println(msg); + return false; + } + return true; + } + + /** */ + public static void showSpellShop() { + if (!checkActiveQuest("Visit the Spell Shop.")) { + return; + } + GuiBase.getInterface().showSpellShop(); + } + + /** */ + public static void showBazaar() { + if (!checkActiveQuest("Visit the Bazaar.")) { + return; + } + GuiBase.getInterface().showBazaar(); + } + + /** */ + public static void chooseAndUnlockEdition() { + if (!checkActiveQuest("Unlock Editions.")) { + return; + } + final QuestController qData = FModel.getQuest(); + ImmutablePair toUnlock = QuestUtilUnlockSets.chooseSetToUnlock(qData, false, null); + if (toUnlock == null) { + return; + } + + CardEdition unlocked = toUnlock.left; + qData.getAssets().subtractCredits(toUnlock.right); + SOptionPane.showMessageDialog("You have successfully unlocked " + unlocked.getName() + "!", + unlocked.getName() + " unlocked!", null); + + QuestUtilUnlockSets.doUnlock(qData, unlocked); + } + + /** */ + public static void startGame() { + if (!checkActiveQuest("Start a duel.") || null == event) { + return; + } + final QuestController qData = FModel.getQuest(); + + Deck deck = null; + if (event instanceof QuestEventChallenge) { + // Predefined HumanDeck + deck = ((QuestEventChallenge) event).getHumanDeck(); + } + if (deck == null) { + // If no predefined Deck, use the Player's Deck + deck = getCurrentDeck(); + } + if (deck == null) { + String msg = "Please select a Quest Deck."; + SOptionPane.showErrorDialog(msg, "No Deck"); + System.out.println(msg); + return; + } + + if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { + String errorMessage = GameType.Quest.getDecksFormat().getDeckConformanceProblem(deck); + if (null != errorMessage) { + SOptionPane.showErrorDialog("Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck"); + return; + } + } + + FThreads.invokeInBackgroundThread(new Runnable() { + @Override + public void run() { + qData.getDuelsManager().randomizeOpponents(); + qData.setCurrentEvent(event); + qData.save(); + } + }); + + int extraLifeHuman = 0; + Integer lifeHuman = null; + boolean useBazaar = true; + Boolean forceAnte = null; + int lifeAI = 20; + if (event instanceof QuestEventChallenge) { + QuestEventChallenge qc = ((QuestEventChallenge) event); + lifeAI = qc.getAILife(); + lifeHuman = qc.getHumanLife(); + + if (qData.getAssets().hasItem(QuestItemType.ZEPPELIN)) { + extraLifeHuman = 3; + } + + useBazaar = qc.isUseBazaar(); + forceAnte = qc.isForceAnte(); + } + + RegisteredPlayer humanStart = new RegisteredPlayer(deck); + RegisteredPlayer aiStart = new RegisteredPlayer(event.getEventDeck()); + + if (lifeHuman != null) { + humanStart.setStartingLife(lifeHuman); + } else { + humanStart.setStartingLife(qData.getAssets().getLife(qData.getMode()) + extraLifeHuman); + } + + if (useBazaar) { + humanStart.setCardsOnBattlefield(QuestUtil.getHumanStartingCards(qData, event)); + aiStart.setStartingLife(lifeAI); + aiStart.setCardsOnBattlefield(QuestUtil.getComputerStartingCards(event)); + } + + List starter = new ArrayList(); + starter.add(humanStart.setPlayer(GuiBase.getInterface().getQuestPlayer())); + + LobbyPlayer aiPlayer = GuiBase.getInterface().getAiPlayer(event.getOpponent() == null ? event.getTitle() : event.getOpponent()); + GuiBase.getInterface().setPlayerAvatar(aiPlayer, event.getIconImageKey()); + starter.add(aiStart.setPlayer(aiPlayer)); + + boolean useRandomFoil = FModel.getPreferences().getPrefBoolean(FPref.UI_RANDOM_FOIL); + for(RegisteredPlayer rp : starter) { + rp.setRandomFoil(useRandomFoil); + } + boolean useAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE); + boolean matchAnteRarity = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE_MATCH_RARITY); + if(forceAnte != null) + useAnte = forceAnte.booleanValue(); + GameRules rules = new GameRules(GameType.Quest); + rules.setPlayForAnte(useAnte); + rules.setMatchAnteRarity(matchAnteRarity); + rules.setGamesPerMatch(qData.getCharmState() ? 5 : 3); + rules.setManaBurn(FModel.getPreferences().getPrefBoolean(FPref.UI_MANABURN)); + rules.canCloneUseTargetsImage = FModel.getPreferences().getPrefBoolean(FPref.UI_CLONE_MODE_SOURCE); + final Match mc = new Match(rules, starter); + FThreads.invokeInEdtLater(new Runnable(){ + @Override + public void run() { + GuiBase.getInterface().startGame(mc); + } + }); + } + + /** + * Checks to see if a game can be started and displays relevant dialogues. + * @return + */ + public static boolean canStartGame() { + if (!checkActiveQuest("Start a duel.") || null == event) { + return false; + } + + Deck deck = null; + if (event instanceof QuestEventChallenge) { + // Predefined HumanDeck + deck = ((QuestEventChallenge) event).getHumanDeck(); + } + + if (deck == null) { + // If no predefined Deck, use the Player's Deck + deck = getCurrentDeck(); + } + + if (deck == null) { + String msg = "Please select a Quest Deck."; + SOptionPane.showErrorDialog(msg, "No Deck"); + System.out.println(msg); + return false; + } + + if (FModel.getPreferences().getPrefBoolean(FPref.ENFORCE_DECK_LEGALITY)) { + String errorMessage = GameType.Quest.getDecksFormat().getDeckConformanceProblem(deck); + if (null != errorMessage) { + SOptionPane.showErrorDialog("Your deck " + errorMessage + " Please edit or choose a different deck.", "Invalid Deck"); + return false; + } + } + + return true; + } + + /** Duplicate in DeckEditorQuestMenu and + * probably elsewhere...can streamline at some point + * (probably shouldn't be here). + * + * @param in   {@link java.lang.String} + * @return {@link java.lang.String} + */ + public static String cleanString(final String in) { + final StringBuffer out = new StringBuffer(); + final char[] c = in.toCharArray(); + + for (int i = 0; (i < c.length) && (i < 20); i++) { + if (Character.isLetterOrDigit(c[i]) || (c[i] == '-') || (c[i] == '_') || (c[i] == ' ')) { + out.append(c[i]); + } + } + + return out.toString(); + } } // QuestUtil