package script; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Map; import abstracts.Entity; import dialogue.NewDialogue; public class Script { public int triggerID; public ArrayList<Map.Entry<Integer, Movement>> moves; public ArrayList<Map.Entry<Integer, Movement>> affirmativeMoves; public ArrayList<Map.Entry<Integer, Movement>> negativeMoves; public ArrayList<Map.Entry<Integer, NewDialogue>> dialogues; public ArrayList<Map.Entry<Integer, NewDialogue>> affirmativeDialogues; public ArrayList<Map.Entry<Integer, NewDialogue>> negativeDialogues; public int iteration; public int affirmativeIteration; public int negativeIteration; public Boolean questionResponse; public boolean repeat; public Script() { this.triggerID = 0; this.moves = new ArrayList<Map.Entry<Integer, Movement>>(); this.affirmativeMoves = new ArrayList<Map.Entry<Integer, Movement>>(); this.negativeMoves = new ArrayList<Map.Entry<Integer, Movement>>(); this.dialogues = new ArrayList<Map.Entry<Integer, NewDialogue>>(); this.affirmativeDialogues = new ArrayList<Map.Entry<Integer, NewDialogue>>(); this.negativeDialogues = new ArrayList<Map.Entry<Integer, NewDialogue>>(); this.iteration = 0; this.affirmativeIteration = 0; this.negativeIteration = 0; this.questionResponse = null; this.repeat = false; } public Script(Script s) { //Deep copy this.triggerID = s.triggerID; this.moves = new ArrayList<Map.Entry<Integer, Movement>>(); for (Map.Entry<Integer, Movement> e : s.moves) this.moves.add(new AbstractMap.SimpleEntry<Integer, Movement>(e.getKey(), new Movement(e.getValue()))); this.affirmativeMoves = new ArrayList<Map.Entry<Integer, Movement>>(); for (Map.Entry<Integer, Movement> e : s.affirmativeMoves) this.affirmativeMoves.add(new AbstractMap.SimpleEntry<Integer, Movement>(e.getKey(), new Movement(e.getValue()))); this.negativeMoves = new ArrayList<Map.Entry<Integer, Movement>>(); for (Map.Entry<Integer, Movement> e : s.negativeMoves) this.negativeMoves.add(new AbstractMap.SimpleEntry<Integer, Movement>(e.getKey(), new Movement(e.getValue()))); this.dialogues = new ArrayList<Map.Entry<Integer, NewDialogue>>(); for (Map.Entry<Integer, NewDialogue> e : s.dialogues) this.dialogues.add(new AbstractMap.SimpleEntry<Integer, NewDialogue>(e.getKey(), new NewDialogue(e.getValue()))); this.affirmativeDialogues = new ArrayList<Map.Entry<Integer, NewDialogue>>(); for (Map.Entry<Integer, NewDialogue> e : s.affirmativeDialogues) this.affirmativeDialogues.add(new AbstractMap.SimpleEntry<Integer, NewDialogue>(e.getKey(), new NewDialogue(e.getValue()))); this.negativeDialogues = new ArrayList<Map.Entry<Integer, NewDialogue>>(); for (Map.Entry<Integer, NewDialogue> e : s.negativeDialogues) this.negativeDialogues.add(new AbstractMap.SimpleEntry<Integer, NewDialogue>(e.getKey(), new NewDialogue(e.getValue()))); this.iteration = s.iteration; this.affirmativeIteration = s.affirmativeIteration; this.negativeIteration = s.negativeIteration; this.questionResponse = s.questionResponse; this.repeat = s.repeat; } public Movement getIteratedMoves() { if (this.questionResponse == null) { for (Map.Entry<Integer, Movement> entry : this.moves) { if (entry.getKey() == this.iteration) return entry.getValue(); } } else if (this.questionResponse == Boolean.TRUE) { for (Map.Entry<Integer, Movement> entry : this.affirmativeMoves) { if (entry.getKey() == this.affirmativeIteration) return entry.getValue(); } } else if (this.questionResponse == Boolean.FALSE) { for (Map.Entry<Integer, Movement> entry : this.negativeMoves) { if (entry.getKey() == this.negativeIteration) return entry.getValue(); } } return null; } public NewDialogue getIteratedDialogues() { if (this.questionResponse == null) { for (Map.Entry<Integer, NewDialogue> entry : this.dialogues) { if (entry.getKey() == this.iteration) { return entry.getValue(); } } } else if (this.questionResponse == Boolean.TRUE) { for (Map.Entry<Integer, NewDialogue> entry : this.affirmativeDialogues) { if (entry.getKey() == this.affirmativeIteration) { return entry.getValue(); } } } else if (this.questionResponse == Boolean.FALSE) { for (Map.Entry<Integer, NewDialogue> entry : this.negativeDialogues) { if (entry.getKey() == this.negativeIteration) { return entry.getValue(); } } } return null; } public void setAffirmativeFlag() { this.questionResponse = Boolean.TRUE; } public void setNegativeFlag() { this.questionResponse = Boolean.FALSE; } private void resetResponseFlag() { this.questionResponse = null; } public boolean incrementIteration() throws Exception { if (this.questionResponse == null) { this.iteration++; int size = this.moves.size() + this.dialogues.size(); if (this.iteration < size) return true; return false; } else if (this.questionResponse == Boolean.TRUE) { this.resetResponseFlag(); this.affirmativeIteration++; int size = this.affirmativeMoves.size() + this.affirmativeDialogues.size(); if (this.affirmativeIteration < size) return true; return false; } else { //FALSE this.resetResponseFlag(); this.negativeIteration++; int size = this.negativeMoves.size() + this.negativeDialogues.size(); if (this.negativeIteration < size) return true; return false; } } /** * <p> * Loads triggers according to the script file. * </p> * * <p> * The script file is a database of all triggers of a a certain map. All scripts within the file can only be triggered by that area. * </p> * * <p> * Currently needs fixing and testing. Will be completed when all issues have been sorted out. * </p> * * @param filename * - A String object of the file name of the SCRIPT file. * @return An ArrayList<Script> object, containing all of the triggers and scripted events located within the SCRIPT file. * * */ public static ArrayList<Script> loadScript(String filename, boolean isModdedScript) { ArrayList<Script> result = new ArrayList<Script>(); // Scripts must contain a trigger data for Area to use, and must contain movements for Area to read. Script script = null; int iteration = 0; int affirmativeIteration = 0; int negativeIteration = 0; BufferedReader reader = null; try { if (isModdedScript){ reader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(filename)))); } else { reader = new BufferedReader(new InputStreamReader(Script.class.getClassLoader().getResourceAsStream(filename))); } String line; while ((line = reader.readLine()) != null) { if (line.startsWith("/") || line.startsWith("@") || line.isEmpty()) // Ignored tags continue; else if (line.startsWith("$")) { // Start of script int triggerID = Integer.valueOf(line.substring(1)); if (triggerID > 0) { if (script == null) script = new Script(); script.triggerID = triggerID; } } else if (line.startsWith("^")) { // Movement if (script != null) { Movement moves = new Movement(); append(moves, line.substring(1).toCharArray()); script.moves.add(new AbstractMap.SimpleEntry<Integer, Movement>(iteration, moves)); iteration++; } } else if (line.startsWith("%")) { // Script delimiter if (script != null) { result.add(script); script = null; iteration = 0; } } else if (line.startsWith("#")) { // speech dialogue NewDialogue d = NewDialogue.createText(line.substring(1).replace("_", " "), NewDialogue.MAX_STRING_LENGTH, NewDialogue.DIALOGUE_SPEECH, true); script.dialogues.add(new AbstractMap.SimpleEntry<Integer, NewDialogue>(iteration, d)); iteration++; } else if (line.startsWith("?")) { // question dialogue NewDialogue d = NewDialogue.createText(line.substring(1).replace("_", " "), NewDialogue.MAX_STRING_LENGTH, NewDialogue.DIALOGUE_QUESTION, true); script.dialogues.add(new AbstractMap.SimpleEntry<Integer, NewDialogue>(iteration, d)); iteration++; } else if (line.startsWith("+")) { // affirmative dialogue NewDialogue d = NewDialogue.createText(line.substring(1).replace("_", " "), NewDialogue.MAX_STRING_LENGTH, NewDialogue.DIALOGUE_SPEECH, true); script.affirmativeDialogues.add(new AbstractMap.SimpleEntry<Integer, NewDialogue>(affirmativeIteration, d)); affirmativeIteration++; } else if (line.startsWith("-")) { // negative dialogue NewDialogue d = NewDialogue.createText(line.substring(1).replace("_", " "), NewDialogue.MAX_STRING_LENGTH, NewDialogue.DIALOGUE_SPEECH, true); script.negativeDialogues.add(new AbstractMap.SimpleEntry<Integer, NewDialogue>(negativeIteration, d)); negativeIteration++; } else if (line.startsWith("[")) { // affirmative action if (script != null) { Movement moves = new Movement(); append(moves, line.substring(1).toCharArray()); script.affirmativeMoves.add(new AbstractMap.SimpleEntry<Integer, Movement>(affirmativeIteration, moves)); affirmativeIteration++; } } else if (line.startsWith("]")) { // negative action if (script != null) { Movement moves = new Movement(); append(moves, line.substring(1).toCharArray()); script.negativeMoves.add(new AbstractMap.SimpleEntry<Integer, Movement>(negativeIteration, moves)); negativeIteration++; } } else if (line.startsWith(";")) { if (script != null) { script.repeat = true; } } } } catch (Exception e) { e.printStackTrace(); } finally { if (reader != null){ try { reader.close(); } catch (IOException e) { e.printStackTrace(); } } } return result; } private static void append(Movement moves, char[] list) { int direction = -1; int steps = -1; try { for (int i = 0; i < list.length; i += 2) { char d = list[i]; char s = list[i + 1]; switch (d) { case 'U': direction = Entity.UP; break; case 'D': direction = Entity.DOWN; break; case 'L': direction = Entity.LEFT; break; case 'R': direction = Entity.RIGHT; break; default: direction = -1; break; } steps = Character.getNumericValue(s); if (direction != -1 && steps != -1 && steps != -2 && (steps <= 9 && steps >= 0)) { Map.Entry<Integer, Integer> entry = new AbstractMap.SimpleEntry<Integer, Integer>(direction, steps); moves.moves.add(entry); } } } catch (Exception e) { e.printStackTrace(); throw new NumberFormatException("Incorrect script syntax from \"script.txt\""); } } /** * Load all default scripts. * */ public static ArrayList<Script> loadDefaultScripts(){ return Script.loadScript("script/scripts.txt", false); } /** * Load all modded scripts. * */ public static ArrayList<Script> loadModdedScripts() { ArrayList<Script> results = null; File modDirectory = new File("mod"); if (modDirectory.exists() && modDirectory.isDirectory()){ String[] folders = modDirectory.list(); LOOP: for (int i =0; i<folders.length; i++){ File directory = new File(modDirectory.getPath() + File.separator + folders[i]); if (directory.exists() && directory.isDirectory() && directory.getName().equals("script")){ String[] scripts = directory.list(); for (int j = 0; j<scripts.length;j++){ String filePath = directory.getPath() + File.separator + scripts[j]; if (filePath.endsWith(".script")){ if (results == null) results = Script.loadScript(filePath, true); else results.addAll(Script.loadScript(filePath, true)); } } break LOOP; } } } return results; } }