Read named grant keys and signed values from new COBJECTS JSON
Grant pair lists now carry name strings ("HLR-021", "Unarmed Combat")
instead of integer hashes, so they are stored as name -> value maps.
Unresolved hashes are kept as their decimal string and logged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
b56d4ee243
commit
1ac5a248db
5 files changed
+52
-32
No files matched your search
+33
-8
@@ -121,8 +121,6 @@ public class CacheParserUtil {
|
||||
}
|
||||
|
||||
// [{keyName: "Strength", valueName: 40}, ...] -> enum map
|
||||
// Negative values are stored unsigned in the JSON (-5 is 4294967291),
|
||||
// so values are read as long and wrapped to int.
|
||||
|
||||
public static <E extends Enum<E>> EnumMap<E, Integer> readEnumValueMap(Class<E> enumClass, JSONArray entriesJson,
|
||||
String keyName, String valueName,
|
||||
@@ -137,7 +135,7 @@ public class CacheParserUtil {
|
||||
enumValue = readEnum(enumClass, entry.getString(keyName), templateId, fieldName);
|
||||
|
||||
if (enumValue != null)
|
||||
enumMap.put(enumValue, (int) entry.getLong(valueName));
|
||||
enumMap.put(enumValue, entry.getInt(valueName));
|
||||
}
|
||||
|
||||
return enumMap;
|
||||
@@ -176,7 +174,7 @@ public class CacheParserUtil {
|
||||
return enumMap;
|
||||
}
|
||||
|
||||
// Values are read as long and wrapped to int so unsigned 32-bit hashes survive.
|
||||
// Hash and flag fields are still unsigned in the JSON; read as long and wrapped to int.
|
||||
|
||||
public static int[] readIntArray(JSONArray valuesJson) {
|
||||
|
||||
@@ -258,7 +256,34 @@ public class CacheParserUtil {
|
||||
return userPowerActions;
|
||||
}
|
||||
|
||||
public static ArrayList<PowerGrant> readPowerGrants(JSONArray grantsJson) {
|
||||
// [[key, value], ...] -> map in file order. Keys are names when the exporter
|
||||
// knows the hash, otherwise the raw hash, which is kept as its decimal string.
|
||||
|
||||
public static LinkedHashMap<String, Integer> readGrantPairs(JSONArray pairsJson, int templateId, String fieldName) {
|
||||
|
||||
LinkedHashMap<String, Integer> grantPairs = new LinkedHashMap<>();
|
||||
JSONArray pair;
|
||||
Object key;
|
||||
String keyName;
|
||||
|
||||
for (int i = 0; i < pairsJson.length(); i++) {
|
||||
pair = pairsJson.getJSONArray(i);
|
||||
key = pair.get(0);
|
||||
|
||||
if (key instanceof String) {
|
||||
keyName = (String) key;
|
||||
} else {
|
||||
keyName = Long.toString(pair.getLong(0));
|
||||
Logger.warn(templateId + ": " + fieldName + " has unresolved hash " + keyName);
|
||||
}
|
||||
|
||||
grantPairs.put(keyName, pair.getInt(1));
|
||||
}
|
||||
|
||||
return grantPairs;
|
||||
}
|
||||
|
||||
public static ArrayList<PowerGrant> readPowerGrants(JSONArray grantsJson, int templateId) {
|
||||
|
||||
ArrayList<PowerGrant> powerGrants = new ArrayList<>();
|
||||
JSONObject entry;
|
||||
@@ -270,9 +295,9 @@ public class CacheParserUtil {
|
||||
|
||||
powerGrant.power_type = entry.getString("power_type");
|
||||
powerGrant.power_value = entry.getInt("power_value");
|
||||
powerGrant.power_granted_attrs = entry.getJSONArray("power_granted_attrs");
|
||||
powerGrant.power_granted_skills.addAll(readIntArrays(entry.getJSONArray("power_granted_skills")));
|
||||
powerGrant.power_granted_powers.addAll(readIntArrays(entry.getJSONArray("power_granted_powers")));
|
||||
powerGrant.power_granted_attrs.putAll(readGrantPairs(entry.getJSONArray("power_granted_attrs"), templateId, "power_granted_attrs"));
|
||||
powerGrant.power_granted_skills.putAll(readGrantPairs(entry.getJSONArray("power_granted_skills"), templateId, "power_granted_skills"));
|
||||
powerGrant.power_granted_powers.putAll(readGrantPairs(entry.getJSONArray("power_granted_powers"), templateId, "power_granted_powers"));
|
||||
powerGrant.power_monster_types = entry.getJSONArray("power_monster_types");
|
||||
|
||||
powerGrants.add(powerGrant);
|
||||
|
||||
+1
-1
@@ -149,7 +149,7 @@ public class DeedParser {
|
||||
deed.item_rank_req = deedJson.getInt("item_rank_req");
|
||||
deed.item_sex_req = CacheParserUtil.readEnum(mbEnums.SexType.class, deedJson.getString("item_sex_req"), templateId, "item_sex_req");
|
||||
deed.item_user_power_action.addAll(CacheParserUtil.readUserPowerActions(deedJson.getJSONArray("item_user_power_action")));
|
||||
deed.item_power_grant.addAll(CacheParserUtil.readPowerGrants(deedJson.getJSONArray("item_power_grant")));
|
||||
deed.item_power_grant.addAll(CacheParserUtil.readPowerGrants(deedJson.getJSONArray("item_power_grant"), templateId));
|
||||
deed.item_power_action.putAll(CacheParserUtil.readPowerActions(deedJson.getJSONArray("item_power_action")));
|
||||
deed.item_sheathable = deedJson.getBoolean("item_sheathable");
|
||||
deed.item_has_stub = deedJson.getBoolean("item_has_stub");
|
||||
|
||||
+7
-4
@@ -165,7 +165,7 @@ public class RuneParser {
|
||||
rune.item_rank_req = runeJson.getInt("item_rank_req");
|
||||
rune.item_sex_req = CacheParserUtil.readEnum(mbEnums.SexType.class, runeJson.getString("item_sex_req"), templateId, "item_sex_req");
|
||||
rune.item_user_power_action.addAll(CacheParserUtil.readUserPowerActions(runeJson.getJSONArray("item_user_power_action")));
|
||||
rune.item_power_grant.addAll(CacheParserUtil.readPowerGrants(runeJson.getJSONArray("item_power_grant")));
|
||||
rune.item_power_grant.addAll(CacheParserUtil.readPowerGrants(runeJson.getJSONArray("item_power_grant"), templateId));
|
||||
rune.item_power_action.putAll(CacheParserUtil.readPowerActions(runeJson.getJSONArray("item_power_action")));
|
||||
rune.item_sheathable = runeJson.getBoolean("item_sheathable");
|
||||
rune.item_has_stub = runeJson.getBoolean("item_has_stub");
|
||||
@@ -239,9 +239,12 @@ public class RuneParser {
|
||||
|
||||
skillGrant.skill_type = skillGrantJson.getString("skill_type");
|
||||
skillGrant.skill_value = skillGrantJson.getInt("skill_value");
|
||||
skillGrant.skill_granted_attrs = skillGrantJson.getJSONArray("skill_granted_attrs");
|
||||
skillGrant.skill_granted_skills.addAll(CacheParserUtil.readIntArrays(skillGrantJson.getJSONArray("skill_granted_skills")));
|
||||
skillGrant.skill_granted_powers = skillGrantJson.getJSONArray("skill_granted_powers");
|
||||
skillGrant.skill_granted_attrs.putAll(CacheParserUtil.readGrantPairs(skillGrantJson.getJSONArray("skill_granted_attrs"),
|
||||
templateId, "skill_granted_attrs"));
|
||||
skillGrant.skill_granted_skills.putAll(CacheParserUtil.readGrantPairs(skillGrantJson.getJSONArray("skill_granted_skills"),
|
||||
templateId, "skill_granted_skills"));
|
||||
skillGrant.skill_granted_powers.putAll(CacheParserUtil.readGrantPairs(skillGrantJson.getJSONArray("skill_granted_powers"),
|
||||
templateId, "skill_granted_powers"));
|
||||
skillGrant.skill_monster_types = skillGrantJson.getJSONArray("skill_monster_types");
|
||||
|
||||
rune.rune_skill_grant.add(skillGrant);
|
||||
|
||||
@@ -10,24 +10,18 @@ package engine.parsers.objects;
|
||||
|
||||
import org.json.JSONArray;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedHashMap;
|
||||
|
||||
// One entry of item_power_grant.
|
||||
//
|
||||
// power_granted_skills and power_granted_powers entries look like
|
||||
// [hash, value] pairs (first element is a 32-bit string hash, some
|
||||
// exceed Integer.MAX_VALUE in the JSON and are stored wrapped to int).
|
||||
// This reading is from the data only and has not been confirmed in the client.
|
||||
//
|
||||
// power_granted_attrs and power_monster_types are empty in every DEED and
|
||||
// RUNE file, so their shape is unknown and they are kept as raw JSON.
|
||||
// The granted lists are [key, value] pairs, unsigned key and signed value (sb.exe 0x6D7640).
|
||||
// power_monster_types is empty in every DEED and RUNE file, so it is kept as raw JSON.
|
||||
|
||||
public class PowerGrant {
|
||||
|
||||
public String power_type;
|
||||
public int power_value;
|
||||
public JSONArray power_granted_attrs;
|
||||
public final ArrayList<int[]> power_granted_skills = new ArrayList<>();
|
||||
public final ArrayList<int[]> power_granted_powers = new ArrayList<>();
|
||||
public final LinkedHashMap<String, Integer> power_granted_attrs = new LinkedHashMap<>();
|
||||
public final LinkedHashMap<String, Integer> power_granted_skills = new LinkedHashMap<>();
|
||||
public final LinkedHashMap<String, Integer> power_granted_powers = new LinkedHashMap<>();
|
||||
public JSONArray power_monster_types;
|
||||
}
|
||||
@@ -189,18 +189,16 @@ public class RuneTemplate {
|
||||
public int rune_natural_power_attack;
|
||||
public final HashMap<String, String> rune_sparse_data = new HashMap<>();
|
||||
|
||||
// One entry of rune_skill_grant.
|
||||
// skill_granted_skills entries look like [hash, value] pairs; not confirmed in the client.
|
||||
// skill_granted_attrs, skill_granted_powers and skill_monster_types are empty
|
||||
// in every RUNE file, so they are kept as raw JSON.
|
||||
// One entry of rune_skill_grant; same layout as PowerGrant.
|
||||
// skill_monster_types is empty in every RUNE file, so it is kept as raw JSON.
|
||||
|
||||
public static class SkillGrant {
|
||||
|
||||
public String skill_type;
|
||||
public int skill_value;
|
||||
public JSONArray skill_granted_attrs;
|
||||
public final ArrayList<int[]> skill_granted_skills = new ArrayList<>();
|
||||
public JSONArray skill_granted_powers;
|
||||
public final LinkedHashMap<String, Integer> skill_granted_attrs = new LinkedHashMap<>();
|
||||
public final LinkedHashMap<String, Integer> skill_granted_skills = new LinkedHashMap<>();
|
||||
public final LinkedHashMap<String, Integer> skill_granted_powers = new LinkedHashMap<>();
|
||||
public JSONArray skill_monster_types;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user