diff options
| author | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2019-01-17 18:33:14 -0400 |
|---|---|---|
| committer | Benjamin J. Culkin <bjculkin@mix.wvu.edu> | 2019-01-17 18:33:14 -0400 |
| commit | 8c613819790ae737150a9ad8bb82332a1aaab690 (patch) | |
| tree | 03fd2180f3685ddfe6265568b542e18dae8b9280 | |
| parent | 45e6547632957bfa5b806825eaebd6c0f8bdb736 (diff) | |
Refactor AffixLister
AffixLister got refactored some more, in preparation for adding the
ability to load things that aren't affixes.
| -rwxr-xr-x | genafx-test.sh | 2 | ||||
| -rw-r--r-- | pom.xml | 2 | ||||
| -rw-r--r-- | src/main/java/tlIItools/Affix.java | 98 | ||||
| -rw-r--r-- | src/main/java/tlIItools/AffixLister.java | 314 | ||||
| -rw-r--r-- | src/main/java/tlIItools/AffixSet.java | 34 | ||||
| -rw-r--r-- | src/main/java/tlIItools/Effect.java | 129 | ||||
| -rw-r--r-- | src/main/java/tlIItools/Main.java | 7 | ||||
| -rw-r--r-- | src/main/java/tlIItools/NameFileReader.java | 190 |
8 files changed, 526 insertions, 250 deletions
diff --git a/genafx-test.sh b/genafx-test.sh index 4f9726f9..06ee634f 100755 --- a/genafx-test.sh +++ b/genafx-test.sh @@ -5,7 +5,7 @@ set -e baseout="$1" shift 1 fileset="$@" -listopts="-z -n named" +listopts="-l -z -n named" outputfle=output/"$baseout".txt errfle=output/"$baseout".err outputopts="-o $outputfle -e $errfle" @@ -43,7 +43,7 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> - <main.class>AffixLister</main.class> + <main.class>tlIItools.AffixLister</main.class> </properties> <dependencies> diff --git a/src/main/java/tlIItools/Affix.java b/src/main/java/tlIItools/Affix.java index 424b2dad..8b1c2b03 100644 --- a/src/main/java/tlIItools/Affix.java +++ b/src/main/java/tlIItools/Affix.java @@ -2,12 +2,17 @@ package tlIItools; import java.util.ArrayList; import java.util.List; +import java.util.Scanner; /** * Represents a Torchlight II affix. */ public class Affix { /** + * Whether or not to record timing info. + */ + public static boolean doTiming; + /** * Internal name of the affix. */ public String intName; @@ -18,7 +23,7 @@ public class Affix { * In general, only one of these is set for a given affix. * * NOTE: Some affixes have a mis-set suffix/prefix ordering, and - * may need to be changed. + * may need to be changed in their files. */ public String affixSuffix; public String affixPrefix; @@ -129,6 +134,10 @@ public class Affix { @Override public String toString() { + return intName; + } + + public String toLongString() { StringBuilder sb = new StringBuilder(); if (isSocketable) sb.append("Socketable "); else if (isPerson || (intName != null && intName.startsWith("HERO_"))) sb.append("Personal "); @@ -165,8 +174,7 @@ public class Affix { sb.append("Max Level: "); sb.append(maxLevel); } else if (maxLevel == 999) { - sb.append("Minimum Level: "); - sb.append(minLevel); + sb.append("Minimum Level: "); sb.append(minLevel); } sb.append("\n"); @@ -221,4 +229,88 @@ public class Affix { return sb.toString(); } + + /** + * Load an affix from an input source. + * + * @param scn + * The input source to load from. + * + * @param fName + * The name of the input source in question. + * + * @return + * The loaded affix. + */ + public static Affix loadAffix(Scanner scn, String fName) { + return loadAffix(scn, fName, new ArrayList<>()); + } + + public static Affix loadAffix(Scanner scn, String scnName, List<String> errors) { + Affix afx = new Affix(); + + long startTime = System.nanoTime(); + + while (scn.hasNextLine()) { + String ln = scn.nextLine(); + ln = ln.replaceAll("\\p{Cntrl}", ""); + + if (ln.contains("[NOT_UNITTYPES]")) { + afx.setEquipType(true); + continue; + } else if (ln.contains("[UNITTYPES]")) { + afx.setEquipType(false); + continue; + } + + String[] splits = ln.split(":"); + if (ln.contains("<TRANSLATE>")) { + splits[0] = splits[0].substring(11); + + switch (splits[0]) { + case "SUFFIX": + afx.affixSuffix = splits[1]; + break; + case "PREFIX": + afx.affixPrefix = splits[1]; + break; + default: + errors.add(String.format("Misformed affix translation: (%s) (%s) (%s)\n", splits[0], splits[1], scnName)); + } + } else if (ln.contains("MIN_SPAWN_RANGE")) { + afx.minLevel = Integer.parseInt(splits[1]); + } else if (ln.contains("MAX_SPAWN_RANGE")) { + afx.maxLevel = Integer.parseInt(splits[1]); + } else if (ln.contains("WEIGHT:")) { + afx.weight = Integer.parseInt(splits[1]); + } else if (ln.contains("SLOTS_OCCUPY")) { + afx.weight = Integer.parseInt(splits[1]); + } else if (ln.contains("UNITTYPE") && !ln.contains("/")) { + if (splits.length == 1) + errors.add(String.format("Malformed equip type: (%s) (%s)\n", splits[0], scnName)); + afx.addEquipType(splits[1]); + } else if (splits[0].equals("<STRING>NAME")) { + if (splits.length == 1) + errors.add(String.format("Malformed name: (%s) (%s)\n", splits[0], scnName)); + afx.intName = splits[1]; + } else if (ln.contains("[EFFECT]")) { + List<String> eftErrs = new ArrayList<>(); + + Effect eft = Effect.parseEffect(afx, scn, scnName, errors); + errors.addAll(eftErrs); + + afx.effects.add(eft); + } + } + + long endTime = System.nanoTime(); + if (doTiming) { + String fmt = "\tProcessed affix %s from %s in %d nanoseconds (%.2f seconds)\n\n"; + double seconds = ((double)(endTime - startTime) / 1000000000); + + errors.add(String.format(fmt, afx.intName, scnName, endTime - startTime, seconds)); + } + + return afx; + } } diff --git a/src/main/java/tlIItools/AffixLister.java b/src/main/java/tlIItools/AffixLister.java index 27ea0c70..76e93996 100644 --- a/src/main/java/tlIItools/AffixLister.java +++ b/src/main/java/tlIItools/AffixLister.java @@ -19,15 +19,24 @@ import java.util.Set; * @author Ben Culkin */ public class AffixLister { + /** + * Count of effects this class has loaded. + */ private static int effectCount = 0; - private static boolean doTiming = false; + /** + * Should the class record timing data? + */ + public static boolean doTiming = false; /** * Should the file name be attached to things? */ public static boolean addFileName = false; + /** + * Output streams to use. + */ public static PrintStream normOut = System.out; public static PrintStream errOut = System.err; @@ -49,55 +58,24 @@ public class AffixLister { NAMED; } - private static int readNamesFromFile(Map<String, List<String>> fNames, String from, String defGroup, boolean guessGroups) { - int numFiles = 0; - try (FileReader fr = new FileReader(from)) { - Scanner scn = new Scanner(fr); - - String curGroup = defGroup; - List<String> curList = fNames.get(curGroup); - - while (scn.hasNextLine()) { - String ln = scn.nextLine(); - - if (ln.startsWith("#")) { - curGroup = ln.substring(1); - - if (!fNames.containsKey(curGroup)) { - curList = new ArrayList<>(); - fNames.put(curGroup, curList); - } else { - curList = fNames.get(curGroup); - } - } else if (guessGroups && ln.contains("/mods/")) { - curGroup = ln.replaceAll(".*/mods/([^/]+)/*", "$1"); - - if (!fNames.containsKey(curGroup)) { - curList = new ArrayList<>(); - fNames.put(curGroup, curList); - } else { - curList = fNames.get(curGroup); - } - } else { - numFiles += 1; - curList.add(ln); - } - } - } catch (IOException ioex) { - errOut.printf("Error reading names from file %s\n", from); - ioex.printStackTrace(errOut); - errOut.println(); - } - - return numFiles; - } - /** * Main method. * * @param args The names of the files to read affix data from. */ public static void main(String[] args) { + listAffixes(args); + } + + /** + * Main method that actually does stuff. + * + * @param args + * The names of the files to read affix data from. + */ + public static AffixSet listAffixes(String[] args) { + AffixSet afst = new AffixSet(); + boolean doingArgs = true; boolean omitZeros = false; @@ -106,26 +84,22 @@ public class AffixLister { NameMode nameMode = NameMode.ALL; - long startTime = System.nanoTime(); - - int fCount = 0; - int namedCount = 0; int unnamedCount = 0; int zeroCount = 0; int groupCount = 0; - Map<String, List<String>> groupContents = new HashMap<>(); + Map<String, List<Affix>> groupContents = afst.affixGroups; - List<String> nonGroupContents = new ArrayList<>(); + List<Affix> nonGroupContents = afst.ungroupedAffixes; int argCount = 0; - Map<String, List<String>> fGroups = new HashMap<>(); - List<String> fNames = new ArrayList<>(); + NameFileReader nfr = new NameFileReader(false); + nfr.groupRx = ".*/mods/([^/]+)/*"; + + long startTime = System.nanoTime(); - String curGroup = "default"; - fGroups.put(curGroup, fNames); for(int i = 0; i < args.length; i++) { String fName = args[i]; @@ -154,10 +128,12 @@ public class AffixLister { case "--timing": case "-t": doTiming = true; + Effect.doTiming = true; break; case "--no-timing": case "-T": doTiming = false; + Effect.doTiming = false; break; case "--file-names": case "-f": @@ -175,6 +151,7 @@ public class AffixLister { } nameMode = NameMode.valueOf(args[++i].toUpperCase()); + break; case "--file-group": case "-g": @@ -183,19 +160,16 @@ public class AffixLister { break; } - curGroup = args[++i]; - if (fGroups.containsKey(curGroup)) { - fNames = fGroups.get(curGroup); - } else { - fNames = new ArrayList<>(); - fGroups.put(curGroup, fNames); - } + nfr.swapGroup(args[++i]); + break; case "--guess-groups": - guessGroups = true; + nfr.guessGroups = true; + break; case "--no-guess-groups": - guessGroups = false; + nfr.guessGroups = false; + break; case "--read-names-from-file": case "-r": @@ -204,7 +178,8 @@ public class AffixLister { break; } - fCount += readNamesFromFile(fGroups, args[++i], curGroup, guessGroups); + nfr.readFrom(args[++i]); + break; case "--output": case "-o": @@ -212,13 +187,17 @@ public class AffixLister { errOut.printf("ERROR: output file argument requires the file to use be specified\n"); break; } + try { normOut = new PrintStream(args[++i]); + + nfr.normOut = normOut; } catch (IOException ioex) { errOut.printf("Could not open output file %s\n", args[i]); ioex.printStackTrace(errOut); } + break; case "--output-errors": case "-e": @@ -226,13 +205,26 @@ public class AffixLister { errOut.printf("ERROR: error output file argument requires the file to use be specified\n"); break; } + try { errOut = new PrintStream(args[++i]); + + nfr.errOut = errOut; } catch (IOException ioex) { errOut.printf("Could not open error output file %s\n", args[i]); ioex.printStackTrace(errOut); } + + break; + case "--guess-regex": + if (i + 1 >= args.length) { + errOut.printf("ERROR: group regex argument requires the regex to use be specified\n"); + break; + } + + nfr.groupRx = args[++i]; + break; default: isArg = false; @@ -240,25 +232,25 @@ public class AffixLister { if (isArg) { argCount += 1; + continue; } - fCount += 1; - fNames.add(fName); + nfr.addFile(fName); } else { - fCount += 1; - fNames.add(fName); + nfr.addFile(fName); } } - for (Entry<String, List<String>> fGroup : fGroups.entrySet()) { + for (Entry<String, List<String>> fGroup : nfr.fNames.entrySet()) { if (fGroup.getValue().size() == 0) continue; normOut.printf("\nFile Group '%s' starting\n", fGroup.getKey()); for (String fName : fGroup.getValue()) { try (FileReader fr = new FileReader(fName)) { Scanner sc = new Scanner(fr); - Affix afx = processFile(sc, fName); + Affix afx = Affix.loadAffix(sc, fName); + effectCount += afx.effects.size(); if (afx.intName != null && afx.weight != 0) { String groupRx = "(.*_?)\\d+\\Z"; @@ -274,12 +266,12 @@ public class AffixLister { groupContents.put(groupName, new ArrayList<>()); } else { - nonGroupContents.add(afx.intName); + nonGroupContents.add(afx); } } else if (hasGroup) { - groupContents.get(groupName).add(afx.intName); + groupContents.get(groupName).add(afx); } else { - nonGroupContents.add(afx.intName); + nonGroupContents.add(afx); } } @@ -297,7 +289,7 @@ public class AffixLister { if (nameMode == NameMode.UNNAMED && isNamed) continue; if (nameMode == NameMode.NAMED && !isNamed) continue; - normOut.printf("\n%s\n", afx.toString()); + normOut.printf("\n%s\n", afx.toLongString()); } } catch (Exception ex) { errOut.printf("Something bad happened for file %s:%s\n", fName, ex.getMessage()); @@ -311,184 +303,16 @@ public class AffixLister { } errOut.println("\nGroup Contents: "); - for (Entry<String, List<String>> ent: groupContents.entrySet()) { + for (Entry<String, List<Affix>> ent: groupContents.entrySet()) { errOut.printf("\t%s: %s\n", ent.getKey(), ent.getValue()); } errOut.println(); errOut.println(); long endTime = System.nanoTime(); - errOut.printf("\nProcessed %,d affixes (%,d named, %,d unnamed, %,d zero-weight) (%,d effects) (%,d distinct groups, %,d actual groups, %,d nongrouped affixes) out of %,d files (%,d groups) in %,d nanoseconds (%.2f seconds)\n", fCount, namedCount, unnamedCount, zeroCount, effectCount, groupCount, groupContents.size(), nonGroupContents.size(), fCount, fGroups.size(), endTime - startTime, ((double)(endTime - startTime) / 1000000000)); + errOut.printf("\nProcessed %,d affixes (%,d named, %,d unnamed, %,d zero-weight) (%,d effects) (%,d distinct groups, %,d actual groups, %,d nongrouped affixes) out of %,d files (%,d groups) in %,d nanoseconds (%.2f seconds)\n", nfr.fCount, namedCount, unnamedCount, zeroCount, effectCount, groupCount, groupContents.size(), nonGroupContents.size(), nfr.fCount, nfr.fNames.size(), endTime - startTime, ((double)(endTime - startTime) / 1000000000)); errOut.printf("\tOptions: Name Mode: %s, Special-case zero weight: %s, Noting zero-weight in special case: %s\n", nameMode, !listZeros, !omitZeros); - } - - // Process an affix file - private static Affix processFile(Scanner scn, String fName) { - Affix afx = new Affix(); - - long startTime = System.nanoTime(); - - while (scn.hasNextLine()) { - String ln = scn.nextLine(); - ln = ln.replaceAll("\\p{Cntrl}", ""); - - if (ln.contains("[NOT_UNITTYPES]")) { - afx.setEquipType(true); - continue; - } else if (ln.contains("[UNITTYPES]")) { - afx.setEquipType(false); - continue; - } - - String[] splits = ln.split(":"); - if (ln.contains("<TRANSLATE>")) { - splits[0] = splits[0].substring(11); - - switch (splits[0]) { - case "SUFFIX": - afx.affixSuffix = splits[1]; - break; - case "PREFIX": - afx.affixPrefix = splits[1]; - break; - default: - errOut.printf("Misformed affix translation: (%s) (%s) (%s)\n", splits[0], splits[1], fName); - } - } else if (ln.contains("MIN_SPAWN_RANGE")) { - afx.minLevel = Integer.parseInt(splits[1]); - } else if (ln.contains("MAX_SPAWN_RANGE")) { - afx.maxLevel = Integer.parseInt(splits[1]); - } else if (ln.contains("WEIGHT:")) { - afx.weight = Integer.parseInt(splits[1]); - } else if (ln.contains("SLOTS_OCCUPY")) { - afx.weight = Integer.parseInt(splits[1]); - } else if (ln.contains("UNITTYPE") && !ln.contains("/")) { - if (splits.length == 1) - errOut.printf("Malformed equip type: (%s) (%s)\n", splits[0], fName); - afx.addEquipType(splits[1]); - } else if (splits[0].equals("<STRING>NAME")) { - if (splits.length == 1) - errOut.printf("Malformed name: (%s) (%s)\n", splits[0], fName); - afx.intName = splits[1]; - } else if (ln.contains("[EFFECT]")) { - afx.effects.add(parseEffect(afx, scn, fName)); - } - } - - long endTime = System.nanoTime(); - if (doTiming) errOut.printf("\tProcessed affix %s from %s in %d nanoseconds (%.2f seconds)\n\n", afx.intName, fName, endTime - startTime, ((double)(endTime - startTime) / 1000000000)); - - return afx; - } - - private static Effect parseEffect(Affix afx, Scanner scn, String fName) { - Effect efct = new Effect(); - - long startTime = System.nanoTime(); - - efct.fName = fName; - - while (scn.hasNextLine()) { - String ln = scn.nextLine(); - ln = ln.replaceAll("\\p{Cntrl}", ""); - - if (ln.contains("[/EFFECT]")) break; - - String[] splits = ln.split(":"); - - // Empty field - if (splits.length == 1) continue; - - if (ln.contains("NAME")) { - efct.name = splits[1]; - } else if (ln.contains("DAMAGE_TYPE")) { - efct.damageType = splits[1]; - } else if (ln.contains("TYPE")) { - efct.type = splits[1]; - } else if (ln.contains("ACTIVATION")) { - switch (splits[1]) { - case "DYNAMIC": - case "PASSIVE": - // Passive is the default, and - // dynamic doesn't have much - // actual difference. - break; - case "TRANSFER": - efct.isTransfer = true; - break; - default: - errOut.printf("Malformed activation type: (%s) (%s) (%s)\n", splits[1], efct.name, afx.intName); - } - } else if (ln.contains("DURATION")) { - if (splits[1].equals("ALWAYS")) { - efct.hasDuration = false; - - efct.duration = Double.POSITIVE_INFINITY; - } else if (splits[1].equals("INSTANT")) { - efct.hasDuration = false; - - efct.duration = Double.NaN; - } else if (splits[1].equals("PERCENT")) { - efct.hasDuration = false; - - efct.duration = Double.NaN; - - errOut.printf("WARN: Punting on DURATION:PERCENT for %s\n", fName); - } else if (splits[1].equals("0")) { - efct.hasDuration = false; - efct.duration = 0.0; - } else { - efct.hasDuration = true; - - efct.duration = Double.parseDouble(splits[1]); - } - } else if (ln.contains("<FLOAT>MIN:")) { - efct.minValue = Double.parseDouble(splits[1]); - } else if (ln.contains("<FLOAT>MAX:")) { - efct.maxValue = Double.parseDouble(splits[1]); - } else if (ln.contains("USEOWNERLEVEL")) { - // We don't care about this, for now - } else if (ln.contains("LEVEL:")) { - efct.level = Integer.parseInt(splits[1]); - } else if (ln.contains("EXCLUSIVE")) { - efct.exclusive = Boolean.parseBoolean(splits[1]); - } else if (ln.contains("GRAPHOVERRIDE")) { - efct.graphOverride = splits[1]; - } else if (ln.contains("USEOWNERLEVEL")) { - efct.ownerLevel = Boolean.parseBoolean(splits[1]); - } else if (ln.contains("NOGRAPH")) { - efct.useGraph = Boolean.parseBoolean(splits[1]); - } else if (ln.contains("STATNAME")) { - efct.statName = splits[1]; - } else if (ln.contains("STATPERCENT")) { - efct.statPercent = Double.parseDouble(splits[1]); - } else if (ln.contains("STATMODIFIERISBONUS")) { - efct.isStatBonus = Boolean.parseBoolean(splits[1]); - } else if (ln.contains("RESISTANCE:")) { - efct.resist = Double.parseDouble(splits[1]); - } else if (ln.contains("FORCE:")) { - efct.resist = Double.parseDouble(splits[1]); - } else if (ln.contains("MIN_PER")) { - efct.minPer = Double.parseDouble(splits[1]); - } else if (ln.contains("MAX_PER")) { - efct.maxPer = Double.parseDouble(splits[1]); - } else if (ln.contains("RANGE:") || ln.contains("RADIUS")) { - efct.range = Double.parseDouble(splits[1]); - } else if (ln.contains("MAX_COUNT:") || ln.contains("MAX_TARGETS")) { - efct.maxCount = Double.parseDouble(splits[1]); - } else if (ln.contains("PULSE_RATE")) { - efct.pulse = Double.parseDouble(splits[1]); - } else if (ln.contains("CHANCE:")) { - // NOTE: Should really use its own field - efct.resist = Double.parseDouble(splits[1]); - } - } - - long endTime = System.nanoTime(); - if (doTiming) errOut.printf("\t\tProcessed effect %s from %s in %d nanoseconds (%.2f seconds)\n", efct.name, fName, endTime - startTime, ((double)((endTime - startTime) / 1000000000))); - - effectCount += 1; - return efct; + return afst; } } diff --git a/src/main/java/tlIItools/AffixSet.java b/src/main/java/tlIItools/AffixSet.java new file mode 100644 index 00000000..8f59d7b4 --- /dev/null +++ b/src/main/java/tlIItools/AffixSet.java @@ -0,0 +1,34 @@ +package tlIItools; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +/** + * Container of a set of affixes. + * + * @author Ben Culkin + */ +public class AffixSet { + /** + * All of the affix groups contained in this set. + * + * An affix group is a set of affixs that generally have the same or + * similiar effects, but have different intensities or spawn levels. + */ + public Map<String, List<Affix>> affixGroups; + + /** + * All of the ungrouped affixes contained in this set. + */ + public List<Affix> ungroupedAffixes; + + /** + * Create a new blank affix set. + */ + public AffixSet() { + affixGroups = new HashMap<>(); + + ungroupedAffixes = new ArrayList<>(); + } +} diff --git a/src/main/java/tlIItools/Effect.java b/src/main/java/tlIItools/Effect.java index 1c0af9af..3efec6de 100644 --- a/src/main/java/tlIItools/Effect.java +++ b/src/main/java/tlIItools/Effect.java @@ -17,6 +17,15 @@ import java.util.Scanner; */ public class Effect { /** + * Count of all loaded effects. + */ + public static int effectCount = 0; + /** + * Do timing analysis when loading effects. + */ + public static boolean doTiming; + + /** * The list of detail strings for skills. */ private static Map<String, String> detals; @@ -361,4 +370,124 @@ public class Effect { return sb.toString(); } + + public static Effect parseEffect(Affix afx, Scanner scn, String scnSource) { + return parseEffect(afx, scn, scnSource, new ArrayList<>()); + } + + public static Effect parseEffect(Affix afx, Scanner scn, String scnSource, List<String> errs) { + Effect efct = new Effect(); + + long startTime = System.nanoTime(); + + efct.fName = scnSource; + + while (scn.hasNextLine()) { + String ln = scn.nextLine(); + ln = ln.replaceAll("\\p{Cntrl}", ""); + + if (ln.contains("[/EFFECT]")) break; + + String[] splits = ln.split(":"); + + // Empty field + if (splits.length == 1) continue; + + if (ln.contains("NAME")) { + efct.name = splits[1]; + } else if (ln.contains("DAMAGE_TYPE")) { + efct.damageType = splits[1]; + } else if (ln.contains("TYPE")) { + efct.type = splits[1]; + } else if (ln.contains("ACTIVATION")) { + switch (splits[1]) { + case "DYNAMIC": + case "PASSIVE": + // Passive is the default, and + // dynamic doesn't have much + // actual difference. + break; + case "TRANSFER": + efct.isTransfer = true; + break; + default: + errs.add(String.format("Malformed activation type: (%s) (%s) (%s)\n", splits[1], efct.name, afx.intName)); + } + } else if (ln.contains("DURATION")) { + if (splits[1].equals("ALWAYS")) { + efct.hasDuration = false; + + efct.duration = Double.POSITIVE_INFINITY; + } else if (splits[1].equals("INSTANT")) { + efct.hasDuration = false; + + efct.duration = Double.NaN; + } else if (splits[1].equals("PERCENT")) { + efct.hasDuration = false; + + efct.duration = Double.NaN; + + errs.add(String.format("WARN: Punting on DURATION:PERCENT for %s\n", scnSource)); + } else if (splits[1].equals("0")) { + efct.hasDuration = false; + efct.duration = 0.0; + } else { + efct.hasDuration = true; + + efct.duration = Double.parseDouble(splits[1]); + } + } else if (ln.contains("<FLOAT>MIN:")) { + efct.minValue = Double.parseDouble(splits[1]); + } else if (ln.contains("<FLOAT>MAX:")) { + efct.maxValue = Double.parseDouble(splits[1]); + } else if (ln.contains("USEOWNERLEVEL")) { + // We don't care about this, for now + } else if (ln.contains("LEVEL:")) { + efct.level = Integer.parseInt(splits[1]); + } else if (ln.contains("EXCLUSIVE")) { + efct.exclusive = Boolean.parseBoolean(splits[1]); + } else if (ln.contains("GRAPHOVERRIDE")) { + efct.graphOverride = splits[1]; + } else if (ln.contains("USEOWNERLEVEL")) { + efct.ownerLevel = Boolean.parseBoolean(splits[1]); + } else if (ln.contains("NOGRAPH")) { + efct.useGraph = Boolean.parseBoolean(splits[1]); + } else if (ln.contains("STATNAME")) { + efct.statName = splits[1]; + } else if (ln.contains("STATPERCENT")) { + efct.statPercent = Double.parseDouble(splits[1]); + } else if (ln.contains("STATMODIFIERISBONUS")) { + efct.isStatBonus = Boolean.parseBoolean(splits[1]); + } else if (ln.contains("RESISTANCE:")) { + efct.resist = Double.parseDouble(splits[1]); + } else if (ln.contains("FORCE:")) { + efct.resist = Double.parseDouble(splits[1]); + } else if (ln.contains("MIN_PER")) { + efct.minPer = Double.parseDouble(splits[1]); + } else if (ln.contains("MAX_PER")) { + efct.maxPer = Double.parseDouble(splits[1]); + } else if (ln.contains("RANGE:") || ln.contains("RADIUS")) { + efct.range = Double.parseDouble(splits[1]); + } else if (ln.contains("MAX_COUNT:") || ln.contains("MAX_TARGETS")) { + efct.maxCount = Double.parseDouble(splits[1]); + } else if (ln.contains("PULSE_RATE")) { + efct.pulse = Double.parseDouble(splits[1]); + } else if (ln.contains("CHANCE:")) { + // NOTE: Should really use its own field + efct.resist = Double.parseDouble(splits[1]); + } + } + + long endTime = System.nanoTime(); + if (doTiming) { + String fmt = "\t\tProcessed effect %s from %s in %d nanoseconds (%.2f seconds)\n"; + + double seconds = ((double)((endTime - startTime) / 1000000000)); + errs.add(String.format(fmt, efct.name, scnSource, endTime - startTime, seconds)); + } + + effectCount += 1; + + return efct; + } } diff --git a/src/main/java/tlIItools/Main.java b/src/main/java/tlIItools/Main.java new file mode 100644 index 00000000..4b929381 --- /dev/null +++ b/src/main/java/tlIItools/Main.java @@ -0,0 +1,7 @@ +package tlIItools; + +public class Main { + public static void main(String[] args) { + + } +} diff --git a/src/main/java/tlIItools/NameFileReader.java b/src/main/java/tlIItools/NameFileReader.java new file mode 100644 index 00000000..ad2a83b4 --- /dev/null +++ b/src/main/java/tlIItools/NameFileReader.java @@ -0,0 +1,190 @@ +package tlIItools; + +import java.io.FileReader; +import java.io.IOException; +import java.io.PrintStream; +import java.io.Reader; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Scanner; + +/** + * Reads in a list of file names to process. + * + * @author Ben Culkin + */ +public class NameFileReader { + /** + * Are we attempting to guess group names? + */ + public boolean guessGroups; + + /** + * Regex to use for guessing group names. + */ + public String groupRx; + + /** + * The default group to put files into. + */ + public String defGroup; + + /** + * The map of file groups. + */ + public Map<String, List<String>> fNames; + + /* + * The current group. + */ + private String curGroup; + /* + * The list of files for the current group. + */ + private List<String> curList; + + /** + * Counts the files read in. + */ + public int fCount; + + public PrintStream normOut = System.out; + public PrintStream errOut = System.err; + + /** + * Create a new name reader using the default settings. + * + * Guessing groups is disabled by default. + */ + public NameFileReader() { + this(false); + } + + /** + * Create a new name reader using the default settings. + * + * @param guessGroups + * Controls whether or not to try to guess file groups from file + * names. + */ + public NameFileReader(boolean guessGroups) { + this(new HashMap<>(), "default", guessGroups); + } + + /** + * Create a new name reader using the specified settings. + * + * @param fNames + * The set of groups to add files to. + * + * @param defGroup + * The name of the default file group. + * + * @param guessGroups + * Whether or not to attempt to guess group names. + */ + public NameFileReader(Map<String, List<String>> fNames, String defGroup, boolean guessGroups) { + if (!fNames.containsKey(defGroup)) + fNames.put(defGroup, new ArrayList<>()); + + this.fNames = fNames; + + this.defGroup = defGroup; + + this.guessGroups = guessGroups; + + this.curGroup = defGroup; + this.curList = fNames.get(curGroup); + + this.fCount = 0; + } + + /** + * Read in file names from a file. + * + * @param from + * The name of the file to read from. + * + * @return The number of files read. + */ + public void readFrom(String from) { + int ret; + + try (FileReader fr = new FileReader(from)) { + readFrom(fr); + } catch (IOException ioex) { + errOut.printf("Error reading names from file %s\n", from); + ioex.printStackTrace(errOut); + errOut.println(); + } + } + + /** + * Read in file names from an input source. + * + * @param r + * The input source to read from. + * + * @return The number of files read. + */ + public void readFrom(Reader r) { + int numFiles = 0; + + Scanner scn = new Scanner(r); + + while (scn.hasNextLine()) { + String ln = scn.nextLine(); + + boolean skipAdd = false; + + if (ln.startsWith("#")) { + swapGroup(ln.substring(1)); + + skipAdd = true; + } else if (guessGroups && ln.contains("/mods/")) { + swapGroup(ln.replaceAll(groupRx, "$1")); + } + + if (!skipAdd) { + fCount += 1; + + curList.add(ln); + } + + skipAdd = false; + } + } + + /** + * Swap to a new file group. + * + * @param groupName + * The name of the group to swap to. + */ + public void swapGroup(String groupName) { + curGroup = groupName; + + if (!fNames.containsKey(curGroup)) { + curList = new ArrayList<>(); + + fNames.put(curGroup, curList); + } else { + curList = fNames.get(curGroup); + } + } + + public void addFile(String fName) { + curList.add(fName); + + fCount += 1; + } + + public void addFile(String groupName, String fName) { + fNames.computeIfAbsent(groupName, (key) -> new ArrayList<>()).add(fName); + + fCount += 1; + } +} |
