From 7ed94d171ac9b277b420fbd8d6cbca86878b3f47 Mon Sep 17 00:00:00 2001
From: MagicBot <MagicBot@magicbane.com>
Date: Tue, 20 Aug 2024 12:06:35 -0400
Subject: [PATCH] PowerActionEntry parsing work.

---
 src/engine/wpak/EffectsParser.java         |   1 +
 src/engine/wpak/PowersParser.java          | 445 ++++++++++-----------
 src/engine/wpak/data/PowerActionEntry.java |   3 -
 3 files changed, 221 insertions(+), 228 deletions(-)

diff --git a/src/engine/wpak/EffectsParser.java b/src/engine/wpak/EffectsParser.java
index 15de095c..9cc41380 100644
--- a/src/engine/wpak/EffectsParser.java
+++ b/src/engine/wpak/EffectsParser.java
@@ -43,6 +43,7 @@ public class EffectsParser {
         } catch (IOException e) {
             throw new RuntimeException(e);
         }
+
         String fileContents = new String(fileData);
 
         // Iterate over effect entries from .wpak data
diff --git a/src/engine/wpak/PowersParser.java b/src/engine/wpak/PowersParser.java
index 7935d7df..b9499270 100644
--- a/src/engine/wpak/PowersParser.java
+++ b/src/engine/wpak/PowersParser.java
@@ -57,256 +57,251 @@ public class PowersParser {
 
         PowerEntry powerEntry = new PowerEntry();
 
-        try {
 
-            StringBuilder conditionString = new StringBuilder();
-            StringBuilder powerString = new StringBuilder();
+        StringBuilder conditionString = new StringBuilder();
+        StringBuilder powerString = new StringBuilder();
 
-            int endPos = 0;
+        int endPos = 0;
 
-            // Separate out any conditions from the power data
+        // Separate out any conditions from the power data
 
-            Matcher matcher = CONDITION_REGEX.matcher(powerData);
+        Matcher matcher = CONDITION_REGEX.matcher(powerData);
 
-            while (matcher.find()) {
-                conditionString.append(matcher.group().trim());
-                powerString.append(powerData, endPos, matcher.start());
-                endPos = matcher.end();
-            }
+        while (matcher.find()) {
+            conditionString.append(matcher.group().trim());
+            powerString.append(powerData, endPos, matcher.start());
+            endPos = matcher.end();
+        }
+
+        powerString.append(powerData.substring(endPos));
 
-            powerString.append(powerData.substring(endPos));
+        // Cleanup dangling tags and lines that contain a # and leading/trailing blank lines
 
-            // Cleanup dangling tags and lines that contain a # and leading/trailing blank lines
+        powerString = new StringBuilder(powerString.toString().replaceAll("CONDITIONBEGINCONDITIONEND", ""));
+        powerString = new StringBuilder(powerString.toString().replaceAll("(?m)^(\\s*#.*|\\s*)\r?\n?", ""));
 
-            powerString = new StringBuilder(powerString.toString().replaceAll("CONDITIONBEGINCONDITIONEND", ""));
-            powerString = new StringBuilder(powerString.toString().replaceAll("(?m)^(\\s*#.*|\\s*)\r?\n?", ""));
+        conditionString = new StringBuilder(conditionString.toString().replaceAll("(?m)^(\\s*#.*|\\s*)\r?\n?", ""));
 
-            conditionString = new StringBuilder(conditionString.toString().replaceAll("(?m)^(\\s*#.*|\\s*)\r?\n?", ""));
+        // Parse header line in power data
 
-            // Parse header line in power data
+        String[] lineData = powerString.toString().trim().split("\n");
+        ArrayList<String> powerHeader = new ArrayList<>();
 
-            String[] lineData = powerString.toString().trim().split("\n");
-            ArrayList<String> powerHeader = new ArrayList<>();
+        String headerString = lineData[0];
+        headerString = headerString.replace("\n", " ");
 
-            String headerString = lineData[0];
-            headerString = headerString.replace("\n", " ");
+        matcher = STRSPLIT_REGEX.matcher(headerString);
 
-            matcher = STRSPLIT_REGEX.matcher(headerString);
+        while (matcher.find())
+            powerHeader.add(matcher.group().trim());
 
-            while (matcher.find())
-                powerHeader.add(matcher.group().trim());
+        java.util.Iterator<String> iterator = powerHeader.iterator();
 
-            java.util.Iterator<String> iterator = powerHeader.iterator();
+        powerEntry.power_id = iterator.next();
+        powerEntry.power = iterator.next().replaceAll("\"", "");
 
-            powerEntry.power_id = iterator.next();
-            powerEntry.power = iterator.next().replaceAll("\"", "");
+        PowerData power = new PowerData();
+        power.power_type = mbEnums.PowerType.valueOf(iterator.next());
+        power.icon = Integer.parseInt(iterator.next());
+        power.powerBase = iterator.next().replaceAll("\"", "");
+        powerEntry.powers.add(power);
 
-            PowerData power = new PowerData();
-            power.power_type = mbEnums.PowerType.valueOf(iterator.next());
+        String nextValue = iterator.next();
+
+        // Account for second definition
+
+        if (nextValue.equals("SPELL") || nextValue.equals("SKILL")) {
+            power = new PowerData();
+            power.power_type = mbEnums.PowerType.valueOf(nextValue);
             power.icon = Integer.parseInt(iterator.next());
             power.powerBase = iterator.next().replaceAll("\"", "");
             powerEntry.powers.add(power);
-
-            String nextValue = iterator.next();
-
-            // Account for second definition
-
-            if (nextValue.equals("SPELL") || nextValue.equals("SKILL")) {
-                power = new PowerData();
-                power.power_type = mbEnums.PowerType.valueOf(nextValue);
-                power.icon = Integer.parseInt(iterator.next());
-                power.powerBase = iterator.next().replaceAll("\"", "");
-                powerEntry.powers.add(power);
-                powerEntry.target_type = mbEnums.PowerTargetType.valueOf(iterator.next());
-            } else
-                powerEntry.target_type = mbEnums.PowerTargetType.valueOf(nextValue);
-
-            powerEntry.range = Integer.parseInt(iterator.next());
-            powerEntry.areaType = mbEnums.AreaType.valueOf(iterator.next());
-            powerEntry.areaRange = Integer.parseInt(iterator.next());
-            powerEntry.excludeType = mbEnums.ExcludeType.valueOf(iterator.next());
-            powerEntry.costType = mbEnums.CostType.valueOf(iterator.next());
-            powerEntry.cost = Float.parseFloat(iterator.next());
-            powerEntry.difficulty = Float.parseFloat(iterator.next());
-            powerEntry.precision = Float.parseFloat(iterator.next());
-            powerEntry.init_time = Float.parseFloat(iterator.next().replaceAll("(\\.0)+$", ""));
-            powerEntry.release_time = Float.parseFloat(iterator.next());
-            powerEntry.recycle_time = Float.parseFloat(iterator.next());
-            powerEntry.hitRollYN = Integer.parseInt(iterator.next());
-            powerEntry.castingMode = mbEnums.CastingModeType.valueOf(iterator.next());
-            powerEntry.initAmin = Integer.parseInt(iterator.next());
-            powerEntry.releaseAnim = Integer.parseInt(iterator.next());
-            powerEntry.targetSelect = mbEnums.TargetSelectType.valueOf(iterator.next());
-
-            // Process key value pairs after header
-
-            iterator = Arrays.stream(lineData).iterator();
-            iterator.next(); // Ignore header
-
-            while (iterator.hasNext()) {
-
-                String lineValue = iterator.next();
-                String[] lineValues = lineValue.split("=");
-                String key = lineValues[0].trim();
-                ActionEntry actionEntry;
-                String[] arguments;
-                Matcher matcher1;
-                ArrayList<String> args;
-
-                switch (key) {
-                    case "ACTION":
-                        actionEntry = new ActionEntry();
-                        arguments = lineValues[1].trim().split("\\s+");
-
-                        if (powerEntry.power_id.equals("HNT-050"))
-                            Logger.error("debug");
-
-                        actionEntry.effect_id = arguments[0];
-                        actionEntry.minTrains = Integer.parseInt(arguments[1]);
-                        actionEntry.maxTrains = Integer.parseInt(arguments[2]);
-                        actionEntry.duration = Float.parseFloat(arguments[3]);
-                        actionEntry.curve = mbEnums.CompoundCurveType.valueOf(arguments[4]);
-                        actionEntry.stackingCategory = arguments[5];
-                        actionEntry.stackingPriority = Integer.parseInt(arguments[6]);
-                        actionEntry.categoryToPower = mbEnums.CategoryToPowerType.valueOf(arguments[7]);
-                        powerEntry.actionEntries.add(actionEntry);
-                        break;
-                    case "MaxLevel":
-                        powerEntry.maxLevel = Integer.parseInt(lineValues[1].trim());
-                        break;
-                    case "HateValue":
-                        arguments = lineValues[1].trim().split("\\s+");
-                        powerEntry.hateValue = Integer.parseInt(arguments[0]);
-
-                        // Not all entries have a curve.  Defaults to DefaultFlat;
-
-                        if (arguments.length > 1)
-                            powerEntry.hateCurve = mbEnums.CompoundCurveType.valueOf(arguments[1]);
-                        break;
-                    case "LOOPANIMID":
-                        powerEntry.loopAnimID = Integer.parseInt(lineValues[1].trim());
-                        break;
-                    case "GRANTOVERRIDEVAR":
-                        powerEntry.grantOverrideVar = lineValues[1].trim();
-                        break;
-                    case "DESCRIPTION":
-                        powerEntry.description.add(lineValues[1].trim());
-                        break;
-                    case "CATEGORY":
-                        powerEntry.category = lineValues[1].trim();
-                        break;
-                    case "CURVE":
-                        arguments = lineValues[1].trim().split("\\s+");
-                        powerEntry.curves.put(arguments[0], mbEnums.CompoundCurveType.valueOf(arguments[1]));
-                        break;
-                    case "EQPREREQ":
-                        EquipmentPreReq equipmentPreReq = new EquipmentPreReq();
-                        matcher1 = STRSPLIT_REGEX.matcher(lineValues[1].trim());
-                        args = new ArrayList<>();
-
-                        while (matcher1.find())
-                            args.add(matcher1.group().trim());
-
-                        equipmentPreReq.slot = mbEnums.EquipSlotType.valueOf(args.get(0));
-                        equipmentPreReq.skill = args.get(1).replaceAll("\"", "");
-                        equipmentPreReq.level = Integer.parseInt(args.get(2));
-                        powerEntry.equipmentPreReq = equipmentPreReq;
-                        break;
-                    case "CANCASTWHILEMOVING":
-                        powerEntry.canCastWhileMoving = Boolean.parseBoolean(lineValues[1].trim());
-                        break;
-                    case "CANCASTWHILEFLYING":
-                        powerEntry.canCastWhileFlying = Boolean.parseBoolean(lineValues[1].trim());
-                        break;
-                    case "BLADETRAILS":
-                        powerEntry.bladeTrails = Boolean.parseBoolean(lineValues[1].trim());
-                        break;
-                    case "EFFECTPREREQ":
-                        EffectDescription effectPreReq = new EffectDescription();
-                        arguments = lineValues[1].trim().split("\\s+");
-                        effectPreReq.effect_id = arguments[9];
-                        effectPreReq.level = Integer.parseInt(arguments[1]);
-                        effectPreReq.message = arguments[2];
-                        powerEntry.effectPreReqs.add(effectPreReq);
-                        break;
-                    case "MONSTERTYPERESTRICTS":
-                        arguments = lineValues[1].trim().split("\\s+");
-                        for (String restriction : arguments)
-                            powerEntry.monsterRestricts.add(mbEnums.MonsterType.valueOf(restriction.trim()));
-                        break;
-                    case "MONSTERTYPEPREREQS":
-                        arguments = lineValues[1].trim().split("\\s+");
-                        for (String restriction : arguments)
-                            powerEntry.monsterPrereqs.add(mbEnums.MonsterType.valueOf(restriction.trim()));
-                        break;
-                    case "SHOULDCHECKPATH":
-                        powerEntry.shouldCheckPath = Boolean.parseBoolean(lineValues[1].trim());
-                        break;
-                    case "STICKY":
-                        powerEntry.sticky = Boolean.parseBoolean(lineValues[1].trim());
-                        break;
-                    case "PULSEINFO":
-                        arguments = lineValues[1].trim().split("\\s+");
-                        powerEntry.pulseCycle = Integer.parseInt(arguments[0]);
-                        powerEntry.pulseDuration = Integer.parseInt(arguments[1]);
-                        break;
-                    case "MAXNUMMOBTARGETS":
-                        powerEntry.maxMobTargets = Integer.parseInt(lineValues[1].trim());
-                        break;
-                    case "MAXNUMPLAYERTARGETS":
-                        powerEntry.maxPlayerTargets = Integer.parseInt(lineValues[1].trim());
-                        break;
-                    case "ISADMINPOWER":
-                        powerEntry.isAdminPower = Boolean.parseBoolean(lineValues[1].trim());
-                        break;
-                    case "ISPROJECTILE":
-                        powerEntry.isProjectile = Boolean.parseBoolean(lineValues[1].trim());
-                        break;
-                    case "CASTERSPULSEPARTICLE":
-                        powerEntry.casterPulseParticle = Integer.parseInt(lineValues[1].trim());
-                        break;
-                    case "TARGETEFFECTPREREQS_ORED":
-                        EffectDescription preReq = new EffectDescription();
-                        arguments = lineValues[1].trim().split("\\s+");
-                        preReq.effect_id = arguments[0];
-                        preReq.level = Integer.parseInt(arguments[1]);
-                        powerEntry.targetEffectPrereqs.add(preReq);
-                        break;
-                    case "SOUNDS":   // Values not parsed
-                    case "APPLYDAMAGESELF":
-                    case "APPLYDAMAGECASTER":
-                    case "APPLYDAMAGEOTHER":
-                    case "APPLYDAMAGETARGET":
-                    case "APPLYEFFECTSELF":
-                    case "APPLYEFFECTOTHER":
-                    case "APPLYEFFECTCASTER":
-                    case "APPLYEFFECTTARGET":
-                    case "FIZZLEOTHER":
-                    case "FIZZLESELF":
-                    case "INITSTRING":
-                    case "SUCCESSOTHER":
-                    case "SUCCESSSELF":
-                    case "WEAROFFEFFECTOTHER":
-                    case "WEAROFFEFFECTSELF":
-                        break;
-                    default:
-                        Logger.error("Unhandled variable type:" + key + " for power: " + powerEntry.power_id);
-                }
+            powerEntry.target_type = mbEnums.PowerTargetType.valueOf(iterator.next());
+        } else
+            powerEntry.target_type = mbEnums.PowerTargetType.valueOf(nextValue);
+
+        powerEntry.range = Integer.parseInt(iterator.next());
+        powerEntry.areaType = mbEnums.AreaType.valueOf(iterator.next());
+        powerEntry.areaRange = Integer.parseInt(iterator.next());
+        powerEntry.excludeType = mbEnums.ExcludeType.valueOf(iterator.next());
+        powerEntry.costType = mbEnums.CostType.valueOf(iterator.next());
+        powerEntry.cost = Float.parseFloat(iterator.next());
+        powerEntry.difficulty = Float.parseFloat(iterator.next());
+        powerEntry.precision = Float.parseFloat(iterator.next());
+        powerEntry.init_time = Float.parseFloat(iterator.next().replaceAll("(\\.0)+$", ""));
+        powerEntry.release_time = Float.parseFloat(iterator.next());
+        powerEntry.recycle_time = Float.parseFloat(iterator.next());
+        powerEntry.hitRollYN = Integer.parseInt(iterator.next());
+        powerEntry.castingMode = mbEnums.CastingModeType.valueOf(iterator.next());
+        powerEntry.initAmin = Integer.parseInt(iterator.next());
+        powerEntry.releaseAnim = Integer.parseInt(iterator.next());
+        powerEntry.targetSelect = mbEnums.TargetSelectType.valueOf(iterator.next());
+
+        // Process key value pairs after header
+
+        iterator = Arrays.stream(lineData).iterator();
+        iterator.next(); // Ignore header
+
+        while (iterator.hasNext()) {
+
+            String lineValue = iterator.next();
+            String[] lineValues = lineValue.split("=");
+            String key = lineValues[0].trim();
+            ActionEntry actionEntry;
+            String[] arguments;
+            Matcher matcher1;
+            ArrayList<String> args;
+
+            switch (key) {
+                case "ACTION":
+                    actionEntry = new ActionEntry();
+                    arguments = lineValues[1].trim().split("\\s+");
+
+                    if (powerEntry.power_id.equals("HNT-050"))
+                        Logger.error("debug");
+
+                    actionEntry.effect_id = arguments[0];
+                    actionEntry.minTrains = Integer.parseInt(arguments[1]);
+                    actionEntry.maxTrains = Integer.parseInt(arguments[2]);
+                    actionEntry.duration = Float.parseFloat(arguments[3]);
+                    actionEntry.curve = mbEnums.CompoundCurveType.valueOf(arguments[4]);
+                    actionEntry.stackingCategory = arguments[5];
+                    actionEntry.stackingPriority = Integer.parseInt(arguments[6]);
+                    actionEntry.categoryToPower = mbEnums.CategoryToPowerType.valueOf(arguments[7]);
+                    powerEntry.actionEntries.add(actionEntry);
+                    break;
+                case "MaxLevel":
+                    powerEntry.maxLevel = Integer.parseInt(lineValues[1].trim());
+                    break;
+                case "HateValue":
+                    arguments = lineValues[1].trim().split("\\s+");
+                    powerEntry.hateValue = Integer.parseInt(arguments[0]);
+
+                    // Not all entries have a curve.  Defaults to DefaultFlat;
+
+                    if (arguments.length > 1)
+                        powerEntry.hateCurve = mbEnums.CompoundCurveType.valueOf(arguments[1]);
+                    break;
+                case "LOOPANIMID":
+                    powerEntry.loopAnimID = Integer.parseInt(lineValues[1].trim());
+                    break;
+                case "GRANTOVERRIDEVAR":
+                    powerEntry.grantOverrideVar = lineValues[1].trim();
+                    break;
+                case "DESCRIPTION":
+                    powerEntry.description.add(lineValues[1].trim());
+                    break;
+                case "CATEGORY":
+                    powerEntry.category = lineValues[1].trim();
+                    break;
+                case "CURVE":
+                    arguments = lineValues[1].trim().split("\\s+");
+                    powerEntry.curves.put(arguments[0], mbEnums.CompoundCurveType.valueOf(arguments[1]));
+                    break;
+                case "EQPREREQ":
+                    EquipmentPreReq equipmentPreReq = new EquipmentPreReq();
+                    matcher1 = STRSPLIT_REGEX.matcher(lineValues[1].trim());
+                    args = new ArrayList<>();
+
+                    while (matcher1.find())
+                        args.add(matcher1.group().trim());
+
+                    equipmentPreReq.slot = mbEnums.EquipSlotType.valueOf(args.get(0));
+                    equipmentPreReq.skill = args.get(1).replaceAll("\"", "");
+                    equipmentPreReq.level = Integer.parseInt(args.get(2));
+                    powerEntry.equipmentPreReq = equipmentPreReq;
+                    break;
+                case "CANCASTWHILEMOVING":
+                    powerEntry.canCastWhileMoving = Boolean.parseBoolean(lineValues[1].trim());
+                    break;
+                case "CANCASTWHILEFLYING":
+                    powerEntry.canCastWhileFlying = Boolean.parseBoolean(lineValues[1].trim());
+                    break;
+                case "BLADETRAILS":
+                    powerEntry.bladeTrails = Boolean.parseBoolean(lineValues[1].trim());
+                    break;
+                case "EFFECTPREREQ":
+                    EffectDescription effectPreReq = new EffectDescription();
+                    arguments = lineValues[1].trim().split("\\s+");
+                    effectPreReq.effect_id = arguments[9];
+                    effectPreReq.level = Integer.parseInt(arguments[1]);
+                    effectPreReq.message = arguments[2];
+                    powerEntry.effectPreReqs.add(effectPreReq);
+                    break;
+                case "MONSTERTYPERESTRICTS":
+                    arguments = lineValues[1].trim().split("\\s+");
+                    for (String restriction : arguments)
+                        powerEntry.monsterRestricts.add(mbEnums.MonsterType.valueOf(restriction.trim()));
+                    break;
+                case "MONSTERTYPEPREREQS":
+                    arguments = lineValues[1].trim().split("\\s+");
+                    for (String restriction : arguments)
+                        powerEntry.monsterPrereqs.add(mbEnums.MonsterType.valueOf(restriction.trim()));
+                    break;
+                case "SHOULDCHECKPATH":
+                    powerEntry.shouldCheckPath = Boolean.parseBoolean(lineValues[1].trim());
+                    break;
+                case "STICKY":
+                    powerEntry.sticky = Boolean.parseBoolean(lineValues[1].trim());
+                    break;
+                case "PULSEINFO":
+                    arguments = lineValues[1].trim().split("\\s+");
+                    powerEntry.pulseCycle = Integer.parseInt(arguments[0]);
+                    powerEntry.pulseDuration = Integer.parseInt(arguments[1]);
+                    break;
+                case "MAXNUMMOBTARGETS":
+                    powerEntry.maxMobTargets = Integer.parseInt(lineValues[1].trim());
+                    break;
+                case "MAXNUMPLAYERTARGETS":
+                    powerEntry.maxPlayerTargets = Integer.parseInt(lineValues[1].trim());
+                    break;
+                case "ISADMINPOWER":
+                    powerEntry.isAdminPower = Boolean.parseBoolean(lineValues[1].trim());
+                    break;
+                case "ISPROJECTILE":
+                    powerEntry.isProjectile = Boolean.parseBoolean(lineValues[1].trim());
+                    break;
+                case "CASTERSPULSEPARTICLE":
+                    powerEntry.casterPulseParticle = Integer.parseInt(lineValues[1].trim());
+                    break;
+                case "TARGETEFFECTPREREQS_ORED":
+                    EffectDescription preReq = new EffectDescription();
+                    arguments = lineValues[1].trim().split("\\s+");
+                    preReq.effect_id = arguments[0];
+                    preReq.level = Integer.parseInt(arguments[1]);
+                    powerEntry.targetEffectPrereqs.add(preReq);
+                    break;
+                case "SOUNDS":   // Values not parsed
+                case "APPLYDAMAGESELF":
+                case "APPLYDAMAGECASTER":
+                case "APPLYDAMAGEOTHER":
+                case "APPLYDAMAGETARGET":
+                case "APPLYEFFECTSELF":
+                case "APPLYEFFECTOTHER":
+                case "APPLYEFFECTCASTER":
+                case "APPLYEFFECTTARGET":
+                case "FIZZLEOTHER":
+                case "FIZZLESELF":
+                case "INITSTRING":
+                case "SUCCESSOTHER":
+                case "SUCCESSSELF":
+                case "WEAROFFEFFECTOTHER":
+                case "WEAROFFEFFECTSELF":
+                    break;
+                default:
+                    Logger.error("Unhandled variable type:" + key + " for power: " + powerEntry.power_id);
             }
+        }
 
-            // Parse power conditions
+        // Parse power conditions
 
-            if (conditionString.toString().isEmpty() == false) {
-                String[] conditions = conditionString.toString().split("\n");
+        if (!conditionString.toString().isEmpty()) {
+            String[] conditions = conditionString.toString().split("\n");
 
-                for (String condition : conditions) {
-                    String[] parameters = condition.trim().split("\\s+");
-                    powerEntry.conditions.put(parameters[0], Float.parseFloat(parameters[1]));
-                }
+            for (String condition : conditions) {
+                String[] parameters = condition.trim().split("\\s+");
+                powerEntry.conditions.put(parameters[0], Float.parseFloat(parameters[1]));
             }
-
-        } catch (Exception e) {
-            Logger.error(powerEntry.power_id + " " + e);
         }
 
         return powerEntry;
diff --git a/src/engine/wpak/data/PowerActionEntry.java b/src/engine/wpak/data/PowerActionEntry.java
index b88e50e6..f79921ff 100644
--- a/src/engine/wpak/data/PowerActionEntry.java
+++ b/src/engine/wpak/data/PowerActionEntry.java
@@ -34,7 +34,4 @@ public class PowerActionEntry {
     public boolean applyEffectBlank = false;
     public boolean wearOffEffectBlank = false;
 
-
-
-
 }