package org.mafagafogigante.dungeon.commands; import org.mafagafogigante.dungeon.achievements.Achievement; import org.mafagafogigante.dungeon.achievements.AchievementStoreFactory; import org.mafagafogigante.dungeon.achievements.AchievementTracker; import org.mafagafogigante.dungeon.achievements.AchievementTrackerWriter; import org.mafagafogigante.dungeon.date.Date; import org.mafagafogigante.dungeon.entity.creatures.Creature; import org.mafagafogigante.dungeon.entity.creatures.Hero; import org.mafagafogigante.dungeon.entity.items.CreatureInventory.SimulationResult; import org.mafagafogigante.dungeon.entity.items.Item; import org.mafagafogigante.dungeon.game.DungeonString; import org.mafagafogigante.dungeon.game.Engine; import org.mafagafogigante.dungeon.game.Game; import org.mafagafogigante.dungeon.game.GameState; import org.mafagafogigante.dungeon.game.Id; import org.mafagafogigante.dungeon.game.Location; import org.mafagafogigante.dungeon.game.LocationPreset; import org.mafagafogigante.dungeon.game.LocationPresetStore; import org.mafagafogigante.dungeon.game.Point; import org.mafagafogigante.dungeon.game.Random; import org.mafagafogigante.dungeon.game.World; import org.mafagafogigante.dungeon.gui.WritingSpecifications; import org.mafagafogigante.dungeon.io.Loader; import org.mafagafogigante.dungeon.io.PoemWriter; import org.mafagafogigante.dungeon.io.SavesTableWriter; import org.mafagafogigante.dungeon.io.Version; import org.mafagafogigante.dungeon.io.Writer; import org.mafagafogigante.dungeon.map.WorldMapWriter; import org.mafagafogigante.dungeon.stats.CauseOfDeath; import org.mafagafogigante.dungeon.stats.ExplorationStatistics; import org.mafagafogigante.dungeon.util.CounterMap; import org.mafagafogigante.dungeon.util.Messenger; import org.mafagafogigante.dungeon.util.SystemInformation; import org.mafagafogigante.dungeon.util.Table; import org.mafagafogigante.dungeon.util.Tutorial; import org.mafagafogigante.dungeon.util.library.Libraries; import org.mafagafogigante.dungeon.wiki.WikiSearcher; import org.apache.commons.lang3.StringUtils; import org.jetbrains.annotations.NotNull; import java.awt.Color; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Locale; import java.util.Map; final class CommandSets { private static final Map<String, CommandSet> commandSetMap = initializeCommandSetMap(); private CommandSets() { throw new AssertionError(); } @NotNull private static Map<String, CommandSet> initializeCommandSetMap() { Map<String, CommandSet> map = new HashMap<>(); map.put("default", initializeDefaultCommandSet()); map.put("extra", initializeExtraCommandSet()); map.put("debug", initializeDebugCommandSet()); return map; } private static CommandSet initializeDefaultCommandSet() { CommandSet commandSet = CommandSet.emptyCommandSet(); // Respect the alphabetical ordering of the Command names. commandSet.addCommand(new Command("achievements", "Displays the already unlocked achievements.") { @Override public void execute(@NotNull String[] arguments) { AchievementTrackerWriter.parseCommand(arguments); } }); commandSet.addCommand(new Command("age", "Displays the character's age.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().printAge(); } }); commandSet.addCommand(new Command("cast", "Casts a spell.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().getSpellcaster().parseCast(arguments); } }); commandSet.addCommand(new Command("destroy", "Destroys items on the ground.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().destroyItems(arguments); } }); commandSet.addCommand(new Command("drop", "Drops the specified items.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().dropItems(arguments); } }); commandSet.addCommand(new Command("drink", "Drinks an item.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().drinkItem(arguments); } }); commandSet.addCommand(new Command("eat", "Eats an item.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().eatItem(arguments); } }); commandSet.addCommand(new Command("equip", "Equips the specified item.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().parseEquip(arguments); } }); commandSet.addCommand(new Command("exit", "Exits the game.") { @Override public void execute(@NotNull String[] arguments) { Game.exit(); } }); commandSet.addCommand(new Command("go", "Makes the character move in the specified direction.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().walk(arguments); } }); commandSet.addCommand(new Command("items", "Lists the items in the character's inventory.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().writeInventory(); } }); commandSet.addCommand(new Command("kill", "Attacks the target chosen by the player.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().attackTarget(arguments); } }); commandSet.addCommand(new Command("load", "Loads a saved game.") { @Override public void execute(@NotNull String[] arguments) { GameState loadedGameState = Loader.parseLoadCommand(arguments); if (loadedGameState != null) { Game.unsetGameState(); Game.setGameState(loadedGameState); } } }); commandSet.addCommand(new Command("look", "Describes what the character can see.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().look(); } }); commandSet.addCommand(new Command("map", "Shows a map of your surroundings.") { @Override public void execute(@NotNull String[] arguments) { WorldMapWriter.writeMap(); } }); commandSet.addCommand(new Command("milk", "Attempts to milk a creature.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().parseMilk(arguments); } }); commandSet.addCommand(new Command("new", "Starts a new game.") { @Override public void execute(@NotNull String[] arguments) { Game.unsetGameState(); Game.setGameState(Loader.newGame()); } }); commandSet.addCommand(new Command("pick", "Attempts to pick up items from the current location.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().pickItems(arguments); } }); commandSet.addCommand(new Command("read", "Reads the specified item.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().readItem(arguments); } }); commandSet.addCommand(new Command("rest", "Rests until healing about three fifths of the character's health.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().rest(); } }); commandSet.addCommand(new Command("save", "Saves the game.") { @Override public void execute(@NotNull String[] arguments) { Loader.saveGame(Game.getGameState(), arguments); } }); commandSet.addCommand(new Command("saves", "Displays a table with all the save files.") { @Override public void execute(@NotNull String[] arguments) { SavesTableWriter.writeSavesFolderTable(); } }); commandSet.addCommand(new Command("sleep", "Sleeps until the sun rises.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().sleep(); } }); commandSet.addCommand(new Command("spells", "Lists all the spells known by the character.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().writeSpellList(); } }); commandSet.addCommand(new Command("status", "Displays the character's status.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().printAllStatus(); } }); commandSet.addCommand(new Command("time", "Displays what the character knows about the current time.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().readTime(); } }); commandSet.addCommand(new Command("tutorial", "Displays the tutorial.") { @Override public void execute(@NotNull String[] arguments) { Writer.write(new Tutorial(), new WritingSpecifications(false, 0)); } }); commandSet.addCommand(new Command("unequip", "Unequips the currently equipped item.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getHero().unequipWeapon(); } }); commandSet.addCommand(new Command("wiki", "Searches the wiki for an article.") { @Override public void execute(@NotNull String[] arguments) { WikiSearcher.search(arguments); } }); return commandSet; } private static CommandSet initializeExtraCommandSet() { CommandSet commandSet = CommandSet.emptyCommandSet(); commandSet.addCommand(new Command("text", "Throws an enormous amount of colored text on the screen.") { @Override public void execute(@NotNull String[] arguments) { List<String> alphabet = Arrays.asList("abcdefghijklmnopqrstuvwxyz".split("")); DungeonString dungeonString = new DungeonString(); for (int i = 0; i < 10000; i++) { dungeonString.setColor(new Color(Random.nextInteger(256), Random.nextInteger(256), Random.nextInteger(256))); dungeonString.append(Random.select(alphabet)); } Writer.write(dungeonString); } }); commandSet.addCommand(new Command("hint", "Displays a random hint of the game.") { @Override public void execute(@NotNull String[] arguments) { Writer.write(Libraries.getHintLibrary().next()); } }); commandSet.addCommand(new Command("poem", "Prints a poem from the poem library.") { @Override public void execute(@NotNull String[] arguments) { PoemWriter.parsePoemCommand(arguments); } }); commandSet.addCommand(new Command("statistics", "Displays all available game statistics.") { @Override public void execute(@NotNull String[] arguments) { Game.getGameState().getStatistics().writeStatistics(); } }); commandSet.addCommand(new Command("system", "Displays information about the underlying system.") { @Override public void execute(@NotNull String[] arguments) { Writer.write(new SystemInformation()); } }); commandSet.addCommand(new Command("version", "Displays the game version.") { @Override public void execute(@NotNull String[] arguments) { Writer.write("Dungeon version " + new Version() + "."); } }); return commandSet; } private static CommandSet initializeDebugCommandSet() { CommandSet commandSet = CommandSet.emptyCommandSet(); commandSet.addCommand(new Command("achievements", "Writes the achievements you have not yet unlocked.") { @Override public void execute(@NotNull String[] arguments) { AchievementTracker tracker = Game.getGameState().getHero().getAchievementTracker(); List<Achievement> notYetUnlockedAchievementList = new ArrayList<>(); for (Achievement achievement : AchievementStoreFactory.getDefaultStore().getAchievements()) { if (tracker.hasNotBeenUnlocked(achievement)) { notYetUnlockedAchievementList.add(achievement); } } if (notYetUnlockedAchievementList.isEmpty()) { Writer.write("All achievements have been unlocked."); } else { Collections.sort(notYetUnlockedAchievementList, new Comparator<Achievement>() { @Override public int compare(Achievement o1, Achievement o2) { return o1.getName().compareTo(o2.getName()); } }); for (Achievement achievement : notYetUnlockedAchievementList) { Writer.write(String.format("%s : %s", achievement.getName(), achievement.getInfo())); } } } }); commandSet.addCommand(new Command("exploration", "Writes statistics about your exploration.") { @Override public void execute(@NotNull String[] arguments) { ExplorationStatistics explorationStatistics = Game.getGameState().getStatistics().getExplorationStatistics(); Table table = new Table("Name", "Kills", "Visited so far", "Maximum number of visits"); for (LocationPreset preset : LocationPresetStore.getDefaultLocationPresetStore().getAllPresets()) { String name = preset.getName().getSingular(); String kills = String.valueOf(explorationStatistics.getKillCount(preset.getId())); String visitedSoFar = String.valueOf(explorationStatistics.getVisitedLocations(preset.getId())); String maximumNumberOfVisits = String.valueOf(explorationStatistics.getMaximumNumberOfVisits(preset.getId())); table.insertRow(name, kills, visitedSoFar, maximumNumberOfVisits); } Writer.write(table); } }); commandSet.addCommand(new Command("kills", "Writes statistics about your killings.") { @Override public void execute(@NotNull String[] arguments) { CounterMap<CauseOfDeath> map = Game.getGameState().getStatistics().getBattleStatistics().getKillsByCauseOfDeath(); if (map.isNotEmpty()) { Table table = new Table("Type", "Count"); for (CauseOfDeath causeOfDeath : map.keySet()) { table.insertRow(causeOfDeath.toString(), String.valueOf(map.getCounter(causeOfDeath))); } Writer.write(table); } else { Writer.write("You haven't killed anything yet. Go kill something!"); } } }); commandSet.addCommand(new Command("location", "Writes information about the current location.") { @Override public void execute(@NotNull String[] arguments) { final int width = 40; // The width of the row's "tag". Location heroLocation = Game.getGameState().getHero().getLocation(); Point heroPosition = heroLocation.getPoint(); DungeonString dungeonString = new DungeonString(); dungeonString.append(StringUtils.rightPad("Point:", width)); dungeonString.append(heroPosition.toString()); dungeonString.append("\n"); dungeonString.append(StringUtils.rightPad("Creatures (" + heroLocation.getCreatureCount() + "):", width)); dungeonString.append("\n"); for (Creature creature : heroLocation.getCreatures()) { dungeonString.append(" " + creature.getName()); dungeonString.append("\n"); } if (!heroLocation.getItemList().isEmpty()) { dungeonString.append(StringUtils.rightPad("Items (" + heroLocation.getItemList().size() + "):", width)); dungeonString.append("\n"); for (Item item : heroLocation.getItemList()) { dungeonString.append(" " + item.getQualifiedName()); dungeonString.append("\n"); } } else { dungeonString.append("No items.\n"); } dungeonString.append(StringUtils.rightPad("Luminosity:", width)); dungeonString.append(heroLocation.getLuminosity().toPercentage().toString()); dungeonString.append("\n"); dungeonString.append(StringUtils.rightPad("Permittivity:", width)); dungeonString.append(heroLocation.getLightPermittivity().toString()); dungeonString.append("\n"); dungeonString.append(StringUtils.rightPad("Blocked Entrances:", width)); dungeonString.append(heroLocation.getBlockedEntrances().toString()); dungeonString.append("\n"); Writer.write(dungeonString); } }); commandSet.addCommand(new Command("map", "Produces a map as complete as possible.") { @Override public void execute(@NotNull String[] arguments) { WorldMapWriter.writeDebugMap(); } }); commandSet.addCommand(new Command("give", "Gives items to the character.") { @Override public void execute(@NotNull String[] arguments) { if (arguments.length != 0) { World world = Game.getGameState().getWorld(); Date date = world.getWorldDate(); try { Id id = new Id(arguments[0].toUpperCase(Locale.ENGLISH)); if (world.getItemFactory().canMakeItem(id)) { Item item = world.getItemFactory().makeItem(id, date); Writer.write("Item successfully created."); Hero hero = Game.getGameState().getHero(); if (hero.getInventory().simulateItemAddition(item) == SimulationResult.SUCCESSFUL) { hero.addItem(item); } else { hero.getLocation().addItem(item); Writer.write("Item could not be added to your inventory. Thus, it was added to the current location."); } Engine.refresh(); // Set the game state to unsaved after adding an item to the world. } else { Writer.write("Item could not be created due to a restriction."); } } catch (IllegalArgumentException invalidPreset) { Writer.write("Item could not be created."); } } else { Messenger.printMissingArgumentsMessage(); } } }); commandSet.addCommand(new Command("saved", "Tests if the game is saved or not.") { @Override public void execute(@NotNull String[] arguments) { if (Game.getGameState().isSaved()) { Writer.write("The game is saved."); } else { Writer.write("This game state is not saved."); } } }); commandSet.addCommand(new Command("spawn", "Spawns a creature.") { @Override public void execute(@NotNull String[] arguments) { if (arguments.length != 0) { for (String argument : arguments) { Id givenId = new Id(argument.toUpperCase(Locale.ENGLISH)); World world = Game.getGameState().getWorld(); Creature creature = world.getCreatureFactory().makeCreature(givenId, world); if (creature != null) { Game.getGameState().getHero().getLocation().addCreature(creature); Writer.write("Spawned a " + creature.getName() + "."); Engine.refresh(); // Set the game state to unsaved after adding a creature to the world. } else { Writer.write(givenId + " does not match any known creature."); } } } else { Messenger.printMissingArgumentsMessage(); } } }); commandSet.addCommand(new Command("time", "Writes information about the current time.") { @Override public void execute(@NotNull String[] arguments) { Writer.write(Game.getGameState().getWorld().getWorldDate().toString()); } }); commandSet.addCommand(new Command("wait", "Makes time pass.") { @Override public void execute(@NotNull String[] arguments) { DebugWaitParser.parseDebugWait(arguments); } }); return commandSet; } static boolean hasCommandSet(String identifier) { return commandSetMap.containsKey(identifier); } static CommandSet getCommandSet(String identifier) { return commandSetMap.get(identifier); } }