mirror of
https://github.com/Card-Forge/forge.git
synced 2025-11-19 04:08:01 +00:00
Initial checkin for Puzzle Mode
This commit is contained in:
@@ -54,6 +54,7 @@ public class HostedMatch {
|
||||
private Match match;
|
||||
private Game game;
|
||||
private String title;
|
||||
private Runnable startGameHook = null;
|
||||
private final List<PlayerControllerHuman> humanControllers = Lists.newArrayList();
|
||||
private Map<RegisteredPlayer, IGuiGame> guis;
|
||||
private int humanCount;
|
||||
@@ -62,7 +63,10 @@ public class HostedMatch {
|
||||
private final Map<PlayerControllerHuman, NextGameDecision> nextGameDecisions = Maps.newHashMap();
|
||||
private boolean isMatchOver = false;
|
||||
|
||||
public HostedMatch() {
|
||||
public HostedMatch() {}
|
||||
|
||||
public void setStartGameHook(Runnable hook) {
|
||||
startGameHook = hook;
|
||||
}
|
||||
|
||||
private static GameRules getDefaultRules(final GameType gameType) {
|
||||
@@ -216,9 +220,8 @@ public class HostedMatch {
|
||||
playbackControl.setGame(game);
|
||||
game.subscribeToEvents(playbackControl);
|
||||
}
|
||||
|
||||
// Actually start the game!
|
||||
match.startGame(game);
|
||||
match.startGame(game, startGameHook);
|
||||
|
||||
// After game is over...
|
||||
isMatchOver = match.isMatchOver();
|
||||
|
||||
@@ -62,6 +62,8 @@ public final class ForgeConstants {
|
||||
public static final String MUSIC_DIR = RES_DIR + "music" + PATH_SEPARATOR;
|
||||
public static final String LANG_DIR = RES_DIR + "languages" + PATH_SEPARATOR;
|
||||
public static final String EFFECTS_DIR = RES_DIR + "effects" + PATH_SEPARATOR;
|
||||
public static final String PUZZLE_DIR = RES_DIR + "puzzle" + PATH_SEPARATOR;
|
||||
|
||||
|
||||
private static final String QUEST_DIR = RES_DIR + "quest" + PATH_SEPARATOR;
|
||||
public static final String QUEST_WORLD_DIR = QUEST_DIR + "world" + PATH_SEPARATOR;
|
||||
|
||||
@@ -108,6 +108,7 @@ public class ForgePreferences extends PreferencesStore<ForgePreferences.FPref> {
|
||||
SUBMENU_ONLINE ("false"),
|
||||
SUBMENU_GAUNTLET ("false"),
|
||||
SUBMENU_QUEST ("false"),
|
||||
SUBMENU_PUZZLE("false"),
|
||||
SUBMENU_SETTINGS ("false"),
|
||||
SUBMENU_UTILITIES ("false"),
|
||||
|
||||
|
||||
104
forge-gui/src/main/java/forge/puzzle/Puzzle.java
Normal file
104
forge-gui/src/main/java/forge/puzzle/Puzzle.java
Normal file
@@ -0,0 +1,104 @@
|
||||
package forge.puzzle;
|
||||
|
||||
import forge.ai.GameState;
|
||||
import forge.game.Game;
|
||||
import forge.game.ability.AbilityFactory;
|
||||
import forge.game.card.Card;
|
||||
import forge.game.player.Player;
|
||||
import forge.game.trigger.Trigger;
|
||||
import forge.game.trigger.TriggerHandler;
|
||||
import forge.game.zone.PlayerZone;
|
||||
import forge.game.zone.ZoneType;
|
||||
import forge.item.IPaperCard;
|
||||
import forge.item.InventoryItem;
|
||||
import forge.model.FModel;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class Puzzle extends GameState implements InventoryItem {
|
||||
String name;
|
||||
String goal;
|
||||
String url;
|
||||
int turns;
|
||||
|
||||
public Puzzle(Map<String, List<String>> puzzleLines) {
|
||||
loadMetaData(puzzleLines.get("metadata"));
|
||||
loadGameState(puzzleLines.get("state"));
|
||||
// Generate goal enforcement
|
||||
}
|
||||
|
||||
private void loadMetaData(List<String> metadataLines) {
|
||||
for(String line : metadataLines) {
|
||||
String[] split = line.split(":");
|
||||
if ("Name".equalsIgnoreCase(split[0])) {
|
||||
this.name = split[1];
|
||||
} else if ("Goal".equalsIgnoreCase(split[0])) {
|
||||
this.goal = split[1];
|
||||
} else if ("Url".equalsIgnoreCase(split[0])) {
|
||||
this.url = split[1];
|
||||
} else if ("Turns".equalsIgnoreCase(split[0])) {
|
||||
this.turns = Integer.parseInt(split[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void loadGameState(List<String> stateLines) {
|
||||
this.parse(stateLines);
|
||||
}
|
||||
|
||||
public IPaperCard getPaperCard(final String cardName) {
|
||||
return FModel.getMagicDb().getCommonCards().getCard(cardName);
|
||||
}
|
||||
|
||||
public void addGoalEnforcement(Game game) {
|
||||
Player human = null;
|
||||
for(Player p : game.getPlayers()) {
|
||||
if (p.getController().isGuiPlayer()) {
|
||||
human = p;
|
||||
}
|
||||
}
|
||||
|
||||
Card goalCard = new Card(-1, game);
|
||||
|
||||
goalCard.setOwner(human);
|
||||
goalCard.setImageKey("t:puzzle");
|
||||
goalCard.setName("Puzzle Goal");
|
||||
goalCard.addType("Effect");
|
||||
|
||||
{
|
||||
final String loseTrig = "Mode$ Phase | Phase$ Cleanup | TriggerZones$ Command | Static$ True | " +
|
||||
"ValidPlayer$ You | TriggerDescription$ At the beginning of your cleanup step, you lose the game.";
|
||||
final String loseEff = "DB$ LosesGame | Defined$ You";
|
||||
|
||||
final Trigger loseTrigger = TriggerHandler.parseTrigger(loseTrig, goalCard, true);
|
||||
|
||||
loseTrigger.setOverridingAbility(AbilityFactory.getAbility(loseEff, goalCard));
|
||||
goalCard.addTrigger(loseTrigger);
|
||||
}
|
||||
human.getZone(ZoneType.Command).add(goalCard);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyGameOnThread(final Game game) {
|
||||
super.applyGameOnThread(game);
|
||||
addGoalEnforcement(game);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getItemType() {
|
||||
return "Puzzle";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getImageKey(boolean altState) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toString() { return name; }
|
||||
}
|
||||
50
forge-gui/src/main/java/forge/puzzle/PuzzleIO.java
Normal file
50
forge-gui/src/main/java/forge/puzzle/PuzzleIO.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package forge.puzzle;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import forge.properties.ForgeConstants;
|
||||
import forge.util.FileSection;
|
||||
import forge.util.FileUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class PuzzleIO {
|
||||
|
||||
public static final String TXF_PROMPT = "[New Puzzle]";
|
||||
public static final String SUFFIX_DATA = ".pzl";
|
||||
|
||||
public static ArrayList<Puzzle> loadPuzzles() {
|
||||
String[] pList;
|
||||
// get list of custom draft files
|
||||
final File pFolder = new File(ForgeConstants.PUZZLE_DIR);
|
||||
if (!pFolder.exists()) {
|
||||
throw new RuntimeException("Puzzles : folder not found -- folder is " + pFolder.getAbsolutePath());
|
||||
}
|
||||
|
||||
if (!pFolder.isDirectory()) {
|
||||
throw new RuntimeException("Puzzles : not a folder -- " + pFolder.getAbsolutePath());
|
||||
}
|
||||
|
||||
pList = pFolder.list();
|
||||
|
||||
ArrayList<Puzzle> puzzles = Lists.newArrayList();
|
||||
for (final String element : pList) {
|
||||
if (element.endsWith(SUFFIX_DATA)) {
|
||||
final List<String> pfData = FileUtil.readFile(ForgeConstants.PUZZLE_DIR + element);
|
||||
puzzles.add(new Puzzle(parsePuzzleSections(pfData)));
|
||||
}
|
||||
}
|
||||
return puzzles;
|
||||
}
|
||||
|
||||
public static final Map<String, List<String>> parsePuzzleSections(List<String> pfData) {
|
||||
return FileSection.parseSections(pfData);
|
||||
}
|
||||
|
||||
|
||||
public static File getPuzzleFile(final String name) {
|
||||
return new File(ForgeConstants.PUZZLE_DIR, name + SUFFIX_DATA);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user