Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Should support basic scripting #399

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion checkstyle.xml
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@
<property name="allowMissingParamTags" value="true"/>
<property name="allowMissingThrowsTags" value="true"/>
<property name="allowMissingReturnTag" value="true"/>
<property name="minLineCount" value="2"/>
<property name="minLineCount" value="8"/>
<property name="allowedAnnotations" value="Override, Test"/>
<property name="allowThrowsTagsForSubclasses" value="true"/>
</module>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ public List<Achievement> getAchievements() {
*/
public void addAchievement(Achievement achievement) {
if (locked) {
throw new IllegalStateException("this AchievementStore is locked");
throw new IllegalStateException("This AchievementStore is locked.");
}
if (registeredIds.contains(achievement.getId())) {
throw new IllegalArgumentException("there is already an Achievement with the id " + achievement.getId());
throw new IllegalArgumentException("There is already an Achievement with the id " + achievement.getId() + ".");
}
registeredIds.add(achievement.getId());
achievements.add(achievement);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,10 @@
*/
public class AchievementStoreFactory {

private static volatile AchievementStore defaultStore;

private AchievementStoreFactory() {
throw new AssertionError(); // Shouldn't be instantiated.
}

/**
* Makes a locked AchievementStore with the specified Achievements.
*/
public static AchievementStore makeAchievementStore(Collection<Achievement> achievements) {
public AchievementStore makeAchievementStore(Collection<Achievement> achievements) {
AchievementStore achievementStore = new AchievementStore();
for (Achievement achievement : achievements) {
achievementStore.addAchievement(achievement);
Expand All @@ -42,26 +36,19 @@ public static AchievementStore makeAchievementStore(Collection<Achievement> achi
/**
* Retrieves the default AchievementStore of the application.
*/
public static AchievementStore getDefaultStore() {
if (defaultStore == null) {
synchronized (AchievementStoreFactory.class) {
if (defaultStore == null) {
AchievementStore achievementStore = makeDefaultStore();
achievementStore.lock();
defaultStore = achievementStore;
}
}
}
return defaultStore;
public AchievementStore getDefaultStore() {
AchievementStore achievementStore = makeDefaultStore();
achievementStore.lock();
return achievementStore;
}

private static AchievementStore makeDefaultStore() {
private AchievementStore makeDefaultStore() {
AchievementStore store = new AchievementStore();
loadAchievements(store);
return store;
}

private static CounterMap<Id> idCounterMapFromJsonObject(JsonObject jsonObject) {
private CounterMap<Id> idCounterMapFromJsonObject(JsonObject jsonObject) {
CounterMap<Id> counterMap = new CounterMap<>();
for (Member member : jsonObject) {
counterMap.incrementCounter(new Id(member.getName()), member.getValue().asInt());
Expand All @@ -74,7 +61,7 @@ private static CounterMap<Id> idCounterMapFromJsonObject(JsonObject jsonObject)
*
* <p>Throws an IllegalStateException if the AchievementStore is not empty when this method is called
*/
private static void loadAchievements(AchievementStore store) {
private void loadAchievements(AchievementStore store) {
if (!store.getAchievements().isEmpty()) {
throw new IllegalStateException("called loadAchievements on a not empty AchievementStore");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public void update(AchievementStore achievementStore, Date date) {
}
}
if (dungeonString.getLength() != 0) {
Writer.write(dungeonString);
Writer.getDefaultWriter().write(dungeonString);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,19 +65,19 @@ private static void writeAchievementTracker(AchievementTracker tracker, Comparat
string.setColor(Color.YELLOW);
string.append(String.format(" %s%n", unlockedAchievement.getInfo()));
}
int total = AchievementStoreFactory.getDefaultStore().getAchievements().size();
int total = new AchievementStoreFactory().getDefaultStore().getAchievements().size();
string.setColor(Color.CYAN);
string.append(String.format("Progress: %d/%d", tracker.getUnlockedCount(), total));
Writer.write(string);
string.append(String.format("Unlocked %d out of %d.", tracker.getUnlockedCount(), total));
Writer.getDefaultWriter().write(string);
}

/**
* Writes a listing of valid UnlockedAchievement orderings to the screen.
*/
private static void writeValidOrderings() {
Writer.write("Valid orderings:");
Writer.getDefaultWriter().write("Valid orderings:");
for (String comparatorName : UnlockedAchievementComparators.getComparatorMap().keySet()) {
Writer.write(" " + comparatorName);
Writer.getDefaultWriter().write(" " + comparatorName);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public void execute(@NotNull String[] arguments) {
}
}
if (count == 0 && filter != null) {
Writer.write("No command starts with '" + filter + "'.");
Writer.getDefaultWriter().write("No command starts with '" + filter + "'.");
} else {
if (count > 1) {
dungeonString.append("\nListed ");
Expand All @@ -55,7 +55,7 @@ public void execute(@NotNull String[] arguments) {
dungeonString.append("\nYou can filter the output of this command by typing the beginning of a command.");
}
}
Writer.write(dungeonString);
Writer.getDefaultWriter().write(dungeonString);
}
}
});
Expand Down
106 changes: 84 additions & 22 deletions src/main/java/org/mafagafogigante/dungeon/commands/CommandSets.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
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.ColoredString;
import org.mafagafogigante.dungeon.game.DungeonString;
import org.mafagafogigante.dungeon.game.Engine;
import org.mafagafogigante.dungeon.game.Game;
Expand All @@ -20,22 +21,27 @@
import org.mafagafogigante.dungeon.game.Point;
import org.mafagafogigante.dungeon.game.Random;
import org.mafagafogigante.dungeon.game.World;
import org.mafagafogigante.dungeon.game.Writable;
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.scripts.CommandExecutor;
import org.mafagafogigante.dungeon.scripts.ScriptGroup;
import org.mafagafogigante.dungeon.scripts.ScriptGroupFactory;
import org.mafagafogigante.dungeon.scripts.ScriptIdentifier;
import org.mafagafogigante.dungeon.stats.CauseOfDeath;
import org.mafagafogigante.dungeon.stats.ExplorationStatistics;
import org.mafagafogigante.dungeon.util.ColumnAlignment;
import org.mafagafogigante.dungeon.util.CounterMap;
import org.mafagafogigante.dungeon.util.Messenger;
import org.mafagafogigante.dungeon.util.StopWatch;
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;
Expand Down Expand Up @@ -253,7 +259,7 @@ public void execute(@NotNull String[] arguments) {
commandSet.addCommand(new Command("tutorial", "Displays the tutorial.") {
@Override
public void execute(@NotNull String[] arguments) {
Writer.write(new Tutorial(), new WritingSpecifications(false, 0));
Writer.getDefaultWriter().write(new Tutorial(), new WritingSpecifications(false, 0));
}
});
commandSet.addCommand(new Command("unequip", "Unequips the currently equipped item.") {
Expand Down Expand Up @@ -282,13 +288,13 @@ public void execute(@NotNull String[] arguments) {
dungeonString.setColor(new Color(Random.nextInteger(256), Random.nextInteger(256), Random.nextInteger(256)));
dungeonString.append(Random.select(alphabet));
}
Writer.write(dungeonString);
Writer.getDefaultWriter().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());
Writer.getDefaultWriter().write(Game.getGameState().getHintLibrary().next());
}
});
commandSet.addCommand(new Command("poem", "Prints a poem from the poem library.") {
Expand All @@ -297,6 +303,61 @@ public void execute(@NotNull String[] arguments) {
PoemWriter.parsePoemCommand(arguments);
}
});
commandSet.addCommand(new Command("script", "Executes the specified script.") {
@Override
public void execute(@NotNull String[] arguments) {
if (arguments.length == 0) {
Writer.getDefaultWriter().write("Should provide a script identifier.");
return;
}
String argument = arguments[0];
ScriptIdentifier identifier;
try {
identifier = new ScriptIdentifier(argument);
} catch (IllegalArgumentException ignored) {
Writer.getDefaultWriter().write("The provided argument is not a valid script identifier.");
return;
}
ScriptGroup scriptGroup = ScriptGroupFactory.makeScriptGroup();
if (!scriptGroup.hasScript(identifier)) {
Writer.getDefaultWriter().write("There is no such script.");
return;
}
Writer.getDefaultWriter().write("Running the script.");
Writer.getDefaultWriter().disableForwarding();
DungeonString result = scriptGroup.executeScript(identifier, new CommandExecutor() {
@Override
public DungeonString execute(String command) {
DungeonString result = new DungeonString();
if (IssuedCommand.isValidSource(command)) {
Writer.getDefaultWriter().clearWrittenStrings();
Game.renderTurn(new IssuedCommand(command), new StopWatch());
for (Writable writtenString : Writer.getDefaultWriter().getWrittenStrings()) {
for (ColoredString coloredString : writtenString.toColoredStringList()) {
result.setColor(coloredString.getColor());
result.append(coloredString.getString());
}
}
}
return result;
}
});
Writer.getDefaultWriter().enableForwarding();
Writer.getDefaultWriter().write(result);
}
});
commandSet.addCommand(new Command("scripts", "Lists the available scripts.") {
@Override
public void execute(@NotNull String[] arguments) {
ScriptGroup scriptGroup = ScriptGroupFactory.makeScriptGroup();
StringBuilder builder = new StringBuilder();
for (ScriptIdentifier identifier : scriptGroup.getIdentifiers()) {
builder.append(identifier.asString());
builder.append('\n');
}
Writer.getDefaultWriter().write(builder.toString());
}
});
commandSet.addCommand(new Command("statistics", "Displays all available game statistics.") {
@Override
public void execute(@NotNull String[] arguments) {
Expand All @@ -306,13 +367,13 @@ public void execute(@NotNull String[] arguments) {
commandSet.addCommand(new Command("system", "Displays information about the underlying system.") {
@Override
public void execute(@NotNull String[] arguments) {
Writer.write(new SystemInformation());
Writer.getDefaultWriter().write(new SystemInformation());
}
});
commandSet.addCommand(new Command("version", "Displays the game version.") {
@Override
public void execute(@NotNull String[] arguments) {
Writer.write("Dungeon version " + Version.getCurrentVersion() + ".");
Writer.getDefaultWriter().write("Dungeon version " + Version.getCurrentVersion() + ".");
}
});
return commandSet;
Expand All @@ -325,13 +386,13 @@ private static CommandSet initializeDebugCommandSet() {
public void execute(@NotNull String[] arguments) {
AchievementTracker tracker = Game.getGameState().getHero().getAchievementTracker();
List<Achievement> notYetUnlockedAchievementList = new ArrayList<>();
for (Achievement achievement : AchievementStoreFactory.getDefaultStore().getAchievements()) {
for (Achievement achievement : new AchievementStoreFactory().getDefaultStore().getAchievements()) {
if (tracker.hasNotBeenUnlocked(achievement)) {
notYetUnlockedAchievementList.add(achievement);
}
}
if (notYetUnlockedAchievementList.isEmpty()) {
Writer.write("All achievements have been unlocked.");
Writer.getDefaultWriter().write("All achievements have been unlocked.");
} else {
Collections.sort(notYetUnlockedAchievementList, new Comparator<Achievement>() {
@Override
Expand All @@ -340,7 +401,7 @@ public int compare(Achievement o1, Achievement o2) {
}
});
for (Achievement achievement : notYetUnlockedAchievementList) {
Writer.write(String.format("%s : %s", achievement.getName(), achievement.getInfo()));
Writer.getDefaultWriter().write(String.format("%s : %s", achievement.getName(), achievement.getInfo()));
}
}
}
Expand All @@ -363,7 +424,7 @@ public void execute(@NotNull String[] arguments) {
String maximumNumberOfVisits = String.valueOf(explorationStatistics.getMaximumNumberOfVisits(preset.getId()));
table.insertRow(name, kills, visitedSoFar, maximumNumberOfVisits);
}
Writer.write(table);
Writer.getDefaultWriter().write(table);
}
});
commandSet.addCommand(new Command("kills", "Writes statistics about your killings.") {
Expand All @@ -377,9 +438,9 @@ public void execute(@NotNull String[] arguments) {
for (CauseOfDeath causeOfDeath : map.keySet()) {
table.insertRow(causeOfDeath.toString(), String.valueOf(map.getCounter(causeOfDeath)));
}
Writer.write(table);
Writer.getDefaultWriter().write(table);
} else {
Writer.write("You haven't killed anything yet. Go kill something!");
Writer.getDefaultWriter().write("You haven't killed anything yet. Go kill something!");
}
}
});
Expand Down Expand Up @@ -418,7 +479,7 @@ public void execute(@NotNull String[] arguments) {
dungeonString.append(StringUtils.rightPad("Blocked Entrances:", width));
dungeonString.append(heroLocation.getBlockedEntrances().toString());
dungeonString.append("\n");
Writer.write(dungeonString);
Writer.getDefaultWriter().write(dungeonString);
}
});
commandSet.addCommand(new Command("map", "Produces a map as complete as possible.") {
Expand All @@ -437,20 +498,21 @@ public void execute(@NotNull String[] arguments) {
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.");
Writer.getDefaultWriter().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.");
Writer.getDefaultWriter()
.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.");
Writer.getDefaultWriter().write("Item could not be created due to a restriction.");
}
} catch (IllegalArgumentException invalidPreset) {
Writer.write("Item could not be created.");
Writer.getDefaultWriter().write("Item could not be created.");
}
} else {
Messenger.printMissingArgumentsMessage();
Expand All @@ -461,9 +523,9 @@ public void execute(@NotNull String[] arguments) {
@Override
public void execute(@NotNull String[] arguments) {
if (Game.getGameState().isSaved()) {
Writer.write("The game is saved.");
Writer.getDefaultWriter().write("The game is saved.");
} else {
Writer.write("This game state is not saved.");
Writer.getDefaultWriter().write("This game state is not saved.");
}
}
});
Expand All @@ -477,10 +539,10 @@ public void execute(@NotNull String[] arguments) {
Creature creature = world.getCreatureFactory().makeCreature(givenId, world);
if (creature != null) {
Game.getGameState().getHero().getLocation().addCreature(creature);
Writer.write("Spawned a " + creature.getName() + ".");
Writer.getDefaultWriter().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.");
Writer.getDefaultWriter().write(givenId + " does not match any known creature.");
}
}
} else {
Expand All @@ -491,7 +553,7 @@ public void execute(@NotNull String[] arguments) {
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());
Writer.getDefaultWriter().write(Game.getGameState().getWorld().getWorldDate().toString());
}
});
commandSet.addCommand(new Command("wait", "Makes time pass.") {
Expand Down
Loading