diff --git a/.gitattributes b/.gitattributes
index f100adc7647..d5008acf8dd 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1197,6 +1197,8 @@ forge-gui-mobile/src/forge/screens/match/views/VZoneDisplay.java -text
forge-gui-mobile/src/forge/screens/match/winlose/ControlWinLose.java -text
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/QuestWinLose.java -text
+forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLoseCardViewer.java -text
forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java -text
forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java -text
forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java -text
diff --git a/forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLose.java b/forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLose.java
new file mode 100644
index 00000000000..4c610e5bfb8
--- /dev/null
+++ b/forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLose.java
@@ -0,0 +1,882 @@
+/** Forge: Play Magic: the Gathering.
+ * Copyright (C) 2011 Forge Team
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see
+ * QuestWinLose. + *
+ * Processes win/lose presentation for Quest events. This presentation is + * displayed by WinLoseFrame. Components to be added to pnlCustom in + * WinLoseFrame should use MigLayout. + * + */ +public class QuestWinLose extends ControlWinLose { + private final transient boolean wonMatch; + private final transient ViewWinLose view; + private transient FSkinImage icoTemp; + private transient TitleLabel lblTemp1; + private transient FLabel lblTemp2; + private final transient boolean isAnte; + + private final transient QuestController qData; + private final transient QuestEvent qEvent; + + /** + * Instantiates a new quest win lose handler. + * + * @param view0 ViewWinLose object + * @param match2 + */ + public QuestWinLose(final ViewWinLose view0, Game lastGame) { + super(view0, lastGame); + view = view0; + qData = FModel.getQuest(); + qEvent = qData.getCurrentEvent(); + wonMatch = lastGame.getMatch().isWonBy(GuiBase.getInterface().getQuestPlayer()); + isAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE); + } + + + /** + *+ * populateCustomPanel. + *
+ * Checks conditions of win and fires various reward display methods + * accordingly. + * + * @return true, if successful + */ + @Override + public final boolean populateCustomPanel() { + getView().getBtnRestart().setVisible(false); + QuestController qc = FModel.getQuest(); + + // After the first game, reset the card shop pool to be able to buy back anted cards + if (lastGame.getMatch().getPlayedGames().size() == 1) { + qc.getCards().clearShopList(); + qc.getCards().getShopList(); + } + + final LobbyPlayer questLobbyPlayer = GuiBase.getInterface().getQuestPlayer(); + Player questPlayer = null; + for (Player p : lastGame.getRegisteredPlayers()) { + if (p.getLobbyPlayer().equals(questLobbyPlayer)) { + questPlayer = p; + } + } + if (isAnte) { + //do per-game actions + GameOutcome outcome = lastGame.getOutcome(); + + // Won/lost cards should already be calculated (even in a draw) + GameOutcome.AnteResult anteResult = outcome.anteResult.get(questPlayer); + if (anteResult != null) { + if (anteResult.wonCards != null) + qc.getCards().addAllCards(anteResult.wonCards); + if (anteResult.lostCards != null) + qc.getCards().loseCards(anteResult.lostCards); + anteReport(anteResult.wonCards, anteResult.lostCards, questPlayer.equals(outcome.getWinningPlayer())); + } + } + + if (!lastGame.getMatch().isMatchOver()) { + getView().getBtnQuit().setText("Quit (-15 Credits)"); + return isAnte; + } else { + getView().getBtnContinue().setVisible(false); + if (wonMatch) { + getView().getBtnQuit().setText("Great!"); + } else { + getView().getBtnQuit().setText("OK"); + } + } + + // TODO: We don't have a enum for difficulty? + int difficulty = qData.getAchievements().getDifficulty(); + + + final int wins = qData.getAchievements().getWin(); + // Win case + if (wonMatch) { + // Standard event reward credits + awardEventCredits(); + + // Challenge reward credits + if (qEvent instanceof QuestEventChallenge) { + awardChallengeWin(); + } + + else { + awardSpecialReward("Special bonus reward:"); // If any + // Random rare for winning against a very hard deck + if (qEvent.getDifficulty() == QuestEventDifficulty.EXPERT) { + awardRandomRare("You've won a random rare for winning against a very hard deck."); + } + } + + awardWinStreakBonus(); + + // Random rare given at 50% chance (65% with luck upgrade) + if (getLuckyCoinResult()) { + awardRandomRare("You've won a random rare."); + } + + // Award jackpot every 80 games won (currently 10 rares) + + if ((wins > 0) && (((wins + 1) % 80) == 0)) { + awardJackpot(); + } + + } + // Lose case + else { + penalizeLoss(); + } + + // Grant booster on a win, or on a loss in easy mode + if (wonMatch || difficulty == 0) { + final int outcome = wonMatch ? wins : qData.getAchievements().getLost(); + int winsPerBooster = FModel.getQuestPreferences().getPrefInt(DifficultyPrefs.WINS_BOOSTER, qData.getAchievements().getDifficulty()); + if (winsPerBooster > 0 && (outcome + 1) % winsPerBooster == 0) { + awardBooster(); + } + } + + return true; + } + + private void anteReport(final List+ * actionOnQuit. + *
+ * When "quit" button is pressed, this method adjusts quest data as + * appropriate and saves. + * + */ + @Override + public final void actionOnQuit() { + final int x = FModel.getQuestPreferences().getPrefInt(QPref.PENALTY_LOSS); + + // Record win/loss in quest data + if (wonMatch) { + qData.getAchievements().addWin(); + } + else { + qData.getAchievements().addLost(); + qData.getAssets().subtractCredits(x); + } + + // Reset cards and zeppelin use + if (qData.getAssets().hasItem(QuestItemType.ZEPPELIN)) { + qData.getAssets().setItemLevel(QuestItemType.ZEPPELIN, 1); + } + + if (qEvent instanceof QuestEventChallenge) { + final String id = ((QuestEventChallenge) qEvent).getId(); + qData.getAchievements().getCurrentChallenges().remove(id); + qData.getAchievements().addLockedChallenge(id); + + // Increment challenge counter to limit challenges available + qData.getAchievements().addChallengesPlayed(); + } + + qData.setCurrentEvent(null); + qData.save(); + FModel.getQuestPreferences().save(); + FControl.writeMatchPreferences(); + + FControl.endCurrentGame(); + view.hide(); + } + + /** + *+ * awardEventCredits. + *
+ * Generates and displays standard rewards for gameplay and skill level. + * + */ + private void awardEventCredits() { + // TODO use q.qdPrefs to write bonus credits in prefs file + final StringBuilder sb = new StringBuilder(""); + + int credTotal = 0; + int credBase = 0; + int credGameplay = 0; + int credUndefeated = 0; + int credEstates = 0; + + // Basic win bonus + final int base = FModel.getQuestPreferences().getPrefInt(QPref.REWARDS_BASE); + double multiplier = 1; + + switch (qEvent.getDifficulty()) { + case EASY: multiplier = 1; break; + case MEDIUM: multiplier = 1.5; break; + case HARD: multiplier = 2; break; + case EXPERT: multiplier = 3; break; + } + + credBase = (int) (base * multiplier); + + sb.append(StringUtils.capitalize(qEvent.getDifficulty().getTitle())); + sb.append(" opponent: ").append(credBase).append(" credits.