mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-17 03:08:02 +00:00
Initial commit for Planar Conquest mode
This commit is contained in:
11
.gitattributes
vendored
11
.gitattributes
vendored
@@ -1279,6 +1279,11 @@ 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/LimitedWinLose.java -text
|
||||||
forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLose.java -text
|
forge-gui-mobile/src/forge/screens/match/winlose/QuestWinLose.java -text
|
||||||
forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java -text
|
forge-gui-mobile/src/forge/screens/match/winlose/ViewWinLose.java -text
|
||||||
|
forge-gui-mobile/src/forge/screens/planarconquest/ConquestMapScreen.java -text
|
||||||
|
forge-gui-mobile/src/forge/screens/planarconquest/ConquestMenu.java -text
|
||||||
|
forge-gui-mobile/src/forge/screens/planarconquest/ConquestPrefsScreen.java -text
|
||||||
|
forge-gui-mobile/src/forge/screens/planarconquest/LoadConquestScreen.java -text
|
||||||
|
forge-gui-mobile/src/forge/screens/planarconquest/NewConquestScreen.java -text
|
||||||
forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java -text
|
forge-gui-mobile/src/forge/screens/quest/LoadQuestScreen.java -text
|
||||||
forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java -text
|
forge-gui-mobile/src/forge/screens/quest/NewQuestScreen.java -text
|
||||||
forge-gui-mobile/src/forge/screens/quest/QuestBazaarScreen.java -text
|
forge-gui-mobile/src/forge/screens/quest/QuestBazaarScreen.java -text
|
||||||
@@ -17134,6 +17139,12 @@ forge-gui/src/main/java/forge/model/MetaSet.java -text
|
|||||||
forge-gui/src/main/java/forge/model/MultipleForgeJarsFoundError.java -text
|
forge-gui/src/main/java/forge/model/MultipleForgeJarsFoundError.java -text
|
||||||
forge-gui/src/main/java/forge/model/UnOpenedMeta.java -text
|
forge-gui/src/main/java/forge/model/UnOpenedMeta.java -text
|
||||||
forge-gui/src/main/java/forge/model/package-info.java svneol=native#text/plain
|
forge-gui/src/main/java/forge/model/package-info.java svneol=native#text/plain
|
||||||
|
forge-gui/src/main/java/forge/planarconquest/ConquestController.java -text
|
||||||
|
forge-gui/src/main/java/forge/planarconquest/ConquestData.java -text
|
||||||
|
forge-gui/src/main/java/forge/planarconquest/ConquestDataIO.java -text
|
||||||
|
forge-gui/src/main/java/forge/planarconquest/ConquestDeckMap.java -text
|
||||||
|
forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java -text
|
||||||
|
forge-gui/src/main/java/forge/planarconquest/ConquestPreferences.java -text
|
||||||
forge-gui/src/main/java/forge/player/GamePlayerUtil.java -text
|
forge-gui/src/main/java/forge/player/GamePlayerUtil.java -text
|
||||||
forge-gui/src/main/java/forge/player/HumanCostDecision.java -text
|
forge-gui/src/main/java/forge/player/HumanCostDecision.java -text
|
||||||
forge-gui/src/main/java/forge/player/HumanPlay.java -text
|
forge-gui/src/main/java/forge/player/HumanPlay.java -text
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import forge.util.PredicateString.StringOp;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Filtering conditions specific for CardRules class, defined here along with
|
* Filtering conditions specific for CardRules class, defined here along with
|
||||||
@@ -149,6 +150,23 @@ public final class CardRulesPredicates {
|
|||||||
return new LeafString(LeafString.CardField.JOINED_TYPE, op, what);
|
return new LeafString(LeafString.CardField.JOINED_TYPE, op, what);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Predicate<CardRules> hasCreatureType(final String... creatureTypes) {
|
||||||
|
return new Predicate<CardRules>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(final CardRules card) {
|
||||||
|
if (!card.getType().isCreature()) { return false; }
|
||||||
|
|
||||||
|
Set<String> set = card.getType().getCreatureTypes();
|
||||||
|
for (String creatureType : creatureTypes) {
|
||||||
|
if (set.contains(creatureType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Has Keyword.
|
* Has Keyword.
|
||||||
*
|
*
|
||||||
@@ -292,6 +310,15 @@ public final class CardRulesPredicates {
|
|||||||
return new LeafColor(LeafColor.ColorOperator.CountColorsGreaterOrEqual, cntColors);
|
return new LeafColor(LeafColor.ColorOperator.CountColorsGreaterOrEqual, cntColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Predicate<CardRules> hasColorIdentity(final byte colors) {
|
||||||
|
return new Predicate<CardRules>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(CardRules rules) {
|
||||||
|
return rules.getColorIdentity().hasAllColors(colors);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static class LeafString extends PredicateString<CardRules> {
|
private static class LeafString extends PredicateString<CardRules> {
|
||||||
public enum CardField {
|
public enum CardField {
|
||||||
ORACLE_TEXT, NAME, SUBTYPE, JOINED_TYPE, COST
|
ORACLE_TEXT, NAME, SUBTYPE, JOINED_TYPE, COST
|
||||||
|
|||||||
@@ -19,6 +19,11 @@ public class FCollection<T> implements List<T>, Set<T>, FCollectionView<T>, Clon
|
|||||||
public FCollection(T e) {
|
public FCollection(T e) {
|
||||||
add(e);
|
add(e);
|
||||||
}
|
}
|
||||||
|
public FCollection(T[] c) {
|
||||||
|
for (T e : c) {
|
||||||
|
add(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
public FCollection(Collection<T> c) {
|
public FCollection(Collection<T> c) {
|
||||||
for (T e : c) {
|
for (T e : c) {
|
||||||
add(e);
|
add(e);
|
||||||
|
|||||||
@@ -106,6 +106,12 @@ public class FDeckEditor extends TabPageScreen<FDeckEditor> {
|
|||||||
public Deck get() {
|
public Deck get() {
|
||||||
return new Deck();
|
return new Deck();
|
||||||
}
|
}
|
||||||
|
})),
|
||||||
|
PlanarConquest(new DeckController<Deck>(null, new Supplier<Deck>() { //delay setting root folder until conquest loaded
|
||||||
|
@Override
|
||||||
|
public Deck get() {
|
||||||
|
return new Deck();
|
||||||
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
private final DeckController<? extends DeckBase> controller;
|
private final DeckController<? extends DeckBase> controller;
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ import forge.assets.FSkinImage;
|
|||||||
import forge.screens.constructed.ConstructedScreen;
|
import forge.screens.constructed.ConstructedScreen;
|
||||||
import forge.screens.gauntlet.GauntletScreen;
|
import forge.screens.gauntlet.GauntletScreen;
|
||||||
import forge.screens.limited.LimitedScreen;
|
import forge.screens.limited.LimitedScreen;
|
||||||
|
import forge.screens.planarconquest.ConquestMenu;
|
||||||
import forge.screens.quest.QuestMenu;
|
import forge.screens.quest.QuestMenu;
|
||||||
import forge.screens.quest.QuestMenu.LaunchReason;
|
|
||||||
import forge.screens.settings.SettingsScreen;
|
import forge.screens.settings.SettingsScreen;
|
||||||
import forge.toolbox.FButton;
|
import forge.toolbox.FButton;
|
||||||
import forge.toolbox.FEvent;
|
import forge.toolbox.FEvent;
|
||||||
@@ -39,15 +39,16 @@ public class HomeScreen extends FScreen {
|
|||||||
Forge.openScreen(new LimitedScreen());
|
Forge.openScreen(new LimitedScreen());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addButton("???", new FEventHandler() {
|
addButton("Planar Conquest", new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
|
ConquestMenu.launchPlanarConquest(ConquestMenu.LaunchReason.StartPlanarConquest);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addButton("Quest Mode", new FEventHandler() {
|
addButton("Quest Mode", new FEventHandler() {
|
||||||
@Override
|
@Override
|
||||||
public void handleEvent(FEvent e) {
|
public void handleEvent(FEvent e) {
|
||||||
QuestMenu.launchQuestMode(LaunchReason.StartQuestMode);
|
QuestMenu.launchQuestMode(QuestMenu.LaunchReason.StartQuestMode);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
addButton("Gauntlets", new FEventHandler() {
|
addButton("Gauntlets", new FEventHandler() {
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
package forge.screens.planarconquest;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
|
import forge.quest.QuestUtil;
|
||||||
|
import forge.screens.LaunchScreen;
|
||||||
|
import forge.screens.LoadingOverlay;
|
||||||
|
import forge.toolbox.FOptionPane;
|
||||||
|
|
||||||
|
public class ConquestMapScreen extends LaunchScreen {
|
||||||
|
protected static final float PADDING = FOptionPane.PADDING;
|
||||||
|
|
||||||
|
public ConquestMapScreen() {
|
||||||
|
super("", ConquestMenu.getMenu());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void onActivate() {
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void startMatch() {
|
||||||
|
if (creatingMatch) { return; }
|
||||||
|
creatingMatch = true; //ensure user doesn't create multiple matches by tapping multiple times
|
||||||
|
|
||||||
|
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (QuestUtil.canStartGame()) {
|
||||||
|
FThreads.invokeInEdtLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
LoadingOverlay.show("Loading new game...", new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
QuestUtil.finishStartingGame();
|
||||||
|
creatingMatch = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
creatingMatch = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected final boolean buildLaunchParams(LaunchParams launchParams) {
|
||||||
|
return false; //this override isn't needed
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLayoutAboveBtnStart(float startY, float width, float height) {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,116 @@
|
|||||||
|
package forge.screens.planarconquest;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.assets.FSkinImage;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.deck.FDeckEditor.DeckController;
|
||||||
|
import forge.deck.FDeckEditor.EditorType;
|
||||||
|
import forge.menu.FMenuItem;
|
||||||
|
import forge.menu.FPopupMenu;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.planarconquest.ConquestDataIO;
|
||||||
|
import forge.planarconquest.ConquestPreferences.CQPref;
|
||||||
|
import forge.properties.ForgeConstants;
|
||||||
|
import forge.screens.FScreen;
|
||||||
|
import forge.screens.LoadingOverlay;
|
||||||
|
import forge.toolbox.FEvent;
|
||||||
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
|
|
||||||
|
public class ConquestMenu extends FPopupMenu {
|
||||||
|
private static final ConquestMenu conquestMenu = new ConquestMenu();
|
||||||
|
private static final ConquestMapScreen mapScreen = new ConquestMapScreen();
|
||||||
|
private static final ConquestPrefsScreen prefsScreen = new ConquestPrefsScreen();
|
||||||
|
|
||||||
|
private static final FMenuItem mapItem = new FMenuItem("Planar Map", FSkinImage.QUEST_MAP, new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
Forge.openScreen(mapScreen);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public static ConquestMenu getMenu() {
|
||||||
|
return conquestMenu;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConquestMenu() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum LaunchReason {
|
||||||
|
StartPlanarConquest,
|
||||||
|
LoadConquest,
|
||||||
|
NewConquest
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void launchPlanarConquest(final LaunchReason reason) {
|
||||||
|
//attempt to load current quest
|
||||||
|
final File dirConquests = new File(ForgeConstants.CONQUEST_SAVE_DIR);
|
||||||
|
final String questname = FModel.getConquestPreferences().getPref(CQPref.CURRENT_CONQUEST);
|
||||||
|
final File data = new File(dirConquests.getPath(), questname);
|
||||||
|
if (data.exists()) {
|
||||||
|
LoadingOverlay.show("Loading current conquest...", new Runnable() {
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public void run() {
|
||||||
|
FModel.getConquest().load(ConquestDataIO.loadData(data));
|
||||||
|
((DeckController<Deck>)EditorType.PlanarConquest.getController()).setRootFolder(FModel.getConquest().getDecks());
|
||||||
|
if (reason == LaunchReason.StartPlanarConquest) {
|
||||||
|
Forge.openScreen(mapScreen);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mapScreen.update();
|
||||||
|
if (reason == LaunchReason.LoadConquest) {
|
||||||
|
Forge.back();
|
||||||
|
if (Forge.onHomeScreen()) { //open map screen if Load Conquest screen was opening direct from home screen
|
||||||
|
Forge.openScreen(mapScreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Forge.back();
|
||||||
|
if (Forge.getCurrentScreen() instanceof LoadConquestScreen) {
|
||||||
|
Forge.back(); //remove LoadConquestScreen from screen stack
|
||||||
|
}
|
||||||
|
if (Forge.onHomeScreen()) { //open map screen if New Conquest screen was opening direct from home screen
|
||||||
|
Forge.openScreen(mapScreen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if current quest can't be loaded, open New Conquest or Load Conquest screen based on whether a quest exists
|
||||||
|
if (dirConquests.exists() && dirConquests.isDirectory() && dirConquests.list().length > 0) {
|
||||||
|
Forge.openScreen(new LoadConquestScreen());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Forge.openScreen(new NewConquestScreen());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void buildMenu() {
|
||||||
|
FScreen currentScreen = Forge.getCurrentScreen();
|
||||||
|
addItem(mapItem); mapItem.setSelected(currentScreen == mapScreen);
|
||||||
|
addItem(new FMenuItem("New Conquest", FSkinImage.NEW, new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
Forge.openScreen(new NewConquestScreen());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
addItem(new FMenuItem("Load Conquest", FSkinImage.OPEN, new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
Forge.openScreen(new LoadConquestScreen());
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
addItem(new FMenuItem("Preferences", FSkinImage.SETTINGS, new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
Forge.openScreen(prefsScreen);
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
package forge.screens.planarconquest;
|
||||||
|
|
||||||
|
import forge.assets.FImage;
|
||||||
|
import forge.assets.FSkinFont;
|
||||||
|
import forge.assets.FSkinImage;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.planarconquest.ConquestPreferences;
|
||||||
|
import forge.planarconquest.ConquestPreferences.CQPref;
|
||||||
|
import forge.screens.FScreen;
|
||||||
|
import forge.toolbox.FContainer;
|
||||||
|
import forge.toolbox.FDisplayObject;
|
||||||
|
import forge.toolbox.FEvent;
|
||||||
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
|
import forge.toolbox.FLabel;
|
||||||
|
import forge.toolbox.FNumericTextField;
|
||||||
|
import forge.toolbox.FOptionPane;
|
||||||
|
import forge.toolbox.FScrollPane;
|
||||||
|
import forge.toolbox.FTextField;
|
||||||
|
import forge.util.Utils;
|
||||||
|
|
||||||
|
public class ConquestPrefsScreen extends FScreen {
|
||||||
|
private static final float PADDING = Utils.scale(5);
|
||||||
|
|
||||||
|
private enum PrefsGroup {
|
||||||
|
TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
private FScrollPane scroller = add(new FScrollPane() {
|
||||||
|
@Override
|
||||||
|
protected ScrollBounds layoutAndGetScrollBounds(float visibleWidth, float visibleHeight) {
|
||||||
|
float x = PADDING;
|
||||||
|
float y = PADDING;
|
||||||
|
float w = visibleWidth - 2 * PADDING;
|
||||||
|
float fieldHeight = FTextField.getDefaultHeight();
|
||||||
|
float dy = fieldHeight + PADDING;
|
||||||
|
|
||||||
|
for (FDisplayObject child : getChildren()) {
|
||||||
|
if (child.isVisible()) {
|
||||||
|
child.setBounds(x, y, w, fieldHeight);
|
||||||
|
y += dy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ScrollBounds(visibleWidth, y);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
public ConquestPrefsScreen() {
|
||||||
|
super("Conquest Preferences", ConquestMenu.getMenu());
|
||||||
|
|
||||||
|
scroller.add(new PrefsHeader("TODO", FSkinImage.QUEST_COIN, PrefsGroup.TODO));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLayout(float startY, float width, float height) {
|
||||||
|
scroller.setBounds(0, startY, width, height - startY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class PrefsHeader extends FLabel {
|
||||||
|
private PrefsHeader(String title, FImage icon, final PrefsGroup group) {
|
||||||
|
super(new ButtonBuilder().text(title).font(FSkinFont.get(16)).icon(icon).iconScaleFactor(1f)
|
||||||
|
.command(new FEventHandler() {
|
||||||
|
private boolean showOptions = true;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
showOptions = !showOptions;
|
||||||
|
for (FDisplayObject child : scroller.getChildren()) {
|
||||||
|
if (child instanceof PrefsOption && ((PrefsOption)child).group == group) {
|
||||||
|
child.setVisible(showOptions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scroller.revalidate();
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PrefsOption extends FContainer {
|
||||||
|
private static final float FIELD_WIDTH = new FTextField("99999").getAutoSizeWidth(); //base width on 5 digit number
|
||||||
|
|
||||||
|
private final FLabel label = add(new FLabel.Builder().build());
|
||||||
|
private final OptionField field = add(new OptionField());
|
||||||
|
private final CQPref pref;
|
||||||
|
private final PrefsGroup group;
|
||||||
|
|
||||||
|
private PrefsOption(String label0, CQPref pref0, PrefsGroup group0) {
|
||||||
|
label.setText(label0);
|
||||||
|
pref = pref0;
|
||||||
|
group = group0;
|
||||||
|
field.setText(FModel.getConquestPreferences().getPref(pref0));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLayout(float width, float height) {
|
||||||
|
label.setBounds(0, 0, width - FIELD_WIDTH - PADDING, height);
|
||||||
|
field.setBounds(width - FIELD_WIDTH, 0, FIELD_WIDTH, height);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class OptionField extends FNumericTextField {
|
||||||
|
private OptionField() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean validate() {
|
||||||
|
if (super.validate()) {
|
||||||
|
final ConquestPreferences prefs = FModel.getConquestPreferences();
|
||||||
|
|
||||||
|
int val = Integer.parseInt(getText());
|
||||||
|
|
||||||
|
String validationError = prefs.validatePreference(pref, val);
|
||||||
|
if (validationError != null) {
|
||||||
|
String prefType;
|
||||||
|
switch (group) {
|
||||||
|
default:
|
||||||
|
prefType = "TODO";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
FOptionPane.showErrorDialog(validationError, "Save Failed - " + prefType);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
prefs.setPref(pref, getText());
|
||||||
|
prefs.save();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,310 @@
|
|||||||
|
package forge.screens.planarconquest;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FilenameFilter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.g2d.BitmapFont.HAlignment;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
|
import forge.Forge;
|
||||||
|
import forge.Graphics;
|
||||||
|
import forge.assets.FSkinColor;
|
||||||
|
import forge.assets.FSkinColor.Colors;
|
||||||
|
import forge.assets.FSkinFont;
|
||||||
|
import forge.assets.FSkinImage;
|
||||||
|
import forge.card.CardRenderer;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.planarconquest.ConquestController;
|
||||||
|
import forge.planarconquest.ConquestData;
|
||||||
|
import forge.planarconquest.ConquestDataIO;
|
||||||
|
import forge.planarconquest.ConquestPreferences.CQPref;
|
||||||
|
import forge.properties.ForgeConstants;
|
||||||
|
import forge.quest.QuestUtil;
|
||||||
|
import forge.screens.FScreen;
|
||||||
|
import forge.screens.settings.SettingsScreen;
|
||||||
|
import forge.toolbox.FButton;
|
||||||
|
import forge.toolbox.FEvent;
|
||||||
|
import forge.toolbox.FList;
|
||||||
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
|
import forge.util.ThreadUtil;
|
||||||
|
import forge.util.Utils;
|
||||||
|
import forge.util.gui.SOptionPane;
|
||||||
|
|
||||||
|
public class LoadConquestScreen extends FScreen {
|
||||||
|
private static final float PADDING = Utils.AVG_FINGER_HEIGHT * 0.1f;
|
||||||
|
private static final FSkinColor SEL_COLOR = FSkinColor.get(Colors.CLR_ACTIVE);
|
||||||
|
|
||||||
|
private final ConquestFileLister lstConquests = add(new ConquestFileLister());
|
||||||
|
private final FButton btnNewConquest = add(new FButton("New"));
|
||||||
|
private final FButton btnRenameConquest = add(new FButton("Rename"));
|
||||||
|
private final FButton btnDeleteConquest = add(new FButton("Delete"));
|
||||||
|
|
||||||
|
public LoadConquestScreen() {
|
||||||
|
super("Load Planar Conquest");
|
||||||
|
|
||||||
|
btnNewConquest.setFont(FSkinFont.get(16));
|
||||||
|
btnNewConquest.setCommand(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
Forge.openScreen(new NewConquestScreen());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnRenameConquest.setFont(btnNewConquest.getFont());
|
||||||
|
btnRenameConquest.setCommand(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
renameConquest(lstConquests.getSelectedConquest());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
btnDeleteConquest.setFont(btnNewConquest.getFont());
|
||||||
|
btnDeleteConquest.setCommand(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
deleteConquest(lstConquests.getSelectedConquest());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
FThreads.invokeInBackgroundThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final File dirConquests = new File(ForgeConstants.CONQUEST_SAVE_DIR);
|
||||||
|
final ConquestController qc = FModel.getConquest();
|
||||||
|
|
||||||
|
// Iterate over files and load quest data for each.
|
||||||
|
FilenameFilter takeDatFiles = new FilenameFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(final File dir, final String name) {
|
||||||
|
return name.endsWith(".dat");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
File[] arrFiles = dirConquests.listFiles(takeDatFiles);
|
||||||
|
Map<String, ConquestData> arrConquests = new HashMap<String, ConquestData>();
|
||||||
|
for (File f : arrFiles) {
|
||||||
|
arrConquests.put(f.getName(), ConquestDataIO.loadData(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Populate list with available quest data.
|
||||||
|
lstConquests.setConquests(new ArrayList<ConquestData>(arrConquests.values()));
|
||||||
|
|
||||||
|
// If there are quests available, force select.
|
||||||
|
if (arrConquests.size() > 0) {
|
||||||
|
final String questname = FModel.getConquestPreferences().getPref(CQPref.CURRENT_CONQUEST);
|
||||||
|
|
||||||
|
// Attempt to select previous quest.
|
||||||
|
if (arrConquests.get(questname) != null) {
|
||||||
|
lstConquests.setSelectedConquest(arrConquests.get(questname));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lstConquests.setSelectedIndex(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop into AllZone.
|
||||||
|
qc.load(lstConquests.getSelectedConquest());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
qc.load(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void drawOverlay(Graphics g) {
|
||||||
|
float y = lstConquests.getTop();
|
||||||
|
g.drawLine(1, FList.LINE_COLOR, 0, y, getWidth(), y); //draw top border for list
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLayout(float startY, float width, float height) {
|
||||||
|
float buttonWidth = (width - 2 * PADDING) / 3;
|
||||||
|
float buttonHeight = btnNewConquest.getAutoSizeBounds().height * 1.2f;
|
||||||
|
|
||||||
|
float y = startY + 2 * PADDING;
|
||||||
|
lstConquests.setBounds(0, y, width, height - y - buttonHeight - 2 * PADDING);
|
||||||
|
y += lstConquests.getHeight() + PADDING;
|
||||||
|
|
||||||
|
float x = 0;
|
||||||
|
btnNewConquest.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
x += buttonWidth + PADDING;
|
||||||
|
btnRenameConquest.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
x += buttonWidth + PADDING;
|
||||||
|
btnDeleteConquest.setBounds(x, y, buttonWidth, buttonHeight);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void changeConquest() {
|
||||||
|
FModel.getConquestPreferences().setPref(CQPref.CURRENT_CONQUEST,
|
||||||
|
lstConquests.getSelectedConquest().getName() + ".dat");
|
||||||
|
FModel.getConquestPreferences().save();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void renameConquest(final ConquestData quest) {
|
||||||
|
if (quest == null) { return; }
|
||||||
|
|
||||||
|
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
String questName;
|
||||||
|
String oldConquestName = quest.getName();
|
||||||
|
while (true) {
|
||||||
|
questName = SOptionPane.showInputDialog("Enter new name for quest:", "Rename Conquest", null, oldConquestName);
|
||||||
|
if (questName == null) { return; }
|
||||||
|
|
||||||
|
questName = QuestUtil.cleanString(questName);
|
||||||
|
if (questName.equals(oldConquestName)) { return; } //quit if chose same name
|
||||||
|
|
||||||
|
if (questName.isEmpty()) {
|
||||||
|
SOptionPane.showMessageDialog("Please specify a quest name.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean exists = false;
|
||||||
|
for (ConquestData questData : lstConquests) {
|
||||||
|
if (questData.getName().equalsIgnoreCase(questName)) {
|
||||||
|
exists = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (exists) {
|
||||||
|
SOptionPane.showMessageDialog("A quest already exists with that name. Please pick another quest name.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
quest.rename(questName);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void deleteConquest(final ConquestData quest) {
|
||||||
|
if (quest == null) { return; }
|
||||||
|
|
||||||
|
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if (!SOptionPane.showConfirmDialog(
|
||||||
|
"Are you sure you want to delete '" + quest.getName() + "'?",
|
||||||
|
"Delete Conquest", "Delete", "Cancel")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
new File(ForgeConstants.CONQUEST_SAVE_DIR, quest.getName() + ".dat").delete();
|
||||||
|
|
||||||
|
lstConquests.removeConquest(quest);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ConquestFileLister extends FList<ConquestData> {
|
||||||
|
private int selectedIndex = 0;
|
||||||
|
|
||||||
|
private ConquestFileLister() {
|
||||||
|
setListItemRenderer(new ListItemRenderer<ConquestData>() {
|
||||||
|
@Override
|
||||||
|
public boolean tap(Integer index, ConquestData value, float x, float y, int count) {
|
||||||
|
if (count == 2) {
|
||||||
|
changeConquest();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
selectedIndex = index;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getItemHeight() {
|
||||||
|
return CardRenderer.getCardListItemHeight(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void drawValue(Graphics g, Integer index, ConquestData value, FSkinFont font, FSkinColor foreColor, FSkinColor backColor, boolean pressed, float x, float y, float w, float h) {
|
||||||
|
float offset = w * SettingsScreen.INSETS_FACTOR - FList.PADDING; //increase padding for settings items
|
||||||
|
x += offset;
|
||||||
|
y += offset;
|
||||||
|
w -= 2 * offset;
|
||||||
|
h -= 2 * offset;
|
||||||
|
|
||||||
|
float totalHeight = h;
|
||||||
|
String name = value.getName();
|
||||||
|
h = font.getMultiLineBounds(name).height + SettingsScreen.SETTING_PADDING;
|
||||||
|
|
||||||
|
String winRatio = value.getWins() + "W / " + value.getLosses() + "L";
|
||||||
|
float winRatioWidth = font.getBounds(winRatio).width + SettingsScreen.SETTING_PADDING;
|
||||||
|
|
||||||
|
g.drawText(name, font, foreColor, x, y, w - winRatioWidth, h, false, HAlignment.LEFT, false);
|
||||||
|
g.drawText(winRatio, font, foreColor, x, y, w, h, false, HAlignment.RIGHT, false);
|
||||||
|
|
||||||
|
h += SettingsScreen.SETTING_PADDING;
|
||||||
|
y += h;
|
||||||
|
h = totalHeight - h + w * SettingsScreen.INSETS_FACTOR;
|
||||||
|
float iconSize = h + Utils.scale(1);
|
||||||
|
float iconOffset = SettingsScreen.SETTING_PADDING - Utils.scale(2);
|
||||||
|
|
||||||
|
String cards = String.valueOf(value.getCardPool().countAll());
|
||||||
|
font = FSkinFont.get(12);
|
||||||
|
float cardsWidth = font.getBounds(cards).width + iconSize + SettingsScreen.SETTING_PADDING;
|
||||||
|
g.drawImage(FSkinImage.HAND, x + w - cardsWidth + iconOffset, y - SettingsScreen.SETTING_PADDING, iconSize, iconSize);
|
||||||
|
g.drawText(cards, font, SettingsScreen.DESC_COLOR, x + w - cardsWidth + iconSize + SettingsScreen.SETTING_PADDING, y, w, h, false, HAlignment.LEFT, false);
|
||||||
|
g.drawImage(FSkinImage.QUEST_COINSTACK, x + w + iconOffset, y - SettingsScreen.SETTING_PADDING, iconSize, iconSize);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected FSkinColor getItemFillColor(int index) {
|
||||||
|
if (index == selectedIndex) {
|
||||||
|
return SEL_COLOR;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setConquests(List<ConquestData> qd0) {
|
||||||
|
List<ConquestData> sorted = new ArrayList<ConquestData>();
|
||||||
|
for (ConquestData qd : qd0) {
|
||||||
|
sorted.add(qd);
|
||||||
|
}
|
||||||
|
Collections.sort(sorted, new Comparator<ConquestData>() {
|
||||||
|
@Override
|
||||||
|
public int compare(final ConquestData x, final ConquestData y) {
|
||||||
|
return x.getName().toLowerCase().compareTo(y.getName().toLowerCase());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
setListData(sorted);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeConquest(ConquestData qd) {
|
||||||
|
removeItem(qd);
|
||||||
|
if (selectedIndex == getCount()) {
|
||||||
|
selectedIndex--;
|
||||||
|
}
|
||||||
|
revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setSelectedIndex(int i0) {
|
||||||
|
if (i0 >= getCount()) { return false; }
|
||||||
|
selectedIndex = i0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConquestData getSelectedConquest() {
|
||||||
|
if (selectedIndex == -1) { return null; }
|
||||||
|
return getItemAt(selectedIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setSelectedConquest(ConquestData qd0) {
|
||||||
|
for (int i = 0; i < getCount(); i++) {
|
||||||
|
if (getItemAt(i) == qd0) {
|
||||||
|
selectedIndex = i;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,142 @@
|
|||||||
|
package forge.screens.planarconquest;
|
||||||
|
|
||||||
|
import forge.FThreads;
|
||||||
|
import forge.assets.FSkinFont;
|
||||||
|
import forge.assets.FSkinImage;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.planarconquest.ConquestController;
|
||||||
|
import forge.planarconquest.ConquestData;
|
||||||
|
import forge.planarconquest.ConquestPlane;
|
||||||
|
import forge.planarconquest.ConquestPreferences.CQPref;
|
||||||
|
import forge.properties.ForgeConstants;
|
||||||
|
import forge.quest.QuestUtil;
|
||||||
|
import forge.screens.FScreen;
|
||||||
|
import forge.screens.LoadingOverlay;
|
||||||
|
import forge.toolbox.FChoiceList;
|
||||||
|
import forge.toolbox.FComboBox;
|
||||||
|
import forge.toolbox.FEvent;
|
||||||
|
import forge.toolbox.FEvent.FEventHandler;
|
||||||
|
import forge.toolbox.FLabel;
|
||||||
|
import forge.toolbox.FOptionPane;
|
||||||
|
import forge.util.FileUtil;
|
||||||
|
import forge.util.ThreadUtil;
|
||||||
|
import forge.util.Utils;
|
||||||
|
import forge.util.gui.SOptionPane;
|
||||||
|
|
||||||
|
public class NewConquestScreen extends FScreen {
|
||||||
|
private static final float EMBARK_BTN_HEIGHT = 2 * Utils.AVG_FINGER_HEIGHT;
|
||||||
|
private static final float PADDING = FOptionPane.PADDING;
|
||||||
|
|
||||||
|
private final FLabel lblDifficulty = add(new FLabel.Builder().text("Difficulty:").build());
|
||||||
|
private final FComboBox<String> cbxDifficulty = add(new FComboBox<String>(new String[]{ "Easy", "Medium", "Hard", "Expert" }));
|
||||||
|
|
||||||
|
private final FLabel lblStartingPlane = add(new FLabel.Builder().text("Starting world:").build());
|
||||||
|
private final FComboBox<ConquestPlane> cbxStartingPlane = add(new FComboBox<ConquestPlane>(ConquestPlane.values()));
|
||||||
|
|
||||||
|
private final FLabel lblStartingCommander = add(new FLabel.Builder().text("Starting commander:").build());
|
||||||
|
private final FChoiceList<PaperCard> lstCommanders = add(new FChoiceList<PaperCard>(cbxStartingPlane.getSelectedItem().getCommanders()));
|
||||||
|
|
||||||
|
private final FLabel btnEmbark = add(new FLabel.ButtonBuilder()
|
||||||
|
.font(FSkinFont.get(22)).text("Embark!").icon(FSkinImage.QUEST_ZEP).command(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
//create new quest in game thread so option panes can wait for input
|
||||||
|
ThreadUtil.invokeInGameThread(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
newConquest();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).build());
|
||||||
|
|
||||||
|
public NewConquestScreen() {
|
||||||
|
super("New Planar Conquest");
|
||||||
|
|
||||||
|
cbxStartingPlane.setChangedHandler(new FEventHandler() {
|
||||||
|
@Override
|
||||||
|
public void handleEvent(FEvent e) {
|
||||||
|
lstCommanders.setListData(cbxStartingPlane.getSelectedItem().getCommanders());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSelectedDifficulty() {
|
||||||
|
int difficulty = cbxDifficulty.getSelectedIndex();
|
||||||
|
if (difficulty < 0) {
|
||||||
|
difficulty = 0;
|
||||||
|
}
|
||||||
|
return difficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doLayout(float startY, float width, float height) {
|
||||||
|
float x = PADDING;
|
||||||
|
float y = startY + PADDING;
|
||||||
|
float right = width - PADDING;
|
||||||
|
float w = width - 2 * PADDING;
|
||||||
|
float h = cbxStartingPlane.getHeight();
|
||||||
|
float gapY = PADDING / 2;
|
||||||
|
|
||||||
|
lblDifficulty.setBounds(x, y, width / 2 - x, h);
|
||||||
|
x += lblDifficulty.getWidth();
|
||||||
|
cbxDifficulty.setBounds(x, y, right - x, h);
|
||||||
|
x = PADDING;
|
||||||
|
y += h + gapY;
|
||||||
|
|
||||||
|
lblStartingPlane.setBounds(x, y, width / 2 - x, h);
|
||||||
|
x += lblStartingPlane.getWidth();
|
||||||
|
cbxStartingPlane.setBounds(x, y, right - x, h);
|
||||||
|
x = PADDING;
|
||||||
|
y += h + gapY;
|
||||||
|
|
||||||
|
lblStartingCommander.setBounds(x, y, w, h);
|
||||||
|
y += h;
|
||||||
|
lstCommanders.setBounds(x, y, w, height - EMBARK_BTN_HEIGHT - gapY - PADDING - y);
|
||||||
|
y += lstCommanders.getHeight() + gapY;
|
||||||
|
|
||||||
|
btnEmbark.setBounds(x, y, w, EMBARK_BTN_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void newConquest() {
|
||||||
|
String conquestName;
|
||||||
|
while (true) {
|
||||||
|
conquestName = SOptionPane.showInputDialog("Historians will recall your conquest as:", "Conquest Name");
|
||||||
|
if (conquestName == null) { return; }
|
||||||
|
|
||||||
|
conquestName = QuestUtil.cleanString(conquestName);
|
||||||
|
|
||||||
|
if (conquestName.isEmpty()) {
|
||||||
|
SOptionPane.showMessageDialog("Please specify a conquest name.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (FileUtil.doesFileExist(ForgeConstants.CONQUEST_SAVE_DIR + conquestName + ".dat")) {
|
||||||
|
SOptionPane.showMessageDialog("A quest already exists with that name. Please pick another quest name.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
startNewConquest(conquestName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startNewConquest(final String conquestName) {
|
||||||
|
FThreads.invokeInEdtLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
LoadingOverlay.show("Creating new quest...", new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
ConquestController qc = FModel.getConquest();
|
||||||
|
qc.load(new ConquestData(conquestName, getSelectedDifficulty(), cbxStartingPlane.getSelectedItem(), lstCommanders.getSelectedItem()));
|
||||||
|
qc.save();
|
||||||
|
|
||||||
|
// Save in preferences.
|
||||||
|
FModel.getConquestPreferences().setPref(CQPref.CURRENT_CONQUEST, conquestName + ".dat");
|
||||||
|
FModel.getConquestPreferences().save();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package forge.toolbox;
|
package forge.toolbox;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@@ -35,19 +34,19 @@ public class FChoiceList<T> extends FList<T> {
|
|||||||
private final CompactModeHandler compactModeHandler = new CompactModeHandler();
|
private final CompactModeHandler compactModeHandler = new CompactModeHandler();
|
||||||
private final List<Integer> selectedIndices = new ArrayList<Integer>();
|
private final List<Integer> selectedIndices = new ArrayList<Integer>();
|
||||||
|
|
||||||
public FChoiceList(Collection<? extends T> items) {
|
public FChoiceList(Iterable<? extends T> items) {
|
||||||
this(items, null);
|
this(items, null);
|
||||||
}
|
}
|
||||||
protected FChoiceList(Collection<? extends T> items, T typeItem) {
|
protected FChoiceList(Iterable<? extends T> items, T typeItem) {
|
||||||
this(items, 0, 1, typeItem);
|
this(items, 0, 1, typeItem);
|
||||||
if (items.size() > 0) {
|
if (getCount() > 0) {
|
||||||
addSelectedIndex(0); //select first item by default
|
addSelectedIndex(0); //select first item by default
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public FChoiceList(Collection<? extends T> items, int minChoices0, int maxChoices0) {
|
public FChoiceList(Iterable<? extends T> items, int minChoices0, int maxChoices0) {
|
||||||
this(items, minChoices0, maxChoices0, null);
|
this(items, minChoices0, maxChoices0, null);
|
||||||
}
|
}
|
||||||
protected FChoiceList(Collection<? extends T> items, int minChoices0, int maxChoices0, T typeItem) {
|
protected FChoiceList(Iterable<? extends T> items, int minChoices0, int maxChoices0, T typeItem) {
|
||||||
super(items);
|
super(items);
|
||||||
minChoices = minChoices0;
|
minChoices = minChoices0;
|
||||||
maxChoices = maxChoices0;
|
maxChoices = maxChoices0;
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ import forge.gauntlet.GauntletData;
|
|||||||
import forge.interfaces.IProgressBar;
|
import forge.interfaces.IProgressBar;
|
||||||
import forge.itemmanager.ItemManagerConfig;
|
import forge.itemmanager.ItemManagerConfig;
|
||||||
import forge.limited.GauntletMini;
|
import forge.limited.GauntletMini;
|
||||||
|
import forge.planarconquest.ConquestController;
|
||||||
|
import forge.planarconquest.ConquestPreferences;
|
||||||
import forge.player.GamePlayerUtil;
|
import forge.player.GamePlayerUtil;
|
||||||
import forge.properties.ForgeConstants;
|
import forge.properties.ForgeConstants;
|
||||||
import forge.properties.ForgePreferences;
|
import forge.properties.ForgePreferences;
|
||||||
@@ -70,6 +72,7 @@ public class FModel {
|
|||||||
private static StaticData magicDb;
|
private static StaticData magicDb;
|
||||||
|
|
||||||
private static QuestPreferences questPreferences;
|
private static QuestPreferences questPreferences;
|
||||||
|
private static ConquestPreferences conquestPreferences;
|
||||||
private static ForgePreferences preferences;
|
private static ForgePreferences preferences;
|
||||||
|
|
||||||
private static Map<GameType, AchievementCollection> achievements;
|
private static Map<GameType, AchievementCollection> achievements;
|
||||||
@@ -79,6 +82,7 @@ public class FModel {
|
|||||||
private static GauntletMini gauntlet;
|
private static GauntletMini gauntlet;
|
||||||
|
|
||||||
private static QuestController quest;
|
private static QuestController quest;
|
||||||
|
private static ConquestController conquest;
|
||||||
private static CardCollections decks;
|
private static CardCollections decks;
|
||||||
|
|
||||||
private static IStorage<CardBlock> blocks;
|
private static IStorage<CardBlock> blocks;
|
||||||
@@ -153,6 +157,7 @@ public class FModel {
|
|||||||
formats = new GameFormat.Collection(new GameFormat.Reader(new File(ForgeConstants.BLOCK_DATA_DIR + "formats.txt")));
|
formats = new GameFormat.Collection(new GameFormat.Reader(new File(ForgeConstants.BLOCK_DATA_DIR + "formats.txt")));
|
||||||
blocks = new StorageBase<CardBlock>("Block definitions", new CardBlock.Reader(ForgeConstants.BLOCK_DATA_DIR + "blocks.txt", magicDb.getEditions()));
|
blocks = new StorageBase<CardBlock>("Block definitions", new CardBlock.Reader(ForgeConstants.BLOCK_DATA_DIR + "blocks.txt", magicDb.getEditions()));
|
||||||
questPreferences = new QuestPreferences();
|
questPreferences = new QuestPreferences();
|
||||||
|
conquestPreferences = new ConquestPreferences();
|
||||||
fantasyBlocks = new StorageBase<CardBlock>("Custom blocks", new CardBlock.Reader(ForgeConstants.BLOCK_DATA_DIR + "fantasyblocks.txt", magicDb.getEditions()));
|
fantasyBlocks = new StorageBase<CardBlock>("Custom blocks", new CardBlock.Reader(ForgeConstants.BLOCK_DATA_DIR + "fantasyblocks.txt", magicDb.getEditions()));
|
||||||
worlds = new StorageBase<QuestWorld>("Quest worlds", new QuestWorld.Reader(ForgeConstants.QUEST_WORLD_DIR + "worlds.txt"));
|
worlds = new StorageBase<QuestWorld>("Quest worlds", new QuestWorld.Reader(ForgeConstants.QUEST_WORLD_DIR + "worlds.txt"));
|
||||||
|
|
||||||
@@ -169,6 +174,7 @@ public class FModel {
|
|||||||
|
|
||||||
decks = new CardCollections();
|
decks = new CardCollections();
|
||||||
quest = new QuestController();
|
quest = new QuestController();
|
||||||
|
conquest = new ConquestController();
|
||||||
|
|
||||||
CardPreferences.load();
|
CardPreferences.load();
|
||||||
DeckPreferences.load();
|
DeckPreferences.load();
|
||||||
@@ -187,7 +193,11 @@ public class FModel {
|
|||||||
public static QuestController getQuest() {
|
public static QuestController getQuest() {
|
||||||
return quest;
|
return quest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ConquestController getConquest() {
|
||||||
|
return conquest;
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean keywordsLoaded = false;
|
private static boolean keywordsLoaded = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -292,12 +302,16 @@ public class FModel {
|
|||||||
|
|
||||||
public static IStorage<CardBlock> getBlocks() {
|
public static IStorage<CardBlock> getBlocks() {
|
||||||
return blocks;
|
return blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static QuestPreferences getQuestPreferences() {
|
public static QuestPreferences getQuestPreferences() {
|
||||||
return questPreferences;
|
return questPreferences;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static ConquestPreferences getConquestPreferences() {
|
||||||
|
return conquestPreferences;
|
||||||
|
}
|
||||||
|
|
||||||
public static GauntletData getGauntletData() {
|
public static GauntletData getGauntletData() {
|
||||||
return gauntletData;
|
return gauntletData;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Nate
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.planarconquest;
|
||||||
|
|
||||||
|
import com.google.common.eventbus.Subscribe;
|
||||||
|
|
||||||
|
import forge.deck.CardPool;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.game.event.GameEvent;
|
||||||
|
import forge.util.storage.IStorage;
|
||||||
|
|
||||||
|
public class ConquestController {
|
||||||
|
private ConquestData model;
|
||||||
|
private CardPool cardPool;
|
||||||
|
private transient IStorage<Deck> decks;
|
||||||
|
|
||||||
|
public ConquestController() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return model == null ? null : model.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardPool getCardPool() {
|
||||||
|
return cardPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IStorage<Deck> getDecks() {
|
||||||
|
return decks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void load(final ConquestData model0) {
|
||||||
|
model = model0;
|
||||||
|
cardPool = model == null ? null : model.getCardPool();
|
||||||
|
decks = model == null ? null : model.getDeckStorage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void save() {
|
||||||
|
if (model != null) {
|
||||||
|
model.saveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Subscribe
|
||||||
|
public void receiveGameEvent(GameEvent ev) { // Receives events only during planar conquest games
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
140
forge-gui/src/main/java/forge/planarconquest/ConquestData.java
Normal file
140
forge-gui/src/main/java/forge/planarconquest/ConquestData.java
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.planarconquest;
|
||||||
|
|
||||||
|
import forge.deck.CardPool;
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.properties.ForgeConstants;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public final class ConquestData {
|
||||||
|
/** Holds the latest version of the Conquest Data. */
|
||||||
|
public static final int CURRENT_VERSION_NUMBER = 0;
|
||||||
|
|
||||||
|
// This field places the version number into QD instance,
|
||||||
|
// but only when the object is created through the constructor
|
||||||
|
// DO NOT RENAME THIS FIELD
|
||||||
|
private int versionNumber = ConquestData.CURRENT_VERSION_NUMBER;
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private int wins, losses;
|
||||||
|
private int winStreakBest = 0;
|
||||||
|
private int winStreakCurrent = 0;
|
||||||
|
private int difficulty;
|
||||||
|
private ConquestPlane startingPlane, currentPlane;
|
||||||
|
private List<PaperCard> commanders = new ArrayList<PaperCard>();
|
||||||
|
|
||||||
|
private final CardPool cardPool = new CardPool();
|
||||||
|
private final HashMap<String, Deck> decks = new HashMap<String, Deck>();
|
||||||
|
|
||||||
|
public ConquestData() { //needed for XML serialization
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConquestData(String name0, int difficulty0, ConquestPlane startingPlane0, PaperCard startingCommander0) {
|
||||||
|
name = name0;
|
||||||
|
difficulty = difficulty0;
|
||||||
|
startingPlane = startingPlane0;
|
||||||
|
currentPlane = startingPlane0;
|
||||||
|
commanders.add(startingCommander0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getDifficulty() {
|
||||||
|
return difficulty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConquestPlane getStartingPlane() {
|
||||||
|
return startingPlane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConquestPlane getCurrentPlane() {
|
||||||
|
return currentPlane;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardPool getCardPool() {
|
||||||
|
return cardPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConquestDeckMap getDeckStorage() {
|
||||||
|
return new ConquestDeckMap(decks);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWin() {
|
||||||
|
wins++;
|
||||||
|
winStreakCurrent++;
|
||||||
|
|
||||||
|
if (winStreakCurrent > winStreakBest) {
|
||||||
|
winStreakBest = winStreakCurrent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLoss() {
|
||||||
|
losses++;
|
||||||
|
winStreakCurrent = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWins() {
|
||||||
|
return wins;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLosses() {
|
||||||
|
return losses;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWinStreakBest() {
|
||||||
|
return winStreakBest;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getWinStreakCurrent() {
|
||||||
|
return winStreakCurrent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// SERIALIZATION - related things
|
||||||
|
// This must be called by XML-serializer via reflection
|
||||||
|
public Object readResolve() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveData() {
|
||||||
|
ConquestDataIO.saveData(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVersionNumber() {
|
||||||
|
return versionNumber;
|
||||||
|
}
|
||||||
|
public void setVersionNumber(final int versionNumber0) {
|
||||||
|
versionNumber = versionNumber0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rename(final String newName) {
|
||||||
|
File newpath = new File(ForgeConstants.CONQUEST_SAVE_DIR, newName + ".dat");
|
||||||
|
File oldpath = new File(ForgeConstants.CONQUEST_SAVE_DIR, name + ".dat");
|
||||||
|
oldpath.renameTo(newpath);
|
||||||
|
|
||||||
|
name = newName;
|
||||||
|
saveData();
|
||||||
|
}
|
||||||
|
}
|
||||||
144
forge-gui/src/main/java/forge/planarconquest/ConquestDataIO.java
Normal file
144
forge-gui/src/main/java/forge/planarconquest/ConquestDataIO.java
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.planarconquest;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.util.zip.GZIPInputStream;
|
||||||
|
import java.util.zip.GZIPOutputStream;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
|
||||||
|
import org.xml.sax.InputSource;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
|
||||||
|
import com.thoughtworks.xstream.XStream;
|
||||||
|
import forge.deck.CardPool;
|
||||||
|
import forge.properties.ForgeConstants;
|
||||||
|
import forge.util.FileUtil;
|
||||||
|
import forge.util.IgnoringXStream;
|
||||||
|
import forge.util.ItemPool;
|
||||||
|
|
||||||
|
public class ConquestDataIO {
|
||||||
|
static {
|
||||||
|
//ensure save directory exists if this class is used
|
||||||
|
FileUtil.ensureDirectoryExists(ForgeConstants.CONQUEST_SAVE_DIR);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static XStream getSerializer(final boolean isIgnoring) {
|
||||||
|
final XStream xStream = isIgnoring ? new IgnoringXStream() : new XStream();
|
||||||
|
xStream.autodetectAnnotations(true);
|
||||||
|
xStream.alias("CardPool", ItemPool.class);
|
||||||
|
xStream.alias("DeckSection", CardPool.class);
|
||||||
|
return xStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ConquestData loadData(final File xmlSaveFile) {
|
||||||
|
try {
|
||||||
|
ConquestData data = null;
|
||||||
|
|
||||||
|
final GZIPInputStream zin = new GZIPInputStream(new FileInputStream(xmlSaveFile));
|
||||||
|
final StringBuilder xml = new StringBuilder();
|
||||||
|
final char[] buf = new char[1024];
|
||||||
|
final InputStreamReader reader = new InputStreamReader(zin);
|
||||||
|
while (reader.ready()) {
|
||||||
|
final int len = reader.read(buf);
|
||||||
|
if (len == -1) {
|
||||||
|
break;
|
||||||
|
} // when end of stream was reached
|
||||||
|
xml.append(buf, 0, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
zin.close();
|
||||||
|
|
||||||
|
String bigXML = xml.toString();
|
||||||
|
data = (ConquestData) ConquestDataIO.getSerializer(true).fromXML(bigXML);
|
||||||
|
|
||||||
|
if (data.getVersionNumber() != ConquestData.CURRENT_VERSION_NUMBER) {
|
||||||
|
try {
|
||||||
|
ConquestDataIO.updateSaveFile(data, bigXML, xmlSaveFile.getName().replace(".dat", ""));
|
||||||
|
}
|
||||||
|
catch (final Exception e) {
|
||||||
|
//BugReporter.reportException(e);
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
catch (final Exception ex) {
|
||||||
|
//BugReporter.reportException(ex, "Error loading Conquest Data");
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateSaveFile(final ConquestData newData, final String input, String filename) throws ParserConfigurationException, SAXException, IOException, IllegalAccessException, NoSuchFieldException {
|
||||||
|
//final DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
|
||||||
|
final InputSource is = new InputSource();
|
||||||
|
is.setCharacterStream(new StringReader(input));
|
||||||
|
//final Document document = builder.parse(is);
|
||||||
|
|
||||||
|
final int saveVersion = newData.getVersionNumber();
|
||||||
|
switch (saveVersion) {
|
||||||
|
// There should be a fall-through between the cases so that each
|
||||||
|
// version's changes get applied progressively
|
||||||
|
case 0:
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// mark the QD as the latest version
|
||||||
|
newData.setVersionNumber(ConquestData.CURRENT_VERSION_NUMBER);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static synchronized void saveData(final ConquestData qd) {
|
||||||
|
try {
|
||||||
|
final XStream xStream = ConquestDataIO.getSerializer(false);
|
||||||
|
|
||||||
|
final File f = new File(ForgeConstants.CONQUEST_SAVE_DIR, qd.getName());
|
||||||
|
ConquestDataIO.savePacked(f + ".dat", xStream, qd);
|
||||||
|
// ConquestDataIO.saveUnpacked(f + ".xml", xStream, qd);
|
||||||
|
}
|
||||||
|
catch (final Exception ex) {
|
||||||
|
//BugReporter.reportException(ex, "Error saving Conquest Data.");
|
||||||
|
throw new RuntimeException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void savePacked(final String f, final XStream xStream, final ConquestData qd) throws IOException {
|
||||||
|
final BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(f));
|
||||||
|
final GZIPOutputStream zout = new GZIPOutputStream(bout);
|
||||||
|
xStream.toXML(qd, zout);
|
||||||
|
zout.flush();
|
||||||
|
zout.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused") // used only for debug purposes
|
||||||
|
private static void saveUnpacked(final String f, final XStream xStream, final ConquestData qd) throws IOException {
|
||||||
|
final BufferedOutputStream boutUnp = new BufferedOutputStream(new FileOutputStream(f));
|
||||||
|
xStream.toXML(qd, boutUnp);
|
||||||
|
boutUnp.flush();
|
||||||
|
boutUnp.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.planarconquest;
|
||||||
|
|
||||||
|
import forge.deck.Deck;
|
||||||
|
import forge.util.storage.StorageBase;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class ConquestDeckMap extends StorageBase<Deck> {
|
||||||
|
public ConquestDeckMap(Map<String, Deck> in) {
|
||||||
|
super("Conquest decks", in);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void add(final Deck deck) {
|
||||||
|
map.put(deck.getName(), deck);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(final String deckName) {
|
||||||
|
map.remove(deckName);
|
||||||
|
}
|
||||||
|
}
|
||||||
329
forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java
Normal file
329
forge-gui/src/main/java/forge/planarconquest/ConquestPlane.java
Normal file
@@ -0,0 +1,329 @@
|
|||||||
|
/*
|
||||||
|
* Forge: Play Magic: the Gathering.
|
||||||
|
* Copyright (C) 2011 Nate
|
||||||
|
*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.planarconquest;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
|
||||||
|
import forge.card.CardEdition;
|
||||||
|
import forge.card.CardRules;
|
||||||
|
import forge.card.CardRulesPredicates;
|
||||||
|
import forge.card.CardEdition.CardInSet;
|
||||||
|
import forge.card.CardType;
|
||||||
|
import forge.card.MagicColor;
|
||||||
|
import forge.deck.CardPool;
|
||||||
|
import forge.item.PaperCard;
|
||||||
|
import forge.model.FModel;
|
||||||
|
import forge.util.FCollection;
|
||||||
|
import forge.util.FCollectionView;
|
||||||
|
|
||||||
|
|
||||||
|
public enum ConquestPlane {
|
||||||
|
Alara("Alara", new String[] {
|
||||||
|
"ALA", "CON", "ARB"
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Azoria("Azoria", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
BolasMeditationRealm("Bolas's Meditation Realm", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Dominaria("Dominaria", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Equilor("Equilor", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Gastal("Gastal", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Innistrad("Innistrad", new String[] {
|
||||||
|
"ISD", "DKA", "AVR"
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Kamigawa("Kamigawa", new String[] {
|
||||||
|
"CHK", "BOK", "SOK"
|
||||||
|
}, new Region[] {
|
||||||
|
new Region("Towabara", "", CardRulesPredicates.hasColorIdentity(MagicColor.WHITE),
|
||||||
|
new String[] { "Towabara", "Plains" }),
|
||||||
|
new Region("Minamo Academy", "", CardRulesPredicates.hasColorIdentity(MagicColor.BLUE),
|
||||||
|
new String[] { "Minamo", "Academy", "Island" }),
|
||||||
|
new Region("Takenuma", "", CardRulesPredicates.hasColorIdentity(MagicColor.BLACK),
|
||||||
|
new String[] { "Takenuma", "Swamp" }),
|
||||||
|
new Region("Sokenzan Mountains", "", CardRulesPredicates.hasColorIdentity(MagicColor.RED),
|
||||||
|
new String[] { "Sokenzan", "Mountain" }),
|
||||||
|
new Region("Jukai Forest", "", CardRulesPredicates.hasColorIdentity(MagicColor.GREEN),
|
||||||
|
new String[] { "Jukai", "Forest" })
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Lorwyn("Lorwyn", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Mercadia("Mercadia", new String[] {
|
||||||
|
"MMQ", "NEM", "PCY"
|
||||||
|
}, new Region[] {
|
||||||
|
new Region("Deepwood", "", CardRulesPredicates.hasCreatureType("Zombie", "Ghoul", "Dryad"),
|
||||||
|
new String[] { }),
|
||||||
|
new Region("Mercadia City", "", CardRulesPredicates.hasCreatureType("Goblin"),
|
||||||
|
new String[] { }),
|
||||||
|
new Region("Rishada", "", CardRulesPredicates.hasCreatureType("Pirate", "Rebel", "Mercenary"),
|
||||||
|
new String[] { }),
|
||||||
|
new Region("Rushwood", "", CardRulesPredicates.hasCreatureType("Beast", "Troll"),
|
||||||
|
new String[] { }),
|
||||||
|
new Region("Saprazzo", "", CardRulesPredicates.hasCreatureType("Merfolk", "Human"),
|
||||||
|
new String[] { })
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Mirrodin("Mirrodin", new String[] {
|
||||||
|
"MRD", "DST", "5DN", "SOM", "MBS", "NPH"
|
||||||
|
}, new Region[] {
|
||||||
|
new Region("Mirrodin's Core", "Mirrodin's Core", null,
|
||||||
|
new String[] { "Core", "Mycosynth", "Memnarch" }),
|
||||||
|
new Region("The Glimmervoid", "Glimmervoid", CardRulesPredicates.hasKeyword("Sunburst"),
|
||||||
|
new String[] { "Glimmervoid" }),
|
||||||
|
new Region("Mephidross", "", CardRulesPredicates.hasColorIdentity(MagicColor.BLACK),
|
||||||
|
new String[] { "Dross", "Mephidross" }),
|
||||||
|
new Region("The Oxidda Chain", "", CardRulesPredicates.hasColorIdentity(MagicColor.RED),
|
||||||
|
new String[] { "Oxidda", "Chain", "Mountain" }),
|
||||||
|
new Region("The Quicksilver Sea", "", CardRulesPredicates.hasColorIdentity(MagicColor.BLUE),
|
||||||
|
new String[] { "Quicksilver", "Sea", "Island" }),
|
||||||
|
new Region("The Razor Fields", "", CardRulesPredicates.hasColorIdentity(MagicColor.WHITE),
|
||||||
|
new String[] { "Razor", "Fields", "Plains" }),
|
||||||
|
new Region("The Tangle", "", CardRulesPredicates.hasColorIdentity(MagicColor.GREEN),
|
||||||
|
new String[] { "Tangle", "Forest" })
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Rabiah("Rabiah", new String[] {
|
||||||
|
"ARN"
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Rath("Rath", new String[] {
|
||||||
|
"TMP", "STH", "EXO"
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Ravnica("Ravnica", new String[] {
|
||||||
|
"RAV", "GPT", "DIS", "RTR", "GTC", "DGM"
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Segovia("Segovia", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
SerraRealm("Serra's Realm", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Shandalar("Shandalar", new String[] {
|
||||||
|
"2ED", "ARN", "ATQ", "3ED", "LEG", "DRK", "4ED"
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Ulgrotha("Ulgrotha", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Theros("Theros", new String[] {
|
||||||
|
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
}),
|
||||||
|
Zendikar("Zendikar", new String[] {
|
||||||
|
"ZEN", "WWK", "ROE"
|
||||||
|
}, new Region[] {
|
||||||
|
|
||||||
|
}, new String[] {
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
private final FCollection<CardEdition> editions = new FCollection<CardEdition>();
|
||||||
|
private final FCollection<Region> regions;
|
||||||
|
private final FCollection<String> bannedCards;
|
||||||
|
private final CardPool cardPool = new CardPool();
|
||||||
|
private final FCollection<PaperCard> commanders = new FCollection<PaperCard>();
|
||||||
|
|
||||||
|
private ConquestPlane(String name0, String[] setCodes0, Region[] regions0, String[] bannedCards0) {
|
||||||
|
name = name0;
|
||||||
|
regions = new FCollection<Region>(regions0);
|
||||||
|
bannedCards = new FCollection<String>(bannedCards0);
|
||||||
|
for (String setCode : setCodes0) {
|
||||||
|
CardEdition edition = FModel.getMagicDb().getEditions().get(setCode);
|
||||||
|
if (edition != null) {
|
||||||
|
editions.add(edition);
|
||||||
|
for (CardInSet card : edition.getCards()) {
|
||||||
|
if (!bannedCards.contains(card.name)) {
|
||||||
|
PaperCard pc = FModel.getMagicDb().getCommonCards().getCard(card.name, setCode);
|
||||||
|
if (pc != null) {
|
||||||
|
CardType type = pc.getRules().getType();
|
||||||
|
if (!type.isBasicLand()) { //don't include basic lands
|
||||||
|
boolean isCommander = type.isLegendary() && type.isCreature();
|
||||||
|
cardPool.add(pc);
|
||||||
|
if (isCommander) {
|
||||||
|
commanders.add(pc);
|
||||||
|
}
|
||||||
|
int count = 0;
|
||||||
|
for (Region region : regions) {
|
||||||
|
if (region.pred.apply(pc)) {
|
||||||
|
region.cardPool.add(pc);
|
||||||
|
if (isCommander) {
|
||||||
|
region.commanders.add(pc);
|
||||||
|
}
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//if card doesn't match any region's predicate,
|
||||||
|
//make card available to all regions
|
||||||
|
if (count == 0) {
|
||||||
|
for (Region region : regions) {
|
||||||
|
region.cardPool.add(pc);
|
||||||
|
if (isCommander) {
|
||||||
|
region.commanders.add(pc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FCollectionView<CardEdition> getEditions() {
|
||||||
|
return editions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FCollectionView<String> getBannedCards() {
|
||||||
|
return bannedCards;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FCollectionView<Region> getRegions() {
|
||||||
|
return regions;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardPool getCardPool() {
|
||||||
|
return cardPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FCollectionView<PaperCard> getCommanders() {
|
||||||
|
return commanders;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Region {
|
||||||
|
private final String name;
|
||||||
|
private final String artCardName;
|
||||||
|
private final Predicate<PaperCard> pred;
|
||||||
|
private final CardPool cardPool = new CardPool();
|
||||||
|
private final FCollection<PaperCard> commanders = new FCollection<PaperCard>();
|
||||||
|
|
||||||
|
private Region(String name0, String artCardName0, final Predicate<CardRules> rulesPred, final String[] keywords) {
|
||||||
|
name = name0;
|
||||||
|
artCardName = artCardName0;
|
||||||
|
|
||||||
|
pred = new Predicate<PaperCard>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(PaperCard pc) {
|
||||||
|
if (rulesPred != null && rulesPred.apply(pc.getRules())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
for (String s : keywords) {
|
||||||
|
if (pc.getName().contains(s)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CardPool getCardPool() {
|
||||||
|
return cardPool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FCollectionView<PaperCard> getCommanders() {
|
||||||
|
return commanders;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* 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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package forge.planarconquest;
|
||||||
|
|
||||||
|
import forge.properties.ForgeConstants;
|
||||||
|
import forge.properties.PreferencesStore;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@SuppressWarnings("serial")
|
||||||
|
public class ConquestPreferences extends PreferencesStore<ConquestPreferences.CQPref> implements Serializable {
|
||||||
|
/**
|
||||||
|
* Preference identifiers, and their default values.
|
||||||
|
*/
|
||||||
|
public static enum CQPref {
|
||||||
|
CURRENT_CONQUEST("DEFAULT");
|
||||||
|
|
||||||
|
private final String strDefaultVal;
|
||||||
|
|
||||||
|
CQPref(final String s0) {
|
||||||
|
this.strDefaultVal = s0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDefault() {
|
||||||
|
return this.strDefaultVal;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static enum DifficultyPrefs {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ConquestPreferences() {
|
||||||
|
super(ForgeConstants.CONQUEST_PREFS_FILE, CQPref.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CQPref[] getEnumValues() {
|
||||||
|
return CQPref.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected CQPref valueOf(String name) {
|
||||||
|
try {
|
||||||
|
return CQPref.valueOf(name);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getPrefDefault(CQPref key) {
|
||||||
|
return key.getDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPref(DifficultyPrefs pref, int difficultyIndex) {
|
||||||
|
String newCQPref = pref.toString();
|
||||||
|
|
||||||
|
switch (difficultyIndex) {
|
||||||
|
case 0:
|
||||||
|
newCQPref += "_EASY";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
newCQPref += "_MEDIUM";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
newCQPref += "_HARD";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
newCQPref += "_EXPERT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
try {
|
||||||
|
throw new Exception();
|
||||||
|
} catch (final Exception e1) {
|
||||||
|
System.err.println("Difficulty index out of bounds: " + difficultyIndex);
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getPref(CQPref.valueOf(newCQPref));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPrefInt(DifficultyPrefs pref, int difficultyIndex) {
|
||||||
|
return Integer.parseInt(this.getPref(pref, difficultyIndex));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDifficulty(int difficultyIndex) {
|
||||||
|
String s;
|
||||||
|
switch (difficultyIndex) {
|
||||||
|
case 1:
|
||||||
|
s = "EASY";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
s = "MEDIUM";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
s = "HARD";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
s = "EXPERT";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
s = "UNKNOWN";
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String validatePreference(CQPref qpref, int val) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,6 +100,7 @@ public final class ForgeConstants {
|
|||||||
|
|
||||||
// data that is only in the profile dirs
|
// data that is only in the profile dirs
|
||||||
public static final String USER_QUEST_DIR = USER_DIR + "quest/";
|
public static final String USER_QUEST_DIR = USER_DIR + "quest/";
|
||||||
|
public static final String USER_CONQUEST_DIR = USER_DIR + "conquest/";
|
||||||
public static final String USER_PREFS_DIR = USER_DIR + "preferences/";
|
public static final String USER_PREFS_DIR = USER_DIR + "preferences/";
|
||||||
public static final String USER_GAMES_DIR = USER_DIR + "games/";
|
public static final String USER_GAMES_DIR = USER_DIR + "games/";
|
||||||
public static final String LOG_FILE = USER_DIR + "forge.log";
|
public static final String LOG_FILE = USER_DIR + "forge.log";
|
||||||
@@ -113,10 +114,12 @@ public final class ForgeConstants {
|
|||||||
public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar/";
|
public static final String DECK_PLANE_DIR = DECK_BASE_DIR + "planar/";
|
||||||
public static final String DECK_COMMANDER_DIR = DECK_BASE_DIR + "commander/";
|
public static final String DECK_COMMANDER_DIR = DECK_BASE_DIR + "commander/";
|
||||||
public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves/";
|
public static final String QUEST_SAVE_DIR = USER_QUEST_DIR + "saves/";
|
||||||
|
public static final String CONQUEST_SAVE_DIR = USER_CONQUEST_DIR + "saves/";
|
||||||
public static final String MAIN_PREFS_FILE = USER_PREFS_DIR + "forge.preferences";
|
public static final String MAIN_PREFS_FILE = USER_PREFS_DIR + "forge.preferences";
|
||||||
public static final String CARD_PREFS_FILE = USER_PREFS_DIR + "card.preferences";
|
public static final String CARD_PREFS_FILE = USER_PREFS_DIR + "card.preferences";
|
||||||
public static final String DECK_PREFS_FILE = USER_PREFS_DIR + "deck.preferences";
|
public static final String DECK_PREFS_FILE = USER_PREFS_DIR + "deck.preferences";
|
||||||
public static final String QUEST_PREFS_FILE = USER_PREFS_DIR + "quest.preferences";
|
public static final String QUEST_PREFS_FILE = USER_PREFS_DIR + "quest.preferences";
|
||||||
|
public static final String CONQUEST_PREFS_FILE = USER_PREFS_DIR + "conquest.preferences";
|
||||||
public static final String ITEM_VIEW_PREFS_FILE = USER_PREFS_DIR + "item_view.preferences";
|
public static final String ITEM_VIEW_PREFS_FILE = USER_PREFS_DIR + "item_view.preferences";
|
||||||
|
|
||||||
// data that has defaults in the program dir but overrides/additions in the user dir
|
// data that has defaults in the program dir but overrides/additions in the user dir
|
||||||
|
|||||||
Reference in New Issue
Block a user