UI improvements, round 1: WinLose UI streamlined.

This commit is contained in:
Doublestrike
2011-10-02 11:57:04 +00:00
parent 4956eb8e0b
commit ce8d5de10e
8 changed files with 1030 additions and 5 deletions

4
.gitattributes vendored
View File

@@ -10240,6 +10240,8 @@ src/main/java/forge/quest/gui/QuestAbstractPanel.java svneol=native#text/plain
src/main/java/forge/quest/gui/QuestFrame.java svneol=native#text/plain
src/main/java/forge/quest/gui/QuestMainPanel.java -text
src/main/java/forge/quest/gui/QuestOptions.java svneol=native#text/plain
src/main/java/forge/quest/gui/QuestWinLoseCardViewer.java -text
src/main/java/forge/quest/gui/QuestWinLoseHandler.java -text
src/main/java/forge/quest/gui/bazaar/QuestBazaarItem.java svneol=native#text/plain
src/main/java/forge/quest/gui/bazaar/QuestBazaarPanel.java svneol=native#text/plain
src/main/java/forge/quest/gui/bazaar/QuestBazaarStall.java svneol=native#text/plain
@@ -10263,6 +10265,8 @@ src/main/java/forge/view/swing/OldGuiNewGame.java svneol=native#text/plain
src/main/java/forge/view/swing/SplashFrame.java -text
src/main/java/forge/view/swing/SplashProgressComponent.java -text
src/main/java/forge/view/swing/SplashProgressModel.java -text
src/main/java/forge/view/swing/WinLoseFrame.java -text
src/main/java/forge/view/swing/WinLoseModeHandler.java -text
src/main/java/forge/view/swing/package-info.java svneol=native#text/plain
src/main/java/net/slightlymagic/braids/LICENSE.txt svneol=native#text/plain
src/main/java/net/slightlymagic/braids/util/ClumsyRunnable.java svneol=native#text/plain

View File

@@ -29,8 +29,10 @@ import forge.gui.input.Input_PayManaCost_Ability;
import forge.item.CardPrinted;
import forge.properties.ForgeProps;
import forge.properties.NewConstants.LANG.GameAction.GAMEACTION_TEXT;
import forge.quest.gui.QuestWinLoseHandler;
import forge.quest.gui.main.QuestChallenge;
import forge.quest.gui.main.QuestEvent;
import forge.view.swing.WinLoseFrame;
import java.util.ArrayList;
import java.util.Arrays;
@@ -655,13 +657,27 @@ public class GameAction {
AllZone.getDisplay().savePrefs();
frame.setEnabled(false);
//frame.dispose();
Gui_WinLose gwl = new Gui_WinLose(AllZone.getMatchState(), AllZone.getQuestData(), AllZone.getQuestEvent());
//Gui_WinLose gwl = new Gui_WinLose(AllZone.getMatchState(), AllZone.getQuestData(), AllZone.getQuestChallenge());
// New WinLoseFrame below. Old Gui_WinLose above.
// Old code should still work if any problems with new. Doublestrike 02-10-11
WinLoseFrame gwl;
if(AllZone.getQuestData() != null) {
gwl = new WinLoseFrame(new QuestWinLoseHandler());
}
else {
gwl = new WinLoseFrame();
}
//gwl.setAlwaysOnTop(true);
gwl.toFront();
canShowWinLose = false;
return;
}
//do this twice, sometimes creatures/permanents will survive when they shouldn't
for (int q = 0; q < 9; q++) {

View File

@@ -113,18 +113,48 @@ public final class GuiUtils {
/**
* <p>getIconFromFile.</p>
*
* @param iconName a {@link java.lang.String} object.
* @param filename a {@link java.lang.String} object.
* @return a {@link javax.swing.ImageIcon} object.
*/
public static ImageIcon getIconFromFile(final String iconName) {
public static ImageIcon getIconFromFile(final String filename) {
File base = ForgeProps.getFile(NewConstants.IMAGE_ICON);
File file = new File(base, iconName);
if (iconName.equals("") || !file.exists()) {
File file = new File(base, filename);
if (filename.equals("") || !file.exists()) {
return null;
} else {
return new ImageIcon(file.toString());
}
}
/**
* <p>getResizedIcon.</p>
*
* @param {@link java.lang.String} filename.
* @param {@link java.lang.Double} scale
* @return {@link javax.swing.ImageIcon} object
*/
public static ImageIcon getResizedIcon(final String filename, double scale) {
ImageIcon icon = getIconFromFile(filename);
int w = (int) (icon.getIconWidth()*scale);
int h = (int) (icon.getIconHeight()*scale);
return new ImageIcon(icon.getImage().getScaledInstance(w, h, Image.SCALE_SMOOTH));
}
/**
* <p>getResizedIcon.</p>
*
* @param {@link javax.swing.ImageIcon} object
* @param {@link java.lang.Double} scale
* @return {@link javax.swing.ImageIcon} object
*/
public static ImageIcon getResizedIcon(final ImageIcon icon, double scale) {
int w = (int) (icon.getIconWidth()*scale);
int h = (int) (icon.getIconHeight()*scale);
return new ImageIcon(icon.getImage().getScaledInstance(w, h, Image.SCALE_SMOOTH));
}
/**
* <p>getResizedIcon.</p>

View File

@@ -461,6 +461,20 @@ public interface NewConstants {
}
}
public static interface WinLoseFrame {
public static interface WINLOSETEXT {
String WON = "%s/WinLose/won";
String LOST = "%s/WinLose/lost";
String WIN = "%s/WinLose/win";
String LOSE = "%s/WinLose/lose";
String CONTINUE = "%s/WinLose/continue";
String RESTART = "%s/WinLose/restart";
String QUIT = "%s/WinLose/quit";
}
}
// end
// Doublestrike 02-10-11 - this is soon to be deprecated.
public static interface Gui_WinLose {
public static interface WINLOSE_TEXT {
String WON = "%s/WinLose/won";

View File

@@ -0,0 +1,86 @@
package forge.quest.gui;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import forge.AllZone;
import forge.Card;
import forge.CardUtil;
import forge.gui.game.CardDetailPanel;
import forge.gui.game.CardPicturePanel;
import forge.item.CardPrinted;
import java.util.List;
import static java.util.Collections.unmodifiableList;
/**
* A simple JPanel that shows three columns: card list, pic, and description..
*
* @author Forge
* @version $Id: ListChooser.java 9708 2011-08-09 19:34:12Z jendave $
*/
@SuppressWarnings("serial")
public class QuestWinLoseCardViewer extends JPanel {
//Data and number of choices for the list
private List<CardPrinted> list;
//initialized before; listeners may be added to it
private JList jList;
private CardDetailPanel detail;
private CardPicturePanel picture;
public QuestWinLoseCardViewer(List<CardPrinted> list) {
this.list = unmodifiableList(list);
jList = new JList(new ChooserListModel());
detail = new CardDetailPanel(null);
picture = new CardPicturePanel(null);
this.add(new JScrollPane(jList));
this.add(picture);
this.add(detail);
this.setLayout( new java.awt.GridLayout(1, 3, 6, 0) );
// selection is here
jList.getSelectionModel().addListSelectionListener(new SelListener());
jList.setSelectedIndex(0);
}
private class ChooserListModel extends AbstractListModel {
private static final long serialVersionUID = 3871965346333840556L;
public int getSize() { return list.size(); }
public Object getElementAt(int index) { return list.get(index); }
}
private class SelListener implements ListSelectionListener {
private Card[] cache = null;
public void valueChanged(final ListSelectionEvent e) {
int row = jList.getSelectedIndex();
// (String) jList.getSelectedValue();
if (row >= 0 && row < list.size()) {
CardPrinted cp = list.get(row);
ensureCacheHas(row, cp);
detail.setCard(cache[row]);
picture.setCard(cp);
}
}
private void ensureCacheHas(int row, CardPrinted cp) {
if (cache == null) { cache = new Card[list.size()]; }
if (null == cache[row]) {
Card card = AllZone.getCardFactory().getCard(cp.getName(), null);
card.setCurSetCode(cp.getSet());
card.setImageFilename(CardUtil.buildFilename(card));
cache[row] = card;
}
}
}
}

View File

@@ -0,0 +1,541 @@
package forge.quest.gui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import forge.AllZone;
import forge.CardList;
import forge.Constant;
import forge.MyRandom;
import forge.Player;
import forge.SetUtils;
import forge.game.GameEndReason;
import forge.game.GameFormat;
import forge.game.GameLossReason;
import forge.game.GamePlayerRating;
import forge.game.GameSummary;
import forge.gui.GuiUtils;
import forge.item.CardPrinted;
import forge.quest.data.QuestData;
import forge.quest.data.QuestMatchState;
import forge.quest.data.QuestPreferences;
import forge.quest.gui.QuestWinLoseCardViewer;
import forge.quest.gui.main.QuestEvent;
import forge.quest.gui.main.QuestChallenge;
import forge.view.swing.WinLoseModeHandler;
/** <p>QuestWinLoseHandler.</p>
* 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 QuestWinLoseHandler extends WinLoseModeHandler {
private boolean wonMatch;
private ImageIcon icoTemp;
private JLabel lblTemp1;
private JLabel lblTemp2;
int spacer = 50;
private class CommonObjects {
public QuestMatchState qMatchState;
public QuestData qData;
public QuestEvent qEvent;
}
private CommonObjects model;
public QuestWinLoseHandler() {
super();
model = new CommonObjects();
model.qMatchState = AllZone.getMatchState();
model.qData = AllZone.getQuestData();
model.qEvent = AllZone.getQuestEvent();
wonMatch = model.qMatchState.isMatchWonBy(AllZone.getHumanPlayer().getName());
}
/**
* <p>startNextRound.</p>
* Either continues or restarts a current game.
*
* @param e a {@link java.awt.event.ActionEvent} object.
*/
@Override
public void startNextRound() {
if(model.qEvent.getEventType().equals("challenge")) {
int extraLife = 0;
if (model.qData.getInventory().hasItem("Zeppelin")) {
extraLife += 3;
}
// Found this commented out - is it still necessary? Doublestrike 01-10-11
//AllZone.getGameAction().newGame(Constant.Runtime.HumanDeck[0], Constant.Runtime.ComputerDeck[0],
//humanList, computerList, humanLife, computerLife);
CardList humanList = forge.quest.data.QuestUtil.getHumanStartingCards(model.qData,model.qEvent);
CardList computerList = forge.quest.data.QuestUtil.getComputerStartingCards(model.qData,model.qEvent);
int humanLife = model.qData.getLife() + extraLife;
int computerLife = 20;
computerLife = ((QuestChallenge)model.qEvent).getAILife();
AllZone.getGameAction().newGame(Constant.Runtime.HumanDeck[0], Constant.Runtime.ComputerDeck[0],
humanList, computerList, humanLife, computerLife, model.qEvent);
}
super.startNextRound();
}
/**
* <p>populateCustomPanel.</p>
* Checks conditions of win and fires various reward display methods accordingly.
*
* @param boolean indicating if custom panel has contents.
*/
@Override
public boolean populateCustomPanel() {
view.btnRestart.setVisible(false);
if(!model.qMatchState.isMatchOver()) {
view.btnQuit.setText("Surrender (15 Credits)");
return false;
}
// Win case
if(wonMatch) {
// Standard event reward credits
awardEventCredits();
// Challenge reward credits
if(model.qEvent.getEventType().equals("challenge")) {
awardChallengeWin();
}
// Random rare given at 50% chance (65% with luck upgrade)
if (getLuckyCoinResult()) {
awardRandomRare("You've won a random rare.");
}
// Random rare for winning against a very hard deck
if(model.qData.getDifficultyIndex() == 4) {
awardRandomRare("You've won a random rare for winning against a very hard deck.");
}
// Award jackpot every 80 games won (currently 10 rares)
int wins = model.qData.getWin();
if (wins > 0 && wins % 80 == 0) {
awardJackpot();
}
}
// Lose case
else {
penalizeLoss();
}
// Win or lose, still a chance to win a booster, frequency set in preferences
int cntOutcomes = wonMatch ? model.qData.getWin() : model.qData.getLost();
if (cntOutcomes % QuestPreferences.getWinsForBooster(model.qData.getDifficultyIndex()) == 0) {
awardBooster();
}
return true;
}
/**
* <p>actionOnQuit.</p>
* When "quit" button is pressed, this method adjusts quest data as appropriate and saves.
*
*/
@Override
public void actionOnQuit() {
// Record win/loss in quest data
if (model.qMatchState.isMatchWonBy(AllZone.getHumanPlayer().getName())) {
model.qData.addWin();
} else {
model.qData.addLost();
model.qData.subtractCredits(15);
}
//System.out.println("model.qData cardpoolsize:" + AllZone.getQuestData().getCardpool().size());
model.qData.getCards().clearShopList();
if (model.qData.getAvailableChallenges() != null) {
model.qData.clearAvailableChallenges();
}
model.qData.getCards().resetNewList();
model.qMatchState.reset();
AllZone.setQuestEvent(null);
model.qData.saveData();
new QuestFrame();
}
/**
* <p>awardEventCredits.</p>
* Generates and displays standard rewards for gameplay and skill level.
*
*/
private void awardEventCredits() {
// TODO use q.qdPrefs to write bonus credits in prefs file
StringBuilder sb = new StringBuilder("<html>");
int credTotal = 0;
int credBase = 0;
int credGameplay = 0;
int credUndefeated = 0;
int credEstates = 0;
// Basic win bonus
int base = QuestPreferences.getMatchRewardBase();
double multiplier = 1;
String diff = AllZone.getQuestEvent().getDifficulty();
diff = diff.substring(0, 1).toUpperCase() + diff.substring(1);
if(diff.equalsIgnoreCase("medium")) {
multiplier = 1.5;
}
else if(diff.equalsIgnoreCase("hard")) {
multiplier = 2;
}
else if(diff.equalsIgnoreCase("very hard")) {
multiplier = 2.5;
}
else if(diff.equalsIgnoreCase("expert")) {
multiplier = 3;
}
credBase += (int) (base*multiplier +
(QuestPreferences.getMatchRewardTotalWins() * model.qData.getWin()));
sb.append(diff + " opponent: " + credBase + " credits.<br>");
// Gameplay bonuses (for each game win)
boolean hasNeverLost = true;
Player computer = AllZone.getComputerPlayer();
for (GameSummary game : model.qMatchState.getGamesPlayed()) {
if (game.isWinner(computer.getName())) {
hasNeverLost = false;
continue; // no rewards for losing a game
}
// Alternate win
GamePlayerRating aiRating = game.getPlayerRating(computer.getName());
GamePlayerRating humanRating = game.getPlayerRating(AllZone.getHumanPlayer().getName());
GameLossReason whyAiLost = aiRating.getLossReason();
int altReward = getCreditsRewardForAltWin(whyAiLost);
if (altReward > 0) {
String winConditionName = "Unknown (bug)";
if (game.getWinCondition() == GameEndReason.WinsGameSpellEffect) {
winConditionName = game.getWinSpellEffect();
} else {
switch(whyAiLost) {
case Poisoned: winConditionName = "Poison"; break;
case Milled: winConditionName = "Milled"; break;
case SpellEffect: winConditionName = aiRating.getLossSpellName(); break;
default: break;
}
}
credGameplay += 50;
sb.append(String.format("Alternate win condition: <u>%s</u>! " +
"Bonus: %d credits.<br>",
winConditionName, 50));
}
// Mulligan to zero
int cntCardsHumanStartedWith = humanRating.getOpeningHandSize();
int mulliganReward = QuestPreferences.getMatchMullToZero();
if (0 == cntCardsHumanStartedWith) {
credGameplay += mulliganReward;
sb.append(String.format("Mulliganed to zero and still won! " +
"Bonus: %d credits.<br>", mulliganReward));
}
// Early turn bonus
int winTurn = game.getTurnGameEnded();
int turnCredits = getCreditsRewardForWinByTurn(winTurn);
if (winTurn == 0) { System.err.println("QuestWinLoseHandler > " +
"turn calculation error: Zero turn win");
} else if (winTurn == 1) { sb.append("Won in one turn!");
} else if (winTurn <= 5) { sb.append("Won by turn 5!");
} else if (winTurn <= 10) { sb.append("Won by turn 10!");
} else if (winTurn <= 15) { sb.append("Won by turn 15!");
}
if (turnCredits > 0) {
credGameplay += turnCredits;
sb.append(String.format(" Bonus: %d credits.<br>", turnCredits));
}
} // End for(game)
// Undefeated bonus
if (hasNeverLost) {
credUndefeated += QuestPreferences.getMatchRewardNoLosses();
int reward = QuestPreferences.getMatchRewardNoLosses();
sb.append(String.format("You have not lost once! " +
"Bonus: %d credits.<br>", reward));
}
// Estates bonus
credTotal = credBase + credGameplay + credUndefeated;
switch(model.qData.getInventory().getItemLevel("Estates")) {
case 1:
credEstates = (int)0.1*credTotal;
sb.append("Estates bonus: 10%.<br>");
break;
case 2:
credEstates = (int)0.15*credTotal;
sb.append("Estates bonus: 15%.<br>");
break;
case 3:
credEstates = (int)0.2*credTotal;
sb.append("Estates bonus: 20%.<br>");
break;
default: break;
}
credTotal += credEstates;
// Final output
String congrats = "<br><h3>";
if(credTotal < 100) {
congrats += "You've earned";
} else if(credTotal < 250) {
congrats += "Could be worse: ";
} else if(credTotal < 500) {
congrats += "A respectable";
} else if(credTotal < 750) {
congrats += "An impressive";
} else {
congrats += "Spectacular match!";
}
sb.append(String.format("%s <b>%d credits</b> in total.</h3>", congrats, credTotal));
sb.append("</body></html>");
// Generate Swing components and attach.
icoTemp = GuiUtils.getResizedIcon("GoldIcon.png",0.5);
lblTemp1 = new TitleLabel("Gameplay Results");
lblTemp2 = new JLabel(sb.toString());
lblTemp2.setHorizontalAlignment(SwingConstants.CENTER);
lblTemp2.setFont(new Font("Tahoma", Font.PLAIN, 14));
lblTemp2.setForeground(Color.white);
lblTemp2.setIcon(icoTemp);
lblTemp2.setIconTextGap(50);
view.pnlCustom.add(lblTemp1,"align center, width 95%!");
view.pnlCustom.add(lblTemp2,"align center, width 95%!, gaptop 10");
}
/**
* <p>awardRandomRare.</p>
* Generates and displays a random rare win case.
*
*/
private void awardRandomRare(String message) {
CardPrinted c = model.qData.getCards().addRandomRare();
List<CardPrinted> cardsWon = new ArrayList<CardPrinted>();
cardsWon.add(c);
// Generate Swing components and attach.
lblTemp1 = new TitleLabel(message);
QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cardsWon);
view.pnlCustom.add(lblTemp1,"align center, width 95%!, " +
"gaptop " + spacer + ", gapbottom 10");
view.pnlCustom.add(cv,"align center, width 95%!");
}
/**
* <p>awardJackpot.</p>
* Generates and displays jackpot win case.
*
*/
private void awardJackpot() {
List<CardPrinted> cardsWon = model.qData.getCards().addRandomRare(10);
// Generate Swing components and attach.
lblTemp1 = new TitleLabel("You just won 10 random rares!");
QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cardsWon);
view.pnlCustom.add(lblTemp1,"align center, width 95%!, " +
"gaptop " + spacer + ", gapbottom 10");
view.pnlCustom.add(cv,"align center, width 95%!");
}
/**
* <p>awardBooster.</p>
* Generates and displays booster pack win case.
*
*/
private void awardBooster() {
List<GameFormat> sets = SetUtils.getFormats();
int rand = (int)(Math.floor(Math.random()*(sets.size())));
GameFormat selected = sets.get(rand);
List<CardPrinted> cardsWon = model.qData.getCards().addCards(selected.getFilterPrinted());
// Generate Swing components and attach.
lblTemp1 = new TitleLabel("Bonus booster pack from the \""+selected.getName()+"\" set!");
QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cardsWon);
view.pnlCustom.add(lblTemp1,"align center, width 95%!, " +
"gaptop " + spacer + ", gapbottom 10");
view.pnlCustom.add(cv,"align center, width 95%!");
}
/**
* <p>awardChallengeWin.</p>
* Generates and displays win case for challenge event.
*
*/
private void awardChallengeWin() {
if(!((QuestChallenge)model.qEvent).getRepeatable()) {
model.qData.addCompletedChallenge(((QuestChallenge)model.qEvent).getId());
}
// Note: challenge only registers as "played" if it's won.
// This doesn't seem right, but it's easy to fix. Doublestrike 01-10-11
model.qData.addChallengesPlayed();
List<CardPrinted> cardsWon = ((QuestChallenge)model.qEvent).getCardRewardList();
long questRewardCredits = ((QuestChallenge)model.qEvent).getCreditsReward();
StringBuilder sb = new StringBuilder();
sb.append("<html>Challenge completed.<br><br>");
sb.append("Challenge bounty: <b>" + questRewardCredits + " credits.</b></html>");
model.qData.addCredits(questRewardCredits);
// Generate Swing components and attach.
icoTemp = GuiUtils.getResizedIcon("BoxIcon.png",0.5);
lblTemp1 = new TitleLabel("Challenge Rewards for \"" +
((QuestChallenge)model.qEvent).getTitle() + "\"");
lblTemp2 = new JLabel(sb.toString());
lblTemp2.setFont(new Font("Tahoma", Font.PLAIN, 14));
lblTemp2.setForeground(Color.white);
lblTemp2.setHorizontalAlignment(SwingConstants.CENTER);
lblTemp2.setIconTextGap(50);
lblTemp2.setIcon(icoTemp);
view.pnlCustom.add(lblTemp1,"align center, width 95%!, " +
"gaptop " + spacer);
view.pnlCustom.add(lblTemp2,"align center, width 95%!, height 80!, gapbottom 10");
if (cardsWon != null) {
QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cardsWon);
view.pnlCustom.add(cv,"align center, width 95%!");
model.qData.getCards().addAllCards(cardsWon);
}
}
private void penalizeLoss() {
icoTemp = GuiUtils.getResizedIcon("HeartIcon.png",0.5);
lblTemp1 = new TitleLabel("Gameplay Results");
lblTemp2 = new JLabel("You lose! You have lost 15 credits.");
lblTemp2.setFont(new Font("Tahoma", Font.PLAIN, 14));
lblTemp2.setForeground(Color.white);
lblTemp2.setHorizontalAlignment(SwingConstants.CENTER);
lblTemp2.setIconTextGap(50);
lblTemp2.setIcon(icoTemp);
view.pnlCustom.add(lblTemp1,"align center, width 95%!");
view.pnlCustom.add(lblTemp2,"align center, width 95%!, height 80!");
}
/**
* <p>getLuckyCoinResult.</p>
* A chance check, for rewards like random rares.
*
* @return boolean
*/
private boolean getLuckyCoinResult() {
boolean hasCoin = model.qData.getInventory().getItemLevel("Lucky Coin") >= 1;
return MyRandom.random.nextFloat() <= (hasCoin ? 0.65f : 0.5f);
}
/**
* <p>getCreditsRewardForAltWin.</p>
* Retrieves credits for win under special conditions.
*
* @param GameLossReason why AI lost
* @return int
*/
private int getCreditsRewardForAltWin(final GameLossReason whyAiLost) {
switch (whyAiLost) {
case LifeReachedZero: return 0; // nothing special here, ordinary kill
case Milled: return QuestPreferences.getMatchRewardMilledWinBonus();
case Poisoned: return QuestPreferences.getMatchRewardPoisonWinBonus();
case DidNotLoseYet: return QuestPreferences.getMatchRewardAltWinBonus(); // Felidar, Helix Pinnacle, etc.
case SpellEffect: return QuestPreferences.getMatchRewardAltWinBonus(); // Door to Nothingness, etc.
default: return 0;
}
}
/**
* <p>getCreditsRewardForWinByTurn.</p>
* Retrieves credits for win on or under turn count.
*
* @param int turn count
* @return int credits won
*/
private int getCreditsRewardForWinByTurn(final int iTurn) {
int credits = 0;
if (iTurn == 1) {
credits = QuestPreferences.getMatchRewardWinFirst();
}
else if (iTurn <= 5) {
credits = QuestPreferences.getMatchRewardWinByFifth();
}
else if (iTurn <= 10) {
credits = QuestPreferences.getMatchRewardWinByTen();
}
else if (iTurn <= 15) {
credits = QuestPreferences.getMatchRewardWinByFifteen();
}
return credits;
}
@SuppressWarnings("serial")
private class TitleLabel extends JLabel {
TitleLabel(String msg) {
super(msg);
this.setFont(new Font("Tahoma", Font.ITALIC, 16));
this.setPreferredSize(new Dimension(200,40));
this.setHorizontalAlignment(SwingConstants.CENTER);
this.setForeground(Color.white);
this.setBorder(BorderFactory.createMatteBorder(1, 0, 1, 0, Color.white));
}
}
}

View File

@@ -0,0 +1,249 @@
package forge.view.swing;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingConstants;
import forge.AllZone;
import forge.Phase;
import forge.Player;
import forge.properties.ForgeProps;
import forge.properties.NewConstants.LANG.WinLoseFrame.WINLOSETEXT;
import forge.quest.data.QuestMatchState;
import net.miginfocom.swing.MigLayout;
/** <p>WinLoseFrame.</p>
* Core display for win/lose UI shown after completing a game.
* Uses handlers to customize central panel for various game modes.
*
*/
@SuppressWarnings("serial")
public class WinLoseFrame extends JFrame {
private QuestMatchState matchState;
private WinLoseModeHandler modeHandler;
public JButton btnContinue;
public JButton btnQuit;
public JButton btnRestart;
public JLabel lblTitle;
public JLabel lblStats;
public JPanel pnlCustom;
/**
* <p>WinLoseFrame.</p>
* Starts win/lose UI with default display.
*
*/
public WinLoseFrame() {
this(new WinLoseModeHandler());
}
/**
* <p>WinLoseFrame.</p>
* Starts the standard win/lose UI with custom display
* for different game modes (quest, puzzle, etc.)
*
* @param mh {@link forge.view.swing.WinLoseModeHandler}
*/
public WinLoseFrame(WinLoseModeHandler mh) {
super();
// modeHandler handles the unique display for different game modes.
modeHandler = mh;
modeHandler.setView(this);
matchState = AllZone.getMatchState();
Container contentPane = this.getContentPane();
contentPane.setLayout(new MigLayout("wrap, fill"));
contentPane.setBackground(new Color(16,28,50));
int HEAD_HEIGHT = 100;
int FOOT_HEIGHT = 150;
int FRAME_WIDTH_SMALL = 300;
int FRAME_WIDTH_BIG = 600;
// Head panel
JPanel pnlHead = new JPanel(new MigLayout("wrap, fill"));
pnlHead.setOpaque(false);
this.add(pnlHead,"width " + FRAME_WIDTH_SMALL + "!, align center");
lblTitle = new JLabel("WinLoseFrame > lblTitle is broken.");
lblTitle.setForeground(Color.white);
lblTitle.setHorizontalAlignment(SwingConstants.CENTER);
lblTitle.setFont(new Font("Tahoma", Font.PLAIN, 26));
lblStats = new JLabel("WinLoseFrame > lblStats is broken.");
lblStats.setForeground(Color.white);
lblStats.setHorizontalAlignment(SwingConstants.CENTER);
lblStats.setFont(new Font("Tahoma", Font.ITALIC, 21));
pnlHead.add(lblTitle, "growx");
pnlHead.add(lblStats, "growx");
// Custom display panel in center; populated later by mode handler.
JScrollPane scroller = new JScrollPane();
pnlCustom = new JPanel(new MigLayout("wrap, fillx"));
pnlCustom.setBackground(new Color(111,87,59));
pnlCustom.setForeground(Color.white);
this.add(scroller);
scroller.getViewport().add(pnlCustom);
// Foot panel
JPanel pnlFoot = new JPanel(new MigLayout("wrap, fill, hidemode 3"));
pnlFoot.setOpaque(false);
this.add(pnlFoot,"width " + FRAME_WIDTH_SMALL + "!, align center");
this.btnContinue = new WinLoseButton("Continue");
this.btnRestart = new WinLoseButton("Restart");
this.btnQuit = new WinLoseButton("Quit");
pnlFoot.add(btnContinue,"height 30!, gap 0 0 5 5, align center");
pnlFoot.add(btnRestart,"height 30!, gap 0 0 5 5, align center");
pnlFoot.add(btnQuit,"height 30!, gap 0 0 5 5, align center");
// Button actions
btnQuit.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(final ActionEvent e) { btnQuit_actionPerformed(e); }
});
btnContinue.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(final ActionEvent e) { btnContinue_actionPerformed(e); }
});
btnRestart.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(final ActionEvent e) { btnRestart_actionPerformed(e); }
});
// End game and set state of "continue" button
Phase.setGameBegins(0);
if (matchState.isMatchOver()) {
btnContinue.setEnabled(false);
btnQuit.grabFocus();
}
// Show Wins and Loses
Player human = AllZone.getHumanPlayer();
int humanWins = matchState.countGamesWonBy(human.getName());
int humanLosses = matchState.getGamesPlayedCount() - humanWins;
lblStats.setText(ForgeProps.getLocalized(WINLOSETEXT.WON) + humanWins
+ ForgeProps.getLocalized(WINLOSETEXT.LOST) + humanLosses);
// Show "You Won" or "You Lost"
if (matchState.hasWonLastGame(human.getName())) {
lblTitle.setText(ForgeProps.getLocalized(WINLOSETEXT.WIN));
} else {
lblTitle.setText(ForgeProps.getLocalized(WINLOSETEXT.LOSE));
}
// Populate custom panel, if necessary.
boolean hasStuff = modeHandler.populateCustomPanel();
if(!hasStuff) { scroller.setVisible(false); }
// Size and show frame
Dimension screen = this.getToolkit().getScreenSize();
Rectangle bounds = this.getBounds();
if(hasStuff) {
bounds.height = screen.height - 150;
scroller.setPreferredSize(new Dimension(FRAME_WIDTH_BIG,
screen.height - HEAD_HEIGHT - FOOT_HEIGHT));
bounds.width = FRAME_WIDTH_BIG;
bounds.x = (screen.width - FRAME_WIDTH_BIG)/2;
bounds.y = (screen.height - bounds.height)/2;
}
else {
bounds.height = HEAD_HEIGHT + FOOT_HEIGHT;
bounds.width = FRAME_WIDTH_SMALL;
bounds.x = (screen.width - FRAME_WIDTH_SMALL)/2;
bounds.y = (screen.height - bounds.height)/2;
}
this.setBounds(bounds);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setUndecorated(true);
this.setVisible(true);
}
/**
* <p>continueButton_actionPerformed.</p>
*
* @param e a {@link java.awt.event.ActionEvent} object.
*/
final void btnContinue_actionPerformed(ActionEvent e) {
closeWinLoseFrame();
AllZone.getDisplay().setVisible(true);
modeHandler.startNextRound();
}
/**
* <p>restartButton_actionPerformed.</p>
*
* @param e a {@link java.awt.event.ActionEvent} object.
*/
final void btnRestart_actionPerformed(ActionEvent e) {
closeWinLoseFrame();
AllZone.getDisplay().setVisible(true);
matchState.reset();
modeHandler.startNextRound();
}
/**
* <p>btnQuit_actionPerformed.</p>
*
* @param e a {@link java.awt.event.ActionEvent} object.
*/
final void btnQuit_actionPerformed(ActionEvent e) {
closeWinLoseFrame();
matchState.reset();
modeHandler.actionOnQuit();
// clear Image caches, so the program doesn't get slower and slower
// not needed with soft values - will shrink as needed
// ImageUtil.rotatedCache.clear();
// ImageCache.cache.clear();
}
/**
* <p>closeWinLoseFrame.</p>
* Disposes WinLoseFrame UI.
*
* @return {@link javax.swing.JFrame} display frame
*/
final JFrame closeWinLoseFrame() {
// issue 147 - keep battlefield up following win/loss
JFrame frame = (JFrame) AllZone.getDisplay();
frame.dispose();
frame.setEnabled(true);
this.dispose();
return frame;
}
/**
* <p>WinLoseButton.</p>
* Private button class to standardize buttons.
*
*/
private class WinLoseButton extends JButton {
WinLoseButton(String msg) {
super(msg);
this.setFont(new Font("Tahoma", Font.PLAIN, 14));
this.setOpaque(false);
this.setPreferredSize(new Dimension(125,30));
}
}
}

View File

@@ -0,0 +1,85 @@
package forge.view.swing;
import forge.AllZone;
import forge.Constant;
/**
* <p>WinLoseModeHandler.</p>
*
* Superclass of custom mode handling for win/lose UI. Can add swing components
* to custom center panel. Custom mode handling for quest, puzzle, etc.
* should extend this class.
*
*/
public class WinLoseModeHandler {
protected WinLoseFrame view;
/**
* <p>actionOnQuit.</p>
* Action performed when "continue" button is pressed in default win/lose UI.
*
*/
public void actionOnContinue() {
}
/**
* <p>actionOnQuit.</p>
* Action performed when "quit" button is pressed in default win/lose UI.
*
*/
public void actionOnQuit() {
if (System.getenv("NG2") != null) {
if (System.getenv("NG2").equalsIgnoreCase("true")) {
String argz[] = {};
Gui_HomeScreen.main(argz);
} else {
new OldGuiNewGame();
}
} else {
new OldGuiNewGame();
}
}
/**
* <p>actionOnRestart.</p>
* Action performed when "restart" button is pressed in default win/lose UI.
*
*/
public void actionOnRestart() {
}
/**
* <p>startNextRound.</p>
* Either continues or restarts a current game. May be overridden
* for use with other game modes.
*
* @param e a {@link java.awt.event.ActionEvent} object.
*/
public void startNextRound() {
AllZone.getGameAction().newGame(Constant.Runtime.HumanDeck[0], Constant.Runtime.ComputerDeck[0]);
}
/**
* <p>populateCustomPanel.</p>
* May be overridden as required by various mode handlers to show
* custom information in center panel. Default configuration is empty.
*
* @param boolean indicating if custom panel has contents.
*/
public boolean populateCustomPanel() {
return false;
}
/**
* <p>setView.</p>
* Links win/lose swing frame to mode handler, mostly to allow
* direct manipulation of custom center panel.
*
*/
public void setView(WinLoseFrame wlh) {
view = wlh;
}
}