Refactor code to make it easier to show rewards for planar conquest games

This commit is contained in:
drdev
2014-12-06 23:52:54 +00:00
parent ce3b8e6c76
commit f7fbdc05dd
10 changed files with 452 additions and 285 deletions

View File

@@ -16,24 +16,10 @@
*/ */
package forge.screens.match; package forge.screens.match;
import java.awt.Dimension;
import java.util.List;
import javax.swing.SwingConstants;
import forge.assets.FSkinProp;
import forge.game.GameView; import forge.game.GameView;
import forge.item.PaperCard;
import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.quest.QuestWinLoseController; import forge.quest.QuestWinLoseController;
import forge.screens.home.quest.CSubmenuChallenges; import forge.screens.home.quest.CSubmenuChallenges;
import forge.screens.home.quest.CSubmenuDuels; import forge.screens.home.quest.CSubmenuDuels;
import forge.toolbox.FSkin;
import forge.toolbox.FSkin.Colors;
import forge.toolbox.FSkin.SkinColor;
import forge.toolbox.FSkin.SkinIcon;
import forge.toolbox.FSkin.SkinnedLabel;
/** /**
* <p> * <p>
@@ -45,16 +31,8 @@ import forge.toolbox.FSkin.SkinnedLabel;
* *
*/ */
public class QuestWinLose extends ControlWinLose { public class QuestWinLose extends ControlWinLose {
private final transient ViewWinLose view;
private final QuestWinLoseController controller; private final QuestWinLoseController controller;
/** String constraint parameters for title blocks and cardviewer blocks. */
private static final SkinColor FORE_COLOR = FSkin.getColor(Colors.CLR_TEXT);
private static final String CONSTRAINTS_TITLE = "w 95%!, gap 0 0 20px 10px";
private static final String CONSTRAINTS_TEXT = "w 95%!, h 220px!, gap 0 0 0 20px";
private static final String CONSTRAINTS_CARDS = "w 95%!, h 330px!, gap 0 0 0 20px";
private static final String CONSTRAINTS_CARDS_LARGE = "w 95%!, h 600px!, gap 0 0 0 20px";
/** /**
* Instantiates a new quest win lose handler. * Instantiates a new quest win lose handler.
* *
@@ -63,43 +41,7 @@ public class QuestWinLose extends ControlWinLose {
*/ */
public QuestWinLose(final ViewWinLose view0, final GameView game0) { public QuestWinLose(final ViewWinLose view0, final GameView game0) {
super(view0, game0); super(view0, game0);
view = view0; controller = new QuestWinLoseController(game0, view0);
controller = new QuestWinLoseController(game0) {
@Override
protected void showRewards(Runnable runnable) {
runnable.run(); //just run on GUI thread
}
@Override
protected void showCards(String title, List<PaperCard> cards) {
final QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cards);
view.getPnlCustom().add(new TitleLabel(title), QuestWinLose.CONSTRAINTS_TITLE);
if (FModel.getPreferences().getPrefBoolean(FPref.UI_LARGE_CARD_VIEWERS)) {
view.getPnlCustom().add(cv, QuestWinLose.CONSTRAINTS_CARDS_LARGE);
}
else {
view.getPnlCustom().add(cv, QuestWinLose.CONSTRAINTS_CARDS);
}
}
@Override
protected void showMessage(String message, String title, FSkinProp icon) {
SkinIcon icoTemp = FSkin.getIcon(icon).scale(0.5);
if (message.contains("\n")) { //ensure new line characters are encoded
message = "<html>" + message.replace("\n", "<br>") + "</html>";
}
SkinnedLabel lblMessage = new SkinnedLabel(message);
lblMessage.setFont(FSkin.getFont(14));
lblMessage.setForeground(FORE_COLOR);
lblMessage.setHorizontalAlignment(SwingConstants.CENTER);
lblMessage.setIconTextGap(50);
lblMessage.setIcon(icoTemp);
view.getPnlCustom().add(new TitleLabel(title), QuestWinLose.CONSTRAINTS_TITLE);
view.getPnlCustom().add(lblMessage, QuestWinLose.CONSTRAINTS_TEXT);
}
};
} }
@@ -114,7 +56,7 @@ public class QuestWinLose extends ControlWinLose {
*/ */
@Override @Override
public final boolean populateCustomPanel() { public final boolean populateCustomPanel() {
controller.showRewards(view); controller.showRewards();
return true; return true;
} }
@@ -133,20 +75,4 @@ public class QuestWinLose extends ControlWinLose {
CSubmenuChallenges.SINGLETON_INSTANCE.update(); CSubmenuChallenges.SINGLETON_INSTANCE.update();
super.actionOnQuit(); super.actionOnQuit();
} }
/**
* JLabel header between reward sections.
*
*/
@SuppressWarnings("serial")
private class TitleLabel extends SkinnedLabel {
TitleLabel(final String msg) {
super(msg);
setFont(FSkin.getFont(16));
setPreferredSize(new Dimension(200, 40));
setHorizontalAlignment(SwingConstants.CENTER);
setForeground(FORE_COLOR);
setBorder(new FSkin.MatteSkinBorder(1, 0, 1, 0, FORE_COLOR));
}
}
} }

View File

@@ -1,10 +1,12 @@
package forge.screens.match; package forge.screens.match;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Point; import java.awt.Point;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.datatransfer.StringSelection; import java.awt.datatransfer.StringSelection;
import java.util.List;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
@@ -16,17 +18,23 @@ import org.apache.commons.lang3.StringUtils;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.UiCommand; import forge.UiCommand;
import forge.assets.FSkinProp;
import forge.game.GameLogEntry; import forge.game.GameLogEntry;
import forge.game.GameLogEntryType; import forge.game.GameLogEntryType;
import forge.game.GameView; import forge.game.GameView;
import forge.gui.SOverlayUtils; import forge.gui.SOverlayUtils;
import forge.interfaces.IWinLoseView; import forge.interfaces.IWinLoseView;
import forge.item.PaperCard;
import forge.model.FModel; import forge.model.FModel;
import forge.properties.ForgePreferences.FPref;
import forge.toolbox.FButton; import forge.toolbox.FButton;
import forge.toolbox.FLabel; import forge.toolbox.FLabel;
import forge.toolbox.FOverlay; import forge.toolbox.FOverlay;
import forge.toolbox.FScrollPane; import forge.toolbox.FScrollPane;
import forge.toolbox.FSkin; import forge.toolbox.FSkin;
import forge.toolbox.FSkin.Colors;
import forge.toolbox.FSkin.SkinColor;
import forge.toolbox.FSkin.SkinIcon;
import forge.toolbox.FSkin.SkinnedLabel; import forge.toolbox.FSkin.SkinnedLabel;
import forge.toolbox.FSkin.SkinnedPanel; import forge.toolbox.FSkin.SkinnedPanel;
import forge.toolbox.FTextArea; import forge.toolbox.FTextArea;
@@ -39,6 +47,13 @@ public class ViewWinLose implements IWinLoseView<FButton> {
private final SkinnedLabel lblStats = new SkinnedLabel("WinLoseFrame > lblStats needs updating."); private final SkinnedLabel lblStats = new SkinnedLabel("WinLoseFrame > lblStats needs updating.");
private final JPanel pnlOutcomes = new JPanel(new MigLayout("wrap, align center")); private final JPanel pnlOutcomes = new JPanel(new MigLayout("wrap, align center"));
/** String constraint parameters for title blocks and cardviewer blocks. */
private static final SkinColor FORE_COLOR = FSkin.getColor(Colors.CLR_TEXT);
private static final String CONSTRAINTS_TITLE = "w 95%!, gap 0 0 20px 10px";
private static final String CONSTRAINTS_TEXT = "w 95%!, h 220px!, gap 0 0 0 20px";
private static final String CONSTRAINTS_CARDS = "w 95%!, h 330px!, gap 0 0 0 20px";
private static final String CONSTRAINTS_CARDS_LARGE = "w 95%!, h 600px!, gap 0 0 0 20px";
private final GameView game; private final GameView game;
@SuppressWarnings("serial") @SuppressWarnings("serial")
@@ -237,4 +252,55 @@ public class ViewWinLose implements IWinLoseView<FButton> {
public void hide() { public void hide() {
SOverlayUtils.hideOverlay(); SOverlayUtils.hideOverlay();
} }
@Override
public void showRewards(Runnable runnable) {
runnable.run(); //just run on GUI thread
}
@Override
public void showCards(String title, List<PaperCard> cards) {
final QuestWinLoseCardViewer cv = new QuestWinLoseCardViewer(cards);
getPnlCustom().add(new TitleLabel(title), CONSTRAINTS_TITLE);
if (FModel.getPreferences().getPrefBoolean(FPref.UI_LARGE_CARD_VIEWERS)) {
getPnlCustom().add(cv, CONSTRAINTS_CARDS_LARGE);
}
else {
getPnlCustom().add(cv, CONSTRAINTS_CARDS);
}
}
@Override
public void showMessage(String message, String title, FSkinProp icon) {
SkinIcon icoTemp = FSkin.getIcon(icon).scale(0.5);
if (message.contains("\n")) { //ensure new line characters are encoded
message = "<html>" + message.replace("\n", "<br>") + "</html>";
}
SkinnedLabel lblMessage = new SkinnedLabel(message);
lblMessage.setFont(FSkin.getFont(14));
lblMessage.setForeground(FORE_COLOR);
lblMessage.setHorizontalAlignment(SwingConstants.CENTER);
lblMessage.setIconTextGap(50);
lblMessage.setIcon(icoTemp);
getPnlCustom().add(new TitleLabel(title), CONSTRAINTS_TITLE);
getPnlCustom().add(lblMessage, CONSTRAINTS_TEXT);
}
/**
* JLabel header between reward sections.
*
*/
@SuppressWarnings("serial")
private class TitleLabel extends SkinnedLabel {
TitleLabel(final String msg) {
super(msg);
setFont(FSkin.getFont(16));
setPreferredSize(new Dimension(200, 40));
setHorizontalAlignment(SwingConstants.CENTER);
setForeground(FORE_COLOR);
setBorder(new FSkin.MatteSkinBorder(1, 0, 1, 0, FORE_COLOR));
}
}
} }

View File

@@ -16,15 +16,8 @@
*/ */
package forge.screens.match.winlose; package forge.screens.match.winlose;
import java.util.List;
import forge.FThreads;
import forge.assets.FSkinProp;
import forge.game.GameView; import forge.game.GameView;
import forge.item.PaperCard;
import forge.quest.QuestWinLoseController; import forge.quest.QuestWinLoseController;
import forge.util.gui.SGuiChoose;
import forge.util.gui.SOptionPane;
/** /**
* <p> * <p>
@@ -46,28 +39,12 @@ public class QuestWinLose extends ControlWinLose {
*/ */
public QuestWinLose(final ViewWinLose view0, GameView lastGame) { public QuestWinLose(final ViewWinLose view0, GameView lastGame) {
super(view0, lastGame); super(view0, lastGame);
controller = new QuestWinLoseController(lastGame) { controller = new QuestWinLoseController(lastGame, view0);
@Override
protected void showRewards(Runnable runnable) {
//invoke reward logic in background thread so dialogs can be shown
FThreads.invokeInBackgroundThread(runnable);
}
@Override
protected void showCards(String title, List<PaperCard> cards) {
SGuiChoose.reveal(title, cards);
}
@Override
protected void showMessage(String message, String title, FSkinProp icon) {
SOptionPane.showMessageDialog(message, title, icon);
}
};
} }
@Override @Override
public final void showRewards() { public final void showRewards() {
controller.showRewards(getView()); controller.showRewards();
} }
/** /**

View File

@@ -1,19 +1,24 @@
package forge.screens.match.winlose; package forge.screens.match.winlose;
import java.util.List;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.badlogic.gdx.Input.Keys; import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment; import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
import forge.FThreads;
import forge.Forge; import forge.Forge;
import forge.LobbyPlayer; import forge.LobbyPlayer;
import forge.assets.FSkinColor; import forge.assets.FSkinColor;
import forge.assets.FSkinProp;
import forge.assets.FSkinColor.Colors; import forge.assets.FSkinColor.Colors;
import forge.assets.FSkinFont; import forge.assets.FSkinFont;
import forge.game.GameLogEntry; import forge.game.GameLogEntry;
import forge.game.GameLogEntryType; import forge.game.GameLogEntryType;
import forge.game.GameView; import forge.game.GameView;
import forge.interfaces.IWinLoseView; import forge.interfaces.IWinLoseView;
import forge.item.PaperCard;
import forge.menu.FMagnifyView; import forge.menu.FMagnifyView;
import forge.model.FModel; import forge.model.FModel;
import forge.toolbox.FButton; import forge.toolbox.FButton;
@@ -25,6 +30,8 @@ import forge.toolbox.FLabel;
import forge.toolbox.FOverlay; import forge.toolbox.FOverlay;
import forge.toolbox.FTextArea; import forge.toolbox.FTextArea;
import forge.util.Utils; import forge.util.Utils;
import forge.util.gui.SGuiChoose;
import forge.util.gui.SOptionPane;
public class ViewWinLose extends FOverlay implements IWinLoseView<FButton> { public class ViewWinLose extends FOverlay implements IWinLoseView<FButton> {
private static final float INSETS_FACTOR = 0.025f; private static final float INSETS_FACTOR = 0.025f;
@@ -208,4 +215,20 @@ public class ViewWinLose extends FOverlay implements IWinLoseView<FButton> {
} }
return super.keyDown(keyCode); return super.keyDown(keyCode);
} }
@Override
public void showRewards(Runnable runnable) {
//invoke reward logic in background thread so dialogs can be shown
FThreads.invokeInBackgroundThread(runnable);
}
@Override
public void showCards(String title, List<PaperCard> cards) {
SGuiChoose.reveal(title, cards);
}
@Override
public void showMessage(String message, String title, FSkinProp icon) {
SOptionPane.showMessageDialog(message, title, icon);
}
} }

View File

@@ -63,7 +63,7 @@ public class CommandCenterScreen extends FScreen implements IVCommandCenter {
btnEndDay.setCommand(new FEventHandler() { btnEndDay.setCommand(new FEventHandler() {
@Override @Override
public void handleEvent(FEvent e) { public void handleEvent(FEvent e) {
model.endDay(CommandCenterScreen.this); FModel.getConquest().endDay(CommandCenterScreen.this);
} }
}); });
} }

View File

@@ -1,8 +1,17 @@
package forge.interfaces; package forge.interfaces;
import java.util.List;
import forge.assets.FSkinProp;
import forge.item.PaperCard;
public interface IWinLoseView<T extends IButton> { public interface IWinLoseView<T extends IButton> {
T getBtnContinue(); T getBtnContinue();
T getBtnRestart(); T getBtnRestart();
T getBtnQuit(); T getBtnQuit();
void hide(); void hide();
void showRewards(Runnable runnable);
void showCards(String title, List<PaperCard> cards);
void showMessage(String message, String title, FSkinProp icon);
} }

View File

@@ -17,11 +17,31 @@
*/ */
package forge.planarconquest; package forge.planarconquest;
import java.util.ArrayList;
import java.util.List;
import com.google.common.base.Predicate;
import com.google.common.eventbus.Subscribe; import com.google.common.eventbus.Subscribe;
import forge.FThreads;
import forge.card.CardRarity;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.deck.CardPool; import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.game.GameView;
import forge.game.event.GameEvent; import forge.game.event.GameEvent;
import forge.interfaces.IButton;
import forge.interfaces.IWinLoseView;
import forge.item.PaperCard;
import forge.model.FModel;
import forge.planarconquest.ConquestPlaneData.RegionData;
import forge.planarconquest.ConquestPreferences.CQPref;
import forge.player.GamePlayerUtil;
import forge.util.Aggregates;
import forge.util.Lang;
import forge.util.gui.SGuiChoose;
import forge.util.gui.SOptionPane;
import forge.util.storage.IStorage; import forge.util.storage.IStorage;
public class ConquestController { public class ConquestController {
@@ -64,4 +84,299 @@ public class ConquestController {
public void receiveGameEvent(GameEvent ev) { // Receives events only during planar conquest games public void receiveGameEvent(GameEvent ev) { // Receives events only during planar conquest games
} }
public void endDay(final IVCommandCenter commandCenter) {
FThreads.invokeInBackgroundThread(new Runnable() {
@Override
public void run() {
//prompt user if any commander hasn't taken an action
final List<ConquestCommander> commanders = model.getCurrentPlaneData().getCommanders();
for (ConquestCommander commander : commanders) {
if (commander.getCurrentDayAction() == null) {
if (!SOptionPane.showConfirmDialog(commander.getName() + " has not taken an action today. End day anyway?", "Action Not Taken", "End Day", "Cancel")) {
return;
}
}
}
//perform all commander actions
for (ConquestCommander commander : commanders) {
switch (commander.getCurrentDayAction()) {
case Attack1:
playGame(commander, 0, false);
break;
case Attack2:
playGame(commander, 1, false);
break;
case Attack3:
playGame(commander, 2, false);
break;
case Defend:
playGame(commander, Aggregates.randomInt(0, 2), true); //defend against random opponent
break;
case Recruit:
if (!recruit(commander)) { return; }
break;
case Study:
if (!study(commander)) { return; }
break;
case Undeploy:
model.getCurrentPlaneData().getRegionData(commander.getDeployedRegion()).setDeployedCommander(null);
break;
default: //remaining actions don't need to do anything more
break;
}
}
//increment day and reset actions, then update UI for new day
FThreads.invokeInEdtLater(new Runnable() {
@Override
public void run() {
model.incrementDay();
for (ConquestCommander commander : commanders) {
commander.setCurrentDayAction(null);
}
commandCenter.updateCurrentDay();
}
});
}
});
}
private void playGame(ConquestCommander commander, int opponentIndex, boolean isHumanDefending) {
RegionData regionData = model.getCurrentPlaneData().getRegionData(commander.getDeployedRegion());
ConquestCommander opponent = regionData.getOpponent(opponentIndex);
//TODO
}
private boolean recruit(ConquestCommander commander) {
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.RECRUIT_BONUS_CARD_ODDS);
return awardNewCards(commander.getDeployedRegion().getCardPool().getAllCards(),
commander.getName() + " recruited", "new creature", null, null,
CardRulesPredicates.Presets.IS_CREATURE, bonusCard ? 2 : 1);
}
private boolean study(ConquestCommander commander) {
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.STUDY_BONUS_CARD_ODDS);
return awardNewCards(commander.getDeployedRegion().getCardPool().getAllCards(),
commander.getName() + " unlocked", "new spell", null, null,
CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, bonusCard ? 2 : 1);
}
public void showGameRewards(final GameView game, final IWinLoseView<? extends IButton> view) {
view.getBtnRestart().setVisible(false);
view.getBtnContinue().setVisible(false);
if (game.isMatchWonBy(GamePlayerUtil.getGuiPlayer())) { //TODO: Should this be smarter
view.getBtnQuit().setText("Great!");
//give controller a chance to run remaining logic on a separate thread
view.showRewards(new Runnable() {
@Override
public void run() {
awardWinStreakBonus(view);
awardBooster(view);
}
});
}
else {
view.getBtnQuit().setText("OK");
}
}
public void onGameFinished(final GameView game) {
if (game.isMatchWonBy(GamePlayerUtil.getGuiPlayer())) {
model.addWin();
}
else {
model.addLoss();
}
FModel.getConquest().save();
FModel.getConquestPreferences().save();
}
private void awardWinStreakBonus(final IWinLoseView<? extends IButton> view) {
int currentStreak = model.getCurrentPlaneData().getWinStreakCurrent() + 1;
int mod = currentStreak % 10;
int count = (currentStreak - 1) / 10 + 1; //so on 13th win you get 2 commons, etc.
CardRarity rarity = null;
String typeWon = "";
switch (mod) {
case 3:
rarity = CardRarity.Common;
count = 1;
typeWon = "common";
break;
case 5:
rarity = CardRarity.Uncommon;
count = 1;
typeWon = "uncommon";
break;
case 7:
rarity = CardRarity.Rare;
count = 1;
typeWon = "rare";
break;
case 0: //0 is multiple of 10 win
rarity = CardRarity.MythicRare;
count = 1;
typeWon = "mythic rare";
break;
default:
return;
}
awardNewCards(model.getCurrentPlane().getCardPool().getAllCards(), currentStreak + " game win streak - unlocked", typeWon, rarity, view, null, count);
}
private boolean awardNewCards(Iterable<PaperCard> cardPool, String messagePrefix, String messageSuffix, CardRarity rarity, final IWinLoseView<? extends IButton> view, Predicate<CardRules> pred, int count) {
List<PaperCard> commons = new ArrayList<PaperCard>();
List<PaperCard> uncommons = new ArrayList<PaperCard>();
List<PaperCard> rares = new ArrayList<PaperCard>();
List<PaperCard> mythics = new ArrayList<PaperCard>();
int newCardCount = 0;
for (PaperCard c : cardPool) {
if ((pred == null || pred.apply(c.getRules())) && !model.getCollection().contains(c)) {
switch (c.getRarity()) {
case Common:
commons.add(c);
break;
case Uncommon:
uncommons.add(c);
break;
case Rare:
rares.add(c);
break;
case MythicRare:
mythics.add(c);
break;
default:
break;
}
}
}
newCardCount = commons.size() + uncommons.size() + rares.size() + mythics.size();
if (newCardCount == 0) {
return false;
}
ConquestPreferences prefs = FModel.getConquestPreferences();
int rareThreshold = prefs.getPrefInt(CQPref.BOOSTER_RARES);
int uncommonThreshold = rareThreshold + prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS);
int cardsPerPack = uncommonThreshold + prefs.getPrefInt(CQPref.BOOSTER_COMMONS);
List<PaperCard> rewardPool = null;
if (rarity != null) {
switch (rarity) {
case Common:
rewardPool = commons;
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
messageSuffix = messageSuffix.replace("common", "uncommon");
if (rewardPool.isEmpty()) {
rewardPool = rares;
messageSuffix = messageSuffix.replace("uncommon", "rare");
if (rewardPool.isEmpty()) {
rewardPool = mythics;
messageSuffix = messageSuffix.replace("rare", "mythic rare");
}
}
}
break;
case Uncommon:
rewardPool = uncommons;
if (rewardPool.isEmpty()) {
rewardPool = commons;
messageSuffix = messageSuffix.replace("uncommon", "common");
if (rewardPool.isEmpty()) {
rewardPool = rares;
messageSuffix = messageSuffix.replace("common", "rare");
if (rewardPool.isEmpty()) {
rewardPool = mythics;
messageSuffix = messageSuffix.replace("rare", "mythic rare");
}
}
}
break;
case Rare:
rewardPool = rares;
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
messageSuffix = messageSuffix.replace("rare", "uncommon");
if (rewardPool.isEmpty()) {
rewardPool = commons;
messageSuffix = messageSuffix.replace("uncommon", "common");
if (rewardPool.isEmpty()) {
rewardPool = mythics;
messageSuffix = messageSuffix.replace("common", "mythic rare");
}
}
}
break;
case MythicRare:
rewardPool = mythics;
if (rewardPool.isEmpty()) {
rewardPool = rares;
messageSuffix = messageSuffix.replace("mythic rare", "rare");
if (rewardPool.isEmpty()) {
rewardPool = uncommons;
messageSuffix = messageSuffix.replace("rare", "uncommon");
if (rewardPool.isEmpty()) {
rewardPool = commons;
messageSuffix = messageSuffix.replace("uncommon", "common");
}
}
}
break;
default:
return false;
}
newCardCount = rewardPool.size();
}
List<PaperCard> rewards = new ArrayList<PaperCard>();
for (int i = 0; i < count; i++) {
//determine which rarity card to get based on pack ratios if no rarity passed in
if (rarity == null) {
int value = Aggregates.randomInt(1, cardsPerPack);
if (value <= rareThreshold) {
if (mythics.size() > 0 && Aggregates.randomInt(1, 8) == 1) {
rewardPool = mythics;
}
else {
rewardPool = rares;
}
}
else if (value <= uncommonThreshold) {
rewardPool = uncommons;
}
else {
rewardPool = commons;
}
if (rewardPool.isEmpty()) { continue; } //if no cards in selected pool, determine random pool again
}
int index = Aggregates.randomInt(0, rewardPool.size() - 1);
rewards.add(rewardPool.remove(index));
if (--newCardCount == 0) {
break; //break out if no new cards remain
}
}
model.getCollection().add(rewards);
String message = messagePrefix + " " + Lang.nounWithAmount(rewards.size(), messageSuffix);
if (view == null) {
SGuiChoose.reveal(message, rewards);
}
else {
view.showCards(message, rewards);
}
return true;
}
private void awardBooster(final IWinLoseView<? extends IButton> view) {
//TODO
}
} }

View File

@@ -17,29 +17,14 @@
*/ */
package forge.planarconquest; package forge.planarconquest;
import forge.FThreads;
import forge.card.CardRules;
import forge.card.CardRulesPredicates;
import forge.deck.CardPool; import forge.deck.CardPool;
import forge.deck.Deck; import forge.deck.Deck;
import forge.item.PaperCard; import forge.item.PaperCard;
import forge.model.FModel;
import forge.planarconquest.ConquestPlane.Region; import forge.planarconquest.ConquestPlane.Region;
import forge.planarconquest.ConquestPlaneData.RegionData;
import forge.planarconquest.ConquestPreferences.CQPref;
import forge.properties.ForgeConstants; import forge.properties.ForgeConstants;
import forge.util.Aggregates;
import forge.util.Lang;
import forge.util.gui.SGuiChoose;
import forge.util.gui.SOptionPane;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.EnumMap; import java.util.EnumMap;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import com.google.common.base.Predicate;
public final class ConquestData { public final class ConquestData {
/** Holds the latest version of the Conquest Data. */ /** Holds the latest version of the Conquest Data. */
@@ -93,154 +78,8 @@ public final class ConquestData {
public int getDay() { public int getDay() {
return day; return day;
} }
public void incrementDay() {
public void endDay(final IVCommandCenter base) { day++;
FThreads.invokeInBackgroundThread(new Runnable() {
@Override
public void run() {
//prompt user if any commander hasn't taken an action
final List<ConquestCommander> commanders = getCurrentPlaneData().getCommanders();
for (ConquestCommander commander : commanders) {
if (commander.getCurrentDayAction() == null) {
if (!SOptionPane.showConfirmDialog(commander.getName() + " has not taken an action today. End day anyway?", "Action Not Taken", "End Day", "Cancel")) {
return;
}
}
}
//perform all commander actions
for (ConquestCommander commander : commanders) {
switch (commander.getCurrentDayAction()) {
case Attack1:
playGame(commander, 0, false);
break;
case Attack2:
playGame(commander, 1, false);
break;
case Attack3:
playGame(commander, 2, false);
break;
case Defend:
playGame(commander, Aggregates.randomInt(0, 2), true); //defend against random opponent
break;
case Recruit:
if (!recruit(commander)) { return; }
break;
case Study:
if (!study(commander)) { return; }
break;
case Undeploy:
getCurrentPlaneData().getRegionData(commander.getDeployedRegion()).setDeployedCommander(null);
break;
default: //remaining actions don't need to do anything more
break;
}
}
//increment day and reset actions, then update UI for new day
FThreads.invokeInEdtLater(new Runnable() {
@Override
public void run() {
day++;
for (ConquestCommander commander : commanders) {
commander.setCurrentDayAction(null);
}
base.updateCurrentDay();
}
});
}
});
}
private void playGame(ConquestCommander commander, int opponentIndex, boolean isHumanDefending) {
RegionData regionData = getCurrentPlaneData().getRegionData(commander.getDeployedRegion());
ConquestCommander opponent = regionData.getOpponent(opponentIndex);
//TODO
}
private boolean recruit(ConquestCommander commander) {
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.RECRUIT_BONUS_CARD_ODDS);
return rewardNewCards(commander.getDeployedRegion().getCardPool().getAllCards(),
commander.getName() + " recruited", "new creature",
CardRulesPredicates.Presets.IS_CREATURE, bonusCard ? 2 : 1);
}
private boolean study(ConquestCommander commander) {
boolean bonusCard = Aggregates.randomInt(1, 100) <= FModel.getConquestPreferences().getPrefInt(CQPref.STUDY_BONUS_CARD_ODDS);
return rewardNewCards(commander.getDeployedRegion().getCardPool().getAllCards(),
commander.getName() + " unlocked", "new spell",
CardRulesPredicates.Presets.IS_NON_CREATURE_SPELL, bonusCard ? 2 : 1);
}
private boolean rewardNewCards(Iterable<PaperCard> cardPool, String messagePrefix, String messageSuffix, Predicate<CardRules> pred, int count) {
List<PaperCard> commons = new ArrayList<PaperCard>();
List<PaperCard> uncommons = new ArrayList<PaperCard>();
List<PaperCard> rares = new ArrayList<PaperCard>();
List<PaperCard> mythics = new ArrayList<PaperCard>();
int newCardCount = 0;
for (PaperCard c : cardPool) {
if (pred.apply(c.getRules()) && !collection.contains(c)) {
switch (c.getRarity()) {
case Common:
commons.add(c);
break;
case Uncommon:
uncommons.add(c);
break;
case Rare:
rares.add(c);
break;
case MythicRare:
mythics.add(c);
break;
default:
break;
}
}
}
newCardCount = commons.size() + uncommons.size() + rares.size() + mythics.size();
if (newCardCount == 0) {
return false;
}
ConquestPreferences prefs = FModel.getConquestPreferences();
int rareThreshold = prefs.getPrefInt(CQPref.BOOSTER_RARES);
int uncommonThreshold = rareThreshold + prefs.getPrefInt(CQPref.BOOSTER_UNCOMMONS);
int cardsPerPack = uncommonThreshold + prefs.getPrefInt(CQPref.BOOSTER_COMMONS);
List<PaperCard> rewardPool;
List<PaperCard> rewards = new ArrayList<PaperCard>();
for (int i = 0; i < count; i++) {
//determine which rarity card to get based on pack ratios
int value = Aggregates.randomInt(1, cardsPerPack);
if (value <= rareThreshold) {
if (mythics.size() > 0 && Aggregates.randomInt(1, 8) == 1) {
rewardPool = mythics;
}
else {
rewardPool = rares;
}
}
else if (value <= uncommonThreshold) {
rewardPool = uncommons;
}
else {
rewardPool = commons;
}
if (rewardPool.isEmpty()) { continue; } //if no cards in selected pool, determine random pool again
int index = Aggregates.randomInt(0, rewardPool.size() - 1);
rewards.add(rewardPool.remove(index));
if (--newCardCount == 0) {
break; //break out if no new cards remain
}
}
collection.add(rewards);
String message = messagePrefix + " " + Lang.nounWithAmount(rewards.size(), messageSuffix);
SGuiChoose.reveal(message, rewards);
return true;
} }
public ConquestPlane getStartingPlane() { public ConquestPlane getStartingPlane() {

View File

@@ -12,6 +12,8 @@ public class ConquestPlaneData {
private final Map<Region, RegionData> regionDataLookup = new HashMap<Region, RegionData>(); private final Map<Region, RegionData> regionDataLookup = new HashMap<Region, RegionData>();
private int wins, losses; private int wins, losses;
private int winStreakBest = 0;
private int winStreakCurrent = 0;
public List<ConquestCommander> getCommanders() { public List<ConquestCommander> getCommanders() {
return commanders; return commanders;
@@ -19,6 +21,10 @@ public class ConquestPlaneData {
public void addWin() { public void addWin() {
wins++; wins++;
winStreakCurrent++;
if (winStreakCurrent > winStreakBest) {
winStreakBest = winStreakCurrent;
}
} }
public void addLoss() { public void addLoss() {
@@ -33,6 +39,14 @@ public class ConquestPlaneData {
return losses; return losses;
} }
public int getWinStreakBest() {
return winStreakBest;
}
public int getWinStreakCurrent() {
return winStreakCurrent;
}
public RegionData getRegionData(Region region) { public RegionData getRegionData(Region region) {
RegionData regionData = regionDataLookup.get(region); RegionData regionData = regionDataLookup.get(region);
if (regionData == null) { if (regionData == null) {

View File

@@ -34,22 +34,24 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
public abstract class QuestWinLoseController { public class QuestWinLoseController {
private final GameView lastGame; private final GameView lastGame;
private final IWinLoseView<? extends IButton> view;
private final transient boolean wonMatch; private final transient boolean wonMatch;
private final transient boolean isAnte; private final transient boolean isAnte;
private final transient QuestController qData; private final transient QuestController qData;
private final transient QuestEvent qEvent; private final transient QuestEvent qEvent;
public QuestWinLoseController(final GameView game0) { public QuestWinLoseController(final GameView game0, final IWinLoseView<? extends IButton> view0) {
lastGame = game0; lastGame = game0;
view = view0;
qData = FModel.getQuest(); qData = FModel.getQuest();
qEvent = qData.getCurrentEvent(); qEvent = qData.getCurrentEvent();
wonMatch = lastGame.isMatchWonBy(GamePlayerUtil.getQuestPlayer()); wonMatch = lastGame.isMatchWonBy(GamePlayerUtil.getQuestPlayer());
isAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE); isAnte = FModel.getPreferences().getPrefBoolean(FPref.UI_ANTE);
} }
public void showRewards(final IWinLoseView<? extends IButton> view) { public void showRewards() {
view.getBtnRestart().setVisible(false); view.getBtnRestart().setVisible(false);
final QuestController qc = FModel.getQuest(); final QuestController qc = FModel.getQuest();
@@ -83,7 +85,7 @@ public abstract class QuestWinLoseController {
} }
//give controller a chance to run remaining logic on a separate thread //give controller a chance to run remaining logic on a separate thread
showRewards(new Runnable() { view.showRewards(new Runnable() {
@Override @Override
public void run() { public void run() {
if (isAnte) { if (isAnte) {
@@ -158,10 +160,10 @@ public abstract class QuestWinLoseController {
private void anteReport(final List<PaperCard> cardsWon, List<PaperCard> cardsLost, boolean hasWon) { private void anteReport(final List<PaperCard> cardsWon, List<PaperCard> cardsLost, boolean hasWon) {
// Generate Swing components and attach. // Generate Swing components and attach.
if (cardsWon != null && !cardsWon.isEmpty()) { if (cardsWon != null && !cardsWon.isEmpty()) {
showCards("Spoils! Cards won from ante.", cardsWon); view.showCards("Spoils! Cards won from ante.", cardsWon);
} }
if (cardsLost != null && !cardsLost.isEmpty()) { if (cardsLost != null && !cardsLost.isEmpty()) {
showCards("Looted! Cards lost to ante.", cardsLost); view.showCards("Looted! Cards lost to ante.", cardsLost);
} }
} }
@@ -375,7 +377,7 @@ public abstract class QuestWinLoseController {
sb.append(String.format("%s %d credits in total.", congrats, credTotal)); sb.append(String.format("%s %d credits in total.", congrats, credTotal));
qData.getAssets().addCredits(credTotal); qData.getAssets().addCredits(credTotal);
showMessage(sb.toString(), "Gameplay Results", FSkinProp.ICO_QUEST_GOLD); view.showMessage(sb.toString(), "Gameplay Results", FSkinProp.ICO_QUEST_GOLD);
} }
/** /**
@@ -390,7 +392,7 @@ public abstract class QuestWinLoseController {
final List<PaperCard> cardsWon = new ArrayList<PaperCard>(); final List<PaperCard> cardsWon = new ArrayList<PaperCard>();
cardsWon.add(c); cardsWon.add(c);
showCards(message, cardsWon); view.showCards(message, cardsWon);
} }
/** /**
@@ -458,12 +460,12 @@ public abstract class QuestWinLoseController {
} }
if (addDraftToken) { if (addDraftToken) {
showMessage("For achieving a 25 win streak, you have been awarded a draft token!\nUse these tokens to generate new tournaments.", "Bonus Draft Token Reward", FSkinProp.ICO_QUEST_COIN); view.showMessage("For achieving a 25 win streak, you have been awarded a draft token!\nUse these tokens to generate new tournaments.", "Bonus Draft Token Reward", FSkinProp.ICO_QUEST_COIN);
qData.getAchievements().addDraftToken(); qData.getAchievements().addDraftToken();
} }
if (cardsWon.size() > 0) { if (cardsWon.size() > 0) {
showCards("You have achieved a " + (currentStreak == 0 ? "50" : currentStreak) + " win streak and won " + cardsWon.size() + " " + typeWon + " card" + ((cardsWon.size() != 1) ? "s" : "") + "!", cardsWon); view.showCards("You have achieved a " + (currentStreak == 0 ? "50" : currentStreak) + " win streak and won " + cardsWon.size() + " " + typeWon + " card" + ((cardsWon.size() != 1) ? "s" : "") + "!", cardsWon);
} }
} }
@@ -476,7 +478,7 @@ public abstract class QuestWinLoseController {
*/ */
private void awardJackpot() { private void awardJackpot() {
final List<PaperCard> cardsWon = qData.getCards().addRandomRare(10); final List<PaperCard> cardsWon = qData.getCards().addRandomRare(10);
showCards("You just won 10 random rares!", cardsWon); view.showCards("You just won 10 random rares!", cardsWon);
} }
/** /**
@@ -569,7 +571,7 @@ public abstract class QuestWinLoseController {
return c2.getRarity().compareTo(c1.getRarity()); return c2.getRarity().compareTo(c1.getRarity());
} }
}); });
showCards(title, cardsWon); view.showCards(title, cardsWon);
} }
} }
@@ -589,7 +591,7 @@ public abstract class QuestWinLoseController {
qData.getAssets().addCredits(questRewardCredits); qData.getAssets().addCredits(questRewardCredits);
showMessage(sb.toString(), "Challenge Rewards for \"" + ((QuestEventChallenge) qEvent).getTitle() + "\"", FSkinProp.ICO_QUEST_BOX); view.showMessage(sb.toString(), "Challenge Rewards for \"" + ((QuestEventChallenge) qEvent).getTitle() + "\"", FSkinProp.ICO_QUEST_BOX);
awardSpecialReward(null); awardSpecialReward(null);
} }
@@ -627,7 +629,7 @@ public abstract class QuestWinLoseController {
} }
if (!boosterCards.isEmpty()) { if (!boosterCards.isEmpty()) {
qData.getCards().addAllCards(boosterCards); qData.getCards().addAllCards(boosterCards);
showCards("Extra " + ii.getName() + "!", boosterCards); view.showCards("Extra " + ii.getName() + "!", boosterCards);
} }
} }
else if (ii instanceof IQuestRewardCard) { else if (ii instanceof IQuestRewardCard) {
@@ -642,14 +644,14 @@ public abstract class QuestWinLoseController {
if (message == null) { if (message == null) {
message = "Cards Won"; message = "Cards Won";
} }
showCards(message, cardsWon); view.showCards(message, cardsWon);
qData.getCards().addAllCards(cardsWon); qData.getCards().addAllCards(cardsWon);
} }
} }
private void penalizeLoss() { private void penalizeLoss() {
final int x = FModel.getQuestPreferences().getPrefInt(QPref.PENALTY_LOSS); final int x = FModel.getQuestPreferences().getPrefInt(QPref.PENALTY_LOSS);
showMessage("You lose! You have lost " + x + " credits.", "Gameplay Results", FSkinProp.ICO_QUEST_HEART); view.showMessage("You lose! You have lost " + x + " credits.", "Gameplay Results", FSkinProp.ICO_QUEST_HEART);
} }
/** /**
@@ -725,8 +727,4 @@ public abstract class QuestWinLoseController {
return credits; return credits;
} }
protected abstract void showRewards(Runnable runnable);
protected abstract void showCards(String title, List<PaperCard> cards);
protected abstract void showMessage(String message, String title, FSkinProp icon);
} }