Files
Jander_Semester2/Semesterprojekt/src/main/java/thb/jeanluc/adventure/App.java
2026-06-01 23:08:27 +02:00

148 lines
6.0 KiB
Java

package thb.jeanluc.adventure;
import lombok.extern.slf4j.Slf4j;
import thb.jeanluc.adventure.command.CommandParser;
import thb.jeanluc.adventure.command.CommandRegistry;
import thb.jeanluc.adventure.command.impl.DropCommand;
import thb.jeanluc.adventure.command.impl.ExamineCommand;
import thb.jeanluc.adventure.command.impl.GiveCommand;
import thb.jeanluc.adventure.command.impl.GoCommand;
import thb.jeanluc.adventure.command.impl.HelpCommand;
import thb.jeanluc.adventure.command.impl.InventoryCommand;
import thb.jeanluc.adventure.command.impl.LookCommand;
import thb.jeanluc.adventure.command.impl.MapCommand;
import thb.jeanluc.adventure.command.impl.MenuCommand;
import thb.jeanluc.adventure.command.impl.QuestsCommand;
import thb.jeanluc.adventure.command.impl.ReadCommand;
import thb.jeanluc.adventure.command.impl.SaveCommand;
import thb.jeanluc.adventure.command.impl.TakeCommand;
import thb.jeanluc.adventure.command.impl.TalkCommand;
import thb.jeanluc.adventure.command.impl.UseCommand;
import thb.jeanluc.adventure.game.Game;
import thb.jeanluc.adventure.game.GameContext;
import thb.jeanluc.adventure.game.GameSession;
import thb.jeanluc.adventure.game.TutorialGuide;
import thb.jeanluc.adventure.io.ConsoleIO;
import thb.jeanluc.adventure.io.GameIO;
import thb.jeanluc.adventure.io.text.Banner;
import thb.jeanluc.adventure.loader.TutorialLoader;
import thb.jeanluc.adventure.loader.WorldLoader;
import thb.jeanluc.adventure.menu.MainMenu;
import thb.jeanluc.adventure.menu.SettingsMenu;
import thb.jeanluc.adventure.model.Tutorial;
import thb.jeanluc.adventure.save.SaveException;
import thb.jeanluc.adventure.save.SaveService;
import thb.jeanluc.adventure.save.SaveSlotInfo;
import thb.jeanluc.adventure.save.Settings;
import thb.jeanluc.adventure.save.SettingsStore;
import java.util.List;
/**
* Console entry point. Loads settings, then runs the main-menu shell loop:
* New Game / Load / Settings / Quit. Each game runs the shared {@link Game}
* loop and returns here when the player saves-and-exits, reaches an ending,
* or input ends. Shared by console and GUI via {@link #run(GameIO)}.
*/
@Slf4j
public final class App {
private App() {
}
/** Standard JVM entry point. @param args ignored */
public static void main(String[] args) {
GameIO io = new ConsoleIO();
try {
run(io);
} catch (RuntimeException e) {
log.error("Fatal error during game startup", e);
io.write("Fatal error: " + e.getMessage());
System.exit(1);
}
}
/** Runs the menu shell on the given IO until the player quits. */
public static void run(GameIO io) {
SaveService saves = new SaveService();
SettingsStore settingsStore = new SettingsStore();
Settings settings = settingsStore.load();
SettingsMenu.apply(settings, io);
boolean running = true;
while (running) {
switch (MainMenu.show(io)) {
case NEW_GAME -> play(io, saves, newSession(io), true);
case LOAD -> {
SaveSlotInfo slot = MainMenu.pickSlot(io, saves);
if (slot != null) {
try {
play(io, saves, saves.load(slot.slug()), false);
} catch (SaveException e) {
io.write("Could not load: " + e.getUserMessage());
}
}
}
case SETTINGS -> settings = SettingsMenu.show(io, settings, settingsStore);
case QUIT -> running = false;
}
}
io.write("Farewell.");
}
/** Loads a fresh world and binds it to a newly named session. */
private static GameSession newSession(GameIO io) {
WorldLoader.LoadResult loaded = new WorldLoader().load();
String name = MainMenu.promptName(io, "Manor");
return new GameSession(loaded.world(), loaded.player(), name);
}
/** Builds the registry, runs one game to completion, autosaving to its slot. */
private static void play(GameIO io, SaveService saves, GameSession session, boolean withTutorial) {
GameContext ctx = new GameContext(session, io);
ctx.setSaveCallback(() -> {
try {
saves.save(session);
} catch (SaveException e) {
log.warn("Autosave failed", e);
}
});
CommandRegistry registry = new CommandRegistry();
registry.register(new GoCommand(), "go", "move", "walk");
registry.register(new LookCommand(), "look", "l");
registry.register(new InventoryCommand(), "inventory", "inv", "i");
registry.register(new TakeCommand(), "take", "pick", "get");
registry.register(new DropCommand(), "drop", "put");
registry.register(new UseCommand(), "use");
registry.register(new ReadCommand(), "read");
registry.register(new ExamineCommand(), "examine", "x", "inspect");
registry.register(new MapCommand(), "map", "m");
registry.register(new QuestsCommand(), "quests", "log", "journal");
registry.register(new TalkCommand(), "talk", "speak");
registry.register(new GiveCommand(), "give");
registry.register(new SaveCommand(saves), "save");
Game game = new Game(ctx, registry, new CommandParser());
MenuCommand menu = new MenuCommand(saves);
menu.bind(game);
registry.register(menu, "menu", "quit", "exit");
registry.register(new HelpCommand(registry), "help", "?");
if (withTutorial) {
Tutorial tutorial = new TutorialLoader().load();
if (!tutorial.isEmpty()) {
game.setTutorialGuide(new TutorialGuide(tutorial, registry));
}
}
io.print(Banner.welcome(session.getWorld().getTitle()));
io.write(session.getWorld().getWelcomeMessage());
new LookCommand().execute(ctx, List.of());
game.run();
io.setMusic(null); // fade music out when returning to the menu
}
}