diff --git a/mods/Albion/Meta/3DFLOOR0.json b/mods/Albion/Meta/3DFLOOR0.json
index c5f2e16be..4961569d5 100644
--- a/mods/Albion/Meta/3DFLOOR0.json
+++ b/mods/Albion/Meta/3DFLOOR0.json
@@ -1,101 +1,101 @@
{
- "000": { "Id": "floor.1", "PaletteId": 3 },
- "001": { "PaletteId": 3 },
- "002": { "PaletteId": 3 },
- "003": { "PaletteId": 3 },
- "004": { "PaletteId": 3 },
- "005": { "PaletteId": 3 },
- "006": { "PaletteId": 3 },
- "007": { "PaletteId": 3 },
- "008": { "PaletteId": 3 },
- "009": { "PaletteId": 3 },
- "010": { "PaletteId": 3 },
- "011": { "PaletteId": 3 },
- "012": { "PaletteId": 3 },
- "013": { "PaletteId": 3 },
- "014": { "PaletteId": 3 },
- "015": { "PaletteId": 3 },
- "016": { "PaletteId": 3 },
- "017": { "PaletteId": 3 },
- "018": { "PaletteId": 3 },
- "019": { "PaletteId": 3 },
- "020": { "PaletteId": 3 },
- "021": { "PaletteId": 3 },
- "022": { "PaletteId": 3 },
- "023": { "PaletteId": 3 },
- "024": { "PaletteId": 3 },
- "025": { "PaletteId": 3 },
- "026": { "PaletteId": 3 },
- "027": { "PaletteId": 3 },
- "028": { "PaletteId": 3 },
- "029": { "PaletteId": 3 },
- "030": { "PaletteId": 3 },
- "031": { "PaletteId": 7 },
- "032": { "PaletteId": 7 },
- "033": { "PaletteId": 7 },
- "034": { "PaletteId": 7 },
- "035": { "PaletteId": 7 },
- "036": { "PaletteId": 7 },
- "037": { "PaletteId": 7 },
- "038": { "PaletteId": 7 },
- "039": { "PaletteId": 7 },
- "040": { "PaletteId": 8 },
- "041": { "PaletteId": 8 },
- "042": { "PaletteId": 8 },
- "043": { "PaletteId": 8 },
- "044": { "PaletteId": 8 },
- "045": { "PaletteId": 8 },
- "046": { "PaletteId": 8 },
- "047": { "PaletteId": 8 },
- "048": { "PaletteId": 8 },
- "049": { "PaletteId": 8 },
- "050": { "PaletteId": 13 },
- "051": { "PaletteId": 13 },
- "052": { "PaletteId": 13 },
- "053": { "PaletteId": 13 },
- "054": { "PaletteId": 13 },
- "055": { "PaletteId": 13 },
- "056": { "PaletteId": 13 },
- "057": { "PaletteId": 13 },
- "058": { "PaletteId": 29 },
- "059": { "PaletteId": 29 },
- "060": { "PaletteId": 29 },
- "061": { "PaletteId": 29 },
- "062": { "PaletteId": 29 },
- "063": { "PaletteId": 29 },
- "064": { "PaletteId": 29 },
- "065": { "PaletteId": 29 },
- "066": { "PaletteId": 15 },
- "067": { "PaletteId": 15 },
- "068": { "PaletteId": 15 },
- "069": { "PaletteId": 15 },
- "070": { "PaletteId": 15 },
- "071": { "PaletteId": 15 },
- "072": { "PaletteId": 15 },
- "073": { "PaletteId": 15 },
- "074": { "PaletteId": 15 },
- "075": { "PaletteId": 15 },
- "076": { "PaletteId": 15 },
- "077": { "PaletteId": 15 },
- "078": { "PaletteId": 15 },
- "079": { "PaletteId": 15 },
- "080": { "PaletteId": 18 },
- "081": { "PaletteId": 18 },
- "082": { "PaletteId": 18 },
- "083": { "PaletteId": 18 },
- "084": { "PaletteId": 18 },
- "085": { "PaletteId": 18 },
- "086": { "PaletteId": 15 },
- "087": { "PaletteId": 15 },
- "088": { "PaletteId": 15 },
- "089": { "PaletteId": 15 },
- "090": { "PaletteId": 18 },
- "091": { "PaletteId": 18 },
- "092": { "PaletteId": 18 },
- "093": { "PaletteId": 22 },
- "094": { "PaletteId": 22 },
- "095": { "PaletteId": 22 },
- "096": { "PaletteId": 22 },
- "097": { "PaletteId": 22 },
- "098": { "PaletteId": 22 }
+ "floor.1": { "Palette": "pal.3" },
+ "floor.2": { "Palette": "pal.3" },
+ "floor.3": { "Palette": "pal.3" },
+ "floor.4": { "Palette": "pal.3" },
+ "floor.5": { "Palette": "pal.3" },
+ "floor.6": { "Palette": "pal.3" },
+ "floor.7": { "Palette": "pal.3" },
+ "floor.8": { "Palette": "pal.3" },
+ "floor.9": { "Palette": "pal.3" },
+ "floor.10": { "Palette": "pal.3" },
+ "floor.11": { "Palette": "pal.3" },
+ "floor.12": { "Palette": "pal.3" },
+ "floor.13": { "Palette": "pal.3" },
+ "floor.14": { "Palette": "pal.3" },
+ "floor.15": { "Palette": "pal.3" },
+ "floor.16": { "Palette": "pal.3" },
+ "floor.17": { "Palette": "pal.3" },
+ "floor.18": { "Palette": "pal.3" },
+ "floor.19": { "Palette": "pal.3" },
+ "floor.20": { "Palette": "pal.3" },
+ "floor.21": { "Palette": "pal.3" },
+ "floor.22": { "Palette": "pal.3" },
+ "floor.23": { "Palette": "pal.3" },
+ "floor.24": { "Palette": "pal.3" },
+ "floor.25": { "Palette": "pal.3" },
+ "floor.26": { "Palette": "pal.3" },
+ "floor.27": { "Palette": "pal.3" },
+ "floor.28": { "Palette": "pal.3" },
+ "floor.29": { "Palette": "pal.3" },
+ "floor.30": { "Palette": "pal.3" },
+ "floor.31": { "Palette": "pal.3" },
+ "floor.32": { "Palette": "pal.7" },
+ "floor.33": { "Palette": "pal.7" },
+ "floor.34": { "Palette": "pal.7" },
+ "floor.35": { "Palette": "pal.7" },
+ "floor.36": { "Palette": "pal.7" },
+ "floor.37": { "Palette": "pal.7" },
+ "floor.38": { "Palette": "pal.7" },
+ "floor.39": { "Palette": "pal.7" },
+ "floor.40": { "Palette": "pal.7" },
+ "floor.41": { "Palette": "pal.8" },
+ "floor.42": { "Palette": "pal.8" },
+ "floor.43": { "Palette": "pal.8" },
+ "floor.44": { "Palette": "pal.8" },
+ "floor.45": { "Palette": "pal.8" },
+ "floor.46": { "Palette": "pal.8" },
+ "floor.47": { "Palette": "pal.8" },
+ "floor.48": { "Palette": "pal.8" },
+ "floor.49": { "Palette": "pal.8" },
+ "floor.50": { "Palette": "pal.8" },
+ "floor.51": { "Palette": "pal.13" },
+ "floor.52": { "Palette": "pal.13" },
+ "floor.53": { "Palette": "pal.13" },
+ "floor.54": { "Palette": "pal.13" },
+ "floor.55": { "Palette": "pal.13" },
+ "floor.56": { "Palette": "pal.13" },
+ "floor.57": { "Palette": "pal.13" },
+ "floor.58": { "Palette": "pal.13" },
+ "floor.59": { "Palette": "pal.29" },
+ "floor.60": { "Palette": "pal.29" },
+ "floor.61": { "Palette": "pal.29" },
+ "floor.62": { "Palette": "pal.29" },
+ "floor.63": { "Palette": "pal.29" },
+ "floor.64": { "Palette": "pal.29" },
+ "floor.65": { "Palette": "pal.29" },
+ "floor.66": { "Palette": "pal.29" },
+ "floor.67": { "Palette": "pal.15" },
+ "floor.68": { "Palette": "pal.15" },
+ "floor.69": { "Palette": "pal.15" },
+ "floor.70": { "Palette": "pal.15" },
+ "floor.71": { "Palette": "pal.15" },
+ "floor.72": { "Palette": "pal.15" },
+ "floor.73": { "Palette": "pal.15" },
+ "floor.74": { "Palette": "pal.15" },
+ "floor.75": { "Palette": "pal.15" },
+ "floor.76": { "Palette": "pal.15" },
+ "floor.77": { "Palette": "pal.15" },
+ "floor.78": { "Palette": "pal.15" },
+ "floor.79": { "Palette": "pal.15" },
+ "floor.80": { "Palette": "pal.15" },
+ "floor.81": { "Palette": "pal.18" },
+ "floor.82": { "Palette": "pal.18" },
+ "floor.83": { "Palette": "pal.18" },
+ "floor.84": { "Palette": "pal.18" },
+ "floor.85": { "Palette": "pal.18" },
+ "floor.86": { "Palette": "pal.18" },
+ "floor.87": { "Palette": "pal.15" },
+ "floor.88": { "Palette": "pal.15" },
+ "floor.89": { "Palette": "pal.15" },
+ "floor.90": { "Palette": "pal.15" },
+ "floor.91": { "Palette": "pal.18" },
+ "floor.92": { "Palette": "pal.18" },
+ "floor.93": { "Palette": "pal.18" },
+ "floor.94": { "Palette": "pal.22" },
+ "floor.95": { "Palette": "pal.22" },
+ "floor.96": { "Palette": "pal.22" },
+ "floor.97": { "Palette": "pal.22" },
+ "floor.98": { "Palette": "pal.22" },
+ "floor.99": { "Palette": "pal.22" }
}
diff --git a/mods/Albion/Meta/3DFLOOR1.json b/mods/Albion/Meta/3DFLOOR1.json
index ffc86f6a3..be3389287 100644
--- a/mods/Albion/Meta/3DFLOOR1.json
+++ b/mods/Albion/Meta/3DFLOOR1.json
@@ -1,102 +1,102 @@
{
- "000": { "Id": "floor.100", "PaletteId": 22 },
- "001": { "PaletteId": 22 },
- "002": { "PaletteId": 22 },
- "003": { "PaletteId": 22 },
- "004": { "PaletteId": 22 },
- "005": { "PaletteId": 22 },
- "006": { "PaletteId": 22 },
- "007": { "PaletteId": 22 },
- "008": { "PaletteId": 22 },
- "009": { "PaletteId": 22 },
- "010": { "PaletteId": 25 },
- "011": { "PaletteId": 25 },
- "012": { "PaletteId": 25 },
- "013": { "PaletteId": 25 },
- "014": { "PaletteId": 25 },
- "015": { "PaletteId": 25 },
- "016": { "PaletteId": 25 },
- "017": { "PaletteId": 25 },
- "018": { "PaletteId": 25 },
- "019": { "PaletteId": 25 },
- "020": { "PaletteId": 25 },
- "021": { "PaletteId": 25 },
- "022": { "PaletteId": 25 },
- "023": { "PaletteId": 25 },
- "024": { "PaletteId": 25 },
- "025": { "PaletteId": 25 },
- "026": { "PaletteId": 25 },
- "027": { "PaletteId": 25 },
- "028": { "PaletteId": 25 },
- "029": { "PaletteId": 25 },
- "030": { "PaletteId": 25 },
- "031": { "PaletteId": 25 },
- "032": { "PaletteId": 25 },
- "033": { "PaletteId": 25 },
- "034": { "PaletteId": 25 },
- "035": { "PaletteId": 25 },
- "036": { "PaletteId": 25 },
- "037": { "PaletteId": 25 },
- "038": { "PaletteId": 25 },
- "039": { "PaletteId": 25 },
- "040": { "PaletteId": 25 },
- "041": { "PaletteId": 25 },
- "042": { "PaletteId": 25 },
- "043": { "PaletteId": 25 },
- "044": { "PaletteId": 25 },
- "045": { "PaletteId": 25 },
- "046": { "PaletteId": 25 },
- "047": { "PaletteId": 25 },
- "048": { "PaletteId": 25 },
- "049": { "PaletteId": 25 },
- "050": { "PaletteId": 25 },
- "051": { "PaletteId": 25 },
- "052": { "PaletteId": 25 },
- "053": { "PaletteId": 25 },
- "054": { "PaletteId": 25 },
- "055": { "PaletteId": 22 },
- "056": { "PaletteId": 22 },
- "057": { "PaletteId": 22 },
- "058": { "PaletteId": 22 },
- "059": { "PaletteId": 22 },
- "060": { "PaletteId": 22 },
- "061": { "PaletteId": 22 },
- "062": { "PaletteId": 22 },
- "063": { "PaletteId": 22 },
- "064": { "PaletteId": 22 },
- "065": { "PaletteId": 26 },
- "066": { "PaletteId": 26 },
- "067": { "PaletteId": 26 },
- "068": { "PaletteId": 26 },
- "069": { "PaletteId": 26 },
- "070": { "PaletteId": 26 },
- "071": { "PaletteId": 26 },
- "072": { "PaletteId": 26 },
- "073": { "PaletteId": 26 },
- "074": { "PaletteId": 26 },
- "075": { "PaletteId": 26 },
- "076": { "PaletteId": 26 },
- "077": { "PaletteId": 7 },
- "078": { "PaletteId": 7 },
- "079": { "PaletteId": 7 },
- "080": { "PaletteId": 7 },
- "081": { "PaletteId": 7 },
- "082": { "PaletteId": 7 },
- "083": { "PaletteId": 7 },
- "084": { "PaletteId": 7 },
- "085": { "PaletteId": 7 },
- "086": { "PaletteId": 7 },
- "087": { "PaletteId": 7 },
- "088": { "PaletteId": 7 },
- "089": { "PaletteId": 7 },
- "090": { "PaletteId": 7 },
- "091": { "PaletteId": 7 },
- "092": { "PaletteId": 7 },
- "093": { "PaletteId": 8 },
- "094": { "PaletteId": 8 },
- "095": { "PaletteId": 8 },
- "096": { "PaletteId": 8 },
- "097": { "PaletteId": 8 },
- "098": { "PaletteId": 8 },
- "099": { "PaletteId": 25 }
+ "floor.100": { "Palette": "pal.22" },
+ "floor.101": { "Palette": "pal.22" },
+ "floor.102": { "Palette": "pal.22" },
+ "floor.103": { "Palette": "pal.22" },
+ "floor.104": { "Palette": "pal.22" },
+ "floor.105": { "Palette": "pal.22" },
+ "floor.106": { "Palette": "pal.22" },
+ "floor.107": { "Palette": "pal.22" },
+ "floor.108": { "Palette": "pal.22" },
+ "floor.109": { "Palette": "pal.22" },
+ "floor.110": { "Palette": "pal.25" },
+ "floor.111": { "Palette": "pal.25" },
+ "floor.112": { "Palette": "pal.25" },
+ "floor.113": { "Palette": "pal.25" },
+ "floor.114": { "Palette": "pal.25" },
+ "floor.115": { "Palette": "pal.25" },
+ "floor.116": { "Palette": "pal.25" },
+ "floor.117": { "Palette": "pal.25" },
+ "floor.118": { "Palette": "pal.25" },
+ "floor.119": { "Palette": "pal.25" },
+ "floor.120": { "Palette": "pal.25" },
+ "floor.121": { "Palette": "pal.25" },
+ "floor.122": { "Palette": "pal.25" },
+ "floor.123": { "Palette": "pal.25" },
+ "floor.124": { "Palette": "pal.25" },
+ "floor.125": { "Palette": "pal.25" },
+ "floor.126": { "Palette": "pal.25" },
+ "floor.127": { "Palette": "pal.25" },
+ "floor.128": { "Palette": "pal.25" },
+ "floor.129": { "Palette": "pal.25" },
+ "floor.130": { "Palette": "pal.25" },
+ "floor.131": { "Palette": "pal.25" },
+ "floor.132": { "Palette": "pal.25" },
+ "floor.133": { "Palette": "pal.25" },
+ "floor.134": { "Palette": "pal.25" },
+ "floor.135": { "Palette": "pal.25" },
+ "floor.136": { "Palette": "pal.25" },
+ "floor.137": { "Palette": "pal.25" },
+ "floor.138": { "Palette": "pal.25" },
+ "floor.139": { "Palette": "pal.25" },
+ "floor.140": { "Palette": "pal.25" },
+ "floor.141": { "Palette": "pal.25" },
+ "floor.142": { "Palette": "pal.25" },
+ "floor.143": { "Palette": "pal.25" },
+ "floor.144": { "Palette": "pal.25" },
+ "floor.145": { "Palette": "pal.25" },
+ "floor.146": { "Palette": "pal.25" },
+ "floor.147": { "Palette": "pal.25" },
+ "floor.148": { "Palette": "pal.25" },
+ "floor.149": { "Palette": "pal.25" },
+ "floor.150": { "Palette": "pal.25" },
+ "floor.151": { "Palette": "pal.25" },
+ "floor.152": { "Palette": "pal.25" },
+ "floor.153": { "Palette": "pal.25" },
+ "floor.154": { "Palette": "pal.25" },
+ "floor.155": { "Palette": "pal.22" },
+ "floor.156": { "Palette": "pal.22" },
+ "floor.157": { "Palette": "pal.22" },
+ "floor.158": { "Palette": "pal.22" },
+ "floor.159": { "Palette": "pal.22" },
+ "floor.160": { "Palette": "pal.22" },
+ "floor.161": { "Palette": "pal.22" },
+ "floor.162": { "Palette": "pal.22" },
+ "floor.163": { "Palette": "pal.22" },
+ "floor.164": { "Palette": "pal.22" },
+ "floor.165": { "Palette": "pal.26" },
+ "floor.166": { "Palette": "pal.26" },
+ "floor.167": { "Palette": "pal.26" },
+ "floor.168": { "Palette": "pal.26" },
+ "floor.169": { "Palette": "pal.26" },
+ "floor.170": { "Palette": "pal.26" },
+ "floor.171": { "Palette": "pal.26" },
+ "floor.172": { "Palette": "pal.26" },
+ "floor.173": { "Palette": "pal.26" },
+ "floor.174": { "Palette": "pal.26" },
+ "floor.175": { "Palette": "pal.26" },
+ "floor.176": { "Palette": "pal.26" },
+ "floor.177": { "Palette": "pal.7" },
+ "floor.178": { "Palette": "pal.7" },
+ "floor.179": { "Palette": "pal.7" },
+ "floor.180": { "Palette": "pal.7" },
+ "floor.181": { "Palette": "pal.7" },
+ "floor.182": { "Palette": "pal.7" },
+ "floor.183": { "Palette": "pal.7" },
+ "floor.184": { "Palette": "pal.7" },
+ "floor.185": { "Palette": "pal.7" },
+ "floor.186": { "Palette": "pal.7" },
+ "floor.187": { "Palette": "pal.7" },
+ "floor.188": { "Palette": "pal.7" },
+ "floor.189": { "Palette": "pal.7" },
+ "floor.190": { "Palette": "pal.7" },
+ "floor.191": { "Palette": "pal.7" },
+ "floor.192": { "Palette": "pal.7" },
+ "floor.193": { "Palette": "pal.8" },
+ "floor.194": { "Palette": "pal.8" },
+ "floor.195": { "Palette": "pal.8" },
+ "floor.196": { "Palette": "pal.8" },
+ "floor.197": { "Palette": "pal.8" },
+ "floor.198": { "Palette": "pal.8" },
+ "floor.199": { "Palette": "pal.25" }
}
diff --git a/mods/Albion/Meta/3DFLOOR2.json b/mods/Albion/Meta/3DFLOOR2.json
index 6ae1981cf..b3710371d 100644
--- a/mods/Albion/Meta/3DFLOOR2.json
+++ b/mods/Albion/Meta/3DFLOOR2.json
@@ -1,85 +1,85 @@
{
- "000": { "Id": "floor.200", "PaletteId": 25 },
- "001": { "PaletteId": 25 },
- "002": { "PaletteId": 25 },
- "003": { "PaletteId": 25 },
- "004": { "PaletteId": 25 },
- "005": { "PaletteId": 25 },
- "006": { "PaletteId": 25 },
- "007": { "PaletteId": 25 },
- "008": { "PaletteId": 25 },
- "009": { "PaletteId": 25 },
- "010": { "PaletteId": 25 },
- "011": { "PaletteId": 25 },
- "012": { "PaletteId": 25 },
- "013": { "PaletteId": 25 },
- "014": { "PaletteId": 25 },
- "015": { "PaletteId": 25 },
- "016": { "PaletteId": 25 },
- "017": { "PaletteId": 25 },
- "018": { "PaletteId": 25 },
- "019": { "PaletteId": 25 },
- "020": { "PaletteId": 25 },
- "021": { "PaletteId": 25 },
- "022": { "PaletteId": 25 },
- "023": { "PaletteId": 25 },
- "024": { "PaletteId": 25 },
- "025": { "PaletteId": 25 },
- "026": { "PaletteId": 25 },
- "027": { "PaletteId": 25 },
- "028": { "PaletteId": 25 },
- "029": { "PaletteId": 25 },
- "030": { "PaletteId": 25 },
- "031": { "PaletteId": 25 },
- "032": { "PaletteId": 25 },
- "033": { "PaletteId": 25 },
- "034": { "PaletteId": 25 },
- "035": { "PaletteId": 7 },
- "036": { "PaletteId": 7 },
- "037": { "PaletteId": 7 },
- "038": { "PaletteId": 7 },
- "039": { "PaletteId": 7 },
- "040": { "PaletteId": 7 },
- "041": { "PaletteId": 7 },
- "042": { "PaletteId": 18 },
- "043": { "PaletteId": 18 },
- "044": { "PaletteId": 18 },
- "045": { "PaletteId": 18 },
- "046": { "PaletteId": 18 },
- "047": { "PaletteId": 18 },
- "048": { "PaletteId": 18 },
- "049": { "PaletteId": 18 },
- "050": { "PaletteId": 13 },
- "051": { "PaletteId": 13 },
- "052": { "PaletteId": 13 },
- "053": { "PaletteId": 13 },
- "054": { "PaletteId": 13 },
- "055": { "PaletteId": 13 },
- "056": { "PaletteId": 13 },
- "057": { "PaletteId": 13 },
- "058": { "PaletteId": 13 },
- "059": { "PaletteId": 13 },
- "060": { "PaletteId": 13 },
- "061": { "PaletteId": 13 },
- "062": { "PaletteId": 13 },
- "063": { "PaletteId": 13 },
- "064": { "PaletteId": 13 },
- "065": { "PaletteId": 13 },
- "066": { "PaletteId": 13 },
- "067": { "PaletteId": 13 },
- "068": { "PaletteId": 13 },
- "069": { "PaletteId": 13 },
- "070": { "PaletteId": 22 },
- "071": { "PaletteId": 22 },
- "072": { "PaletteId": 22 },
- "073": { "PaletteId": 22 },
- "074": { "PaletteId": 22 },
- "075": { "PaletteId": 22 },
- "076": { "PaletteId": 22 },
- "077": { "PaletteId": 22 },
- "078": { "PaletteId": 22 },
- "079": { "PaletteId": 22 },
- "080": { "PaletteId": 22 },
- "081": { "PaletteId": 22 },
- "082": { "PaletteId": 22 }
+ "floor.200": { "Palette": "pal.25" },
+ "floor.201": { "Palette": "pal.25" },
+ "floor.202": { "Palette": "pal.25" },
+ "floor.203": { "Palette": "pal.25" },
+ "floor.204": { "Palette": "pal.25" },
+ "floor.205": { "Palette": "pal.25" },
+ "floor.206": { "Palette": "pal.25" },
+ "floor.207": { "Palette": "pal.25" },
+ "floor.208": { "Palette": "pal.25" },
+ "floor.209": { "Palette": "pal.25" },
+ "floor.210": { "Palette": "pal.25" },
+ "floor.211": { "Palette": "pal.25" },
+ "floor.212": { "Palette": "pal.25" },
+ "floor.213": { "Palette": "pal.25" },
+ "floor.214": { "Palette": "pal.25" },
+ "floor.215": { "Palette": "pal.25" },
+ "floor.216": { "Palette": "pal.25" },
+ "floor.217": { "Palette": "pal.25" },
+ "floor.218": { "Palette": "pal.25" },
+ "floor.219": { "Palette": "pal.25" },
+ "floor.220": { "Palette": "pal.25" },
+ "floor.221": { "Palette": "pal.25" },
+ "floor.222": { "Palette": "pal.25" },
+ "floor.223": { "Palette": "pal.25" },
+ "floor.224": { "Palette": "pal.25" },
+ "floor.225": { "Palette": "pal.25" },
+ "floor.226": { "Palette": "pal.25" },
+ "floor.227": { "Palette": "pal.25" },
+ "floor.228": { "Palette": "pal.25" },
+ "floor.229": { "Palette": "pal.25" },
+ "floor.230": { "Palette": "pal.25" },
+ "floor.231": { "Palette": "pal.25" },
+ "floor.232": { "Palette": "pal.25" },
+ "floor.233": { "Palette": "pal.25" },
+ "floor.234": { "Palette": "pal.25" },
+ "floor.235": { "Palette": "pal.7" },
+ "floor.236": { "Palette": "pal.7" },
+ "floor.237": { "Palette": "pal.7" },
+ "floor.238": { "Palette": "pal.7" },
+ "floor.239": { "Palette": "pal.7" },
+ "floor.240": { "Palette": "pal.7" },
+ "floor.241": { "Palette": "pal.7" },
+ "floor.242": { "Palette": "pal.18" },
+ "floor.243": { "Palette": "pal.18" },
+ "floor.244": { "Palette": "pal.18" },
+ "floor.245": { "Palette": "pal.18" },
+ "floor.246": { "Palette": "pal.18" },
+ "floor.247": { "Palette": "pal.18" },
+ "floor.248": { "Palette": "pal.18" },
+ "floor.249": { "Palette": "pal.18" },
+ "floor.250": { "Palette": "pal.13" },
+ "floor.251": { "Palette": "pal.13" },
+ "floor.252": { "Palette": "pal.13" },
+ "floor.253": { "Palette": "pal.13" },
+ "floor.254": { "Palette": "pal.13" },
+ "floor.255": { "Palette": "pal.13" },
+ "floor.256": { "Palette": "pal.13" },
+ "floor.257": { "Palette": "pal.13" },
+ "floor.258": { "Palette": "pal.13" },
+ "floor.259": { "Palette": "pal.13" },
+ "floor.260": { "Palette": "pal.13" },
+ "floor.261": { "Palette": "pal.13" },
+ "floor.262": { "Palette": "pal.13" },
+ "floor.263": { "Palette": "pal.13" },
+ "floor.264": { "Palette": "pal.13" },
+ "floor.265": { "Palette": "pal.13" },
+ "floor.266": { "Palette": "pal.13" },
+ "floor.267": { "Palette": "pal.13" },
+ "floor.268": { "Palette": "pal.13" },
+ "floor.269": { "Palette": "pal.13" },
+ "floor.270": { "Palette": "pal.22" },
+ "floor.271": { "Palette": "pal.22" },
+ "floor.272": { "Palette": "pal.22" },
+ "floor.273": { "Palette": "pal.22" },
+ "floor.274": { "Palette": "pal.22" },
+ "floor.275": { "Palette": "pal.22" },
+ "floor.276": { "Palette": "pal.22" },
+ "floor.277": { "Palette": "pal.22" },
+ "floor.278": { "Palette": "pal.22" },
+ "floor.279": { "Palette": "pal.22" },
+ "floor.280": { "Palette": "pal.22" },
+ "floor.281": { "Palette": "pal.22" },
+ "floor.282": { "Palette": "pal.22" }
}
diff --git a/mods/Albion/Meta/3DOBJEC0.json b/mods/Albion/Meta/3DOBJEC0.json
index c13433fbb..8ab16fd47 100644
--- a/mods/Albion/Meta/3DOBJEC0.json
+++ b/mods/Albion/Meta/3DOBJEC0.json
@@ -1,101 +1,101 @@
{
- "000": { "Id": "3dobj.1", "Width": 32, "PaletteId": 3 },
- "001": { "PaletteId": 3, "Width": 16 },
- "002": { "PaletteId": 3, "Width": 64 },
- "003": { "PaletteId": 3, "Width": 31 },
- "004": { "PaletteId": 3, "Width": 31 },
- "005": { "PaletteId": 3, "Width": 61 },
- "006": { "PaletteId": 3, "Width": 61 },
- "007": { "PaletteId": 3, "Width": 36 },
- "008": { "PaletteId": 3, "Width": 25 },
- "009": { "PaletteId": 3, "Width": 23 },
- "010": { "PaletteId": 3, "Width": 27 },
- "011": { "PaletteId": 3, "Width": 66 },
- "012": { "PaletteId": 3, "Width": 63 },
- "013": { "PaletteId": 3, "Width": 74 },
- "014": { "PaletteId": 3, "Width": 39 },
- "015": { "PaletteId": 3, "Width": 63 },
- "016": { "PaletteId": 3, "Width": 66 },
- "017": { "PaletteId": 3, "Width": 119 },
- "018": { "PaletteId": 3, "Width": 60 },
- "019": { "PaletteId": 3, "Width": 89 },
- "020": { "PaletteId": 3, "Width": 20 },
- "021": { "PaletteId": 3, "Width": 19 },
- "022": { "PaletteId": 3, "Width": 19 },
- "023": { "PaletteId": 3, "Width": 15 },
- "024": { "PaletteId": 3, "Width": 24 },
- "025": { "PaletteId": 3, "Width": 17 },
- "026": { "PaletteId": 3, "Width": 50, "Height": 128 },
- "027": { "PaletteId": 3, "Width": 51, "Height": 129 },
- "028": { "PaletteId": 3, "Width": 51, "Height": 129 },
- "029": { "PaletteId": 3, "Width": 42, "Height": 111 },
- "030": { "PaletteId": 3, "Width": 42, "Height": 111 },
- "031": { "PaletteId": 3, "Width": 50, "Height": 129 },
- "032": { "PaletteId": 3, "Width": 51, "Height": 130 },
- "033": { "PaletteId": 3, "Width": 51, "Height": 129 },
- "034": { "PaletteId": 3, "Width": 50 },
- "035": { "PaletteId": 3, "Width": 51 },
- "036": { "PaletteId": 3, "Width": 51 },
- "037": { "PaletteId": 3, "Width": 42 },
- "038": { "PaletteId": 3, "Width": 42 },
- "039": { "PaletteId": 3, "Width": 50 },
- "040": { "PaletteId": 3, "Width": 51 },
- "041": { "PaletteId": 3, "Width": 51 },
- "042": { "PaletteId": 7, "Width": 32 },
- "043": { "PaletteId": 7, "Width": 26 },
- "044": { "PaletteId": 7, "Width": 26 },
- "045": { "PaletteId": 13, "Width": 152 },
- "046": { "PaletteId": 13, "Width": 81 },
- "047": { "PaletteId": 13, "Width": 116 },
- "048": { "PaletteId": 13, "Width": 57 },
- "049": { "PaletteId": 13, "Width": 96 },
- "050": { "PaletteId": 13, "Width": 123 },
- "051": { "PaletteId": 13, "Width": 81 },
- "052": { "PaletteId": 15, "Width": 53 },
- "053": { "PaletteId": 15, "Width": 57, "Height": 135 },
- "054": { "PaletteId": 15, "Width": 28, "Height": 24 },
- "055": { "PaletteId": 15, "Width": 28, "Height": 24 },
- "056": { "PaletteId": 15, "Width": 32, "Height": 52 },
- "057": { "PaletteId": 15, "Width": 21, "Height": 49 },
- "058": { "PaletteId": 15, "Width": 25, "Height": 40 },
- "059": { "PaletteId": 15, "Width": 25, "Height": 40 },
- "060": { "PaletteId": 15, "Width": 21, "Height": 49 },
- "061": { "PaletteId": 15, "Width": 32, "Height": 52 },
- "062": { "PaletteId": 15, "Width": 43 },
- "063": { "PaletteId": 15, "Width": 39 },
- "064": { "PaletteId": 15, "Width": 53 },
- "065": { "PaletteId": 15, "Width": 43 },
- "066": { "PaletteId": 15, "Width": 39 },
- "067": { "PaletteId": 15, "Width": 42 },
- "068": { "PaletteId": 15, "Width": 42 },
- "069": { "PaletteId": 15, "Width": 26 },
- "070": { "PaletteId": 15, "Width": 63 },
- "071": { "Width": 26 },
- "072": { "Width": 17 },
- "073": { "PaletteId": 15, "Width": 26 },
- "074": { "PaletteId": 15, "Width": 31 },
- "075": { "PaletteId": 15, "Width": 20 },
- "076": { "PaletteId": 15, "Width": 19 },
- "077": { "PaletteId": 15, "Width": 54 },
- "078": { "PaletteId": 15, "Width": 33 },
- "079": { "PaletteId": 15, "Width": 54 },
- "080": { "PaletteId": 15, "Width": 33 },
- "081": { "PaletteId": 15, "Width": 100, "Height": 58 },
- "082": { "PaletteId": 15, "Width": 116, "Height": 105 },
- "083": { "PaletteId": 15, "Width": 53 },
- "084": { "PaletteId": 15, "Width": 53 },
- "085": { "PaletteId": 3, "Width": 106 },
- "086": { "PaletteId": 3, "Width": 106 },
- "087": { "PaletteId": 15, "Width": 78 },
- "088": { "PaletteId": 15, "Width": 78 },
- "089": { "PaletteId": 15, "Width": 87 },
- "090": { "PaletteId": 15, "Width": 87, "Height": 88 },
- "091": { "PaletteId": 15, "Width": 100, "Height": 177 },
- "092": { "PaletteId": 15, "Width": 47 },
- "093": { "PaletteId": 15, "Width": 39 },
- "094": { "PaletteId": 15, "Width": 51 },
- "095": { "PaletteId": 15, "Width": 48 },
- "096": { "PaletteId": 15, "Width": 34 },
- "097": { "PaletteId": 15, "Width": 40 },
- "098": { "PaletteId": 11, "Width": 24, "Height": 78 }
+ "3dobj.1": { "Palette": "pal.3", "Width": 32 },
+ "3dobj.2": { "Palette": "pal.3", "Width": 16 },
+ "3dobj.3": { "Palette": "pal.3", "Width": 64 },
+ "3dobj.4": { "Palette": "pal.3", "Width": 31 },
+ "3dobj.5": { "Palette": "pal.3", "Width": 31 },
+ "3dobj.6": { "Palette": "pal.3", "Width": 61 },
+ "3dobj.7": { "Palette": "pal.3", "Width": 61 },
+ "3dobj.8": { "Palette": "pal.3", "Width": 36 },
+ "3dobj.9": { "Palette": "pal.3", "Width": 25 },
+ "3dobj.10": { "Palette": "pal.3", "Width": 23 },
+ "3dobj.11": { "Palette": "pal.3", "Width": 27 },
+ "3dobj.12": { "Palette": "pal.3", "Width": 66 },
+ "3dobj.13": { "Palette": "pal.3", "Width": 63 },
+ "3dobj.14": { "Palette": "pal.3", "Width": 74 },
+ "3dobj.15": { "Palette": "pal.3", "Width": 39 },
+ "3dobj.16": { "Palette": "pal.3", "Width": 63 },
+ "3dobj.17": { "Palette": "pal.3", "Width": 66 },
+ "3dobj.18": { "Palette": "pal.3", "Width": 119 },
+ "3dobj.19": { "Palette": "pal.3", "Width": 60 },
+ "3dobj.20": { "Palette": "pal.3", "Width": 89 },
+ "3dobj.21": { "Palette": "pal.3", "Width": 20 },
+ "3dobj.22": { "Palette": "pal.3", "Width": 19 },
+ "3dobj.23": { "Palette": "pal.3", "Width": 19 },
+ "3dobj.24": { "Palette": "pal.3", "Width": 15 },
+ "3dobj.25": { "Palette": "pal.3", "Width": 24 },
+ "3dobj.26": { "Palette": "pal.3", "Width": 17 },
+ "3dobj.27": { "Palette": "pal.3", "Width": 50, "Height": 128 },
+ "3dobj.28": { "Palette": "pal.3", "Width": 51, "Height": 129 },
+ "3dobj.29": { "Palette": "pal.3", "Width": 51, "Height": 129 },
+ "3dobj.30": { "Palette": "pal.3", "Width": 42, "Height": 111 },
+ "3dobj.31": { "Palette": "pal.3", "Width": 42, "Height": 111 },
+ "3dobj.32": { "Palette": "pal.3", "Width": 50, "Height": 129 },
+ "3dobj.33": { "Palette": "pal.3", "Width": 51, "Height": 130 },
+ "3dobj.34": { "Palette": "pal.3", "Width": 51, "Height": 129 },
+ "3dobj.35": { "Palette": "pal.3", "Width": 50 },
+ "3dobj.36": { "Palette": "pal.3", "Width": 51 },
+ "3dobj.37": { "Palette": "pal.3", "Width": 51 },
+ "3dobj.38": { "Palette": "pal.3", "Width": 42 },
+ "3dobj.39": { "Palette": "pal.3", "Width": 42 },
+ "3dobj.40": { "Palette": "pal.3", "Width": 50 },
+ "3dobj.41": { "Palette": "pal.3", "Width": 51 },
+ "3dobj.42": { "Palette": "pal.3", "Width": 51 },
+ "3dobj.43": { "Palette": "pal.7", "Width": 32 },
+ "3dobj.44": { "Palette": "pal.7", "Width": 26 },
+ "3dobj.45": { "Palette": "pal.7", "Width": 26 },
+ "3dobj.46": { "Palette": "pal.13", "Width": 152 },
+ "3dobj.47": { "Palette": "pal.13", "Width": 81 },
+ "3dobj.48": { "Palette": "pal.13", "Width": 116 },
+ "3dobj.49": { "Palette": "pal.13", "Width": 57 },
+ "3dobj.50": { "Palette": "pal.13", "Width": 96 },
+ "3dobj.51": { "Palette": "pal.13", "Width": 123 },
+ "3dobj.52": { "Palette": "pal.13", "Width": 81 },
+ "3dobj.53": { "Palette": "pal.15", "Width": 53 },
+ "3dobj.54": { "Palette": "pal.15", "Width": 57, "Height": 135 },
+ "3dobj.55": { "Palette": "pal.15", "Width": 28, "Height": 24 },
+ "3dobj.56": { "Palette": "pal.15", "Width": 28, "Height": 24 },
+ "3dobj.57": { "Palette": "pal.15", "Width": 32, "Height": 52 },
+ "3dobj.58": { "Palette": "pal.15", "Width": 21, "Height": 49 },
+ "3dobj.59": { "Palette": "pal.15", "Width": 25, "Height": 40 },
+ "3dobj.60": { "Palette": "pal.15", "Width": 25, "Height": 40 },
+ "3dobj.61": { "Palette": "pal.15", "Width": 21, "Height": 49 },
+ "3dobj.62": { "Palette": "pal.15", "Width": 32, "Height": 52 },
+ "3dobj.63": { "Palette": "pal.15", "Width": 43 },
+ "3dobj.64": { "Palette": "pal.15", "Width": 39 },
+ "3dobj.65": { "Palette": "pal.15", "Width": 53 },
+ "3dobj.66": { "Palette": "pal.15", "Width": 43 },
+ "3dobj.67": { "Palette": "pal.15", "Width": 39 },
+ "3dobj.68": { "Palette": "pal.15", "Width": 42 },
+ "3dobj.69": { "Palette": "pal.15", "Width": 42 },
+ "3dobj.70": { "Palette": "pal.15", "Width": 26 },
+ "3dobj.71": { "Palette": "pal.15", "Width": 63 },
+ "3dobj.72": { "Palette": "pal.15", "Width": 26 },
+ "3dobj.73": { "Palette": "pal.15", "Width": 17 },
+ "3dobj.74": { "Palette": "pal.15", "Width": 26 },
+ "3dobj.75": { "Palette": "pal.15", "Width": 31 },
+ "3dobj.76": { "Palette": "pal.15", "Width": 20 },
+ "3dobj.77": { "Palette": "pal.15", "Width": 19 },
+ "3dobj.78": { "Palette": "pal.15", "Width": 54 },
+ "3dobj.79": { "Palette": "pal.15", "Width": 33 },
+ "3dobj.80": { "Palette": "pal.15", "Width": 54 },
+ "3dobj.81": { "Palette": "pal.15", "Width": 33 },
+ "3dobj.82": { "Palette": "pal.15", "Width": 100, "Height": 58 },
+ "3dobj.83": { "Palette": "pal.15", "Width": 116, "Height": 105 },
+ "3dobj.84": { "Palette": "pal.15", "Width": 53 },
+ "3dobj.85": { "Palette": "pal.15", "Width": 53 },
+ "3dobj.86": { "Palette": "pal.3", "Width": 106 },
+ "3dobj.87": { "Palette": "pal.3", "Width": 106 },
+ "3dobj.88": { "Palette": "pal.15", "Width": 78 },
+ "3dobj.89": { "Palette": "pal.15", "Width": 78 },
+ "3dobj.90": { "Palette": "pal.15", "Width": 87 },
+ "3dobj.91": { "Palette": "pal.15", "Width": 87, "Height": 88 },
+ "3dobj.92": { "Palette": "pal.15", "Width": 100, "Height": 177 },
+ "3dobj.93": { "Palette": "pal.15", "Width": 47 },
+ "3dobj.94": { "Palette": "pal.15", "Width": 39 },
+ "3dobj.95": { "Palette": "pal.15", "Width": 51 },
+ "3dobj.96": { "Palette": "pal.15", "Width": 48 },
+ "3dobj.97": { "Palette": "pal.15", "Width": 34 },
+ "3dobj.98": { "Palette": "pal.15", "Width": 40 },
+ "3dobj.99": { "Palette": "pal.11", "Width": 24, "Height": 78 }
}
diff --git a/mods/Albion/Meta/3DOBJEC1.json b/mods/Albion/Meta/3DOBJEC1.json
index 496b70921..6d0b7d133 100644
--- a/mods/Albion/Meta/3DOBJEC1.json
+++ b/mods/Albion/Meta/3DOBJEC1.json
@@ -1,102 +1,102 @@
{
- "000": { "Id": "3dobj.100", "Width": 24, "Height": 70, "PaletteId": 11 },
- "001": { "PaletteId": 11, "Width": 35, "Height": 82 },
- "002": { "PaletteId": 18, "Width": 74 },
- "003": { "PaletteId": 18, "Width": 74 },
- "004": { "PaletteId": 18, "Width": 74 },
- "005": { "PaletteId": 18, "Width": 74 },
- "006": { "PaletteId": 18, "Width": 24 },
- "007": { "PaletteId": 18, "Width": 79 },
- "008": { "PaletteId": 18, "Width": 79 },
- "009": { "PaletteId": 18, "Width": 79, "Height": 178 },
- "010": { "PaletteId": 18, "Width": 79, "Height": 178 },
- "011": { "PaletteId": 18, "Width": 24 },
- "012": { "PaletteId": 18, "Width": 24 },
- "013": { "PaletteId": 3, "Width": 64 },
- "014": { "PaletteId": 3, "Width": 119 },
- "015": { "PaletteId": 18, "Width": 90 },
- "016": { "PaletteId": 18, "Width": 89 },
- "017": { "PaletteId": 18, "Width": 35 },
- "018": { "PaletteId": 18, "Width": 31 },
- "019": { "PaletteId": 18, "Width": 33 },
- "020": { "PaletteId": 18, "Width": 36 },
- "021": { "PaletteId": 18, "Width": 33 },
- "022": { "PaletteId": 18, "Width": 31 },
- "023": { "PaletteId": 18, "Width": 46 },
- "024": { "PaletteId": 18, "Width": 22 },
- "025": { "PaletteId": 18, "Width": 16 },
- "026": { "PaletteId": 18, "Width": 16 },
- "027": { "PaletteId": 18, "Width": 23 },
- "028": { "PaletteId": 18, "Width": 24 },
- "029": { "PaletteId": 18, "Width": 18 },
- "030": { "PaletteId": 18, "Width": 14 },
- "031": { "PaletteId": 18, "Width": 24 },
- "032": { "PaletteId": 22, "Width": 31 },
- "033": { "PaletteId": 22, "Width": 26 },
- "034": { "PaletteId": 22, "Width": 19 },
- "035": { "PaletteId": 22, "Width": 20 },
- "036": { "PaletteId": 22, "Width": 14 },
- "037": { "PaletteId": 22, "Width": 10 },
- "038": { "PaletteId": 22, "Width": 67 },
- "039": { "PaletteId": 22, "Width": 54 },
- "040": { "PaletteId": 22, "Width": 33 },
- "041": { "PaletteId": 22, "Width": 18 },
- "042": { "PaletteId": 22, "Width": 21 },
- "043": { "PaletteId": 22, "Width": 20 },
- "044": { "PaletteId": 22, "Width": 19 },
- "045": { "PaletteId": 22, "Width": 21 },
- "046": { "PaletteId": 22, "Width": 42 },
- "047": { "PaletteId": 22, "Width": 31 },
- "048": { "PaletteId": 22, "Width": 57 },
- "049": { "PaletteId": 22, "Width": 50 },
- "050": { "PaletteId": 22, "Width": 44 },
- "051": { "PaletteId": 22, "Width": 31 },
- "052": { "PaletteId": 22, "Width": 33 },
- "053": { "PaletteId": 22, "Width": 66, "Height": 74 },
- "054": { "PaletteId": 22, "Width": 67, "Height": 94 },
- "055": { "PaletteId": 22, "Width": 40, "Height": 58 },
- "056": { "PaletteId": 22, "Width": 33, "Height": 48 },
- "057": { "PaletteId": 22, "Width": 64 },
- "058": { "PaletteId": 22, "Width": 64 },
- "059": { "PaletteId": 22, "Width": 63 },
- "060": { "PaletteId": 3, "Width": 58 },
- "061": { "PaletteId": 25, "Width": 141, "Height": 80 },
- "062": { "PaletteId": 25, "Width": 75 },
- "063": { "PaletteId": 25, "Width": 75 },
- "064": { "PaletteId": 25, "Width": 92 },
- "065": { "PaletteId": 25, "Width": 53, "ExtraBytes": 27 },
- "066": { "PaletteId": 25, "Width": 99 },
- "067": { "PaletteId": 25, "Width": 66 },
- "068": { "PaletteId": 25, "Width": 51 },
- "069": { "PaletteId": 25, "Width": 51 },
- "070": { "PaletteId": 25, "Width": 51 },
- "071": { "PaletteId": 25, "Width": 23 },
- "072": { "PaletteId": 25, "Width": 23 },
- "073": { "PaletteId": 25, "Width": 60 },
- "074": { "PaletteId": 25, "Width": 60 },
- "075": { "PaletteId": 25, "Width": 98 },
- "076": { "PaletteId": 25, "Width": 98 },
- "077": { "PaletteId": 25, "Width": 85 },
- "078": { "PaletteId": 25, "Width": 56 },
- "079": { "PaletteId": 25, "Width": 56 },
- "080": { "PaletteId": 25, "Width": 48 },
- "081": { "PaletteId": 25, "Width": 126 },
- "082": { "PaletteId": 25, "Width": 126 },
- "083": { "PaletteId": 25, "Width": 62 },
- "084": { "PaletteId": 25, "Width": 81 },
- "085": { "PaletteId": 25, "Width": 78 },
- "086": { "PaletteId": 25, "Width": 37 },
- "087": { "PaletteId": 25, "Width": 65 },
- "088": { "PaletteId": 25, "Width": 65 },
- "089": { "PaletteId": 25, "Width": 139 },
- "090": { "PaletteId": 25, "Width": 255 },
- "091": { "PaletteId": 25, "Width": 61 },
- "092": { "PaletteId": 25, "Width": 61 },
- "093": { "PaletteId": 25, "Width": 23 },
- "094": { "PaletteId": 25, "Width": 27 },
- "095": { "PaletteId": 25, "Width": 63 },
- "096": { "PaletteId": 25, "Width": 74 },
- "097": { "PaletteId": 25, "Width": 25 },
- "098": { "PaletteId": 25, "Width": 36 },
- "099": { "PaletteId": 22, "Width": 42 }
+ "3dobj.100": { "Palette": "pal.11", "Width": 24, "Height": 70 },
+ "3dobj.101": { "Palette": "pal.11", "Width": 35, "Height": 82 },
+ "3dobj.102": { "Palette": "pal.18", "Width": 74 },
+ "3dobj.103": { "Palette": "pal.18", "Width": 74 },
+ "3dobj.104": { "Palette": "pal.18", "Width": 74 },
+ "3dobj.105": { "Palette": "pal.18", "Width": 74 },
+ "3dobj.106": { "Palette": "pal.18", "Width": 24 },
+ "3dobj.107": { "Palette": "pal.18", "Width": 79 },
+ "3dobj.108": { "Palette": "pal.18", "Width": 79 },
+ "3dobj.109": { "Palette": "pal.18", "Width": 79, "Height": 178 },
+ "3dobj.110": { "Palette": "pal.18", "Width": 79, "Height": 178 },
+ "3dobj.111": { "Palette": "pal.18", "Width": 24 },
+ "3dobj.112": { "Palette": "pal.18", "Width": 24 },
+ "3dobj.113": { "Palette": "pal.3", "Width": 64 },
+ "3dobj.114": { "Palette": "pal.3", "Width": 119 },
+ "3dobj.115": { "Palette": "pal.18", "Width": 90 },
+ "3dobj.116": { "Palette": "pal.18", "Width": 89 },
+ "3dobj.117": { "Palette": "pal.18", "Width": 35 },
+ "3dobj.118": { "Palette": "pal.18", "Width": 31 },
+ "3dobj.119": { "Palette": "pal.18", "Width": 33 },
+ "3dobj.120": { "Palette": "pal.18", "Width": 36 },
+ "3dobj.121": { "Palette": "pal.18", "Width": 33 },
+ "3dobj.122": { "Palette": "pal.18", "Width": 31 },
+ "3dobj.123": { "Palette": "pal.18", "Width": 46 },
+ "3dobj.124": { "Palette": "pal.18", "Width": 22 },
+ "3dobj.125": { "Palette": "pal.18", "Width": 16 },
+ "3dobj.126": { "Palette": "pal.18", "Width": 16 },
+ "3dobj.127": { "Palette": "pal.18", "Width": 23 },
+ "3dobj.128": { "Palette": "pal.18", "Width": 24 },
+ "3dobj.129": { "Palette": "pal.18", "Width": 18 },
+ "3dobj.130": { "Palette": "pal.18", "Width": 14 },
+ "3dobj.131": { "Palette": "pal.18", "Width": 24 },
+ "3dobj.132": { "Palette": "pal.22", "Width": 31 },
+ "3dobj.133": { "Palette": "pal.22", "Width": 26 },
+ "3dobj.134": { "Palette": "pal.22", "Width": 19 },
+ "3dobj.135": { "Palette": "pal.22", "Width": 20 },
+ "3dobj.136": { "Palette": "pal.22", "Width": 14 },
+ "3dobj.137": { "Palette": "pal.22", "Width": 10 },
+ "3dobj.138": { "Palette": "pal.22", "Width": 67 },
+ "3dobj.139": { "Palette": "pal.22", "Width": 54 },
+ "3dobj.140": { "Palette": "pal.22", "Width": 33 },
+ "3dobj.141": { "Palette": "pal.22", "Width": 18 },
+ "3dobj.142": { "Palette": "pal.22", "Width": 21 },
+ "3dobj.143": { "Palette": "pal.22", "Width": 20 },
+ "3dobj.144": { "Palette": "pal.22", "Width": 19 },
+ "3dobj.145": { "Palette": "pal.22", "Width": 21 },
+ "3dobj.146": { "Palette": "pal.22", "Width": 42 },
+ "3dobj.147": { "Palette": "pal.22", "Width": 31 },
+ "3dobj.148": { "Palette": "pal.22", "Width": 57 },
+ "3dobj.149": { "Palette": "pal.22", "Width": 50 },
+ "3dobj.150": { "Palette": "pal.22", "Width": 44 },
+ "3dobj.151": { "Palette": "pal.22", "Width": 31 },
+ "3dobj.152": { "Palette": "pal.22", "Width": 33 },
+ "3dobj.153": { "Palette": "pal.22", "Width": 66, "Height": 74 },
+ "3dobj.154": { "Palette": "pal.22", "Width": 67, "Height": 94 },
+ "3dobj.155": { "Palette": "pal.22", "Width": 40, "Height": 58 },
+ "3dobj.156": { "Palette": "pal.22", "Width": 33, "Height": 48 },
+ "3dobj.157": { "Palette": "pal.22", "Width": 64 },
+ "3dobj.158": { "Palette": "pal.22", "Width": 64 },
+ "3dobj.159": { "Palette": "pal.22", "Width": 63 },
+ "3dobj.160": { "Palette": "pal.3", "Width": 58 },
+ "3dobj.161": { "Palette": "pal.25", "Width": 141, "Height": 80 },
+ "3dobj.162": { "Palette": "pal.25", "Width": 75 },
+ "3dobj.163": { "Palette": "pal.25", "Width": 75 },
+ "3dobj.164": { "Palette": "pal.25", "Width": 92 },
+ "3dobj.165": { "Palette": "pal.25", "Width": 53, "ExtraBytes": 27 },
+ "3dobj.166": { "Palette": "pal.25", "Width": 99 },
+ "3dobj.167": { "Palette": "pal.25", "Width": 66 },
+ "3dobj.168": { "Palette": "pal.25", "Width": 51 },
+ "3dobj.169": { "Palette": "pal.25", "Width": 51 },
+ "3dobj.170": { "Palette": "pal.25", "Width": 51 },
+ "3dobj.171": { "Palette": "pal.25", "Width": 23 },
+ "3dobj.172": { "Palette": "pal.25", "Width": 23 },
+ "3dobj.173": { "Palette": "pal.25", "Width": 60 },
+ "3dobj.174": { "Palette": "pal.25", "Width": 60 },
+ "3dobj.175": { "Palette": "pal.25", "Width": 98 },
+ "3dobj.176": { "Palette": "pal.25", "Width": 98 },
+ "3dobj.177": { "Palette": "pal.25", "Width": 85 },
+ "3dobj.178": { "Palette": "pal.25", "Width": 56 },
+ "3dobj.179": { "Palette": "pal.25", "Width": 56 },
+ "3dobj.180": { "Palette": "pal.25", "Width": 48 },
+ "3dobj.181": { "Palette": "pal.25", "Width": 126 },
+ "3dobj.182": { "Palette": "pal.25", "Width": 126 },
+ "3dobj.183": { "Palette": "pal.25", "Width": 62 },
+ "3dobj.184": { "Palette": "pal.25", "Width": 81 },
+ "3dobj.185": { "Palette": "pal.25", "Width": 78 },
+ "3dobj.186": { "Palette": "pal.25", "Width": 37 },
+ "3dobj.187": { "Palette": "pal.25", "Width": 65 },
+ "3dobj.188": { "Palette": "pal.25", "Width": 65 },
+ "3dobj.189": { "Palette": "pal.25", "Width": 139 },
+ "3dobj.190": { "Palette": "pal.25", "Width": 255 },
+ "3dobj.191": { "Palette": "pal.25", "Width": 61 },
+ "3dobj.192": { "Palette": "pal.25", "Width": 61 },
+ "3dobj.193": { "Palette": "pal.25", "Width": 23 },
+ "3dobj.194": { "Palette": "pal.25", "Width": 27 },
+ "3dobj.195": { "Palette": "pal.25", "Width": 63 },
+ "3dobj.196": { "Palette": "pal.25", "Width": 74 },
+ "3dobj.197": { "Palette": "pal.25", "Width": 25 },
+ "3dobj.198": { "Palette": "pal.25", "Width": 36 },
+ "3dobj.199": { "Palette": "pal.22", "Width": 42 }
}
diff --git a/mods/Albion/Meta/3DOBJEC2.json b/mods/Albion/Meta/3DOBJEC2.json
index 13662ceca..459a7858d 100644
--- a/mods/Albion/Meta/3DOBJEC2.json
+++ b/mods/Albion/Meta/3DOBJEC2.json
@@ -1,102 +1,102 @@
{
- "000": { "Id": "3dobj.200", "Width": 57, "PaletteId": 22 },
- "001": { "PaletteId": 22, "Width": 48 },
- "002": { "PaletteId": 22, "Width": 32 },
- "003": { "PaletteId": 22, "Width": 18 },
- "004": { "PaletteId": 22, "Width": 21 },
- "005": { "PaletteId": 22, "Width": 67 },
- "006": { "PaletteId": 22, "Width": 68 },
- "007": { "PaletteId": 22, "Width": 50, "ExtraBytes": 21 },
- "008": { "PaletteId": 22, "Width": 28 },
- "009": { "PaletteId": 22, "Width": 25 },
- "010": { "PaletteId": 22, "Width": 21, "ExtraBytes": 11 },
- "011": { "PaletteId": 22, "Width": 15 },
- "012": { "PaletteId": 15, "Width": 106 },
- "013": { "PaletteId": 15, "Width": 140 },
- "014": { "PaletteId": 15, "Width": 100 },
- "015": { "PaletteId": 15, "Width": 96 },
- "016": { "PaletteId": 15, "Width": 56 },
- "017": { "PaletteId": 15, "Width": 63 },
- "018": { "PaletteId": 15, "Width": 63 },
- "019": { "PaletteId": 15, "Width": 63 },
- "020": { "PaletteId": 15, "Width": 65 },
- "021": { "PaletteId": 15, "Width": 122 },
- "022": { "PaletteId": 15, "Width": 38 },
- "023": { "PaletteId": 15, "Width": 57 },
- "024": { "PaletteId": 15, "Width": 33, "ExtraBytes": 24 },
- "025": { "PaletteId": 15, "Width": 42 },
- "026": { "PaletteId": 15, "Width": 30 },
- "027": { "PaletteId": 15, "Width": 17 },
- "028": { "PaletteId": 15, "Width": 12 },
- "029": { "PaletteId": 15, "Width": 16 },
- "030": { "PaletteId": 15, "Width": 8 },
- "031": { "PaletteId": 15, "Width": 7 },
- "032": { "PaletteId": 15, "Width": 68 },
- "033": { "PaletteId": 15, "Width": 71 },
- "034": { "PaletteId": 15, "Width": 85 },
- "035": { "PaletteId": 3, "Width": 51, "Height": 130 },
- "036": { "PaletteId": 3, "Width": 51, "Height": 129 },
- "037": { "PaletteId": 3, "Width": 50, "Height": 128 },
- "038": { "PaletteId": 3, "Width": 50, "Height": 129 },
- "039": { "PaletteId": 3, "Width": 56, "Height": 56 },
- "040": { "PaletteId": 3, "Width": 27, "Height": 74 },
- "041": { "PaletteId": 3, "Width": 55 },
- "042": { "PaletteId": 3, "Width": 55 },
- "043": { "PaletteId": 3, "Width": 55 },
- "044": { "PaletteId": 3, "Width": 100, "Height": 100 },
- "045": { "PaletteId": 9, "Width": 64 },
- "046": { "PaletteId": 9, "Width": 64 },
- "047": { "PaletteId": 7, "Width": 10 },
- "048": { "PaletteId": 7, "Width": 63, "Height": 101 },
- "049": { "PaletteId": 7, "Width": 31 },
- "050": { "PaletteId": 25, "Width": 39 },
- "051": { "PaletteId": 25, "Width": 63 },
- "052": { "PaletteId": 25, "Width": 60 },
- "053": { "PaletteId": 25, "Width": 119 },
- "054": { "PaletteId": 25, "Width": 89 },
- "055": { "PaletteId": 25, "Width": 66 },
- "056": { "PaletteId": 25, "Width": 42, "Height": 111 },
- "057": { "PaletteId": 25, "Width": 51, "Height": 129 },
- "058": { "PaletteId": 25, "Width": 51, "Height": 129 },
- "059": { "PaletteId": 25, "Width": 50, "Height": 128 },
- "060": { "PaletteId": 25, "Width": 50, "Height": 129 },
- "061": { "PaletteId": 8, "Width": 32 },
- "062": { "PaletteId": 8, "Width": 26 },
- "063": { "PaletteId": 8, "Width": 26 },
- "064": { "PaletteId": 25, "Width": 56, "Height": 129 },
- "065": { "PaletteId": 25, "Width": 56, "Height": 125 },
- "066": { "PaletteId": 25, "Width": 55, "Height": 129 },
- "067": { "PaletteId": 25, "Width": 56, "Height": 125 },
- "068": { "PaletteId": 25, "Width": 73, "Height": 130 },
- "069": { "PaletteId": 25, "Width": 60, "Height": 109 },
- "070": { "PaletteId": 25, "Width": 60, "Height": 109 },
- "071": { "PaletteId": 25, "Width": 45, "Height": 141 },
- "072": { "PaletteId": 25, "Width": 53, "Height": 141 },
- "073": { "PaletteId": 25, "Width": 47, "Height": 102 },
- "074": { "PaletteId": 25, "Width": 47, "Height": 103 },
- "075": { "PaletteId": 25, "Width": 61 },
- "076": { "PaletteId": 7, "Width": 64 },
- "077": { "PaletteId": 8, "Width": 26 },
- "078": { "PaletteId": 22, "Width": 64 },
- "079": { "PaletteId": 22, "Width": 64 },
- "080": { "PaletteId": 22, "Width": 64 },
- "081": { "PaletteId": 3, "Width": 145, "Height": 165 },
- "082": { "PaletteId": 3, "Width": 66 },
- "083": { "PaletteId": 3, "Width": 66 },
- "084": { "PaletteId": 9, "Width": 64 },
- "085": { "PaletteId": 9, "Width": 64 },
- "086": { "PaletteId": 3, "Width": 27, "Height": 74 },
- "087": { "PaletteId": 3, "Width": 27, "Height": 74 },
- "088": { "PaletteId": 15, "Width": 116 },
- "089": { "PaletteId": 3, "Width": 145, "Height": 165 },
- "090": { "PaletteId": 3, "Width": 81, "Height": 118 },
- "091": { "PaletteId": 3, "Width": 56, "Height": 56 },
- "092": { "PaletteId": 15, "Width": 85, "Height": 122 },
- "093": { "PaletteId": 3, "Width": 81, "Height": 119 },
- "094": { "PaletteId": 3, "Width": 155, "Height": 172 },
- "095": { "PaletteId": 15, "Width": 165, "Height": 147 },
- "096": { "PaletteId": 3, "Width": 24, "Height": 78 },
- "097": { "PaletteId": 3, "Width": 24, "Height": 70 },
- "098": { "PaletteId": 30, "Width": 51, "Height": 130 },
- "099": { "PaletteId": 30, "Width": 56, "Height": 129 }
+ "3dobj.200": { "Palette": "pal.22", "Width": 57 },
+ "3dobj.201": { "Palette": "pal.22", "Width": 48 },
+ "3dobj.202": { "Palette": "pal.22", "Width": 32 },
+ "3dobj.203": { "Palette": "pal.22", "Width": 18 },
+ "3dobj.204": { "Palette": "pal.22", "Width": 21 },
+ "3dobj.205": { "Palette": "pal.22", "Width": 67 },
+ "3dobj.206": { "Palette": "pal.22", "Width": 68 },
+ "3dobj.207": { "Palette": "pal.22", "Width": 50, "ExtraBytes": 21 },
+ "3dobj.208": { "Palette": "pal.22", "Width": 28 },
+ "3dobj.209": { "Palette": "pal.22", "Width": 25 },
+ "3dobj.210": { "Palette": "pal.22", "Width": 21, "ExtraBytes": 11 },
+ "3dobj.211": { "Palette": "pal.22", "Width": 15 },
+ "3dobj.212": { "Palette": "pal.15", "Width": 106 },
+ "3dobj.213": { "Palette": "pal.15", "Width": 140 },
+ "3dobj.214": { "Palette": "pal.15", "Width": 100 },
+ "3dobj.215": { "Palette": "pal.15", "Width": 96 },
+ "3dobj.216": { "Palette": "pal.15", "Width": 56 },
+ "3dobj.217": { "Palette": "pal.15", "Width": 63 },
+ "3dobj.218": { "Palette": "pal.15", "Width": 63 },
+ "3dobj.219": { "Palette": "pal.15", "Width": 63 },
+ "3dobj.220": { "Palette": "pal.15", "Width": 65 },
+ "3dobj.221": { "Palette": "pal.15", "Width": 122 },
+ "3dobj.222": { "Palette": "pal.15", "Width": 38 },
+ "3dobj.223": { "Palette": "pal.15", "Width": 57 },
+ "3dobj.224": { "Palette": "pal.15", "Width": 33, "ExtraBytes": 24 },
+ "3dobj.225": { "Palette": "pal.15", "Width": 42 },
+ "3dobj.226": { "Palette": "pal.15", "Width": 30 },
+ "3dobj.227": { "Palette": "pal.15", "Width": 17 },
+ "3dobj.228": { "Palette": "pal.15", "Width": 12 },
+ "3dobj.229": { "Palette": "pal.15", "Width": 16 },
+ "3dobj.230": { "Palette": "pal.15", "Width": 8 },
+ "3dobj.231": { "Palette": "pal.15", "Width": 7 },
+ "3dobj.232": { "Palette": "pal.15", "Width": 68 },
+ "3dobj.233": { "Palette": "pal.15", "Width": 71 },
+ "3dobj.234": { "Palette": "pal.15", "Width": 85 },
+ "3dobj.235": { "Palette": "pal.3", "Width": 51, "Height": 130 },
+ "3dobj.236": { "Palette": "pal.3", "Width": 51, "Height": 129 },
+ "3dobj.237": { "Palette": "pal.3", "Width": 50, "Height": 128 },
+ "3dobj.238": { "Palette": "pal.3", "Width": 50, "Height": 129 },
+ "3dobj.239": { "Palette": "pal.3", "Width": 56, "Height": 56 },
+ "3dobj.240": { "Palette": "pal.3", "Width": 27, "Height": 74 },
+ "3dobj.241": { "Palette": "pal.3", "Width": 55 },
+ "3dobj.242": { "Palette": "pal.3", "Width": 55 },
+ "3dobj.243": { "Palette": "pal.3", "Width": 55 },
+ "3dobj.244": { "Palette": "pal.3", "Width": 100, "Height": 100 },
+ "3dobj.245": { "Palette": "pal.9", "Width": 64 },
+ "3dobj.246": { "Palette": "pal.9", "Width": 64 },
+ "3dobj.247": { "Palette": "pal.7", "Width": 10 },
+ "3dobj.248": { "Palette": "pal.7", "Width": 63, "Height": 101 },
+ "3dobj.249": { "Palette": "pal.7", "Width": 31 },
+ "3dobj.250": { "Palette": "pal.25", "Width": 39 },
+ "3dobj.251": { "Palette": "pal.25", "Width": 63 },
+ "3dobj.252": { "Palette": "pal.25", "Width": 60 },
+ "3dobj.253": { "Palette": "pal.25", "Width": 119 },
+ "3dobj.254": { "Palette": "pal.25", "Width": 89 },
+ "3dobj.255": { "Palette": "pal.25", "Width": 66 },
+ "3dobj.256": { "Palette": "pal.25", "Width": 42, "Height": 111 },
+ "3dobj.257": { "Palette": "pal.25", "Width": 51, "Height": 129 },
+ "3dobj.258": { "Palette": "pal.25", "Width": 51, "Height": 129 },
+ "3dobj.259": { "Palette": "pal.25", "Width": 50, "Height": 128 },
+ "3dobj.260": { "Palette": "pal.25", "Width": 50, "Height": 129 },
+ "3dobj.261": { "Palette": "pal.8", "Width": 32 },
+ "3dobj.262": { "Palette": "pal.8", "Width": 26 },
+ "3dobj.263": { "Palette": "pal.8", "Width": 26 },
+ "3dobj.264": { "Palette": "pal.25", "Width": 56, "Height": 129 },
+ "3dobj.265": { "Palette": "pal.25", "Width": 56, "Height": 125 },
+ "3dobj.266": { "Palette": "pal.25", "Width": 55, "Height": 129 },
+ "3dobj.267": { "Palette": "pal.25", "Width": 56, "Height": 125 },
+ "3dobj.268": { "Palette": "pal.25", "Width": 73, "Height": 130 },
+ "3dobj.269": { "Palette": "pal.25", "Width": 60, "Height": 109 },
+ "3dobj.270": { "Palette": "pal.25", "Width": 60, "Height": 109 },
+ "3dobj.271": { "Palette": "pal.25", "Width": 45, "Height": 141 },
+ "3dobj.272": { "Palette": "pal.25", "Width": 53, "Height": 141 },
+ "3dobj.273": { "Palette": "pal.25", "Width": 47, "Height": 102 },
+ "3dobj.274": { "Palette": "pal.25", "Width": 47, "Height": 103 },
+ "3dobj.275": { "Palette": "pal.25", "Width": 61 },
+ "3dobj.276": { "Palette": "pal.7", "Width": 64 },
+ "3dobj.277": { "Palette": "pal.8", "Width": 26 },
+ "3dobj.278": { "Palette": "pal.22", "Width": 64 },
+ "3dobj.279": { "Palette": "pal.22", "Width": 64 },
+ "3dobj.280": { "Palette": "pal.22", "Width": 64 },
+ "3dobj.281": { "Palette": "pal.3", "Width": 145, "Height": 165 },
+ "3dobj.282": { "Palette": "pal.3", "Width": 66 },
+ "3dobj.283": { "Palette": "pal.3", "Width": 66 },
+ "3dobj.284": { "Palette": "pal.9", "Width": 64 },
+ "3dobj.285": { "Palette": "pal.9", "Width": 64 },
+ "3dobj.286": { "Palette": "pal.3", "Width": 27, "Height": 74 },
+ "3dobj.287": { "Palette": "pal.3", "Width": 27, "Height": 74 },
+ "3dobj.288": { "Palette": "pal.15", "Width": 116 },
+ "3dobj.289": { "Palette": "pal.3", "Width": 145, "Height": 165 },
+ "3dobj.290": { "Palette": "pal.3", "Width": 81, "Height": 118 },
+ "3dobj.291": { "Palette": "pal.3", "Width": 56, "Height": 56 },
+ "3dobj.292": { "Palette": "pal.15", "Width": 85, "Height": 122 },
+ "3dobj.293": { "Palette": "pal.3", "Width": 81, "Height": 119 },
+ "3dobj.294": { "Palette": "pal.3", "Width": 155, "Height": 172 },
+ "3dobj.295": { "Palette": "pal.15", "Width": 165, "Height": 147 },
+ "3dobj.296": { "Palette": "pal.3", "Width": 24, "Height": 78 },
+ "3dobj.297": { "Palette": "pal.3", "Width": 24, "Height": 70 },
+ "3dobj.298": { "Palette": "pal.30", "Width": 51, "Height": 130 },
+ "3dobj.299": { "Palette": "pal.30", "Width": 56, "Height": 129 }
}
diff --git a/mods/Albion/Meta/3DOBJEC3.json b/mods/Albion/Meta/3DOBJEC3.json
index fb8d4314c..0044db2b6 100644
--- a/mods/Albion/Meta/3DOBJEC3.json
+++ b/mods/Albion/Meta/3DOBJEC3.json
@@ -1,28 +1,28 @@
{
- "000": { "Id": "3dobj.300", "Width": 56, "Height": 125, "PaletteId": 30 },
- "001": { "PaletteId": 30, "Width": 53, "Height": 141 },
- "002": { "PaletteId": 13, "Width": 129, "Height": 164 },
- "003": { "PaletteId": 13, "Width": 165, "Height": 147 },
- "004": { "PaletteId": 13, "Width": 165, "Height": 147 },
- "005": { "PaletteId": 56, "Width": 165, "Height": 147 },
- "006": { "PaletteId": 13, "Width": 90, "Height": 136 },
- "007": { "PaletteId": 16, "Width": 85, "Height": 122 },
- "008": { "PaletteId": 16, "Width": 129, "Height": 164 },
- "009": { "PaletteId": 18, "Width": 183, "Height": 152 },
- "010": { "PaletteId": 18, "Width": 155, "Height": 172 },
- "011": { "PaletteId": 18, "Width": 106, "Height": 112 },
- "012": { "PaletteId": 22, "Width": 49, "Height": 107 },
- "013": { "PaletteId": 22, "Width": 90, "Height": 136 },
- "014": { "PaletteId": 22, "Width": 77, "Height": 147 },
- "015": { "PaletteId": 22, "Width": 123 },
- "016": { "PaletteId": 22, "Width": 77, "Height": 147 },
- "017": { "PaletteId": 56, "Width": 183, "Height": 152 },
- "018": { "PaletteId": 22, "Width": 83, "Height": 84 },
- "019": { "PaletteId": 22, "Width": 54, "Height": 116 },
- "020": { "PaletteId": 22, "Width": 54, "Height": 116 },
- "021": { "PaletteId": 11, "Width": 50, "Height": 120 },
- "022": { "PaletteId": 13, "Width": 75, "Height": 71 },
- "023": { "PaletteId": 13, "Width": 85, "Height": 122 },
- "024": { "PaletteId": 13, "Width": 106, "Height": 112 },
- "025": { "PaletteId": 13, "Width": 83, "Height": 84 }
+ "3dobj.300": { "Palette": "pal.30", "Width": 56, "Height": 125 },
+ "3dobj.301": { "Palette": "pal.30", "Width": 53, "Height": 141 },
+ "3dobj.302": { "Palette": "pal.13", "Width": 129, "Height": 164 },
+ "3dobj.303": { "Palette": "pal.13", "Width": 165, "Height": 147 },
+ "3dobj.304": { "Palette": "pal.13", "Width": 165, "Height": 147 },
+ "3dobj.305": { "Palette": "pal.56", "Width": 165, "Height": 147 },
+ "3dobj.306": { "Palette": "pal.13", "Width": 90, "Height": 136 },
+ "3dobj.307": { "Palette": "pal.16", "Width": 85, "Height": 122 },
+ "3dobj.308": { "Palette": "pal.16", "Width": 129, "Height": 164 },
+ "3dobj.309": { "Palette": "pal.18", "Width": 183, "Height": 152 },
+ "3dobj.310": { "Palette": "pal.18", "Width": 155, "Height": 172 },
+ "3dobj.311": { "Palette": "pal.18", "Width": 106, "Height": 112 },
+ "3dobj.312": { "Palette": "pal.22", "Width": 49, "Height": 107 },
+ "3dobj.313": { "Palette": "pal.22", "Width": 90, "Height": 136 },
+ "3dobj.314": { "Palette": "pal.22", "Width": 77, "Height": 147 },
+ "3dobj.315": { "Palette": "pal.22", "Width": 123 },
+ "3dobj.316": { "Palette": "pal.22", "Width": 77, "Height": 147 },
+ "3dobj.317": { "Palette": "pal.56", "Width": 183, "Height": 152 },
+ "3dobj.318": { "Palette": "pal.22", "Width": 83, "Height": 84 },
+ "3dobj.319": { "Palette": "pal.22", "Width": 54, "Height": 116 },
+ "3dobj.320": { "Palette": "pal.22", "Width": 54, "Height": 116 },
+ "3dobj.321": { "Palette": "pal.11", "Width": 50, "Height": 120 },
+ "3dobj.322": { "Palette": "pal.13", "Width": 75, "Height": 71 },
+ "3dobj.323": { "Palette": "pal.13", "Width": 85, "Height": 122 },
+ "3dobj.324": { "Palette": "pal.13", "Width": 106, "Height": 112 },
+ "3dobj.325": { "Palette": "pal.13", "Width": 83, "Height": 84 }
}
diff --git a/mods/Albion/Meta/3DOVERL0.json b/mods/Albion/Meta/3DOVERL0.json
index 6ece4c268..bb0d808d5 100644
--- a/mods/Albion/Meta/3DOVERL0.json
+++ b/mods/Albion/Meta/3DOVERL0.json
@@ -1,101 +1,101 @@
{
- "000": { "Id": "overlay.1", "Width": 51, "PaletteId": 3 },
- "001": { "PaletteId": 3, "Width": 44 },
- "002": { "PaletteId": 3, "Width": 44 },
- "003": { "PaletteId": 3, "Width": 50 },
- "004": { "PaletteId": 3, "Width": 50 },
- "005": { "PaletteId": 3, "Width": 47 },
- "006": { "PaletteId": 3, "Width": 83 },
- "007": { "PaletteId": 3, "Width": 6 },
- "008": { "PaletteId": 3, "Width": 20 },
- "009": { "PaletteId": 3, "Width": 26 },
- "010": { "PaletteId": 3, "Width": 44 },
- "011": { "PaletteId": 3, "Width": 39 },
- "012": { "PaletteId": 3, "Width": 31 },
- "013": { "PaletteId": 3, "Width": 20 },
- "014": { "PaletteId": 3, "Width": 36 },
- "015": { "PaletteId": 3, "Width": 46 },
- "016": { "PaletteId": 3, "Width": 37 },
- "017": { "PaletteId": 3, "Width": 112 },
- "018": { "PaletteId": 3, "Width": 112 },
- "019": { "PaletteId": 3, "Width": 50 },
- "020": { "PaletteId": 3, "Width": 76 },
- "021": { "Width": 47 },
- "022": { "PaletteId": 8, "Width": 62, "Height": 42 },
- "023": { "PaletteId": 13, "Width": 24 },
- "024": { "PaletteId": 13, "Width": 65 },
- "025": { "PaletteId": 13, "Width": 58 },
- "026": { "PaletteId": 13, "Width": 26 },
- "027": { "PaletteId": 13, "Width": 26 },
- "028": { "PaletteId": 13, "Width": 63 },
- "029": { "PaletteId": 13, "Width": 70 },
- "030": { "PaletteId": 13, "Width": 16 },
- "031": { "PaletteId": 13, "Width": 13 },
- "032": { "PaletteId": 13, "Width": 9 },
- "033": { "PaletteId": 13, "Width": 7 },
- "034": { "PaletteId": 13, "Width": 33 },
- "035": { "PaletteId": 13, "Width": 42 },
- "036": { "PaletteId": 13, "Width": 41 },
- "037": { "PaletteId": 13, "Width": 41 },
- "038": { "PaletteId": 13, "Width": 52 },
- "039": { "PaletteId": 13, "Width": 41 },
- "040": { "PaletteId": 13, "Width": 40 },
- "041": { "PaletteId": 13, "Width": 23 },
- "042": { "PaletteId": 13, "Width": 52 },
- "043": { "PaletteId": 13, "Width": 48 },
- "044": { "PaletteId": 13, "Width": 128 },
- "045": { "PaletteId": 13, "Width": 128 },
- "046": { "PaletteId": 13, "Width": 30 },
- "047": { "PaletteId": 13, "Width": 30 },
- "048": { "PaletteId": 13, "Width": 128 },
- "049": { "PaletteId": 13, "Width": 128 },
- "050": { "PaletteId": 13, "Width": 36 },
- "051": { "PaletteId": 13, "Width": 56 },
- "052": { "PaletteId": 13, "Width": 25 },
- "053": { "PaletteId": 13, "Width": 36 },
- "054": { "PaletteId": 13, "Width": 25 },
- "055": { "PaletteId": 13, "Width": 24, "ExtraBytes": 7 },
- "056": { "PaletteId": 13, "Width": 29 },
- "057": { "PaletteId": 13, "Width": 128 },
- "058": { "PaletteId": 13, "Width": 128 },
- "059": { "PaletteId": 13, "Width": 96 },
- "060": { "PaletteId": 13, "Width": 29 },
- "061": { "PaletteId": 13, "Width": 62 },
- "062": { "PaletteId": 15, "Width": 130 },
- "063": { "PaletteId": 15, "Width": 130 },
- "064": { "PaletteId": 15, "Width": 130 },
- "065": { "PaletteId": 15, "Width": 130 },
- "066": { "PaletteId": 15, "Width": 37 },
- "067": { "PaletteId": 15, "Width": 34 },
- "068": { "PaletteId": 15, "Width": 39 },
- "069": { "PaletteId": 15, "Width": 38 },
- "070": { "PaletteId": 15, "Width": 39 },
- "071": { "PaletteId": 15, "Width": 41 },
- "072": { "PaletteId": 11, "Width": 134 },
- "073": { "PaletteId": 11, "Width": 134 },
- "074": { "PaletteId": 11, "Width": 134 },
- "075": { "PaletteId": 11, "Width": 134 },
- "076": { "PaletteId": 11, "Width": 134 },
- "077": { "PaletteId": 11, "Width": 134 },
- "078": { "PaletteId": 11, "Width": 59 },
- "079": { "PaletteId": 11, "Width": 86 },
- "080": { "PaletteId": 15, "Width": 55 },
- "081": { "PaletteId": 18, "Width": 134 },
- "082": { "PaletteId": 18, "Width": 115 },
- "083": { "PaletteId": 18, "Width": 116 },
- "084": { "PaletteId": 18, "Width": 114 },
- "085": { "PaletteId": 18, "Width": 116 },
- "086": { "PaletteId": 18, "Width": 115 },
- "087": { "PaletteId": 18, "Width": 18 },
- "088": { "PaletteId": 18, "Width": 30 },
- "089": { "PaletteId": 18, "Width": 36 },
- "090": { "PaletteId": 18, "Width": 36 },
- "091": { "PaletteId": 18, "Width": 30 },
- "092": { "PaletteId": 18, "Width": 36 },
- "093": { "PaletteId": 18, "Width": 29 },
- "094": { "PaletteId": 18, "Width": 38 },
- "095": { "PaletteId": 18, "Width": 87 },
- "096": { "PaletteId": 18, "Width": 42 },
- "097": { "PaletteId": 18, "Width": 134 },
- "098": { "PaletteId": 18, "Width": 134 }
+ "overlay.1": { "Palette": "pal.3", "Width": 51},
+ "overlay.2": { "Palette": "pal.3", "Width": 44 },
+ "overlay.3": { "Palette": "pal.3", "Width": 44 },
+ "overlay.4": { "Palette": "pal.3", "Width": 50 },
+ "overlay.5": { "Palette": "pal.3", "Width": 50 },
+ "overlay.6": { "Palette": "pal.3", "Width": 47 },
+ "overlay.7": { "Palette": "pal.3", "Width": 83 },
+ "overlay.8": { "Palette": "pal.3", "Width": 6 },
+ "overlay.9": { "Palette": "pal.3", "Width": 20 },
+ "overlay.10": { "Palette": "pal.3", "Width": 26 },
+ "overlay.11": { "Palette": "pal.3", "Width": 44 },
+ "overlay.12": { "Palette": "pal.3", "Width": 39 },
+ "overlay.13": { "Palette": "pal.3", "Width": 31 },
+ "overlay.14": { "Palette": "pal.3", "Width": 20 },
+ "overlay.15": { "Palette": "pal.3", "Width": 36 },
+ "overlay.16": { "Palette": "pal.3", "Width": 46 },
+ "overlay.17": { "Palette": "pal.3", "Width": 37 },
+ "overlay.18": { "Palette": "pal.3", "Width": 112 },
+ "overlay.19": { "Palette": "pal.3", "Width": 112 },
+ "overlay.20": { "Palette": "pal.3", "Width": 50 },
+ "overlay.21": { "Palette": "pal.3", "Width": 76 },
+ "overlay.22": { "Palette": "pal.8", "Width": 47 },
+ "overlay.23": { "Palette": "pal.8", "Width": 62, "Height": 42 },
+ "overlay.24": { "Palette": "pal.13", "Width": 24 },
+ "overlay.25": { "Palette": "pal.13", "Width": 65 },
+ "overlay.26": { "Palette": "pal.13", "Width": 58 },
+ "overlay.27": { "Palette": "pal.13", "Width": 26 },
+ "overlay.28": { "Palette": "pal.13", "Width": 26 },
+ "overlay.29": { "Palette": "pal.13", "Width": 63 },
+ "overlay.30": { "Palette": "pal.13", "Width": 70 },
+ "overlay.31": { "Palette": "pal.13", "Width": 16 },
+ "overlay.32": { "Palette": "pal.13", "Width": 13 },
+ "overlay.33": { "Palette": "pal.13", "Width": 9 },
+ "overlay.34": { "Palette": "pal.13", "Width": 7 },
+ "overlay.35": { "Palette": "pal.13", "Width": 33 },
+ "overlay.36": { "Palette": "pal.13", "Width": 42 },
+ "overlay.37": { "Palette": "pal.13", "Width": 41 },
+ "overlay.38": { "Palette": "pal.13", "Width": 41 },
+ "overlay.39": { "Palette": "pal.13", "Width": 52 },
+ "overlay.40": { "Palette": "pal.13", "Width": 41 },
+ "overlay.41": { "Palette": "pal.13", "Width": 40 },
+ "overlay.42": { "Palette": "pal.13", "Width": 23 },
+ "overlay.43": { "Palette": "pal.13", "Width": 52 },
+ "overlay.44": { "Palette": "pal.13", "Width": 48 },
+ "overlay.45": { "Palette": "pal.13", "Width": 128 },
+ "overlay.46": { "Palette": "pal.13", "Width": 128 },
+ "overlay.47": { "Palette": "pal.13", "Width": 30 },
+ "overlay.48": { "Palette": "pal.13", "Width": 30 },
+ "overlay.49": { "Palette": "pal.13", "Width": 128 },
+ "overlay.50": { "Palette": "pal.13", "Width": 128 },
+ "overlay.51": { "Palette": "pal.13", "Width": 36 },
+ "overlay.52": { "Palette": "pal.13", "Width": 56 },
+ "overlay.53": { "Palette": "pal.13", "Width": 25 },
+ "overlay.54": { "Palette": "pal.13", "Width": 36 },
+ "overlay.55": { "Palette": "pal.13", "Width": 25 },
+ "overlay.56": { "Palette": "pal.13", "Width": 24, "ExtraBytes": 7 },
+ "overlay.57": { "Palette": "pal.13", "Width": 29 },
+ "overlay.58": { "Palette": "pal.13", "Width": 128 },
+ "overlay.59": { "Palette": "pal.13", "Width": 128 },
+ "overlay.60": { "Palette": "pal.13", "Width": 96 },
+ "overlay.61": { "Palette": "pal.13", "Width": 29 },
+ "overlay.62": { "Palette": "pal.13", "Width": 62 },
+ "overlay.63": { "Palette": "pal.15", "Width": 130 },
+ "overlay.64": { "Palette": "pal.15", "Width": 130 },
+ "overlay.65": { "Palette": "pal.15", "Width": 130 },
+ "overlay.66": { "Palette": "pal.15", "Width": 130 },
+ "overlay.67": { "Palette": "pal.15", "Width": 37 },
+ "overlay.68": { "Palette": "pal.15", "Width": 34 },
+ "overlay.69": { "Palette": "pal.15", "Width": 39 },
+ "overlay.70": { "Palette": "pal.15", "Width": 38 },
+ "overlay.71": { "Palette": "pal.15", "Width": 39 },
+ "overlay.72": { "Palette": "pal.15", "Width": 41 },
+ "overlay.73": { "Palette": "pal.11", "Width": 134 },
+ "overlay.74": { "Palette": "pal.11", "Width": 134 },
+ "overlay.75": { "Palette": "pal.11", "Width": 134 },
+ "overlay.76": { "Palette": "pal.11", "Width": 134 },
+ "overlay.77": { "Palette": "pal.11", "Width": 134 },
+ "overlay.78": { "Palette": "pal.11", "Width": 134 },
+ "overlay.79": { "Palette": "pal.11", "Width": 59 },
+ "overlay.80": { "Palette": "pal.11", "Width": 86 },
+ "overlay.81": { "Palette": "pal.15", "Width": 55 },
+ "overlay.82": { "Palette": "pal.18", "Width": 134 },
+ "overlay.83": { "Palette": "pal.18", "Width": 115 },
+ "overlay.84": { "Palette": "pal.18", "Width": 116 },
+ "overlay.85": { "Palette": "pal.18", "Width": 114 },
+ "overlay.86": { "Palette": "pal.18", "Width": 116 },
+ "overlay.87": { "Palette": "pal.18", "Width": 115 },
+ "overlay.88": { "Palette": "pal.18", "Width": 18 },
+ "overlay.89": { "Palette": "pal.18", "Width": 30 },
+ "overlay.90": { "Palette": "pal.18", "Width": 36 },
+ "overlay.91": { "Palette": "pal.18", "Width": 36 },
+ "overlay.92": { "Palette": "pal.18", "Width": 30 },
+ "overlay.93": { "Palette": "pal.18", "Width": 36 },
+ "overlay.94": { "Palette": "pal.18", "Width": 29 },
+ "overlay.95": { "Palette": "pal.18", "Width": 38 },
+ "overlay.96": { "Palette": "pal.18", "Width": 87 },
+ "overlay.97": { "Palette": "pal.18", "Width": 42 },
+ "overlay.98": { "Palette": "pal.18", "Width": 134 },
+ "overlay.99": { "Palette": "pal.18", "Width": 134 }
}
diff --git a/mods/Albion/Meta/3DOVERL1.json b/mods/Albion/Meta/3DOVERL1.json
index 5b63dd719..4f41e09ed 100644
--- a/mods/Albion/Meta/3DOVERL1.json
+++ b/mods/Albion/Meta/3DOVERL1.json
@@ -1,102 +1,102 @@
{
- "000": { "Id": "overlay.100", "Width": 35, "PaletteId": 18 },
- "001": { "PaletteId": 18, "Width": 82 },
- "002": { "PaletteId": 18, "Width": 38 },
- "003": { "PaletteId": 18, "Width": 48 },
- "004": { "PaletteId": 18, "Width": 74 },
- "005": { "PaletteId": 18, "Width": 27 },
- "006": { "PaletteId": 18, "Width": 31 },
- "007": { "PaletteId": 18, "Width": 21 },
- "008": { "PaletteId": 18, "Width": 21 },
- "009": { "PaletteId": 18, "Width": 30 },
- "010": { "PaletteId": 18, "Width": 33 },
- "011": { "PaletteId": 18, "Width": 24 },
- "012": { "PaletteId": 18, "Width": 21 },
- "013": { "PaletteId": 18, "Width": 40 },
- "014": { "PaletteId": 3, "Width": 38 },
- "015": { "PaletteId": 25, "Width": 36 },
- "016": { "PaletteId": 25, "Width": 36 },
- "017": { "PaletteId": 25, "Width": 52 },
- "018": { "PaletteId": 25, "Width": 29, "ExtraBytes": 10 },
- "019": { "PaletteId": 25, "Width": 30 },
- "020": { "PaletteId": 25, "Width": 52 },
- "021": { "PaletteId": 25, "Width": 51 },
- "022": { "PaletteId": 25, "Width": 52 },
- "023": { "PaletteId": 25, "Width": 51 },
- "024": { "PaletteId": 25, "Width": 49 },
- "025": { "PaletteId": 25, "Width": 18 },
- "026": { "PaletteId": 25, "Width": 16 },
- "027": { "PaletteId": 25, "Width": 50 },
- "028": { "PaletteId": 25, "Width": 22 },
- "029": { "PaletteId": 25, "Width": 43 },
- "030": { "PaletteId": 25, "Width": 42 },
- "031": { "PaletteId": 25, "Width": 24 },
- "032": { "PaletteId": 25, "Width": 53 },
- "033": { "PaletteId": 25, "Width": 53 },
- "034": { "PaletteId": 25, "Width": 68 },
- "035": { "PaletteId": 25, "Width": 58 },
- "036": { "PaletteId": 25, "Width": 57 },
- "037": { "PaletteId": 25, "Width": 29 },
- "038": { "PaletteId": 25, "Width": 29 },
- "039": { "PaletteId": 25, "Width": 42 },
- "040": { "PaletteId": 25, "Width": 50 },
- "041": { "PaletteId": 25, "Width": 50 },
- "042": { "PaletteId": 25, "Width": 53 },
- "043": { "PaletteId": 25, "Width": 53 },
- "044": { "PaletteId": 25, "Width": 64 },
- "045": { "PaletteId": 25, "Width": 64 },
- "046": { "PaletteId": 25, "Width": 29 },
- "047": { "PaletteId": 25, "Width": 29 },
- "048": { "PaletteId": 25, "Width": 68 },
- "049": { "PaletteId": 25, "Width": 68 },
- "050": { "PaletteId": 25, "Width": 75 },
- "051": { "PaletteId": 25, "Width": 75 },
- "052": { "PaletteId": 25, "Width": 76 },
- "053": { "PaletteId": 25, "Width": 76 },
- "054": { "PaletteId": 25, "Width": 76 },
- "055": { "PaletteId": 25, "Width": 76 },
- "056": { "PaletteId": 25, "Width": 80 },
- "057": { "PaletteId": 25, "Width": 80 },
- "058": { "PaletteId": 25, "Width": 27 },
- "059": { "PaletteId": 25, "Width": 27 },
- "060": { "PaletteId": 25, "Width": 27 },
- "061": { "PaletteId": 25, "Width": 27 },
- "062": { "PaletteId": 25, "Width": 27 },
- "063": { "PaletteId": 25, "Width": 27 },
- "064": { "PaletteId": 25, "Width": 27 },
- "065": { "PaletteId": 25, "Width": 27 },
- "066": { "PaletteId": 25, "Width": 95 },
- "067": { "PaletteId": 25, "Width": 95 },
- "068": { "PaletteId": 25, "Width": 109 },
- "069": { "PaletteId": 25, "Width": 95 },
- "070": { "PaletteId": 25, "Width": 94 },
- "071": { "PaletteId": 25, "Width": 91 },
- "072": { "PaletteId": 25, "Width": 55 },
- "073": { "PaletteId": 25, "Width": 57 },
- "074": { "PaletteId": 3, "Width": 40 },
- "075": { "PaletteId": 13, "Width": 128 },
- "076": { "PaletteId": 13, "Width": 128 },
- "077": { "PaletteId": 22, "Width": 11 },
- "078": { "PaletteId": 22, "Width": 14 },
- "079": { "PaletteId": 22, "Width": 30 },
- "080": { "PaletteId": 22, "Width": 25 },
- "081": { "PaletteId": 22, "Width": 55 },
- "082": { "PaletteId": 6, "Width": 52 },
- "083": { "PaletteId": 6, "Width": 52 },
- "084": { "PaletteId": 22, "Width": 7 },
- "085": { "PaletteId": 22, "Width": 7 },
- "086": { "PaletteId": 22, "Width": 12 },
- "087": { "PaletteId": 22, "Width": 12 },
- "088": { "PaletteId": 3, "Width": 128 },
- "089": { "PaletteId": 7, "Width": 27 },
- "090": { "PaletteId": 7, "Width": 27 },
- "091": { "PaletteId": 7, "Width": 21 },
- "092": { "PaletteId": 7, "Width": 21 },
- "093": { "PaletteId": 7, "Width": 21 },
- "094": { "PaletteId": 7, "Width": 21 },
- "095": { "PaletteId": 7, "Width": 21 },
- "096": { "PaletteId": 7, "Width": 21 },
- "097": { "PaletteId": 7, "Width": 21 },
- "098": { "PaletteId": 7, "Width": 21 },
- "099": { "PaletteId": 7, "Width": 26 }
+ "overlay.100": { "Palette": "pal.18", "Width": 35 },
+ "overlay.101": { "Palette": "pal.18", "Width": 82 },
+ "overlay.102": { "Palette": "pal.18", "Width": 38 },
+ "overlay.103": { "Palette": "pal.18", "Width": 48 },
+ "overlay.104": { "Palette": "pal.18", "Width": 74 },
+ "overlay.105": { "Palette": "pal.18", "Width": 27 },
+ "overlay.106": { "Palette": "pal.18", "Width": 31 },
+ "overlay.107": { "Palette": "pal.18", "Width": 21 },
+ "overlay.108": { "Palette": "pal.18", "Width": 21 },
+ "overlay.109": { "Palette": "pal.18", "Width": 30 },
+ "overlay.110": { "Palette": "pal.18", "Width": 33 },
+ "overlay.111": { "Palette": "pal.18", "Width": 24 },
+ "overlay.112": { "Palette": "pal.18", "Width": 21 },
+ "overlay.113": { "Palette": "pal.18", "Width": 40 },
+ "overlay.114": { "Palette": "pal.3", "Width": 38 },
+ "overlay.115": { "Palette": "pal.25", "Width": 36 },
+ "overlay.116": { "Palette": "pal.25", "Width": 36 },
+ "overlay.117": { "Palette": "pal.25", "Width": 52 },
+ "overlay.118": { "Palette": "pal.25", "Width": 29, "ExtraBytes": 10 },
+ "overlay.119": { "Palette": "pal.25", "Width": 30 },
+ "overlay.120": { "Palette": "pal.25", "Width": 52 },
+ "overlay.121": { "Palette": "pal.25", "Width": 51 },
+ "overlay.122": { "Palette": "pal.25", "Width": 52 },
+ "overlay.123": { "Palette": "pal.25", "Width": 51 },
+ "overlay.124": { "Palette": "pal.25", "Width": 49 },
+ "overlay.125": { "Palette": "pal.25", "Width": 18 },
+ "overlay.126": { "Palette": "pal.25", "Width": 16 },
+ "overlay.127": { "Palette": "pal.25", "Width": 50 },
+ "overlay.128": { "Palette": "pal.25", "Width": 22 },
+ "overlay.129": { "Palette": "pal.25", "Width": 43 },
+ "overlay.130": { "Palette": "pal.25", "Width": 42 },
+ "overlay.131": { "Palette": "pal.25", "Width": 24 },
+ "overlay.132": { "Palette": "pal.25", "Width": 53 },
+ "overlay.133": { "Palette": "pal.25", "Width": 53 },
+ "overlay.134": { "Palette": "pal.25", "Width": 68 },
+ "overlay.135": { "Palette": "pal.25", "Width": 58 },
+ "overlay.136": { "Palette": "pal.25", "Width": 57 },
+ "overlay.137": { "Palette": "pal.25", "Width": 29 },
+ "overlay.138": { "Palette": "pal.25", "Width": 29 },
+ "overlay.139": { "Palette": "pal.25", "Width": 42 },
+ "overlay.140": { "Palette": "pal.25", "Width": 50 },
+ "overlay.141": { "Palette": "pal.25", "Width": 50 },
+ "overlay.142": { "Palette": "pal.25", "Width": 53 },
+ "overlay.143": { "Palette": "pal.25", "Width": 53 },
+ "overlay.144": { "Palette": "pal.25", "Width": 64 },
+ "overlay.145": { "Palette": "pal.25", "Width": 64 },
+ "overlay.146": { "Palette": "pal.25", "Width": 29 },
+ "overlay.147": { "Palette": "pal.25", "Width": 29 },
+ "overlay.148": { "Palette": "pal.25", "Width": 68 },
+ "overlay.149": { "Palette": "pal.25", "Width": 68 },
+ "overlay.150": { "Palette": "pal.25", "Width": 75 },
+ "overlay.151": { "Palette": "pal.25", "Width": 75 },
+ "overlay.152": { "Palette": "pal.25", "Width": 76 },
+ "overlay.153": { "Palette": "pal.25", "Width": 76 },
+ "overlay.154": { "Palette": "pal.25", "Width": 76 },
+ "overlay.155": { "Palette": "pal.25", "Width": 76 },
+ "overlay.156": { "Palette": "pal.25", "Width": 80 },
+ "overlay.157": { "Palette": "pal.25", "Width": 80 },
+ "overlay.158": { "Palette": "pal.25", "Width": 27 },
+ "overlay.159": { "Palette": "pal.25", "Width": 27 },
+ "overlay.160": { "Palette": "pal.25", "Width": 27 },
+ "overlay.161": { "Palette": "pal.25", "Width": 27 },
+ "overlay.162": { "Palette": "pal.25", "Width": 27 },
+ "overlay.163": { "Palette": "pal.25", "Width": 27 },
+ "overlay.164": { "Palette": "pal.25", "Width": 27 },
+ "overlay.165": { "Palette": "pal.25", "Width": 27 },
+ "overlay.166": { "Palette": "pal.25", "Width": 95 },
+ "overlay.167": { "Palette": "pal.25", "Width": 95 },
+ "overlay.168": { "Palette": "pal.25", "Width": 109 },
+ "overlay.169": { "Palette": "pal.25", "Width": 95 },
+ "overlay.170": { "Palette": "pal.25", "Width": 94 },
+ "overlay.171": { "Palette": "pal.25", "Width": 91 },
+ "overlay.172": { "Palette": "pal.25", "Width": 55 },
+ "overlay.173": { "Palette": "pal.25", "Width": 57 },
+ "overlay.174": { "Palette": "pal.3", "Width": 40 },
+ "overlay.175": { "Palette": "pal.13", "Width": 128 },
+ "overlay.176": { "Palette": "pal.13", "Width": 128 },
+ "overlay.177": { "Palette": "pal.22", "Width": 11 },
+ "overlay.178": { "Palette": "pal.22", "Width": 14 },
+ "overlay.179": { "Palette": "pal.22", "Width": 30 },
+ "overlay.180": { "Palette": "pal.22", "Width": 25 },
+ "overlay.181": { "Palette": "pal.22", "Width": 55 },
+ "overlay.182": { "Palette": "pal.6", "Width": 52 },
+ "overlay.183": { "Palette": "pal.6", "Width": 52 },
+ "overlay.184": { "Palette": "pal.22", "Width": 7 },
+ "overlay.185": { "Palette": "pal.22", "Width": 7 },
+ "overlay.186": { "Palette": "pal.22", "Width": 12 },
+ "overlay.187": { "Palette": "pal.22", "Width": 12 },
+ "overlay.188": { "Palette": "pal.3", "Width": 128 },
+ "overlay.189": { "Palette": "pal.7", "Width": 27 },
+ "overlay.190": { "Palette": "pal.7", "Width": 27 },
+ "overlay.191": { "Palette": "pal.7", "Width": 21 },
+ "overlay.192": { "Palette": "pal.7", "Width": 21 },
+ "overlay.193": { "Palette": "pal.7", "Width": 21 },
+ "overlay.194": { "Palette": "pal.7", "Width": 21 },
+ "overlay.195": { "Palette": "pal.7", "Width": 21 },
+ "overlay.196": { "Palette": "pal.7", "Width": 21 },
+ "overlay.197": { "Palette": "pal.7", "Width": 21 },
+ "overlay.198": { "Palette": "pal.7", "Width": 21 },
+ "overlay.199": { "Palette": "pal.7", "Width": 26 }
}
diff --git a/mods/Albion/Meta/3DOVERL2.json b/mods/Albion/Meta/3DOVERL2.json
index 3c7ebc8b0..618b7369e 100644
--- a/mods/Albion/Meta/3DOVERL2.json
+++ b/mods/Albion/Meta/3DOVERL2.json
@@ -1,43 +1,43 @@
{
- "000": { "Id": "overlay.200", "Width": 26, "PaletteId": 7 },
- "001": { "PaletteId": 7, "Width": 20, "Height": 6 },
- "002": { "PaletteId": 7, "Width": 20, "Height": 6 },
- "003": { "PaletteId": 7, "Width": 20, "Height": 6 },
- "004": { "PaletteId": 7, "Width": 20, "Height": 6 },
- "005": { "PaletteId": 7, "Width": 31 },
- "006": { "PaletteId": 7, "Width": 31 },
- "007": { "PaletteId": 7, "Width": 64 },
- "008": { "PaletteId": 7, "Width": 64 },
- "009": { "PaletteId": 25, "Width": 112 },
- "010": { "PaletteId": 25, "Width": 112 },
- "011": { "PaletteId": 25, "Width": 47 },
- "012": { "PaletteId": 25, "Width": 83 },
- "013": { "PaletteId": 25, "Width": 76 },
- "014": { "PaletteId": 25, "Width": 50 },
- "015": { "PaletteId": 7, "Width": 17 },
- "016": { "PaletteId": 7, "Width": 17 },
- "017": { "PaletteId": 7, "Width": 17 },
- "018": { "PaletteId": 7, "Width": 17 },
- "019": { "PaletteId": 7, "Width": 17 },
- "020": { "PaletteId": 7, "Width": 17 },
- "021": { "PaletteId": 7, "Width": 17 },
- "022": { "PaletteId": 7, "Width": 17 },
- "023": { "PaletteId": 7, "Width": 17 },
- "024": { "PaletteId": 7, "Width": 17 },
- "025": { "PaletteId": 7, "Width": 33 },
- "026": { "PaletteId": 7, "Width": 33 },
- "027": { "PaletteId": 7, "Width": 33, "Height": 35 },
- "028": { "PaletteId": 7, "Width": 14, "Height": 14 },
- "029": { "PaletteId": 7, "Width": 12, "Height": 12 },
- "030": { "PaletteId": 7, "Width": 12, "Height": 12 },
- "031": { "PaletteId": 7, "Width": 12, "Height": 11 },
- "032": { "PaletteId": 7, "Width": 12, "Height": 11 },
- "033": { "PaletteId": 18, "Width": 84 },
- "034": { "PaletteId": 18, "Width": 84 },
- "035": { "PaletteId": 18, "Width": 84 },
- "036": { "PaletteId": 18, "Width": 84 },
- "037": { "PaletteId": 18, "Width": 52 },
- "038": { "PaletteId": 18, "Width": 52 },
- "039": { "PaletteId": 18, "Width": 18 },
- "040": { "PaletteId": 18, "Width": 18 }
+ "overlay.200": { "Palette": "pal.7", "Width": 26 },
+ "overlay.201": { "Palette": "pal.7", "Width": 20, "Height": 6 },
+ "overlay.202": { "Palette": "pal.7", "Width": 20, "Height": 6 },
+ "overlay.203": { "Palette": "pal.7", "Width": 20, "Height": 6 },
+ "overlay.204": { "Palette": "pal.7", "Width": 20, "Height": 6 },
+ "overlay.205": { "Palette": "pal.7", "Width": 31 },
+ "overlay.206": { "Palette": "pal.7", "Width": 31 },
+ "overlay.207": { "Palette": "pal.7", "Width": 64 },
+ "overlay.208": { "Palette": "pal.7", "Width": 64 },
+ "overlay.209": { "Palette": "pal.25", "Width": 112 },
+ "overlay.210": { "Palette": "pal.25", "Width": 112 },
+ "overlay.211": { "Palette": "pal.25", "Width": 47 },
+ "overlay.212": { "Palette": "pal.25", "Width": 83 },
+ "overlay.213": { "Palette": "pal.25", "Width": 76 },
+ "overlay.214": { "Palette": "pal.25", "Width": 50 },
+ "overlay.215": { "Palette": "pal.7", "Width": 17 },
+ "overlay.216": { "Palette": "pal.7", "Width": 17 },
+ "overlay.217": { "Palette": "pal.7", "Width": 17 },
+ "overlay.218": { "Palette": "pal.7", "Width": 17 },
+ "overlay.219": { "Palette": "pal.7", "Width": 17 },
+ "overlay.220": { "Palette": "pal.7", "Width": 17 },
+ "overlay.221": { "Palette": "pal.7", "Width": 17 },
+ "overlay.222": { "Palette": "pal.7", "Width": 17 },
+ "overlay.223": { "Palette": "pal.7", "Width": 17 },
+ "overlay.224": { "Palette": "pal.7", "Width": 17 },
+ "overlay.225": { "Palette": "pal.7", "Width": 33 },
+ "overlay.226": { "Palette": "pal.7", "Width": 33 },
+ "overlay.227": { "Palette": "pal.7", "Width": 33, "Height": 35 },
+ "overlay.228": { "Palette": "pal.7", "Width": 14, "Height": 14 },
+ "overlay.229": { "Palette": "pal.7", "Width": 12, "Height": 12 },
+ "overlay.230": { "Palette": "pal.7", "Width": 12, "Height": 12 },
+ "overlay.231": { "Palette": "pal.7", "Width": 12, "Height": 11 },
+ "overlay.232": { "Palette": "pal.7", "Width": 12, "Height": 11 },
+ "overlay.233": { "Palette": "pal.18", "Width": 84 },
+ "overlay.234": { "Palette": "pal.18", "Width": 84 },
+ "overlay.235": { "Palette": "pal.18", "Width": 84 },
+ "overlay.236": { "Palette": "pal.18", "Width": 84 },
+ "overlay.237": { "Palette": "pal.18", "Width": 52 },
+ "overlay.238": { "Palette": "pal.18", "Width": 52 },
+ "overlay.239": { "Palette": "pal.18", "Width": 18 },
+ "overlay.240": { "Palette": "pal.18", "Width": 18 }
}
diff --git a/mods/Albion/Meta/3DWALLS0.json b/mods/Albion/Meta/3DWALLS0.json
index 757e43dd6..1458aa5c0 100644
--- a/mods/Albion/Meta/3DWALLS0.json
+++ b/mods/Albion/Meta/3DWALLS0.json
@@ -1,101 +1,101 @@
{
- "000": { "Id": "wall.1", "Width": 112, "PaletteId": 3 },
- "001": { "PaletteId": 3, "Width": 112 },
- "002": { "PaletteId": 3, "Width": 112 },
- "003": { "PaletteId": 3, "Width": 112 },
- "004": { "PaletteId": 3, "Width": 112 },
- "005": { "PaletteId": 3, "Width": 112 },
- "006": { "PaletteId": 3, "Width": 112 },
- "007": { "PaletteId": 3, "Width": 112 },
- "008": { "PaletteId": 3, "Width": 112 },
- "009": { "PaletteId": 3, "Width": 112 },
- "010": { "PaletteId": 7, "Width": 80 },
- "011": { "PaletteId": 7, "Width": 80 },
- "012": { "PaletteId": 7, "Width": 80 },
- "013": { "PaletteId": 7, "Width": 80 },
- "014": { "PaletteId": 7, "Width": 80 },
- "015": { "PaletteId": 7, "Width": 80 },
- "016": { "PaletteId": 8, "Width": 107 },
- "017": { "PaletteId": 8, "Width": 107 },
- "018": { "PaletteId": 8, "Width": 107 },
- "019": { "PaletteId": 8, "Width": 107 },
- "020": { "PaletteId": 8, "Width": 107 },
- "021": { "PaletteId": 8, "Width": 107 },
- "022": { "PaletteId": 8, "Width": 107 },
- "023": { "PaletteId": 8, "Width": 107 },
- "024": { "PaletteId": 8, "Width": 107 },
- "025": { "PaletteId": 8, "Width": 107 },
- "026": { "PaletteId": 13, "Width": 128 },
- "027": { "PaletteId": 13, "Width": 128 },
- "028": { "PaletteId": 13, "Width": 128 },
- "029": { "PaletteId": 13, "Width": 128 },
- "030": { "PaletteId": 13, "Width": 128 },
- "031": { "PaletteId": 13, "Width": 128 },
- "032": { "PaletteId": 13, "Width": 128 },
- "033": { "PaletteId": 13, "Width": 128 },
- "034": { "PaletteId": 13, "Width": 128 },
- "035": { "PaletteId": 13, "Width": 128 },
- "036": { "PaletteId": 13, "Width": 128 },
- "037": { "PaletteId": 13, "Width": 128 },
- "038": { "PaletteId": 13, "Width": 198 },
- "039": { "PaletteId": 13, "Width": 198 },
- "040": { "PaletteId": 13, "Width": 198 },
- "041": { "PaletteId": 13, "Width": 198 },
- "042": { "PaletteId": 13, "Width": 128 },
- "043": { "PaletteId": 13, "Width": 128 },
- "044": { "PaletteId": 13, "Width": 32 },
- "045": { "PaletteId": 15, "Width": 130 },
- "046": { "PaletteId": 15, "Width": 130 },
- "047": { "PaletteId": 15, "Width": 130 },
- "048": { "PaletteId": 15, "Width": 130 },
- "049": { "Width": 128 },
- "050": { "Width": 156 },
- "051": { "PaletteId": 15, "Width": 130, "Height": 106 },
- "052": { "PaletteId": 3, "Width": 130 },
- "053": { "PaletteId": 3, "Width": 130 },
- "054": { "PaletteId": 11, "Width": 134 },
- "055": { "PaletteId": 11, "Width": 134 },
- "056": { "PaletteId": 11, "Width": 134 },
- "057": { "PaletteId": 11, "Width": 134 },
- "058": { "PaletteId": 11, "Width": 134 },
- "059": { "PaletteId": 11, "Width": 134 },
- "060": { "PaletteId": 11, "Width": 134 },
- "061": { "PaletteId": 15, "Width": 112 },
- "062": { "PaletteId": 15, "Width": 112 },
- "063": { "PaletteId": 15, "Width": 112 },
- "064": { "Width": 8 },
- "065": { "PaletteId": 18, "Width": 134 },
- "066": { "PaletteId": 18, "Width": 134 },
- "067": { "PaletteId": 18, "Width": 84 },
- "068": { "PaletteId": 18, "Width": 84 },
- "069": { "PaletteId": 18, "Width": 84 },
- "070": { "PaletteId": 18, "Width": 84 },
- "071": { "PaletteId": 22, "Width": 144 },
- "072": { "PaletteId": 22, "Width": 144 },
- "073": { "PaletteId": 22, "Width": 144 },
- "074": { "PaletteId": 25, "Width": 196 },
- "075": { "PaletteId": 25, "Width": 53 },
- "076": { "PaletteId": 25, "Width": 81 },
- "077": { "PaletteId": 25, "Width": 196 },
- "078": { "PaletteId": 25, "Width": 196 },
- "079": { "PaletteId": 25, "Width": 196 },
- "080": { "PaletteId": 25, "Width": 196 },
- "081": { "PaletteId": 25, "Width": 196 },
- "082": { "PaletteId": 25, "Width": 196 },
- "083": { "PaletteId": 25, "Width": 196 },
- "084": { "PaletteId": 25, "Width": 196 },
- "085": { "PaletteId": 25, "Width": 196 },
- "086": { "PaletteId": 25, "Width": 196 },
- "087": { "PaletteId": 25, "Width": 196 },
- "088": { "PaletteId": 25, "Width": 196 },
- "089": { "PaletteId": 25, "Width": 196 },
- "090": { "PaletteId": 25, "Width": 196 },
- "091": { "PaletteId": 25, "Width": 196 },
- "092": { "PaletteId": 25, "Width": 196 },
- "093": { "PaletteId": 25, "Width": 98 },
- "094": { "PaletteId": 25, "Width": 98 },
- "095": { "PaletteId": 25, "Width": 98 },
- "096": { "PaletteId": 25, "Width": 98 },
- "097": { "PaletteId": 25, "Width": 98 },
- "098": { "PaletteId": 25, "Width": 98 }
+ "wall.1": { "Palette": "pal.3", "Width": 112 },
+ "wall.2": { "Palette": "pal.3", "Width": 112 },
+ "wall.3": { "Palette": "pal.3", "Width": 112 },
+ "wall.4": { "Palette": "pal.3", "Width": 112 },
+ "wall.5": { "Palette": "pal.3", "Width": 112 },
+ "wall.6": { "Palette": "pal.3", "Width": 112 },
+ "wall.7": { "Palette": "pal.3", "Width": 112 },
+ "wall.8": { "Palette": "pal.3", "Width": 112 },
+ "wall.9": { "Palette": "pal.3", "Width": 112 },
+ "wall.10": { "Palette": "pal.3", "Width": 112 },
+ "wall.11": { "Palette": "pal.7", "Width": 80 },
+ "wall.12": { "Palette": "pal.7", "Width": 80 },
+ "wall.13": { "Palette": "pal.7", "Width": 80 },
+ "wall.14": { "Palette": "pal.7", "Width": 80 },
+ "wall.15": { "Palette": "pal.7", "Width": 80 },
+ "wall.16": { "Palette": "pal.7", "Width": 80 },
+ "wall.17": { "Palette": "pal.8", "Width": 107 },
+ "wall.18": { "Palette": "pal.8", "Width": 107 },
+ "wall.19": { "Palette": "pal.8", "Width": 107 },
+ "wall.20": { "Palette": "pal.8", "Width": 107 },
+ "wall.21": { "Palette": "pal.8", "Width": 107 },
+ "wall.22": { "Palette": "pal.8", "Width": 107 },
+ "wall.23": { "Palette": "pal.8", "Width": 107 },
+ "wall.24": { "Palette": "pal.8", "Width": 107 },
+ "wall.25": { "Palette": "pal.8", "Width": 107 },
+ "wall.26": { "Palette": "pal.8", "Width": 107 },
+ "wall.27": { "Palette": "pal.13", "Width": 128 },
+ "wall.28": { "Palette": "pal.13", "Width": 128 },
+ "wall.29": { "Palette": "pal.13", "Width": 128 },
+ "wall.30": { "Palette": "pal.13", "Width": 128 },
+ "wall.31": { "Palette": "pal.13", "Width": 128 },
+ "wall.32": { "Palette": "pal.13", "Width": 128 },
+ "wall.33": { "Palette": "pal.13", "Width": 128 },
+ "wall.34": { "Palette": "pal.13", "Width": 128 },
+ "wall.35": { "Palette": "pal.13", "Width": 128 },
+ "wall.36": { "Palette": "pal.13", "Width": 128 },
+ "wall.37": { "Palette": "pal.13", "Width": 128 },
+ "wall.38": { "Palette": "pal.13", "Width": 128 },
+ "wall.39": { "Palette": "pal.13", "Width": 198 },
+ "wall.40": { "Palette": "pal.13", "Width": 198 },
+ "wall.41": { "Palette": "pal.13", "Width": 198 },
+ "wall.42": { "Palette": "pal.13", "Width": 198 },
+ "wall.43": { "Palette": "pal.13", "Width": 128 },
+ "wall.44": { "Palette": "pal.13", "Width": 128 },
+ "wall.45": { "Palette": "pal.13", "Width": 32 },
+ "wall.46": { "Palette": "pal.15", "Width": 130 },
+ "wall.47": { "Palette": "pal.15", "Width": 130 },
+ "wall.48": { "Palette": "pal.15", "Width": 130 },
+ "wall.49": { "Palette": "pal.15", "Width": 130 },
+ "wall.50": { "Palette": "pal.0", "Width": 128 },
+ "wall.51": { "Palette": "pal.0", "Width": 156 },
+ "wall.52": { "Palette": "pal.15", "Width": 130, "Height": 106 },
+ "wall.53": { "Palette": "pal.3", "Width": 130 },
+ "wall.54": { "Palette": "pal.3", "Width": 130 },
+ "wall.55": { "Palette": "pal.11", "Width": 134 },
+ "wall.56": { "Palette": "pal.11", "Width": 134 },
+ "wall.57": { "Palette": "pal.11", "Width": 134 },
+ "wall.58": { "Palette": "pal.11", "Width": 134 },
+ "wall.59": { "Palette": "pal.11", "Width": 134 },
+ "wall.60": { "Palette": "pal.11", "Width": 134 },
+ "wall.61": { "Palette": "pal.11", "Width": 134 },
+ "wall.62": { "Palette": "pal.15", "Width": 112 },
+ "wall.63": { "Palette": "pal.15", "Width": 112 },
+ "wall.64": { "Palette": "pal.15", "Width": 112 },
+ "wall.65": { "Palette": "pal.0", "Width": 8 },
+ "wall.66": { "Palette": "pal.18", "Width": 134 },
+ "wall.67": { "Palette": "pal.18", "Width": 134 },
+ "wall.68": { "Palette": "pal.18", "Width": 84 },
+ "wall.69": { "Palette": "pal.18", "Width": 84 },
+ "wall.70": { "Palette": "pal.18", "Width": 84 },
+ "wall.71": { "Palette": "pal.18", "Width": 84 },
+ "wall.72": { "Palette": "pal.22", "Width": 144 },
+ "wall.73": { "Palette": "pal.22", "Width": 144 },
+ "wall.74": { "Palette": "pal.22", "Width": 144 },
+ "wall.75": { "Palette": "pal.25", "Width": 196 },
+ "wall.76": { "Palette": "pal.25", "Width": 53 },
+ "wall.77": { "Palette": "pal.25", "Width": 81 },
+ "wall.78": { "Palette": "pal.25", "Width": 196 },
+ "wall.79": { "Palette": "pal.25", "Width": 196 },
+ "wall.80": { "Palette": "pal.25", "Width": 196 },
+ "wall.81": { "Palette": "pal.25", "Width": 196 },
+ "wall.82": { "Palette": "pal.25", "Width": 196 },
+ "wall.83": { "Palette": "pal.25", "Width": 196 },
+ "wall.84": { "Palette": "pal.25", "Width": 196 },
+ "wall.85": { "Palette": "pal.25", "Width": 196 },
+ "wall.86": { "Palette": "pal.25", "Width": 196 },
+ "wall.87": { "Palette": "pal.25", "Width": 196 },
+ "wall.88": { "Palette": "pal.25", "Width": 196 },
+ "wall.89": { "Palette": "pal.25", "Width": 196 },
+ "wall.90": { "Palette": "pal.25", "Width": 196 },
+ "wall.91": { "Palette": "pal.25", "Width": 196 },
+ "wall.92": { "Palette": "pal.25", "Width": 196 },
+ "wall.93": { "Palette": "pal.25", "Width": 196 },
+ "wall.94": { "Palette": "pal.25", "Width": 98 },
+ "wall.95": { "Palette": "pal.25", "Width": 98 },
+ "wall.96": { "Palette": "pal.25", "Width": 98 },
+ "wall.97": { "Palette": "pal.25", "Width": 98 },
+ "wall.98": { "Palette": "pal.25", "Width": 98 },
+ "wall.99": { "Palette": "pal.25", "Width": 98 }
}
diff --git a/mods/Albion/Meta/3DWALLS1.json b/mods/Albion/Meta/3DWALLS1.json
index ed18c4d46..853df3c33 100644
--- a/mods/Albion/Meta/3DWALLS1.json
+++ b/mods/Albion/Meta/3DWALLS1.json
@@ -1,40 +1,40 @@
{
- "000": { "Id": "wall.100", "Width": 98, "PaletteId": 25 },
- "001": { "PaletteId": 25, "Width": 98 },
- "002": { "PaletteId": 25, "Width": 98 },
- "003": { "PaletteId": 25, "Width": 98 },
- "004": { "PaletteId": 25, "Width": 98 },
- "005": { "PaletteId": 25, "Width": 98 },
- "006": { "PaletteId": 13, "Width": 128 },
- "007": { "PaletteId": 13, "Width": 128 },
- "008": { "PaletteId": 13, "Width": 128 },
- "009": { "PaletteId": 22, "Width": 144 },
- "010": { "PaletteId": 22, "Width": 144 },
- "011": { "PaletteId": 22, "Width": 144 },
- "012": { "PaletteId": 15, "Width": 130 },
- "013": { "PaletteId": 15, "Width": 130 },
- "014": { "PaletteId": 13, "Width": 128 },
- "015": { "PaletteId": 13, "Width": 128 },
- "016": { "PaletteId": 13, "Width": 128 },
- "017": { "PaletteId": 13, "Width": 128 },
- "018": { "PaletteId": 13, "Width": 128 },
- "019": { "PaletteId": 13, "Width": 100, "Height": 100 },
- "020": { "PaletteId": 13, "Width": 128 },
- "021": { "PaletteId": 7, "Width": 80, "Height": 128 },
- "022": { "PaletteId": 7, "Width": 80 },
- "023": { "PaletteId": 7, "Width": 79, "ExtraBytes": 49 },
- "024": { "PaletteId": 25, "Width": 197 },
- "025": { "PaletteId": 25, "Width": 197 },
- "026": { "PaletteId": 25, "Width": 197 },
- "027": { "PaletteId": 25, "Width": 140, "ExtraBytes": 40 },
- "028": { "PaletteId": 25, "Width": 64 },
- "029": { "PaletteId": 16, "Width": 134 },
- "030": { "PaletteId": 22, "Width": 144 },
- "031": { "PaletteId": 22, "Width": 144 },
- "032": { "PaletteId": 22, "Width": 144 },
- "033": { "PaletteId": 22, "Width": 144 },
- "034": { "PaletteId": 22, "Width": 144 },
- "035": { "PaletteId": 18, "Width": 134 },
- "036": { "PaletteId": 18, "Width": 134 },
- "037": { "PaletteId": 18, "Width": 100, "Height": 100 }
+ "wall.100": { "Palette": "pal.25", "Width": 98 },
+ "wall.101": { "Palette": "pal.25", "Width": 98 },
+ "wall.102": { "Palette": "pal.25", "Width": 98 },
+ "wall.103": { "Palette": "pal.25", "Width": 98 },
+ "wall.104": { "Palette": "pal.25", "Width": 98 },
+ "wall.105": { "Palette": "pal.25", "Width": 98 },
+ "wall.106": { "Palette": "pal.13", "Width": 128 },
+ "wall.107": { "Palette": "pal.13", "Width": 128 },
+ "wall.108": { "Palette": "pal.13", "Width": 128 },
+ "wall.109": { "Palette": "pal.22", "Width": 144 },
+ "wall.110": { "Palette": "pal.22", "Width": 144 },
+ "wall.111": { "Palette": "pal.22", "Width": 144 },
+ "wall.112": { "Palette": "pal.15", "Width": 130 },
+ "wall.113": { "Palette": "pal.15", "Width": 130 },
+ "wall.114": { "Palette": "pal.13", "Width": 128 },
+ "wall.115": { "Palette": "pal.13", "Width": 128 },
+ "wall.116": { "Palette": "pal.13", "Width": 128 },
+ "wall.117": { "Palette": "pal.13", "Width": 128 },
+ "wall.118": { "Palette": "pal.13", "Width": 128 },
+ "wall.119": { "Palette": "pal.13", "Width": 100, "Height": 100 },
+ "wall.120": { "Palette": "pal.13", "Width": 128 },
+ "wall.121": { "Palette": "pal.7", "Width": 80, "Height": 128 },
+ "wall.122": { "Palette": "pal.7", "Width": 80 },
+ "wall.123": { "Palette": "pal.7", "Width": 79, "ExtraBytes": 49 },
+ "wall.124": { "Palette": "pal.25", "Width": 197 },
+ "wall.125": { "Palette": "pal.25", "Width": 197 },
+ "wall.126": { "Palette": "pal.25", "Width": 197 },
+ "wall.127": { "Palette": "pal.25", "Width": 140, "ExtraBytes": 40 },
+ "wall.128": { "Palette": "pal.25", "Width": 64 },
+ "wall.129": { "Palette": "pal.16", "Width": 134 },
+ "wall.130": { "Palette": "pal.22", "Width": 144 },
+ "wall.131": { "Palette": "pal.22", "Width": 144 },
+ "wall.132": { "Palette": "pal.22", "Width": 144 },
+ "wall.133": { "Palette": "pal.22", "Width": 144 },
+ "wall.134": { "Palette": "pal.22", "Width": 144 },
+ "wall.135": { "Palette": "pal.18", "Width": 134 },
+ "wall.136": { "Palette": "pal.18", "Width": 134 },
+ "wall.137": { "Palette": "pal.18", "Width": 100, "Height": 100 }
}
diff --git a/mods/Albion/Meta/COMBACK0.json b/mods/Albion/Meta/COMBACK0.json
index e501ff560..0191587f3 100644
--- a/mods/Albion/Meta/COMBACK0.json
+++ b/mods/Albion/Meta/COMBACK0.json
@@ -1,21 +1,21 @@
{
- "000": { "Id": "combg.1", "PaletteId": 23 },
- "001": { "PaletteId": 24 },
- "002": { "PaletteId": 27 },
- "003": { "PaletteId": 32 },
- "004": { "PaletteId": 33 },
- "005": { "PaletteId": 34 },
- "006": { "PaletteId": 35 },
- "007": { "PaletteId": 36 },
- "008": { "PaletteId": 37 },
- "009": { "PaletteId": 38 },
- "010": { "PaletteId": 39 },
- "011": { "PaletteId": 40 },
- "012": { "PaletteId": 41 },
- "013": { "PaletteId": 42 },
- "014": { "PaletteId": 43 },
- "015": { "PaletteId": 44 },
- "016": { "PaletteId": 52 },
- "017": { "PaletteId": 53 },
- "018": { "PaletteId": 54 }
+ "combg.1": { "Palette": "pal.23" },
+ "combg.2": { "Palette": "pal.24" },
+ "combg.3": { "Palette": "pal.27" },
+ "combg.4": { "Palette": "pal.32" },
+ "combg.5": { "Palette": "pal.33" },
+ "combg.6": { "Palette": "pal.34" },
+ "combg.7": { "Palette": "pal.35" },
+ "combg.8": { "Palette": "pal.36" },
+ "combg.9": { "Palette": "pal.37" },
+ "combg.10": { "Palette": "pal.38" },
+ "combg.11": { "Palette": "pal.39" },
+ "combg.12": { "Palette": "pal.40" },
+ "combg.13": { "Palette": "pal.41" },
+ "combg.14": { "Palette": "pal.42" },
+ "combg.15": { "Palette": "pal.43" },
+ "combg.16": { "Palette": "pal.44" },
+ "combg.17": { "Palette": "pal.52" },
+ "combg.18": { "Palette": "pal.53" },
+ "combg.19": { "Palette": "pal.54" }
}
diff --git a/mods/Albion/Meta/LABDATA0.json b/mods/Albion/Meta/LABDATA0.json
index a8a4c5dac..590a3e882 100644
--- a/mods/Albion/Meta/LABDATA0.json
+++ b/mods/Albion/Meta/LABDATA0.json
@@ -1,11 +1,11 @@
{
- "0": { "Id": "lab.1", "PaletteId": 3 }, // Test1
- "1": { "PaletteId": 7 }, // Test2
- "2": { "PaletteId": 8 }, // Test3
- "3": { "PaletteId": 13 }, // Test4
- "4": { "PaletteId": 14}, // Test5
- "5": { "PaletteId": 15 }, // TestArgim
- "6": { "PaletteId": 15 }, // Unknown7
- "7": { "PaletteId": 11 }, // Unknown8
- "8": { "PaletteId": 3 } // Unknown9
+ "lab.1": { "Palette": "pal.3" }, // Test1
+ "lab.2": { "Palette": "pal.7" }, // Test2
+ "lab.3": { "Palette": "pal.8" }, // Test3
+ "lab.4": { "Palette": "pal.13" }, // Test4
+ "lab.5": { "Palette": "pal.14"}, // Test5
+ "lab.6": { "Palette": "pal.15" }, // TestArgim
+ "lab.7": { "Palette": "pal.15" }, // Unknown7
+ "lab.8": { "Palette": "pal.11" }, // Unknown8
+ "lab.9": { "Palette": "pal.3" } // Unknown9
}
diff --git a/mods/Albion/Meta/LABDATA1.json b/mods/Albion/Meta/LABDATA1.json
index b3b9beb83..dbe7c6413 100644
--- a/mods/Albion/Meta/LABDATA1.json
+++ b/mods/Albion/Meta/LABDATA1.json
@@ -1,27 +1,27 @@
{
- "1": { "Id": "lab.101", "PaletteId": 3 }, // TestSrimalinar
- "2": { "PaletteId": 7 }, // Toronto1
- "3": { "PaletteId": 8 }, // Toronto2
- "4": { "PaletteId": 13 }, // TestDrinno
- "5": { "PaletteId": 13 }, // Unknown105
- "6": { "PaletteId": 15 }, // Argim
- "7": { "PaletteId": 15 }, // Unknown107
- "8": { "PaletteId": 18 }, // TestKenget
- "9": { "PaletteId": 3 }, // Jirinaar
- "10": { "PaletteId": 25 }, // Test110
- "11": { "PaletteId": 15 }, // HunterCellar
- "12": { "PaletteId": 13 }, // Drinno
- "13": { "PaletteId": 18 }, // Unknown113
- "14": { "PaletteId": 29 }, // ArgimDead
- "15": { "PaletteId": 18 }, // Unknown115
- "16": { "PaletteId": 18 }, // Unknown116
- "17": { "PaletteId": 22 }, // TransportCaves
- "18": { "PaletteId": 18 }, // Kenget1
- "19": { "PaletteId": 18 }, // Kenget2
- "20": { "PaletteId": 18 }, // Kenget3
- "21": { "PaletteId": 18 }, // Kenget4
- "22": { "PaletteId": 18 }, // Kenget5
- "23": { "PaletteId": 18 }, // Kenget6
- "24": { "PaletteId": 18 }, // Kenget7
- "25": { "PaletteId": 18 } // Kenget8
+ "lab.101": { "Palette": "pal.3" }, // TestSrimalinar
+ "lab.102": { "Palette": "pal.7" }, // Toronto1
+ "lab.103": { "Palette": "pal.8" }, // Toronto2
+ "lab.104": { "Palette": "pal.13" }, // TestDrinno
+ "lab.105": { "Palette": "pal.13" }, // Unknown105
+ "lab.106": { "Palette": "pal.15" }, // Argim
+ "lab.107": { "Palette": "pal.15" }, // Unknown107
+ "lab.108": { "Palette": "pal.18" }, // TestKenget
+ "lab.109": { "Palette": "pal.3" }, // Jirinaar
+ "lab.110": { "Palette": "pal.25" }, // Test110
+ "lab.111": { "Palette": "pal.15" }, // HunterCellar
+ "lab.112": { "Palette": "pal.13" }, // Drinno
+ "lab.113": { "Palette": "pal.18" }, // Unknown113
+ "lab.114": { "Palette": "pal.29" }, // ArgimDead
+ "lab.115": { "Palette": "pal.18" }, // Unknown115
+ "lab.116": { "Palette": "pal.18" }, // Unknown116
+ "lab.117": { "Palette": "pal.22" }, // TransportCaves
+ "lab.118": { "Palette": "pal.18" }, // Kenget1
+ "lab.119": { "Palette": "pal.18" }, // Kenget2
+ "lab.120": { "Palette": "pal.18" }, // Kenget3
+ "lab.121": { "Palette": "pal.18" }, // Kenget4
+ "lab.122": { "Palette": "pal.18" }, // Kenget5
+ "lab.123": { "Palette": "pal.18" }, // Kenget6
+ "lab.124": { "Palette": "pal.18" }, // Kenget7
+ "lab.125": { "Palette": "pal.18" } // Kenget8
}
diff --git a/mods/Albion/Meta/LABDATA2.json b/mods/Albion/Meta/LABDATA2.json
index 2d0f7cd36..558e1abbf 100644
--- a/mods/Albion/Meta/LABDATA2.json
+++ b/mods/Albion/Meta/LABDATA2.json
@@ -1,13 +1,13 @@
{
- "0": { "Id": "lab.200", "PaletteId": 22 }, // KounosCave
- "1": { "PaletteId": 25 }, // Unknown201
- "2": { "PaletteId": 13 }, // Kontos
- "3": { "PaletteId": 25 }, // Beloveno
- "4": { "PaletteId": 3 }, // Srimalinar
- "5": { "PaletteId": 25 }, // Unknown205
- "6": { "PaletteId": 25 }, // UmajoKenta
- "7": { "PaletteId": 30 }, // UmajoPrison
- "8": { "PaletteId": 13 }, // DeviceMaker
- "9": { "PaletteId": 13 }, // Unknown209
- "10": { "PaletteId": 30 } // MountainPass
+ "lab.200": { "Palette": "pal.22" }, // KounosCave
+ "lab.201": { "Palette": "pal.25" }, // Unknown201
+ "lab.202": { "Palette": "pal.13" }, // Kontos
+ "lab.203": { "Palette": "pal.25" }, // Beloveno
+ "lab.204": { "Palette": "pal.3" }, // Srimalinar
+ "lab.205": { "Palette": "pal.25" }, // Unknown205
+ "lab.206": { "Palette": "pal.25" }, // UmajoKenta
+ "lab.207": { "Palette": "pal.30" }, // UmajoPrison
+ "lab.208": { "Palette": "pal.13" }, // DeviceMaker
+ "lab.209": { "Palette": "pal.13" }, // Unknown209
+ "lab.210": { "Palette": "pal.30" } // MountainPass
}
diff --git a/mods/Albion/Meta/MONGFX0.json b/mods/Albion/Meta/MONGFX0.json
index d2e810d73..357067034 100644
--- a/mods/Albion/Meta/MONGFX0.json
+++ b/mods/Albion/Meta/MONGFX0.json
@@ -1,8 +1,7 @@
{
- "000": { "Id": "mongfx.1" },
- "027": { "PaletteId": 38 },
- "045": { "PaletteId": 38 },
- "046": { "PaletteId": 38 },
- "058": { "PaletteId": 39 },
- "059": { "PaletteId": 38 }
+ "mongfx.28": { "Palette": "pal.38" },
+ "mongfx.46": { "Palette": "pal.38" },
+ "mongfx.47": { "Palette": "pal.38" },
+ "mongfx.59": { "Palette": "pal.39" },
+ "mongfx.60": { "Palette": "pal.38" }
}
diff --git a/mods/Albion/Meta/MainExe.json b/mods/Albion/Meta/MainExe.json
index 4246681d3..65fd90de0 100644
--- a/mods/Albion/Meta/MainExe.json
+++ b/mods/Albion/Meta/MainExe.json
@@ -1,94 +1,92 @@
{
- "000": { "Id": "coregfx.0",
- "Offset": 1031768, "Width": 14, "Height": 14, "Hotspot": " 1 1" }, // Cursor
- "001": { "Offset": 1031964, "Width": 16, "Height": 16, "Hotspot": " 7 3" }, // Cursor3dUp
- "002": { "Offset": 1032220, "Width": 16, "Height": 16, "Hotspot": " 7 10" }, // Cursor3dDown
- "003": { "Offset": 1032476, "Width": 16, "Height": 16, "Hotspot": " 2 6" }, // Cursor3dLeft
- "004": { "Offset": 1032732, "Width": 16, "Height": 16, "Hotspot": "13 6" }, // Cursor3dRight
- "005": { "Offset": 1032988, "Width": 16, "Height": 16, "Hotspot": " 1 7" }, // Cursor3dTurnLeft90
- "006": { "Offset": 1033244, "Width": 16, "Height": 16, "Hotspot": "14 7" }, // Cursor3dTurnRight90
- "007": { "Offset": 1033500, "Width": 16, "Height": 16, "Hotspot": " 5 13" }, // Cursor3dTurnLeft180
- "008": { "Offset": 1033756, "Width": 16, "Height": 16, "Hotspot": "10 13" }, // Cursor3dTurnRight180
- "009": { "Offset": 1034012, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dUp
- "010": { "Offset": 1034268, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dDown
- "011": { "Offset": 1034524, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dLeft
- "012": { "Offset": 1034780, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dRight
- "013": { "Offset": 1035036, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dUpLeft
- "014": { "Offset": 1035292, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dUpRight
- "015": { "Offset": 1035548, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dDownRight
- "016": { "Offset": 1035804, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dDownLeft
- "017": { "Offset": 1036060, "Width": 14, "Height": 12, "Hotspot": " 1 1" }, // CursorSelected
- "018": { "Offset": 1036216, "Width": 24, "Height": 15, "Hotspot": "12 7" }, // CursorCdLoad
- "019": { "Offset": 1036576, "Width": 16, "Height": 19, "Hotspot": " 8 9" }, // CursorWait
- "020": { "Offset": 1036880, "Width": 18, "Height": 25, "Hotspot": " 8 12" }, // CursorMouseClick
- "021": { "Offset": 1037330, "Width": 8, "Height": 8, "Hotspot": " 1 1" }, // CursorSmall
- "022": { "Offset": 1037394, "Width": 20, "Height": 19, "Hotspot": " 9 9" }, // CursorCrossSelected
- "023": { "Offset": 1037774, "Width": 22, "Height": 21, "Hotspot": "10 10" }, // CursorCrossUnselected
- "024": { "Offset": 1038236, "Width": 28, "Height": 20, "Hotspot": "14 10" }, // CursorMemoryLoad
- "025": { "Offset": 1038826, "Width": 16, "Height": 16, "Hotspot": " 3 3" }, // CursorUpLeft
- "026": { "Offset": 1039084, "Width": 16, "Height": 14, "Hotspot": "13 3" }, // CursorUpRight
- "027": { "Offset": 1039632, "Width": 32, "Height": 64 }, // UiBackground
- "028": { "Offset": 1041680, "Width": 16, "Height": 12 }, // UiBackgroundStriped
- "029": { "Offset": 1041872, "Width": 16, "Height": 3 }, // UiBackgroundLines1
- "030": { "Offset": 1041920, "Width": 16, "Height": 3 }, // UiBackgroundLines2
- "031": { "Offset": 1041968, "Width": 16, "Height": 3 }, // UiBackgroundLines3
- "032": { "Offset": 1042016, "Width": 16, "Height": 3 }, // UiBackgroundLines4
- "033": { "Offset": 1042064, "Width": 16, "Height": 16 }, // UiWindowTopLeft
- "034": { "Offset": 1042320, "Width": 16, "Height": 16 }, // UiWindowTopRight
- "035": { "Offset": 1042576, "Width": 16, "Height": 16 }, // UiWindowBottomLeft
- "036": { "Offset": 1042832, "Width": 16, "Height": 16 }, // UiWindowBottomRight
- "037": { "Offset": 1043088, "Width": 56, "Height": 16 }, // UiExitButton
- "038": { "Offset": 1043984, "Width": 56, "Height": 16 }, // UiExitButtonPressed
- "039": { "Offset": 1044880, "Width": 56, "Height": 16 }, // UiExitButtonHover
- "040": { "Offset": 1045776, "Width": 8, "Height": 8 }, // UiOffensiveValue
- "041": { "Offset": 1045840, "Width": 6, "Height": 8 }, // UiDefensiveValue
- "042": { "Offset": 1045888, "Width": 12, "Height": 10 }, // UiGold
- "043": { "Offset": 1046008, "Width": 20, "Height": 10 }, // UiFood
- "044": { "Offset": 1046208, "Width": 16, "Height": 16 }, // UiNa
- "045": { "Offset": 1046464, "Width": 16, "Height": 16 }, // UiBroken
- "046": { "Offset": 1046720, "Width": 50, "Height": 8 }, // UiSpellAdvance
- "047": { "Offset": 1047120, "Width": 16, "Height": 16 }, // CombatMove
- "048": { "Offset": 1047376, "Width": 16, "Height": 16 }, // CombatAttackMelee
- "049": { "Offset": 1047632, "Width": 16, "Height": 16 }, // CombatAttackRange
- "050": { "Offset": 1047888, "Width": 16, "Height": 16 }, // CombatRetreat
- "051": { "Offset": 1048144, "Width": 16, "Height": 16 }, // CombatMagic
- "052": { "Offset": 1048400, "Width": 16, "Height": 16 }, // CombatMagicItem
- "053": { "Offset": 1048656, "Width": 32, "Height": 27 }, // MonsterEyeOff
- "054": { "Offset": 1049520, "Width": 32, "Height": 27 }, // MonsterEyeOn
- "055": { "Offset": 1050384, "Width": 32, "Height": 25 }, // Clock
- "056": { "Offset": 1051184, "Width": 6, "Height": 7 }, // ClockNum0
- "057": { "Offset": 1051226, "Width": 6, "Height": 7 }, // ClockNum1
- "058": { "Offset": 1051268, "Width": 6, "Height": 7 }, // ClockNum2
- "059": { "Offset": 1051310, "Width": 6, "Height": 7 }, // ClockNum3
- "060": { "Offset": 1051352, "Width": 6, "Height": 7 }, // ClockNum4
- "061": { "Offset": 1051394, "Width": 6, "Height": 7 }, // ClockNum5
- "062": { "Offset": 1051436, "Width": 6, "Height": 7 }, // ClockNum6
- "063": { "Offset": 1051478, "Width": 6, "Height": 7 }, // ClockNum7
- "064": { "Offset": 1051520, "Width": 6, "Height": 7 }, // ClockNum8
- "065": { "Offset": 1051562, "Width": 6, "Height": 7 }, // ClockNum9
- "066": { "Offset": 1051604, "Width": 30, "Height": 29 }, // CompassDe
- "067": { "Offset": 1052474, "Width": 30, "Height": 29 }, // CompassEn
- "068": { "Offset": 1053344, "Width": 30, "Height": 29 }, // CompassFr
- "069": { "Offset": 1054214, "Width": 6, "Height": 6 }, // CompassDot0
- "070": { "Offset": 1054250, "Width": 6, "Height": 6 }, // CompassDot1
- "071": { "Offset": 1054286, "Width": 6, "Height": 6 }, // CompassDot2
- "072": { "Offset": 1054322, "Width": 6, "Height": 6 }, // CompassDot3
- "073": { "Offset": 1054358, "Width": 6, "Height": 6 }, // CompassDot4
- "074": { "Offset": 1054394, "Width": 6, "Height": 6 }, // CompassDot5
- "075": { "Offset": 1054430, "Width": 6, "Height": 6 }, // CompassDot6
- "076": { "Offset": 1054466, "Width": 6, "Height": 6 }, // CompassDot7
- "077": { "Offset": 1054502, "Width": 18, "Height": 18 }, // Select
- "078": { "Offset": 1054826, "Width": 22, "Height": 22 }, // Lock
- "079": { "Offset": 1055310, "Width": 34, "Height": 48 }, // Producer
- "080": { "Offset": 1056942, "Width": 32, "Height": 32 }, // CharEffect1
- "081": { "Offset": 1057966, "Width": 32, "Height": 32 }, // CharEffect2
- "082": { "Offset": 1058989, "Width": 14, "Height": 13 }, // CharEffect3
- "083": { "Offset": 1059171, "Width": 16, "Height": 16 }, // ArrowTurnLeft90
- "084": { "Offset": 1059427, "Width": 16, "Height": 16 }, // ArrowTurnRight90
- "085": { "Offset": 1059683, "Width": 16, "Height": 16 }, // ArrowTurnLeft180
- "086": { "Offset": 1059939, "Width": 16, "Height": 16 }, // ArrowTurnRight180
- "087": { "Offset": 1060195, "Width": 16, "Height": 16 }, // ArrowLookUp
- "088": { "Offset": 1060451, "Width": 16, "Height": 16 } // ArrowLookDown
+ "coregfx.0": { "Offset": 1031768, "Width": 14, "Height": 14, "Hotspot": " 1 1" }, // Cursor
+ "coregfx.1": { "Offset": 1031964, "Width": 16, "Height": 16, "Hotspot": " 7 3" }, // Cursor3dUp
+ "coregfx.2": { "Offset": 1032220, "Width": 16, "Height": 16, "Hotspot": " 7 10" }, // Cursor3dDown
+ "coregfx.3": { "Offset": 1032476, "Width": 16, "Height": 16, "Hotspot": " 2 6" }, // Cursor3dLeft
+ "coregfx.4": { "Offset": 1032732, "Width": 16, "Height": 16, "Hotspot": "13 6" }, // Cursor3dRight
+ "coregfx.5": { "Offset": 1032988, "Width": 16, "Height": 16, "Hotspot": " 1 7" }, // Cursor3dTurnLeft90
+ "coregfx.6": { "Offset": 1033244, "Width": 16, "Height": 16, "Hotspot": "14 7" }, // Cursor3dTurnRight90
+ "coregfx.7": { "Offset": 1033500, "Width": 16, "Height": 16, "Hotspot": " 5 13" }, // Cursor3dTurnLeft180
+ "coregfx.8": { "Offset": 1033756, "Width": 16, "Height": 16, "Hotspot": "10 13" }, // Cursor3dTurnRight180
+ "coregfx.9": { "Offset": 1034012, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dUp
+ "coregfx.10": { "Offset": 1034268, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dDown
+ "coregfx.11": { "Offset": 1034524, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dLeft
+ "coregfx.12": { "Offset": 1034780, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dRight
+ "coregfx.13": { "Offset": 1035036, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dUpLeft
+ "coregfx.14": { "Offset": 1035292, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dUpRight
+ "coregfx.15": { "Offset": 1035548, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dDownRight
+ "coregfx.16": { "Offset": 1035804, "Width": 16, "Height": 16, "Hotspot": " 7 7" }, // Cursor2dDownLeft
+ "coregfx.17": { "Offset": 1036060, "Width": 14, "Height": 12, "Hotspot": " 1 1" }, // CursorSelected
+ "coregfx.18": { "Offset": 1036216, "Width": 24, "Height": 15, "Hotspot": "12 7" }, // CursorCdLoad
+ "coregfx.19": { "Offset": 1036576, "Width": 16, "Height": 19, "Hotspot": " 8 9" }, // CursorWait
+ "coregfx.20": { "Offset": 1036880, "Width": 18, "Height": 25, "Hotspot": " 8 12" }, // CursorMouseClick
+ "coregfx.21": { "Offset": 1037330, "Width": 8, "Height": 8, "Hotspot": " 1 1" }, // CursorSmall
+ "coregfx.22": { "Offset": 1037394, "Width": 20, "Height": 19, "Hotspot": " 9 9" }, // CursorCrossSelected
+ "coregfx.23": { "Offset": 1037774, "Width": 22, "Height": 21, "Hotspot": "10 10" }, // CursorCrossUnselected
+ "coregfx.24": { "Offset": 1038236, "Width": 28, "Height": 20, "Hotspot": "14 10" }, // CursorMemoryLoad
+ "coregfx.25": { "Offset": 1038826, "Width": 16, "Height": 16, "Hotspot": " 3 3" }, // CursorUpLeft
+ "coregfx.26": { "Offset": 1039084, "Width": 16, "Height": 14, "Hotspot": "13 3" }, // CursorUpRight
+ "coregfx.27": { "Offset": 1039632, "Width": 32, "Height": 64 }, // UiBackground
+ "coregfx.28": { "Offset": 1041680, "Width": 16, "Height": 12 }, // UiBackgroundStriped
+ "coregfx.29": { "Offset": 1041872, "Width": 16, "Height": 3 }, // UiBackgroundLines1
+ "coregfx.30": { "Offset": 1041920, "Width": 16, "Height": 3 }, // UiBackgroundLines2
+ "coregfx.31": { "Offset": 1041968, "Width": 16, "Height": 3 }, // UiBackgroundLines3
+ "coregfx.32": { "Offset": 1042016, "Width": 16, "Height": 3 }, // UiBackgroundLines4
+ "coregfx.33": { "Offset": 1042064, "Width": 16, "Height": 16 }, // UiWindowTopLeft
+ "coregfx.34": { "Offset": 1042320, "Width": 16, "Height": 16 }, // UiWindowTopRight
+ "coregfx.35": { "Offset": 1042576, "Width": 16, "Height": 16 }, // UiWindowBottomLeft
+ "coregfx.36": { "Offset": 1042832, "Width": 16, "Height": 16 }, // UiWindowBottomRight
+ "coregfx.37": { "Offset": 1043088, "Width": 56, "Height": 16 }, // UiExitButton
+ "coregfx.38": { "Offset": 1043984, "Width": 56, "Height": 16 }, // UiExitButtonPressed
+ "coregfx.39": { "Offset": 1044880, "Width": 56, "Height": 16 }, // UiExitButtonHover
+ "coregfx.40": { "Offset": 1045776, "Width": 8, "Height": 8 }, // UiOffensiveValue
+ "coregfx.41": { "Offset": 1045840, "Width": 6, "Height": 8 }, // UiDefensiveValue
+ "coregfx.42": { "Offset": 1045888, "Width": 12, "Height": 10 }, // UiGold
+ "coregfx.43": { "Offset": 1046008, "Width": 20, "Height": 10 }, // UiFood
+ "coregfx.44": { "Offset": 1046208, "Width": 16, "Height": 16 }, // UiNa
+ "coregfx.45": { "Offset": 1046464, "Width": 16, "Height": 16 }, // UiBroken
+ "coregfx.46": { "Offset": 1046720, "Width": 50, "Height": 8 }, // UiSpellAdvance
+ "coregfx.47": { "Offset": 1047120, "Width": 16, "Height": 16 }, // CombatMove
+ "coregfx.48": { "Offset": 1047376, "Width": 16, "Height": 16 }, // CombatAttackMelee
+ "coregfx.49": { "Offset": 1047632, "Width": 16, "Height": 16 }, // CombatAttackRange
+ "coregfx.50": { "Offset": 1047888, "Width": 16, "Height": 16 }, // CombatRetreat
+ "coregfx.51": { "Offset": 1048144, "Width": 16, "Height": 16 }, // CombatMagic
+ "coregfx.52": { "Offset": 1048400, "Width": 16, "Height": 16 }, // CombatMagicItem
+ "coregfx.53": { "Offset": 1048656, "Width": 32, "Height": 27 }, // MonsterEyeOff
+ "coregfx.54": { "Offset": 1049520, "Width": 32, "Height": 27 }, // MonsterEyeOn
+ "coregfx.55": { "Offset": 1050384, "Width": 32, "Height": 25 }, // Clock
+ "coregfx.56": { "Offset": 1051184, "Width": 6, "Height": 7 }, // ClockNum0
+ "coregfx.57": { "Offset": 1051226, "Width": 6, "Height": 7 }, // ClockNum1
+ "coregfx.58": { "Offset": 1051268, "Width": 6, "Height": 7 }, // ClockNum2
+ "coregfx.59": { "Offset": 1051310, "Width": 6, "Height": 7 }, // ClockNum3
+ "coregfx.60": { "Offset": 1051352, "Width": 6, "Height": 7 }, // ClockNum4
+ "coregfx.61": { "Offset": 1051394, "Width": 6, "Height": 7 }, // ClockNum5
+ "coregfx.62": { "Offset": 1051436, "Width": 6, "Height": 7 }, // ClockNum6
+ "coregfx.63": { "Offset": 1051478, "Width": 6, "Height": 7 }, // ClockNum7
+ "coregfx.64": { "Offset": 1051520, "Width": 6, "Height": 7 }, // ClockNum8
+ "coregfx.65": { "Offset": 1051562, "Width": 6, "Height": 7 }, // ClockNum9
+ "coregfx.66": { "Offset": 1051604, "Width": 30, "Height": 29 }, // CompassDe
+ "coregfx.67": { "Offset": 1052474, "Width": 30, "Height": 29 }, // CompassEn
+ "coregfx.68": { "Offset": 1053344, "Width": 30, "Height": 29 }, // CompassFr
+ "coregfx.69": { "Offset": 1054214, "Width": 6, "Height": 6 }, // CompassDot0
+ "coregfx.70": { "Offset": 1054250, "Width": 6, "Height": 6 }, // CompassDot1
+ "coregfx.71": { "Offset": 1054286, "Width": 6, "Height": 6 }, // CompassDot2
+ "coregfx.72": { "Offset": 1054322, "Width": 6, "Height": 6 }, // CompassDot3
+ "coregfx.73": { "Offset": 1054358, "Width": 6, "Height": 6 }, // CompassDot4
+ "coregfx.74": { "Offset": 1054394, "Width": 6, "Height": 6 }, // CompassDot5
+ "coregfx.75": { "Offset": 1054430, "Width": 6, "Height": 6 }, // CompassDot6
+ "coregfx.76": { "Offset": 1054466, "Width": 6, "Height": 6 }, // CompassDot7
+ "coregfx.77": { "Offset": 1054502, "Width": 18, "Height": 18 }, // Select
+ "coregfx.78": { "Offset": 1054826, "Width": 22, "Height": 22 }, // Lock
+ "coregfx.79": { "Offset": 1055310, "Width": 34, "Height": 48 }, // Producer
+ "coregfx.80": { "Offset": 1056942, "Width": 32, "Height": 32 }, // CharEffect1
+ "coregfx.81": { "Offset": 1057966, "Width": 32, "Height": 32 }, // CharEffect2
+ "coregfx.82": { "Offset": 1058989, "Width": 14, "Height": 13 }, // CharEffect3
+ "coregfx.83": { "Offset": 1059171, "Width": 16, "Height": 16 }, // ArrowTurnLeft90
+ "coregfx.84": { "Offset": 1059427, "Width": 16, "Height": 16 }, // ArrowTurnRight90
+ "coregfx.85": { "Offset": 1059683, "Width": 16, "Height": 16 }, // ArrowTurnLeft180
+ "coregfx.86": { "Offset": 1059939, "Width": 16, "Height": 16 }, // ArrowTurnRight180
+ "coregfx.87": { "Offset": 1060195, "Width": 16, "Height": 16 }, // ArrowLookUp
+ "coregfx.88": { "Offset": 1060451, "Width": 16, "Height": 16 } // ArrowLookDown
}
-
diff --git a/mods/Albion/Meta/MainExe_DE.json b/mods/Albion/Meta/MainExe_DE.json
index 83f389494..53fc008c7 100644
--- a/mods/Albion/Meta/MainExe_DE.json
+++ b/mods/Albion/Meta/MainExe_DE.json
@@ -1,94 +1,93 @@
{
- "000": { "Id": "coregfx.0",
- "Offset": 1025980, "Width": 14, "Height": 14, "Hotspot": " 1 1" } , // Cursor
- "001": { "Offset": 1026176, "Width": 16, "Height": 16, "Hotspot": " 7 3" } , // Cursor3dUp
- "002": { "Offset": 1026432, "Width": 16, "Height": 16, "Hotspot": " 7 10" } , // Cursor3dDown
- "003": { "Offset": 1026688, "Width": 16, "Height": 16, "Hotspot": " 2 6" } , // Cursor3dLeft
- "004": { "Offset": 1026944, "Width": 16, "Height": 16, "Hotspot": "13 6" } , // Cursor3dRight
- "005": { "Offset": 1027200, "Width": 16, "Height": 16, "Hotspot": " 1 7" } , // Cursor3dTurnLeft90
- "006": { "Offset": 1027456, "Width": 16, "Height": 16, "Hotspot": "14 7" } , // Cursor3dTurnRight90
- "007": { "Offset": 1027712, "Width": 16, "Height": 16, "Hotspot": " 5 13" } , // Cursor3dTurnLeft180
- "008": { "Offset": 1027968, "Width": 16, "Height": 16, "Hotspot": "10 13" } , // Cursor3dTurnRight180
- "009": { "Offset": 1028224, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dUp
- "010": { "Offset": 1028480, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dDown
- "011": { "Offset": 1028736, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dLeft
- "012": { "Offset": 1028992, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dRight
- "013": { "Offset": 1029248, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dUpLeft
- "014": { "Offset": 1029504, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dUpRight
- "015": { "Offset": 1029760, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dDownRight
- "016": { "Offset": 1030016, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dDownLeft
- "017": { "Offset": 1030272, "Width": 14, "Height": 12, "Hotspot": " 1 1" } , // CursorSelected
- "018": { "Offset": 1030452, "Width": 24, "Height": 15, "Hotspot": "12 7" } , // CursorCdLoad
- "019": { "Offset": 1030788, "Width": 16, "Height": 19, "Hotspot": " 8 9" } , // CursorWait
- "020": { "Offset": 1031092, "Width": 18, "Height": 25, "Hotspot": " 8 12" } , // CursorMouseClick
- "021": { "Offset": 1031542, "Width": 8, "Height": 8, "Hotspot": " 1 1" } , // CursorSmall
- "022": { "Offset": 1031606, "Width": 20, "Height": 19, "Hotspot": " 9 9" } , // CursorCrossSelected
- "023": { "Offset": 1031986, "Width": 22, "Height": 21, "Hotspot": "10 10" } , // CursorCrossUnselected
- "024": { "Offset": 1032448, "Width": 28, "Height": 20, "Hotspot": "14 10" } , // CursorMemoryLoad
- "025": { "Offset": 1033038, "Width": 16, "Height": 16, "Hotspot": " 3 3" } , // CursorUpLeft
- "026": { "Offset": 1033296, "Width": 16, "Height": 14, "Hotspot": "13 3" } , // CursorUpRight
- "027": { "Offset": 1033844, "Width": 32, "Height": 64 }, // UiBackground
- "028": { "Offset": 1035892, "Width": 16, "Height": 12 }, // UiBackgroundStriped
- "029": { "Offset": 1036084, "Width": 16, "Height": 3 }, // UiBackgroundLines1
- "030": { "Offset": 1036132, "Width": 16, "Height": 3 }, // UiBackgroundLines2
- "031": { "Offset": 1036180, "Width": 16, "Height": 3 }, // UiBackgroundLines3
- "032": { "Offset": 1036228, "Width": 16, "Height": 3 }, // UiBackgroundLines4
- "033": { "Offset": 1036276, "Width": 16, "Height": 16 }, // UiWindowTopLeft
- "034": { "Offset": 1036532, "Width": 16, "Height": 16 }, // UiWindowTopRight
- "035": { "Offset": 1036788, "Width": 16, "Height": 16 }, // UiWindowBottomLeft
- "036": { "Offset": 1037044, "Width": 16, "Height": 16 }, // UiWindowBottomRight
- "037": { "Offset": 1037300, "Width": 56, "Height": 16 }, // UiExitButton
- "038": { "Offset": 1038196, "Width": 56, "Height": 16 }, // UiExitButtonPressed
- "039": { "Offset": 1039092, "Width": 56, "Height": 16 }, // UiExitButtonHover
- "040": { "Offset": 1039988, "Width": 8, "Height": 8 }, // UiOffensiveValue
- "041": { "Offset": 1040052, "Width": 6, "Height": 8 }, // UiDefensiveValue
- "042": { "Offset": 1040100, "Width": 12, "Height": 10 }, // UiGold
- "043": { "Offset": 1040220, "Width": 20, "Height": 10 }, // UiFood
- "044": { "Offset": 1040420, "Width": 16, "Height": 16 }, // UiNa
- "045": { "Offset": 1040676, "Width": 16, "Height": 16 }, // UiBroken
- "046": { "Offset": 1040932, "Width": 50, "Height": 8 }, // UiSpellAdvance
- "047": { "Offset": 1041332, "Width": 16, "Height": 16 }, // CombatMove
- "048": { "Offset": 1041588, "Width": 16, "Height": 16 }, // CombatAttackMelee
- "049": { "Offset": 1041844, "Width": 16, "Height": 16 }, // CombatAttackRange
- "050": { "Offset": 1042100, "Width": 16, "Height": 16 }, // CombatRetreat
- "051": { "Offset": 1042356, "Width": 16, "Height": 16 }, // CombatMagic
- "052": { "Offset": 1042612, "Width": 16, "Height": 16 }, // CombatMagicItem
- "053": { "Offset": 1042868, "Width": 32, "Height": 27 }, // MonsterEyeOff
- "054": { "Offset": 1043732, "Width": 32, "Height": 27 }, // MonsterEyeOn
- "055": { "Offset": 1044596, "Width": 32, "Height": 25 }, // Clock
- "056": { "Offset": 1045396, "Width": 6, "Height": 7 }, // ClockNum0
- "057": { "Offset": 1045438, "Width": 6, "Height": 7 }, // ClockNum1
- "058": { "Offset": 1045480, "Width": 6, "Height": 7 }, // ClockNum2
- "059": { "Offset": 1045522, "Width": 6, "Height": 7 }, // ClockNum3
- "060": { "Offset": 1045564, "Width": 6, "Height": 7 }, // ClockNum4
- "061": { "Offset": 1045606, "Width": 6, "Height": 7 }, // ClockNum5
- "062": { "Offset": 1045648, "Width": 6, "Height": 7 }, // ClockNum6
- "063": { "Offset": 1045690, "Width": 6, "Height": 7 }, // ClockNum7
- "064": { "Offset": 1045732, "Width": 6, "Height": 7 }, // ClockNum8
- "065": { "Offset": 1045774, "Width": 6, "Height": 7 }, // ClockNum9
- "066": { "Offset": 1045816, "Width": 30, "Height": 29 }, // CompassDe
- // "067": { "Offset": 1046686, "Width": 30, "Height": 29 }, // CompassEn
- // "068": { "Offset": 1047556, "Width": 30, "Height": 29 }, // CompassFr
- "069": { "Offset": 1046686, "Width": 6, "Height": 6 }, // CompassDot0
- "070": { "Offset": 1046722, "Width": 6, "Height": 6 }, // CompassDot1
- "071": { "Offset": 1046758, "Width": 6, "Height": 6 }, // CompassDot2
- "072": { "Offset": 1046794, "Width": 6, "Height": 6 }, // CompassDot3
- "073": { "Offset": 1046830, "Width": 6, "Height": 6 }, // CompassDot4
- "074": { "Offset": 1046866, "Width": 6, "Height": 6 }, // CompassDot5
- "075": { "Offset": 1046902, "Width": 6, "Height": 6 }, // CompassDot6
- "076": { "Offset": 1046938, "Width": 6, "Height": 6 }, // CompassDot7
- "077": { "Offset": 1046974, "Width": 18, "Height": 18 }, // Select
- "078": { "Offset": 1047298, "Width": 22, "Height": 22 }, // Lock
- "079": { "Offset": 1047782, "Width": 34, "Height": 48 }, // Producer
- "080": { "Offset": 1049414, "Width": 32, "Height": 32 }, // CharEffect1
- "081": { "Offset": 1050438, "Width": 32, "Height": 32 }, // CharEffect2
- "082": { "Offset": 1051461, "Width": 14, "Height": 13 }, // CharEffect3
- "083": { "Offset": 1051643, "Width": 16, "Height": 16 }, // ArrowTurnLeft90
- "084": { "Offset": 1051899, "Width": 16, "Height": 16 }, // ArrowTurnRight90
- "085": { "Offset": 1052155, "Width": 16, "Height": 16 }, // ArrowTurnLeft180
- "086": { "Offset": 1052411, "Width": 16, "Height": 16 }, // ArrowTurnRight180
- "087": { "Offset": 1052667, "Width": 16, "Height": 16 }, // ArrowLookUp
- "088": { "Offset": 1052923, "Width": 16, "Height": 16 } // ArrowLookDown
- // Strange cursor at 1067914 (0x104b8a), width 11
- // Circular thingy at 1068065 (0x104c21), width 16
+ "coregfx.0": { "Offset": 1025980, "Width": 14, "Height": 14, "Hotspot": " 1 1" } , // Cursor
+ "coregfx.1": { "Offset": 1026176, "Width": 16, "Height": 16, "Hotspot": " 7 3" } , // Cursor3dUp
+ "coregfx.2": { "Offset": 1026432, "Width": 16, "Height": 16, "Hotspot": " 7 10" } , // Cursor3dDown
+ "coregfx.3": { "Offset": 1026688, "Width": 16, "Height": 16, "Hotspot": " 2 6" } , // Cursor3dLeft
+ "coregfx.4": { "Offset": 1026944, "Width": 16, "Height": 16, "Hotspot": "13 6" } , // Cursor3dRight
+ "coregfx.5": { "Offset": 1027200, "Width": 16, "Height": 16, "Hotspot": " 1 7" } , // Cursor3dTurnLeft90
+ "coregfx.6": { "Offset": 1027456, "Width": 16, "Height": 16, "Hotspot": "14 7" } , // Cursor3dTurnRight90
+ "coregfx.7": { "Offset": 1027712, "Width": 16, "Height": 16, "Hotspot": " 5 13" } , // Cursor3dTurnLeft180
+ "coregfx.8": { "Offset": 1027968, "Width": 16, "Height": 16, "Hotspot": "10 13" } , // Cursor3dTurnRight180
+ "coregfx.9": { "Offset": 1028224, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dUp
+ "coregfx.10": { "Offset": 1028480, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dDown
+ "coregfx.11": { "Offset": 1028736, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dLeft
+ "coregfx.12": { "Offset": 1028992, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dRight
+ "coregfx.13": { "Offset": 1029248, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dUpLeft
+ "coregfx.14": { "Offset": 1029504, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dUpRight
+ "coregfx.15": { "Offset": 1029760, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dDownRight
+ "coregfx.16": { "Offset": 1030016, "Width": 16, "Height": 16, "Hotspot": " 7 7" } , // Cursor2dDownLeft
+ "coregfx.17": { "Offset": 1030272, "Width": 14, "Height": 12, "Hotspot": " 1 1" } , // CursorSelected
+ "coregfx.18": { "Offset": 1030452, "Width": 24, "Height": 15, "Hotspot": "12 7" } , // CursorCdLoad
+ "coregfx.19": { "Offset": 1030788, "Width": 16, "Height": 19, "Hotspot": " 8 9" } , // CursorWait
+ "coregfx.20": { "Offset": 1031092, "Width": 18, "Height": 25, "Hotspot": " 8 12" } , // CursorMouseClick
+ "coregfx.21": { "Offset": 1031542, "Width": 8, "Height": 8, "Hotspot": " 1 1" } , // CursorSmall
+ "coregfx.22": { "Offset": 1031606, "Width": 20, "Height": 19, "Hotspot": " 9 9" } , // CursorCrossSelected
+ "coregfx.23": { "Offset": 1031986, "Width": 22, "Height": 21, "Hotspot": "10 10" } , // CursorCrossUnselected
+ "coregfx.24": { "Offset": 1032448, "Width": 28, "Height": 20, "Hotspot": "14 10" } , // CursorMemoryLoad
+ "coregfx.25": { "Offset": 1033038, "Width": 16, "Height": 16, "Hotspot": " 3 3" } , // CursorUpLeft
+ "coregfx.26": { "Offset": 1033296, "Width": 16, "Height": 14, "Hotspot": "13 3" } , // CursorUpRight
+ "coregfx.27": { "Offset": 1033844, "Width": 32, "Height": 64 }, // UiBackground
+ "coregfx.28": { "Offset": 1035892, "Width": 16, "Height": 12 }, // UiBackgroundStriped
+ "coregfx.29": { "Offset": 1036084, "Width": 16, "Height": 3 }, // UiBackgroundLines1
+ "coregfx.30": { "Offset": 1036132, "Width": 16, "Height": 3 }, // UiBackgroundLines2
+ "coregfx.31": { "Offset": 1036180, "Width": 16, "Height": 3 }, // UiBackgroundLines3
+ "coregfx.32": { "Offset": 1036228, "Width": 16, "Height": 3 }, // UiBackgroundLines4
+ "coregfx.33": { "Offset": 1036276, "Width": 16, "Height": 16 }, // UiWindowTopLeft
+ "coregfx.34": { "Offset": 1036532, "Width": 16, "Height": 16 }, // UiWindowTopRight
+ "coregfx.35": { "Offset": 1036788, "Width": 16, "Height": 16 }, // UiWindowBottomLeft
+ "coregfx.36": { "Offset": 1037044, "Width": 16, "Height": 16 }, // UiWindowBottomRight
+ "coregfx.37": { "Offset": 1037300, "Width": 56, "Height": 16 }, // UiExitButton
+ "coregfx.38": { "Offset": 1038196, "Width": 56, "Height": 16 }, // UiExitButtonPressed
+ "coregfx.39": { "Offset": 1039092, "Width": 56, "Height": 16 }, // UiExitButtonHover
+ "coregfx.40": { "Offset": 1039988, "Width": 8, "Height": 8 }, // UiOffensiveValue
+ "coregfx.41": { "Offset": 1040052, "Width": 6, "Height": 8 }, // UiDefensiveValue
+ "coregfx.42": { "Offset": 1040100, "Width": 12, "Height": 10 }, // UiGold
+ "coregfx.43": { "Offset": 1040220, "Width": 20, "Height": 10 }, // UiFood
+ "coregfx.44": { "Offset": 1040420, "Width": 16, "Height": 16 }, // UiNa
+ "coregfx.45": { "Offset": 1040676, "Width": 16, "Height": 16 }, // UiBroken
+ "coregfx.46": { "Offset": 1040932, "Width": 50, "Height": 8 }, // UiSpellAdvance
+ "coregfx.47": { "Offset": 1041332, "Width": 16, "Height": 16 }, // CombatMove
+ "coregfx.48": { "Offset": 1041588, "Width": 16, "Height": 16 }, // CombatAttackMelee
+ "coregfx.49": { "Offset": 1041844, "Width": 16, "Height": 16 }, // CombatAttackRange
+ "coregfx.50": { "Offset": 1042100, "Width": 16, "Height": 16 }, // CombatRetreat
+ "coregfx.51": { "Offset": 1042356, "Width": 16, "Height": 16 }, // CombatMagic
+ "coregfx.52": { "Offset": 1042612, "Width": 16, "Height": 16 }, // CombatMagicItem
+ "coregfx.53": { "Offset": 1042868, "Width": 32, "Height": 27 }, // MonsterEyeOff
+ "coregfx.54": { "Offset": 1043732, "Width": 32, "Height": 27 }, // MonsterEyeOn
+ "coregfx.55": { "Offset": 1044596, "Width": 32, "Height": 25 }, // Clock
+ "coregfx.56": { "Offset": 1045396, "Width": 6, "Height": 7 }, // ClockNum0
+ "coregfx.57": { "Offset": 1045438, "Width": 6, "Height": 7 }, // ClockNum1
+ "coregfx.58": { "Offset": 1045480, "Width": 6, "Height": 7 }, // ClockNum2
+ "coregfx.59": { "Offset": 1045522, "Width": 6, "Height": 7 }, // ClockNum3
+ "coregfx.60": { "Offset": 1045564, "Width": 6, "Height": 7 }, // ClockNum4
+ "coregfx.61": { "Offset": 1045606, "Width": 6, "Height": 7 }, // ClockNum5
+ "coregfx.62": { "Offset": 1045648, "Width": 6, "Height": 7 }, // ClockNum6
+ "coregfx.63": { "Offset": 1045690, "Width": 6, "Height": 7 }, // ClockNum7
+ "coregfx.64": { "Offset": 1045732, "Width": 6, "Height": 7 }, // ClockNum8
+ "coregfx.65": { "Offset": 1045774, "Width": 6, "Height": 7 }, // ClockNum9
+ "coregfx.66": { "Offset": 1045816, "Width": 30, "Height": 29 }, // CompassDe
+ // "coregfx.67": { "Offset": 1046686, "Width": 30, "Height": 29 }, // CompassEn
+ // "coregfx.68": { "Offset": 1047556, "Width": 30, "Height": 29 }, // CompassFr
+ "coregfx.69": { "Offset": 1046686, "Width": 6, "Height": 6 }, // CompassDot0
+ "coregfx.70": { "Offset": 1046722, "Width": 6, "Height": 6 }, // CompassDot1
+ "coregfx.71": { "Offset": 1046758, "Width": 6, "Height": 6 }, // CompassDot2
+ "coregfx.72": { "Offset": 1046794, "Width": 6, "Height": 6 }, // CompassDot3
+ "coregfx.73": { "Offset": 1046830, "Width": 6, "Height": 6 }, // CompassDot4
+ "coregfx.74": { "Offset": 1046866, "Width": 6, "Height": 6 }, // CompassDot5
+ "coregfx.75": { "Offset": 1046902, "Width": 6, "Height": 6 }, // CompassDot6
+ "coregfx.76": { "Offset": 1046938, "Width": 6, "Height": 6 }, // CompassDot7
+ "coregfx.77": { "Offset": 1046974, "Width": 18, "Height": 18 }, // Select
+ "coregfx.78": { "Offset": 1047298, "Width": 22, "Height": 22 }, // Lock
+ "coregfx.79": { "Offset": 1047782, "Width": 34, "Height": 48 }, // Producer
+ "coregfx.80": { "Offset": 1049414, "Width": 32, "Height": 32 }, // CharEffect1
+ "coregfx.81": { "Offset": 1050438, "Width": 32, "Height": 32 }, // CharEffect2
+ "coregfx.82": { "Offset": 1051461, "Width": 14, "Height": 13 }, // CharEffect3
+ "coregfx.83": { "Offset": 1051643, "Width": 16, "Height": 16 }, // ArrowTurnLeft90
+ "coregfx.84": { "Offset": 1051899, "Width": 16, "Height": 16 }, // ArrowTurnRight90
+ "coregfx.85": { "Offset": 1052155, "Width": 16, "Height": 16 }, // ArrowTurnLeft180
+ "coregfx.86": { "Offset": 1052411, "Width": 16, "Height": 16 }, // ArrowTurnRight180
+ "coregfx.87": { "Offset": 1052667, "Width": 16, "Height": 16 }, // ArrowLookUp
+ "coregfx.88": { "Offset": 1052923, "Width": 16, "Height": 16 } // ArrowLookDown
+ // Strange cursor at 1067914 (0x104b8a), width 11
+ // Circular thingy at 1068065 (0x104c21), width 16
}
diff --git a/mods/Albion/Meta/NPCGR0.json b/mods/Albion/Meta/NPCGR0.json
index 773811034..558d368f6 100644
--- a/mods/Albion/Meta/NPCGR0.json
+++ b/mods/Albion/Meta/NPCGR0.json
@@ -1,101 +1,101 @@
{
- "000": { "Id": "npclarge.1", "PaletteId": 6 },
- "001": { "PaletteId": 6 },
- "002": { "PaletteId": 6 },
- "003": { "PaletteId": 6 },
- "004": { "PaletteId": 6 },
- "005": { "PaletteId": 6 },
- "006": { "PaletteId": 6 },
- "007": { "PaletteId": 6 },
- "008": { "PaletteId": 6 },
- "009": { "PaletteId": 6 },
- "010": { "PaletteId": 6 },
- "011": { "PaletteId": 6 },
- "012": { "PaletteId": 6 },
- "013": { "PaletteId": 6 },
- "014": { "PaletteId": 6 },
- "015": { "PaletteId": 6 },
- "016": { "PaletteId": 6 },
- "017": { "PaletteId": 6 },
- "018": { "PaletteId": 26 },
- "019": { "PaletteId": 26 },
- "020": { "PaletteId": 26 },
- "021": { "PaletteId": 26 },
- "022": { "PaletteId": 26 },
- "023": { "PaletteId": 26 },
- "024": { "PaletteId": 26 },
- "025": { "PaletteId": 26 },
- "026": { "PaletteId": 6 },
- "027": { "PaletteId": 6 },
- "028": { "PaletteId": 6 },
- "029": { "PaletteId": 6 },
- "030": { "PaletteId": 6 },
- "031": { "PaletteId": 6 },
- "032": { "PaletteId": 6 },
- "033": { "PaletteId": 6 },
- "034": { "PaletteId": 6 },
- "035": { "PaletteId": 6 },
- "036": { "PaletteId": 6 },
- "037": { "PaletteId": 6 },
- "038": { "PaletteId": 9 },
- "039": { "PaletteId": 9 },
- "040": { "PaletteId": 9 },
- "041": { "PaletteId": 9 },
- "042": { "PaletteId": 9 },
- "043": { "PaletteId": 9 },
- "044": { "PaletteId": 9 },
- "045": { "PaletteId": 9 },
- "046": { "PaletteId": 9 },
- "047": { "PaletteId": 9 },
- "048": { "PaletteId": 9 },
- "049": { "PaletteId": 9 },
- "050": { "PaletteId": 9 },
- "051": { "PaletteId": 9 },
- "052": { "PaletteId": 9 },
- "053": { "PaletteId": 9 },
- "054": { "PaletteId": 9 },
- "055": { "PaletteId": 9 },
- "056": { "PaletteId": 9 },
- "057": { "PaletteId": 9 },
- "058": { "PaletteId": 9 },
- "059": { "PaletteId": 9 },
- "060": { "PaletteId": 9 },
- "061": { "PaletteId": 9 },
- "062": { "PaletteId": 9 },
- "063": { "PaletteId": 9 },
- "064": { "PaletteId": 9 },
- "065": { "PaletteId": 9 },
- "066": { "PaletteId": 9 },
- "067": { "PaletteId": 9 },
- "068": { "PaletteId": 9 },
- "069": { "PaletteId": 9 },
- "070": { "PaletteId": 9 },
- "071": { "PaletteId": 9 },
- "072": { "PaletteId": 9 },
- "073": { "PaletteId": 9 },
- "074": { "PaletteId": 9 },
- "075": { "PaletteId": 9 },
- "076": { "PaletteId": 9 },
- "077": { "PaletteId": 9 },
- "078": { "PaletteId": 9 },
- "079": { "PaletteId": 9 },
- "080": { "PaletteId": 9 },
- "081": { "PaletteId": 9 },
- "082": { "PaletteId": 9 },
- "083": { "PaletteId": 9 },
- "084": { "PaletteId": 9 },
- "085": { "PaletteId": 9 },
- "086": { "PaletteId": 9 },
- "087": { "PaletteId": 9 },
- "088": { "PaletteId": 9 },
- "089": { "PaletteId": 9 },
- "090": { "PaletteId": 9 },
- "091": { "PaletteId": 9 },
- "092": { "PaletteId": 9 },
- "093": { "PaletteId": 26 },
- "094": { "PaletteId": 9 },
- "095": { "PaletteId": 9 },
- "096": { "PaletteId": 26 },
- "097": { "PaletteId": 26 },
- "098": { "PaletteId": 26 }
+ "npclarge.1": { "Palette": "pal.6" },
+ "npclarge.2": { "Palette": "pal.6" },
+ "npclarge.3": { "Palette": "pal.6" },
+ "npclarge.4": { "Palette": "pal.6" },
+ "npclarge.5": { "Palette": "pal.6" },
+ "npclarge.6": { "Palette": "pal.6" },
+ "npclarge.7": { "Palette": "pal.6" },
+ "npclarge.8": { "Palette": "pal.6" },
+ "npclarge.9": { "Palette": "pal.6" },
+ "npclarge.10": { "Palette": "pal.6" },
+ "npclarge.11": { "Palette": "pal.6" },
+ "npclarge.12": { "Palette": "pal.6" },
+ "npclarge.13": { "Palette": "pal.6" },
+ "npclarge.14": { "Palette": "pal.6" },
+ "npclarge.15": { "Palette": "pal.6" },
+ "npclarge.16": { "Palette": "pal.6" },
+ "npclarge.17": { "Palette": "pal.6" },
+ "npclarge.18": { "Palette": "pal.6" },
+ "npclarge.19": { "Palette": "pal.26" },
+ "npclarge.20": { "Palette": "pal.26" },
+ "npclarge.21": { "Palette": "pal.26" },
+ "npclarge.22": { "Palette": "pal.26" },
+ "npclarge.23": { "Palette": "pal.26" },
+ "npclarge.24": { "Palette": "pal.26" },
+ "npclarge.25": { "Palette": "pal.26" },
+ "npclarge.26": { "Palette": "pal.26" },
+ "npclarge.27": { "Palette": "pal.6" },
+ "npclarge.28": { "Palette": "pal.6" },
+ "npclarge.29": { "Palette": "pal.6" },
+ "npclarge.30": { "Palette": "pal.6" },
+ "npclarge.31": { "Palette": "pal.6" },
+ "npclarge.32": { "Palette": "pal.6" },
+ "npclarge.33": { "Palette": "pal.6" },
+ "npclarge.34": { "Palette": "pal.6" },
+ "npclarge.35": { "Palette": "pal.6" },
+ "npclarge.36": { "Palette": "pal.6" },
+ "npclarge.37": { "Palette": "pal.6" },
+ "npclarge.38": { "Palette": "pal.6" },
+ "npclarge.39": { "Palette": "pal.9" },
+ "npclarge.40": { "Palette": "pal.9" },
+ "npclarge.41": { "Palette": "pal.9" },
+ "npclarge.42": { "Palette": "pal.9" },
+ "npclarge.43": { "Palette": "pal.9" },
+ "npclarge.44": { "Palette": "pal.9" },
+ "npclarge.45": { "Palette": "pal.9" },
+ "npclarge.46": { "Palette": "pal.9" },
+ "npclarge.47": { "Palette": "pal.9" },
+ "npclarge.48": { "Palette": "pal.9" },
+ "npclarge.49": { "Palette": "pal.9" },
+ "npclarge.50": { "Palette": "pal.9" },
+ "npclarge.51": { "Palette": "pal.9" },
+ "npclarge.52": { "Palette": "pal.9" },
+ "npclarge.53": { "Palette": "pal.9" },
+ "npclarge.54": { "Palette": "pal.9" },
+ "npclarge.55": { "Palette": "pal.9" },
+ "npclarge.56": { "Palette": "pal.9" },
+ "npclarge.57": { "Palette": "pal.9" },
+ "npclarge.58": { "Palette": "pal.9" },
+ "npclarge.59": { "Palette": "pal.9" },
+ "npclarge.60": { "Palette": "pal.9" },
+ "npclarge.61": { "Palette": "pal.9" },
+ "npclarge.62": { "Palette": "pal.9" },
+ "npclarge.63": { "Palette": "pal.9" },
+ "npclarge.64": { "Palette": "pal.9" },
+ "npclarge.65": { "Palette": "pal.9" },
+ "npclarge.66": { "Palette": "pal.9" },
+ "npclarge.67": { "Palette": "pal.9" },
+ "npclarge.68": { "Palette": "pal.9" },
+ "npclarge.69": { "Palette": "pal.9" },
+ "npclarge.70": { "Palette": "pal.9" },
+ "npclarge.71": { "Palette": "pal.9" },
+ "npclarge.72": { "Palette": "pal.9" },
+ "npclarge.73": { "Palette": "pal.9" },
+ "npclarge.74": { "Palette": "pal.9" },
+ "npclarge.75": { "Palette": "pal.9" },
+ "npclarge.76": { "Palette": "pal.9" },
+ "npclarge.77": { "Palette": "pal.9" },
+ "npclarge.78": { "Palette": "pal.9" },
+ "npclarge.79": { "Palette": "pal.9" },
+ "npclarge.80": { "Palette": "pal.9" },
+ "npclarge.81": { "Palette": "pal.9" },
+ "npclarge.82": { "Palette": "pal.9" },
+ "npclarge.83": { "Palette": "pal.9" },
+ "npclarge.84": { "Palette": "pal.9" },
+ "npclarge.85": { "Palette": "pal.9" },
+ "npclarge.86": { "Palette": "pal.9" },
+ "npclarge.87": { "Palette": "pal.9" },
+ "npclarge.88": { "Palette": "pal.9" },
+ "npclarge.89": { "Palette": "pal.9" },
+ "npclarge.90": { "Palette": "pal.9" },
+ "npclarge.91": { "Palette": "pal.9" },
+ "npclarge.92": { "Palette": "pal.9" },
+ "npclarge.93": { "Palette": "pal.9" },
+ "npclarge.94": { "Palette": "pal.26" },
+ "npclarge.95": { "Palette": "pal.9" },
+ "npclarge.96": { "Palette": "pal.9" },
+ "npclarge.97": { "Palette": "pal.26" },
+ "npclarge.98": { "Palette": "pal.26" },
+ "npclarge.99": { "Palette": "pal.26" }
}
diff --git a/mods/Albion/Meta/NPCGR1.json b/mods/Albion/Meta/NPCGR1.json
index 46592b897..19e498528 100644
--- a/mods/Albion/Meta/NPCGR1.json
+++ b/mods/Albion/Meta/NPCGR1.json
@@ -1,80 +1,80 @@
{
- "000": { "Id": "npclarge.100", "PaletteId": 26 },
- "001": { "PaletteId": 26 },
- "002": { "PaletteId": 26 },
- "003": { "PaletteId": 26 },
- "004": { "PaletteId": 9 },
- "005": { "PaletteId": 9 },
- "006": { "PaletteId": 9 },
- "007": { "PaletteId": 9 },
- "008": { "PaletteId": 26 },
- "009": { "PaletteId": 26 },
- "010": { "PaletteId": 26 },
- "011": { "PaletteId": 9 },
- "012": { "PaletteId": 9 },
- "013": { "PaletteId": 9 },
- "014": { "PaletteId": 9 },
- "015": { "PaletteId": 9 },
- "016": { "PaletteId": 9 },
- "017": { "PaletteId": 9 },
- "018": { "PaletteId": 9 },
- "019": { "PaletteId": 6 },
- "020": { "PaletteId": 6 },
- "021": { "PaletteId": 16 },
- "022": { "PaletteId": 16 },
- "023": { "PaletteId": 16 },
- "024": { "PaletteId": 16 },
- "025": { "PaletteId": 16 },
- "026": { "PaletteId": 16 },
- "027": { "PaletteId": 16 },
- "028": { "PaletteId": 16 },
- "029": { "PaletteId": 16 },
- "030": { "PaletteId": 16 },
- "031": { "PaletteId": 16 },
- "032": { "PaletteId": 16 },
- "033": { "PaletteId": 16 },
- "034": { "PaletteId": 16 },
- "035": { "PaletteId": 16 },
- "036": { "PaletteId": 16 },
- "037": { "PaletteId": 16 },
- "038": { "PaletteId": 16 },
- "039": { "PaletteId": 16 },
- "040": { "PaletteId": 16 },
- "041": { "PaletteId": 16 },
- "042": { "PaletteId": 16 },
- "043": { "PaletteId": 16 },
- "044": { "PaletteId": 16 },
- "045": { "PaletteId": 16 },
- "046": { "PaletteId": 16 },
- "047": { "PaletteId": 16 },
- "048": { "PaletteId": 16 },
- "049": { "PaletteId": 16 },
- "050": { "PaletteId": 16 },
- "051": { "PaletteId": 16 },
- "052": { "PaletteId": 16 },
- "053": { "PaletteId": 16 },
- "054": { "PaletteId": 9 },
- "055": { "PaletteId": 16 },
- "056": { "PaletteId": 16 },
- "057": { "PaletteId": 16 },
- "058": { "PaletteId": 16 },
- "059": { "PaletteId": 16 },
- "060": { "PaletteId": 16 },
- "061": { "PaletteId": 16 },
- "062": { "PaletteId": 16 },
- "063": { "PaletteId": 16 },
- "064": { "PaletteId": 16 },
- "065": { "PaletteId": 16 },
- "066": { "PaletteId": 16 },
- "067": { "PaletteId": 26 },
- "068": { "PaletteId": 45 },
- "069": { "PaletteId": 45 },
- "070": { "PaletteId": 45 },
- "071": { "PaletteId": 5 },
- "072": { "PaletteId": 5 },
- "073": { "PaletteId": 5 },
- "074": { "PaletteId": 5 },
- "075": { "PaletteId": 5 },
- "076": { "PaletteId": 6 },
- "077": { "PaletteId": 6 }
+ "npclarge.100": { "Palette": "pal.26" },
+ "npclarge.101": { "Palette": "pal.26" },
+ "npclarge.102": { "Palette": "pal.26" },
+ "npclarge.103": { "Palette": "pal.26" },
+ "npclarge.104": { "Palette": "pal.9" },
+ "npclarge.105": { "Palette": "pal.9" },
+ "npclarge.106": { "Palette": "pal.9" },
+ "npclarge.107": { "Palette": "pal.9" },
+ "npclarge.108": { "Palette": "pal.26" },
+ "npclarge.109": { "Palette": "pal.26" },
+ "npclarge.110": { "Palette": "pal.26" },
+ "npclarge.111": { "Palette": "pal.9" },
+ "npclarge.112": { "Palette": "pal.9" },
+ "npclarge.113": { "Palette": "pal.9" },
+ "npclarge.114": { "Palette": "pal.9" },
+ "npclarge.115": { "Palette": "pal.9" },
+ "npclarge.116": { "Palette": "pal.9" },
+ "npclarge.117": { "Palette": "pal.9" },
+ "npclarge.118": { "Palette": "pal.9" },
+ "npclarge.119": { "Palette": "pal.6" },
+ "npclarge.120": { "Palette": "pal.6" },
+ "npclarge.121": { "Palette": "pal.16" },
+ "npclarge.122": { "Palette": "pal.16" },
+ "npclarge.123": { "Palette": "pal.16" },
+ "npclarge.124": { "Palette": "pal.16" },
+ "npclarge.125": { "Palette": "pal.16" },
+ "npclarge.126": { "Palette": "pal.16" },
+ "npclarge.127": { "Palette": "pal.16" },
+ "npclarge.128": { "Palette": "pal.16" },
+ "npclarge.129": { "Palette": "pal.16" },
+ "npclarge.130": { "Palette": "pal.16" },
+ "npclarge.131": { "Palette": "pal.16" },
+ "npclarge.132": { "Palette": "pal.16" },
+ "npclarge.133": { "Palette": "pal.16" },
+ "npclarge.134": { "Palette": "pal.16" },
+ "npclarge.135": { "Palette": "pal.16" },
+ "npclarge.136": { "Palette": "pal.16" },
+ "npclarge.137": { "Palette": "pal.16" },
+ "npclarge.138": { "Palette": "pal.16" },
+ "npclarge.139": { "Palette": "pal.16" },
+ "npclarge.140": { "Palette": "pal.16" },
+ "npclarge.141": { "Palette": "pal.16" },
+ "npclarge.142": { "Palette": "pal.16" },
+ "npclarge.143": { "Palette": "pal.16" },
+ "npclarge.144": { "Palette": "pal.16" },
+ "npclarge.145": { "Palette": "pal.16" },
+ "npclarge.146": { "Palette": "pal.16" },
+ "npclarge.147": { "Palette": "pal.16" },
+ "npclarge.148": { "Palette": "pal.16" },
+ "npclarge.149": { "Palette": "pal.16" },
+ "npclarge.150": { "Palette": "pal.16" },
+ "npclarge.151": { "Palette": "pal.16" },
+ "npclarge.152": { "Palette": "pal.16" },
+ "npclarge.153": { "Palette": "pal.16" },
+ "npclarge.154": { "Palette": "pal.9" },
+ "npclarge.155": { "Palette": "pal.16" },
+ "npclarge.156": { "Palette": "pal.16" },
+ "npclarge.157": { "Palette": "pal.16" },
+ "npclarge.158": { "Palette": "pal.16" },
+ "npclarge.159": { "Palette": "pal.16" },
+ "npclarge.160": { "Palette": "pal.16" },
+ "npclarge.161": { "Palette": "pal.16" },
+ "npclarge.162": { "Palette": "pal.16" },
+ "npclarge.163": { "Palette": "pal.16" },
+ "npclarge.164": { "Palette": "pal.16" },
+ "npclarge.165": { "Palette": "pal.16" },
+ "npclarge.166": { "Palette": "pal.16" },
+ "npclarge.167": { "Palette": "pal.26" },
+ "npclarge.168": { "Palette": "pal.45" },
+ "npclarge.169": { "Palette": "pal.45" },
+ "npclarge.170": { "Palette": "pal.45" },
+ "npclarge.171": { "Palette": "pal.5" },
+ "npclarge.172": { "Palette": "pal.5" },
+ "npclarge.173": { "Palette": "pal.5" },
+ "npclarge.174": { "Palette": "pal.5" },
+ "npclarge.175": { "Palette": "pal.5" },
+ "npclarge.176": { "Palette": "pal.6" },
+ "npclarge.177": { "Palette": "pal.6" }
}
diff --git a/mods/Albion/Meta/SPELLDAT.json b/mods/Albion/Meta/SPELLDAT.json
index 2ed9fc1d4..4ba8342e7 100644
--- a/mods/Albion/Meta/SPELLDAT.json
+++ b/mods/Albion/Meta/SPELLDAT.json
@@ -1,213 +1,213 @@
{
- "0": { "Id": "spell.1", "School": "DjiKas", "SpellNumber": 0, "Name": "stext.203" },
- "1": { "School": "DjiKas", "SpellNumber": 1, "Name": "stext.204" },
- "2": { "School": "DjiKas", "SpellNumber": 2, "Name": "stext.205" },
- "3": { "School": "DjiKas", "SpellNumber": 3, "Name": "stext.206" },
- "4": { "School": "DjiKas", "SpellNumber": 4, "Name": "stext.207" },
- "5": { "School": "DjiKas", "SpellNumber": 5, "Name": "stext.208" },
- "6": { "School": "DjiKas", "SpellNumber": 6, "Name": "stext.209" },
- "7": { "School": "DjiKas", "SpellNumber": 7, "Name": "stext.210" },
- "8": { "School": "DjiKas", "SpellNumber": 8, "Name": "stext.211" },
- "9": { "School": "DjiKas", "SpellNumber": 9, "Name": "stext.212" },
- "10": { "School": "DjiKas", "SpellNumber": 10, "Name": "stext.213" },
- "11": { "School": "DjiKas", "SpellNumber": 11, "Name": "stext.214" },
- "12": { "School": "DjiKas", "SpellNumber": 12, "Name": "stext.215" },
- "13": { "School": "DjiKas", "SpellNumber": 13, "Name": "stext.216" },
- "14": { "School": "DjiKas", "SpellNumber": 14, "Name": "stext.217" },
- "15": { "School": "DjiKas", "SpellNumber": 15, "Name": "stext.218" },
- "16": { "School": "DjiKas", "SpellNumber": 16, "Name": "stext.219" },
- "17": { "School": "DjiKas", "SpellNumber": 17, "Name": "stext.220" },
- "18": { "School": "DjiKas", "SpellNumber": 18, "Name": "stext.221" },
- "19": { "School": "DjiKas", "SpellNumber": 19, "Name": "stext.222" },
- "20": { "School": "DjiKas", "SpellNumber": 20, "Name": "stext.223" },
- "21": { "School": "DjiKas", "SpellNumber": 21, "Name": "stext.224" },
- "22": { "School": "DjiKas", "SpellNumber": 22, "Name": "stext.225" },
- "23": { "School": "DjiKas", "SpellNumber": 23, "Name": "stext.226" },
- "24": { "School": "DjiKas", "SpellNumber": 24, "Name": "stext.227" },
- "25": { "School": "DjiKas", "SpellNumber": 25, "Name": "stext.228" },
- "26": { "School": "DjiKas", "SpellNumber": 26, "Name": "stext.229" },
- "27": { "School": "DjiKas", "SpellNumber": 27, "Name": "stext.230" },
- "28": { "School": "DjiKas", "SpellNumber": 28, "Name": "stext.231" },
- "29": { "School": "DjiKas", "SpellNumber": 29, "Name": "stext.232" },
- "30": { "School": "DjiKantos", "SpellNumber": 0, "Name": "stext.233" },
- "31": { "School": "DjiKantos", "SpellNumber": 1, "Name": "stext.234" },
- "32": { "School": "DjiKantos", "SpellNumber": 2, "Name": "stext.235" },
- "33": { "School": "DjiKantos", "SpellNumber": 3, "Name": "stext.236" },
- "34": { "School": "DjiKantos", "SpellNumber": 4, "Name": "stext.237" },
- "35": { "School": "DjiKantos", "SpellNumber": 5, "Name": "stext.238" },
- "36": { "School": "DjiKantos", "SpellNumber": 6, "Name": "stext.239" },
- "37": { "School": "DjiKantos", "SpellNumber": 7, "Name": "stext.240" },
- "38": { "School": "DjiKantos", "SpellNumber": 8, "Name": "stext.241" },
- "39": { "School": "DjiKantos", "SpellNumber": 9, "Name": "stext.242" },
- "40": { "School": "DjiKantos", "SpellNumber": 10, "Name": "stext.243" },
- "41": { "School": "DjiKantos", "SpellNumber": 11, "Name": "stext.244" },
- "42": { "School": "DjiKantos", "SpellNumber": 12, "Name": "stext.245" },
- "43": { "School": "DjiKantos", "SpellNumber": 13, "Name": "stext.246" },
- "44": { "School": "DjiKantos", "SpellNumber": 14, "Name": "stext.247" },
- "45": { "School": "DjiKantos", "SpellNumber": 15, "Name": "stext.248" },
- "46": { "School": "DjiKantos", "SpellNumber": 16, "Name": "stext.249" },
- "47": { "School": "DjiKantos", "SpellNumber": 17, "Name": "stext.250" },
- "48": { "School": "DjiKantos", "SpellNumber": 18, "Name": "stext.251" },
- "49": { "School": "DjiKantos", "SpellNumber": 19, "Name": "stext.252" },
- "50": { "School": "DjiKantos", "SpellNumber": 20, "Name": "stext.253" },
- "51": { "School": "DjiKantos", "SpellNumber": 21, "Name": "stext.254" },
- "52": { "School": "DjiKantos", "SpellNumber": 22, "Name": "stext.255" },
- "53": { "School": "DjiKantos", "SpellNumber": 23, "Name": "stext.256" },
- "54": { "School": "DjiKantos", "SpellNumber": 24, "Name": "stext.257" },
- "55": { "School": "DjiKantos", "SpellNumber": 25, "Name": "stext.258" },
- "56": { "School": "DjiKantos", "SpellNumber": 26, "Name": "stext.259" },
- "57": { "School": "DjiKantos", "SpellNumber": 27, "Name": "stext.260" },
- "58": { "School": "DjiKantos", "SpellNumber": 28, "Name": "stext.261" },
- "59": { "School": "DjiKantos", "SpellNumber": 29, "Name": "stext.262" },
- "60": { "School": "Druid", "SpellNumber": 0, "Name": "stext.263" },
- "61": { "School": "Druid", "SpellNumber": 1, "Name": "stext.264" },
- "62": { "School": "Druid", "SpellNumber": 2, "Name": "stext.265" },
- "63": { "School": "Druid", "SpellNumber": 3, "Name": "stext.266" },
- "64": { "School": "Druid", "SpellNumber": 4, "Name": "stext.267" },
- "65": { "School": "Druid", "SpellNumber": 5, "Name": "stext.268" },
- "66": { "School": "Druid", "SpellNumber": 6, "Name": "stext.269" },
- "67": { "School": "Druid", "SpellNumber": 7, "Name": "stext.270" },
- "68": { "School": "Druid", "SpellNumber": 8, "Name": "stext.271" },
- "69": { "School": "Druid", "SpellNumber": 9, "Name": "stext.272" },
- "70": { "School": "Druid", "SpellNumber": 10, "Name": "stext.273" },
- "71": { "School": "Druid", "SpellNumber": 11, "Name": "stext.274" },
- "72": { "School": "Druid", "SpellNumber": 12, "Name": "stext.275" },
- "73": { "School": "Druid", "SpellNumber": 13, "Name": "stext.276" },
- "74": { "School": "Druid", "SpellNumber": 14, "Name": "stext.277" },
- "75": { "School": "Druid", "SpellNumber": 15, "Name": "stext.278" },
- "76": { "School": "Druid", "SpellNumber": 16, "Name": "stext.279" },
- "77": { "School": "Druid", "SpellNumber": 17, "Name": "stext.280" },
- "78": { "School": "Druid", "SpellNumber": 18, "Name": "stext.281" },
- "79": { "School": "Druid", "SpellNumber": 19, "Name": "stext.282" },
- "80": { "School": "Druid", "SpellNumber": 20, "Name": "stext.283" },
- "81": { "School": "Druid", "SpellNumber": 21, "Name": "stext.284" },
- "82": { "School": "Druid", "SpellNumber": 22, "Name": "stext.285" },
- "83": { "School": "Druid", "SpellNumber": 23, "Name": "stext.286" },
- "84": { "School": "Druid", "SpellNumber": 24, "Name": "stext.287" },
- "85": { "School": "Druid", "SpellNumber": 25, "Name": "stext.288" },
- "86": { "School": "Druid", "SpellNumber": 26, "Name": "stext.289" },
- "87": { "School": "Druid", "SpellNumber": 27, "Name": "stext.290" },
- "88": { "School": "Druid", "SpellNumber": 28, "Name": "stext.291" },
- "89": { "School": "Druid", "SpellNumber": 29, "Name": "stext.292" },
- "90": { "School": "OquloKamulos", "SpellNumber": 0, "Name": "stext.293" },
- "91": { "School": "OquloKamulos", "SpellNumber": 1, "Name": "stext.294" },
- "92": { "School": "OquloKamulos", "SpellNumber": 2, "Name": "stext.295" },
- "93": { "School": "OquloKamulos", "SpellNumber": 3, "Name": "stext.296" },
- "94": { "School": "OquloKamulos", "SpellNumber": 4, "Name": "stext.297" },
- "95": { "School": "OquloKamulos", "SpellNumber": 5, "Name": "stext.298" },
- "96": { "School": "OquloKamulos", "SpellNumber": 6, "Name": "stext.299" },
- "97": { "School": "OquloKamulos", "SpellNumber": 7, "Name": "stext.300" },
- "98": { "School": "OquloKamulos", "SpellNumber": 8, "Name": "stext.301" },
- "99": { "School": "OquloKamulos", "SpellNumber": 9, "Name": "stext.302" },
- "100": { "School": "OquloKamulos", "SpellNumber": 10, "Name": "stext.303" },
- "101": { "School": "OquloKamulos", "SpellNumber": 11, "Name": "stext.304" },
- "102": { "School": "OquloKamulos", "SpellNumber": 12, "Name": "stext.305" },
- "103": { "School": "OquloKamulos", "SpellNumber": 13, "Name": "stext.306" },
- "104": { "School": "OquloKamulos", "SpellNumber": 14, "Name": "stext.307" },
- "105": { "School": "OquloKamulos", "SpellNumber": 15, "Name": "stext.308" },
- "106": { "School": "OquloKamulos", "SpellNumber": 16, "Name": "stext.309" },
- "107": { "School": "OquloKamulos", "SpellNumber": 17, "Name": "stext.310" },
- "108": { "School": "OquloKamulos", "SpellNumber": 18, "Name": "stext.311" },
- "109": { "School": "OquloKamulos", "SpellNumber": 19, "Name": "stext.312" },
- "110": { "School": "OquloKamulos", "SpellNumber": 20, "Name": "stext.313" },
- "111": { "School": "OquloKamulos", "SpellNumber": 21, "Name": "stext.314" },
- "112": { "School": "OquloKamulos", "SpellNumber": 22, "Name": "stext.315" },
- "113": { "School": "OquloKamulos", "SpellNumber": 23, "Name": "stext.316" },
- "114": { "School": "OquloKamulos", "SpellNumber": 24, "Name": "stext.317" },
- "115": { "School": "OquloKamulos", "SpellNumber": 25, "Name": "stext.318" },
- "116": { "School": "OquloKamulos", "SpellNumber": 26, "Name": "stext.319" },
- "117": { "School": "OquloKamulos", "SpellNumber": 27, "Name": "stext.320" },
- "118": { "School": "OquloKamulos", "SpellNumber": 28, "Name": "stext.321" },
- "119": { "School": "OquloKamulos", "SpellNumber": 29, "Name": "stext.322" },
- "120": { "School": "Unk4", "SpellNumber": 0, "Name": "stext.323" },
- "121": { "School": "Unk4", "SpellNumber": 1, "Name": "stext.324" },
- "122": { "School": "Unk4", "SpellNumber": 2, "Name": "stext.325" },
- "123": { "School": "Unk4", "SpellNumber": 3, "Name": "stext.326" },
- "124": { "School": "Unk4", "SpellNumber": 4, "Name": "stext.327" },
- "125": { "School": "Unk4", "SpellNumber": 5, "Name": "stext.328" },
- "126": { "School": "Unk4", "SpellNumber": 6, "Name": "stext.329" },
- "127": { "School": "Unk4", "SpellNumber": 7, "Name": "stext.330" },
- "128": { "School": "Unk4", "SpellNumber": 8, "Name": "stext.331" },
- "129": { "School": "Unk4", "SpellNumber": 9, "Name": "stext.332" },
- "130": { "School": "Unk4", "SpellNumber": 10, "Name": "stext.333" },
- "131": { "School": "Unk4", "SpellNumber": 11, "Name": "stext.334" },
- "132": { "School": "Unk4", "SpellNumber": 12, "Name": "stext.335" },
- "133": { "School": "Unk4", "SpellNumber": 13, "Name": "stext.336" },
- "134": { "School": "Unk4", "SpellNumber": 14, "Name": "stext.337" },
- "135": { "School": "Unk4", "SpellNumber": 15, "Name": "stext.338" },
- "136": { "School": "Unk4", "SpellNumber": 16, "Name": "stext.339" },
- "137": { "School": "Unk4", "SpellNumber": 17, "Name": "stext.340" },
- "138": { "School": "Unk4", "SpellNumber": 18, "Name": "stext.341" },
- "139": { "School": "Unk4", "SpellNumber": 19, "Name": "stext.342" },
- "140": { "School": "Unk4", "SpellNumber": 20, "Name": "stext.343" },
- "141": { "School": "Unk4", "SpellNumber": 21, "Name": "stext.344" },
- "142": { "School": "Unk4", "SpellNumber": 22, "Name": "stext.345" },
- "143": { "School": "Unk4", "SpellNumber": 23, "Name": "stext.346" },
- "144": { "School": "Unk4", "SpellNumber": 24, "Name": "stext.347" },
- "145": { "School": "Unk4", "SpellNumber": 25, "Name": "stext.348" },
- "146": { "School": "Unk4", "SpellNumber": 26, "Name": "stext.349" },
- "147": { "School": "Unk4", "SpellNumber": 27, "Name": "stext.350" },
- "148": { "School": "Unk4", "SpellNumber": 28, "Name": "stext.351" },
- "149": { "School": "Unk4", "SpellNumber": 29, "Name": "stext.352" },
- "150": { "School": "ZombieMagic", "SpellNumber": 0, "Name": "stext.353" },
- "151": { "School": "ZombieMagic", "SpellNumber": 1, "Name": "stext.354" },
- "152": { "School": "ZombieMagic", "SpellNumber": 2, "Name": "stext.355" },
- "153": { "School": "ZombieMagic", "SpellNumber": 3, "Name": "stext.356" },
- "154": { "School": "ZombieMagic", "SpellNumber": 4, "Name": "stext.357" },
- "155": { "School": "ZombieMagic", "SpellNumber": 5, "Name": "stext.358" },
- "156": { "School": "ZombieMagic", "SpellNumber": 6, "Name": "stext.359" },
- "157": { "School": "ZombieMagic", "SpellNumber": 7, "Name": "stext.360" },
- "158": { "School": "ZombieMagic", "SpellNumber": 8, "Name": "stext.361" },
- "159": { "School": "ZombieMagic", "SpellNumber": 9, "Name": "stext.362" },
- "160": { "School": "ZombieMagic", "SpellNumber": 10, "Name": "stext.363" },
- "161": { "School": "ZombieMagic", "SpellNumber": 11, "Name": "stext.364" },
- "162": { "School": "ZombieMagic", "SpellNumber": 12, "Name": "stext.365" },
- "163": { "School": "ZombieMagic", "SpellNumber": 13, "Name": "stext.366" },
- "164": { "School": "ZombieMagic", "SpellNumber": 14, "Name": "stext.367" },
- "165": { "School": "ZombieMagic", "SpellNumber": 15, "Name": "stext.368" },
- "166": { "School": "ZombieMagic", "SpellNumber": 16, "Name": "stext.369" },
- "167": { "School": "ZombieMagic", "SpellNumber": 17, "Name": "stext.370" },
- "168": { "School": "ZombieMagic", "SpellNumber": 18, "Name": "stext.371" },
- "169": { "School": "ZombieMagic", "SpellNumber": 19, "Name": "stext.372" },
- "170": { "School": "ZombieMagic", "SpellNumber": 20, "Name": "stext.373" },
- "171": { "School": "ZombieMagic", "SpellNumber": 21, "Name": "stext.374" },
- "172": { "School": "ZombieMagic", "SpellNumber": 22, "Name": "stext.375" },
- "173": { "School": "ZombieMagic", "SpellNumber": 23, "Name": "stext.376" },
- "174": { "School": "ZombieMagic", "SpellNumber": 24, "Name": "stext.377" },
- "175": { "School": "ZombieMagic", "SpellNumber": 25, "Name": "stext.378" },
- "176": { "School": "ZombieMagic", "SpellNumber": 26, "Name": "stext.379" },
- "177": { "School": "ZombieMagic", "SpellNumber": 27, "Name": "stext.380" },
- "178": { "School": "ZombieMagic", "SpellNumber": 28, "Name": "stext.381" },
- "179": { "School": "ZombieMagic", "SpellNumber": 29, "Name": "stext.382" },
- "180": { "School": "Unk6", "SpellNumber": 0, "Name": "stext.383" },
- "181": { "School": "Unk6", "SpellNumber": 1, "Name": "stext.384" },
- "182": { "School": "Unk6", "SpellNumber": 2, "Name": "stext.385" },
- "183": { "School": "Unk6", "SpellNumber": 3, "Name": "stext.386" },
- "184": { "School": "Unk6", "SpellNumber": 4, "Name": "stext.387" },
- "185": { "School": "Unk6", "SpellNumber": 5, "Name": "stext.388" },
- "186": { "School": "Unk6", "SpellNumber": 6, "Name": "stext.389" },
- "187": { "School": "Unk6", "SpellNumber": 7, "Name": "stext.390" },
- "188": { "School": "Unk6", "SpellNumber": 8, "Name": "stext.391" },
- "189": { "School": "Unk6", "SpellNumber": 9, "Name": "stext.392" },
- "190": { "School": "Unk6", "SpellNumber": 10, "Name": "stext.393" },
- "191": { "School": "Unk6", "SpellNumber": 11, "Name": "stext.394" },
- "192": { "School": "Unk6", "SpellNumber": 12, "Name": "stext.395" },
- "193": { "School": "Unk6", "SpellNumber": 13, "Name": "stext.396" },
- "194": { "School": "Unk6", "SpellNumber": 14, "Name": "stext.397" },
- "195": { "School": "Unk6", "SpellNumber": 15, "Name": "stext.398" },
- "196": { "School": "Unk6", "SpellNumber": 16, "Name": "stext.399" },
- "197": { "School": "Unk6", "SpellNumber": 17, "Name": "stext.400" },
- "198": { "School": "Unk6", "SpellNumber": 18, "Name": "stext.401" },
- "199": { "School": "Unk6", "SpellNumber": 19, "Name": "stext.402" },
- "200": { "School": "Unk6", "SpellNumber": 20, "Name": "stext.403" },
- "201": { "School": "Unk6", "SpellNumber": 21, "Name": "stext.404" },
- "202": { "School": "Unk6", "SpellNumber": 22, "Name": "stext.405" },
- "203": { "School": "Unk6", "SpellNumber": 23, "Name": "stext.406" },
- "204": { "School": "Unk6", "SpellNumber": 24, "Name": "stext.407" },
- "205": { "School": "Unk6", "SpellNumber": 25, "Name": "stext.408" },
- "206": { "School": "Unk6", "SpellNumber": 26, "Name": "stext.409" },
- "207": { "School": "Unk6", "SpellNumber": 27, "Name": "stext.410" },
- "208": { "School": "Unk6", "SpellNumber": 28, "Name": "stext.411" },
- "209": { "School": "Unk6", "SpellNumber": 29, "Name": "stext.412" }
+ "spell.1": { "School": "DjiKas", "SpellNumber": 0, "Name": "stext.203" },
+ "spell.2": { "School": "DjiKas", "SpellNumber": 1, "Name": "stext.204" },
+ "spell.3": { "School": "DjiKas", "SpellNumber": 2, "Name": "stext.205" },
+ "spell.4": { "School": "DjiKas", "SpellNumber": 3, "Name": "stext.206" },
+ "spell.5": { "School": "DjiKas", "SpellNumber": 4, "Name": "stext.207" },
+ "spell.6": { "School": "DjiKas", "SpellNumber": 5, "Name": "stext.208" },
+ "spell.7": { "School": "DjiKas", "SpellNumber": 6, "Name": "stext.209" },
+ "spell.8": { "School": "DjiKas", "SpellNumber": 7, "Name": "stext.210" },
+ "spell.9": { "School": "DjiKas", "SpellNumber": 8, "Name": "stext.211" },
+ "spell.10": { "School": "DjiKas", "SpellNumber": 9, "Name": "stext.212" },
+ "spell.11": { "School": "DjiKas", "SpellNumber": 10, "Name": "stext.213" },
+ "spell.12": { "School": "DjiKas", "SpellNumber": 11, "Name": "stext.214" },
+ "spell.13": { "School": "DjiKas", "SpellNumber": 12, "Name": "stext.215" },
+ "spell.14": { "School": "DjiKas", "SpellNumber": 13, "Name": "stext.216" },
+ "spell.15": { "School": "DjiKas", "SpellNumber": 14, "Name": "stext.217" },
+ "spell.16": { "School": "DjiKas", "SpellNumber": 15, "Name": "stext.218" },
+ "spell.17": { "School": "DjiKas", "SpellNumber": 16, "Name": "stext.219" },
+ "spell.18": { "School": "DjiKas", "SpellNumber": 17, "Name": "stext.220" },
+ "spell.19": { "School": "DjiKas", "SpellNumber": 18, "Name": "stext.221" },
+ "spell.20": { "School": "DjiKas", "SpellNumber": 19, "Name": "stext.222" },
+ "spell.21": { "School": "DjiKas", "SpellNumber": 20, "Name": "stext.223" },
+ "spell.22": { "School": "DjiKas", "SpellNumber": 21, "Name": "stext.224" },
+ "spell.23": { "School": "DjiKas", "SpellNumber": 22, "Name": "stext.225" },
+ "spell.24": { "School": "DjiKas", "SpellNumber": 23, "Name": "stext.226" },
+ "spell.25": { "School": "DjiKas", "SpellNumber": 24, "Name": "stext.227" },
+ "spell.26": { "School": "DjiKas", "SpellNumber": 25, "Name": "stext.228" },
+ "spell.27": { "School": "DjiKas", "SpellNumber": 26, "Name": "stext.229" },
+ "spell.28": { "School": "DjiKas", "SpellNumber": 27, "Name": "stext.230" },
+ "spell.29": { "School": "DjiKas", "SpellNumber": 28, "Name": "stext.231" },
+ "spell.30": { "School": "DjiKas", "SpellNumber": 29, "Name": "stext.232" },
+ "spell.31": { "School": "DjiKantos", "SpellNumber": 0, "Name": "stext.233" },
+ "spell.32": { "School": "DjiKantos", "SpellNumber": 1, "Name": "stext.234" },
+ "spell.33": { "School": "DjiKantos", "SpellNumber": 2, "Name": "stext.235" },
+ "spell.34": { "School": "DjiKantos", "SpellNumber": 3, "Name": "stext.236" },
+ "spell.35": { "School": "DjiKantos", "SpellNumber": 4, "Name": "stext.237" },
+ "spell.36": { "School": "DjiKantos", "SpellNumber": 5, "Name": "stext.238" },
+ "spell.37": { "School": "DjiKantos", "SpellNumber": 6, "Name": "stext.239" },
+ "spell.38": { "School": "DjiKantos", "SpellNumber": 7, "Name": "stext.240" },
+ "spell.39": { "School": "DjiKantos", "SpellNumber": 8, "Name": "stext.241" },
+ "spell.40": { "School": "DjiKantos", "SpellNumber": 9, "Name": "stext.242" },
+ "spell.41": { "School": "DjiKantos", "SpellNumber": 10, "Name": "stext.243" },
+ "spell.42": { "School": "DjiKantos", "SpellNumber": 11, "Name": "stext.244" },
+ "spell.43": { "School": "DjiKantos", "SpellNumber": 12, "Name": "stext.245" },
+ "spell.44": { "School": "DjiKantos", "SpellNumber": 13, "Name": "stext.246" },
+ "spell.45": { "School": "DjiKantos", "SpellNumber": 14, "Name": "stext.247" },
+ "spell.46": { "School": "DjiKantos", "SpellNumber": 15, "Name": "stext.248" },
+ "spell.47": { "School": "DjiKantos", "SpellNumber": 16, "Name": "stext.249" },
+ "spell.48": { "School": "DjiKantos", "SpellNumber": 17, "Name": "stext.250" },
+ "spell.49": { "School": "DjiKantos", "SpellNumber": 18, "Name": "stext.251" },
+ "spell.50": { "School": "DjiKantos", "SpellNumber": 19, "Name": "stext.252" },
+ "spell.51": { "School": "DjiKantos", "SpellNumber": 20, "Name": "stext.253" },
+ "spell.52": { "School": "DjiKantos", "SpellNumber": 21, "Name": "stext.254" },
+ "spell.53": { "School": "DjiKantos", "SpellNumber": 22, "Name": "stext.255" },
+ "spell.54": { "School": "DjiKantos", "SpellNumber": 23, "Name": "stext.256" },
+ "spell.55": { "School": "DjiKantos", "SpellNumber": 24, "Name": "stext.257" },
+ "spell.56": { "School": "DjiKantos", "SpellNumber": 25, "Name": "stext.258" },
+ "spell.57": { "School": "DjiKantos", "SpellNumber": 26, "Name": "stext.259" },
+ "spell.58": { "School": "DjiKantos", "SpellNumber": 27, "Name": "stext.260" },
+ "spell.59": { "School": "DjiKantos", "SpellNumber": 28, "Name": "stext.261" },
+ "spell.60": { "School": "DjiKantos", "SpellNumber": 29, "Name": "stext.262" },
+ "spell.61": { "School": "Druid", "SpellNumber": 0, "Name": "stext.263" },
+ "spell.62": { "School": "Druid", "SpellNumber": 1, "Name": "stext.264" },
+ "spell.63": { "School": "Druid", "SpellNumber": 2, "Name": "stext.265" },
+ "spell.64": { "School": "Druid", "SpellNumber": 3, "Name": "stext.266" },
+ "spell.65": { "School": "Druid", "SpellNumber": 4, "Name": "stext.267" },
+ "spell.66": { "School": "Druid", "SpellNumber": 5, "Name": "stext.268" },
+ "spell.67": { "School": "Druid", "SpellNumber": 6, "Name": "stext.269" },
+ "spell.68": { "School": "Druid", "SpellNumber": 7, "Name": "stext.270" },
+ "spell.69": { "School": "Druid", "SpellNumber": 8, "Name": "stext.271" },
+ "spell.70": { "School": "Druid", "SpellNumber": 9, "Name": "stext.272" },
+ "spell.71": { "School": "Druid", "SpellNumber": 10, "Name": "stext.273" },
+ "spell.72": { "School": "Druid", "SpellNumber": 11, "Name": "stext.274" },
+ "spell.73": { "School": "Druid", "SpellNumber": 12, "Name": "stext.275" },
+ "spell.74": { "School": "Druid", "SpellNumber": 13, "Name": "stext.276" },
+ "spell.75": { "School": "Druid", "SpellNumber": 14, "Name": "stext.277" },
+ "spell.76": { "School": "Druid", "SpellNumber": 15, "Name": "stext.278" },
+ "spell.77": { "School": "Druid", "SpellNumber": 16, "Name": "stext.279" },
+ "spell.78": { "School": "Druid", "SpellNumber": 17, "Name": "stext.280" },
+ "spell.79": { "School": "Druid", "SpellNumber": 18, "Name": "stext.281" },
+ "spell.80": { "School": "Druid", "SpellNumber": 19, "Name": "stext.282" },
+ "spell.81": { "School": "Druid", "SpellNumber": 20, "Name": "stext.283" },
+ "spell.82": { "School": "Druid", "SpellNumber": 21, "Name": "stext.284" },
+ "spell.83": { "School": "Druid", "SpellNumber": 22, "Name": "stext.285" },
+ "spell.84": { "School": "Druid", "SpellNumber": 23, "Name": "stext.286" },
+ "spell.85": { "School": "Druid", "SpellNumber": 24, "Name": "stext.287" },
+ "spell.86": { "School": "Druid", "SpellNumber": 25, "Name": "stext.288" },
+ "spell.87": { "School": "Druid", "SpellNumber": 26, "Name": "stext.289" },
+ "spell.88": { "School": "Druid", "SpellNumber": 27, "Name": "stext.290" },
+ "spell.89": { "School": "Druid", "SpellNumber": 28, "Name": "stext.291" },
+ "spell.90": { "School": "Druid", "SpellNumber": 29, "Name": "stext.292" },
+ "spell.91": { "School": "OquloKamulos", "SpellNumber": 0, "Name": "stext.293" },
+ "spell.92": { "School": "OquloKamulos", "SpellNumber": 1, "Name": "stext.294" },
+ "spell.93": { "School": "OquloKamulos", "SpellNumber": 2, "Name": "stext.295" },
+ "spell.94": { "School": "OquloKamulos", "SpellNumber": 3, "Name": "stext.296" },
+ "spell.95": { "School": "OquloKamulos", "SpellNumber": 4, "Name": "stext.297" },
+ "spell.96": { "School": "OquloKamulos", "SpellNumber": 5, "Name": "stext.298" },
+ "spell.97": { "School": "OquloKamulos", "SpellNumber": 6, "Name": "stext.299" },
+ "spell.98": { "School": "OquloKamulos", "SpellNumber": 7, "Name": "stext.300" },
+ "spell.99": { "School": "OquloKamulos", "SpellNumber": 8, "Name": "stext.301" },
+ "spell.100": { "School": "OquloKamulos", "SpellNumber": 9, "Name": "stext.302" },
+ "spell.101": { "School": "OquloKamulos", "SpellNumber": 10, "Name": "stext.303" },
+ "spell.102": { "School": "OquloKamulos", "SpellNumber": 11, "Name": "stext.304" },
+ "spell.103": { "School": "OquloKamulos", "SpellNumber": 12, "Name": "stext.305" },
+ "spell.104": { "School": "OquloKamulos", "SpellNumber": 13, "Name": "stext.306" },
+ "spell.105": { "School": "OquloKamulos", "SpellNumber": 14, "Name": "stext.307" },
+ "spell.106": { "School": "OquloKamulos", "SpellNumber": 15, "Name": "stext.308" },
+ "spell.107": { "School": "OquloKamulos", "SpellNumber": 16, "Name": "stext.309" },
+ "spell.108": { "School": "OquloKamulos", "SpellNumber": 17, "Name": "stext.310" },
+ "spell.109": { "School": "OquloKamulos", "SpellNumber": 18, "Name": "stext.311" },
+ "spell.110": { "School": "OquloKamulos", "SpellNumber": 19, "Name": "stext.312" },
+ "spell.111": { "School": "OquloKamulos", "SpellNumber": 20, "Name": "stext.313" },
+ "spell.112": { "School": "OquloKamulos", "SpellNumber": 21, "Name": "stext.314" },
+ "spell.113": { "School": "OquloKamulos", "SpellNumber": 22, "Name": "stext.315" },
+ "spell.114": { "School": "OquloKamulos", "SpellNumber": 23, "Name": "stext.316" },
+ "spell.115": { "School": "OquloKamulos", "SpellNumber": 24, "Name": "stext.317" },
+ "spell.116": { "School": "OquloKamulos", "SpellNumber": 25, "Name": "stext.318" },
+ "spell.117": { "School": "OquloKamulos", "SpellNumber": 26, "Name": "stext.319" },
+ "spell.118": { "School": "OquloKamulos", "SpellNumber": 27, "Name": "stext.320" },
+ "spell.119": { "School": "OquloKamulos", "SpellNumber": 28, "Name": "stext.321" },
+ "spell.120": { "School": "OquloKamulos", "SpellNumber": 29, "Name": "stext.322" },
+ "spell.121": { "School": "Unk4", "SpellNumber": 0, "Name": "stext.323" },
+ "spell.122": { "School": "Unk4", "SpellNumber": 1, "Name": "stext.324" },
+ "spell.123": { "School": "Unk4", "SpellNumber": 2, "Name": "stext.325" },
+ "spell.124": { "School": "Unk4", "SpellNumber": 3, "Name": "stext.326" },
+ "spell.125": { "School": "Unk4", "SpellNumber": 4, "Name": "stext.327" },
+ "spell.126": { "School": "Unk4", "SpellNumber": 5, "Name": "stext.328" },
+ "spell.127": { "School": "Unk4", "SpellNumber": 6, "Name": "stext.329" },
+ "spell.128": { "School": "Unk4", "SpellNumber": 7, "Name": "stext.330" },
+ "spell.129": { "School": "Unk4", "SpellNumber": 8, "Name": "stext.331" },
+ "spell.130": { "School": "Unk4", "SpellNumber": 9, "Name": "stext.332" },
+ "spell.131": { "School": "Unk4", "SpellNumber": 10, "Name": "stext.333" },
+ "spell.132": { "School": "Unk4", "SpellNumber": 11, "Name": "stext.334" },
+ "spell.133": { "School": "Unk4", "SpellNumber": 12, "Name": "stext.335" },
+ "spell.134": { "School": "Unk4", "SpellNumber": 13, "Name": "stext.336" },
+ "spell.135": { "School": "Unk4", "SpellNumber": 14, "Name": "stext.337" },
+ "spell.136": { "School": "Unk4", "SpellNumber": 15, "Name": "stext.338" },
+ "spell.137": { "School": "Unk4", "SpellNumber": 16, "Name": "stext.339" },
+ "spell.138": { "School": "Unk4", "SpellNumber": 17, "Name": "stext.340" },
+ "spell.139": { "School": "Unk4", "SpellNumber": 18, "Name": "stext.341" },
+ "spell.140": { "School": "Unk4", "SpellNumber": 19, "Name": "stext.342" },
+ "spell.141": { "School": "Unk4", "SpellNumber": 20, "Name": "stext.343" },
+ "spell.142": { "School": "Unk4", "SpellNumber": 21, "Name": "stext.344" },
+ "spell.143": { "School": "Unk4", "SpellNumber": 22, "Name": "stext.345" },
+ "spell.144": { "School": "Unk4", "SpellNumber": 23, "Name": "stext.346" },
+ "spell.145": { "School": "Unk4", "SpellNumber": 24, "Name": "stext.347" },
+ "spell.146": { "School": "Unk4", "SpellNumber": 25, "Name": "stext.348" },
+ "spell.147": { "School": "Unk4", "SpellNumber": 26, "Name": "stext.349" },
+ "spell.148": { "School": "Unk4", "SpellNumber": 27, "Name": "stext.350" },
+ "spell.149": { "School": "Unk4", "SpellNumber": 28, "Name": "stext.351" },
+ "spell.150": { "School": "Unk4", "SpellNumber": 29, "Name": "stext.352" },
+ "spell.151": { "School": "ZombieMagic", "SpellNumber": 0, "Name": "stext.353" },
+ "spell.152": { "School": "ZombieMagic", "SpellNumber": 1, "Name": "stext.354" },
+ "spell.153": { "School": "ZombieMagic", "SpellNumber": 2, "Name": "stext.355" },
+ "spell.154": { "School": "ZombieMagic", "SpellNumber": 3, "Name": "stext.356" },
+ "spell.155": { "School": "ZombieMagic", "SpellNumber": 4, "Name": "stext.357" },
+ "spell.156": { "School": "ZombieMagic", "SpellNumber": 5, "Name": "stext.358" },
+ "spell.157": { "School": "ZombieMagic", "SpellNumber": 6, "Name": "stext.359" },
+ "spell.158": { "School": "ZombieMagic", "SpellNumber": 7, "Name": "stext.360" },
+ "spell.159": { "School": "ZombieMagic", "SpellNumber": 8, "Name": "stext.361" },
+ "spell.160": { "School": "ZombieMagic", "SpellNumber": 9, "Name": "stext.362" },
+ "spell.161": { "School": "ZombieMagic", "SpellNumber": 10, "Name": "stext.363" },
+ "spell.162": { "School": "ZombieMagic", "SpellNumber": 11, "Name": "stext.364" },
+ "spell.163": { "School": "ZombieMagic", "SpellNumber": 12, "Name": "stext.365" },
+ "spell.164": { "School": "ZombieMagic", "SpellNumber": 13, "Name": "stext.366" },
+ "spell.165": { "School": "ZombieMagic", "SpellNumber": 14, "Name": "stext.367" },
+ "spell.166": { "School": "ZombieMagic", "SpellNumber": 15, "Name": "stext.368" },
+ "spell.167": { "School": "ZombieMagic", "SpellNumber": 16, "Name": "stext.369" },
+ "spell.168": { "School": "ZombieMagic", "SpellNumber": 17, "Name": "stext.370" },
+ "spell.169": { "School": "ZombieMagic", "SpellNumber": 18, "Name": "stext.371" },
+ "spell.170": { "School": "ZombieMagic", "SpellNumber": 19, "Name": "stext.372" },
+ "spell.171": { "School": "ZombieMagic", "SpellNumber": 20, "Name": "stext.373" },
+ "spell.172": { "School": "ZombieMagic", "SpellNumber": 21, "Name": "stext.374" },
+ "spell.173": { "School": "ZombieMagic", "SpellNumber": 22, "Name": "stext.375" },
+ "spell.174": { "School": "ZombieMagic", "SpellNumber": 23, "Name": "stext.376" },
+ "spell.175": { "School": "ZombieMagic", "SpellNumber": 24, "Name": "stext.377" },
+ "spell.176": { "School": "ZombieMagic", "SpellNumber": 25, "Name": "stext.378" },
+ "spell.177": { "School": "ZombieMagic", "SpellNumber": 26, "Name": "stext.379" },
+ "spell.178": { "School": "ZombieMagic", "SpellNumber": 27, "Name": "stext.380" },
+ "spell.179": { "School": "ZombieMagic", "SpellNumber": 28, "Name": "stext.381" },
+ "spell.180": { "School": "ZombieMagic", "SpellNumber": 29, "Name": "stext.382" },
+ "spell.181": { "School": "Unk6", "SpellNumber": 0, "Name": "stext.383" },
+ "spell.182": { "School": "Unk6", "SpellNumber": 1, "Name": "stext.384" },
+ "spell.183": { "School": "Unk6", "SpellNumber": 2, "Name": "stext.385" },
+ "spell.184": { "School": "Unk6", "SpellNumber": 3, "Name": "stext.386" },
+ "spell.185": { "School": "Unk6", "SpellNumber": 4, "Name": "stext.387" },
+ "spell.186": { "School": "Unk6", "SpellNumber": 5, "Name": "stext.388" },
+ "spell.187": { "School": "Unk6", "SpellNumber": 6, "Name": "stext.389" },
+ "spell.188": { "School": "Unk6", "SpellNumber": 7, "Name": "stext.390" },
+ "spell.189": { "School": "Unk6", "SpellNumber": 8, "Name": "stext.391" },
+ "spell.190": { "School": "Unk6", "SpellNumber": 9, "Name": "stext.392" },
+ "spell.191": { "School": "Unk6", "SpellNumber": 10, "Name": "stext.393" },
+ "spell.192": { "School": "Unk6", "SpellNumber": 11, "Name": "stext.394" },
+ "spell.193": { "School": "Unk6", "SpellNumber": 12, "Name": "stext.395" },
+ "spell.194": { "School": "Unk6", "SpellNumber": 13, "Name": "stext.396" },
+ "spell.195": { "School": "Unk6", "SpellNumber": 14, "Name": "stext.397" },
+ "spell.196": { "School": "Unk6", "SpellNumber": 15, "Name": "stext.398" },
+ "spell.197": { "School": "Unk6", "SpellNumber": 16, "Name": "stext.399" },
+ "spell.198": { "School": "Unk6", "SpellNumber": 17, "Name": "stext.400" },
+ "spell.199": { "School": "Unk6", "SpellNumber": 18, "Name": "stext.401" },
+ "spell.200": { "School": "Unk6", "SpellNumber": 19, "Name": "stext.402" },
+ "spell.201": { "School": "Unk6", "SpellNumber": 20, "Name": "stext.403" },
+ "spell.202": { "School": "Unk6", "SpellNumber": 21, "Name": "stext.404" },
+ "spell.203": { "School": "Unk6", "SpellNumber": 22, "Name": "stext.405" },
+ "spell.204": { "School": "Unk6", "SpellNumber": 23, "Name": "stext.406" },
+ "spell.205": { "School": "Unk6", "SpellNumber": 24, "Name": "stext.407" },
+ "spell.206": { "School": "Unk6", "SpellNumber": 25, "Name": "stext.408" },
+ "spell.207": { "School": "Unk6", "SpellNumber": 26, "Name": "stext.409" },
+ "spell.208": { "School": "Unk6", "SpellNumber": 27, "Name": "stext.410" },
+ "spell.209": { "School": "Unk6", "SpellNumber": 28, "Name": "stext.411" },
+ "spell.210": { "School": "Unk6", "SpellNumber": 29, "Name": "stext.412" }
}
diff --git a/mods/Albion/alb_assets.json b/mods/Albion/alb_assets.json
index db0b7caab..b6117eb0d 100644
--- a/mods/Albion/alb_assets.json
+++ b/mods/Albion/alb_assets.json
@@ -1,348 +1,433 @@
{
- "StringMappings": {
- "itemname.*": "special.ItemNames",
- "stext.*": "special.SystemStrings",
- "utext.*": "special.UAlbionStrings",
- "word.0-499": "special.Words1:0",
- "word.500-999": "special.Words2:500",
- "word.1000-1499": "special.Words3:1000"
+ "special.SoundBank": {
+ "Files": {
+ "Albion/DRIVERS/ALBISND.OPL": {
+ "Container": "raw",
+ "Loader": "soundbank",
+ "IsReadOnly": true
+ }
+ }
},
- "Files": {
- // Misc
- "Albion/DRIVERS/ALBISND.OPL": {
- "Container": "raw",
- "Loader": "soundbank",
- "Max": 0,
- "Map": { "0": { "Id": "special.SoundBank" } }
+ "special.ItemNamesSingleLang": {
+ "Files": {
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
+ "Loader": "itemnameMeta",
+ "Target": "special.ItemNamesMultiLang",
+ "IsReadOnly": true
+ },
- // Dummy item for some dodgy edge cases
- "dummy": { "Loader": "dummy", "Container": "dummy", "Max": 0, "Map": { "0": {"Id": "special.DummyObject" } } },
+ "special.ItemNamesMultiLang": {
+ "Files": {
+ "Albion/CD/XLDLIBS/ITEMNAME.DAT": {
+ "Loader": "itemname",
+ "Container": "raw"
+ }
+ }
+ },
- // Items
- "Albion/CD/XLDLIBS/ITEMLIST.DAT": { "Loader": "itemdata", "Container": "items", "Map": { "0": { "Id": "item.1" } } },
- "Albion/CD/XLDLIBS/ITEMNAME.DAT": { "Loader": "itemname", "Container": "raw", "Max": 0, "Map": { "0": { "Id": "special.ItemNames" } } },
+ "special.SystemStrings": {
+ "Files": {
+ "Albion/CD/XLDLIBS/GERMAN/SYSTEXTS": { "Language": "GERMAN" },
+ "Albion/CD/XLDLIBS/ENGLISH/SYSTEXTS": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/SYSTEXTS": { "Language": "FRENCH" }
+ },
+ "Loader": "stext",
+ "Container": "raw",
+ "IsReadOnly": true
+ },
- // Events
- "Albion/CD/XLDLIBS/EVNTSET0.XLD": { "Loader": "eset", "Max": 98, "Map": { "0": { "Id": "eset.1" } } },
- "Albion/CD/XLDLIBS/EVNTSET1.XLD": { "Loader": "eset", "Map": { "0": { "Id": "eset.100" } } },
- "Albion/CD/XLDLIBS/EVNTSET2.XLD": { "Loader": "eset", "Map": { "0": { "Id": "eset.200" } } },
- "Albion/CD/XLDLIBS/EVNTSET3.XLD": { "Loader": "eset", "Map": { "1": { "Id": "eset.301" } } },
- "Albion/CD/XLDLIBS/EVNTSET9.XLD": { "Loader": "eset", "Max": 98, "Map": { "81": { "Id": "eset.981" } } },
- "Albion/CD/XLDLIBS/SCRIPT0.XLD": { "Loader": "script", "Map": { "1": { "Id": "script.2" } } },
- "Albion/CD/XLDLIBS/SCRIPT2.XLD": { "Loader": "script", "MinimumCount": 100, "Map": { "0": { "Id": "script.200" } } },
+ "special.Words1-Words3": {
+ "Files": {
+ "Albion/CD/XLDLIBS/GERMAN/WORDLIS0.XLD": { "Language": "GERMAN" },
+ "Albion/CD/XLDLIBS/ENGLISH/WORDLIS0.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/WORDLIS0.XLD": { "Language": "FRENCH" }
+ },
+ "Loader": "wordlist"
+ },
- // Maps
- "Albion/CD/XLDLIBS/BLKLIST0.XLD": { "Loader": "block", "Map": { "0": {"Id": "block.1" } } },
- "Albion/CD/XLDLIBS/LABDATA0.XLD": { "Loader": "lab", "MapFile": "Meta/LABDATA0.json" },
- "Albion/CD/XLDLIBS/LABDATA1.XLD": { "Loader": "lab", "MinimumCount": 100, "MapFile": "Meta/LABDATA1.json" },
- "Albion/CD/XLDLIBS/LABDATA2.XLD": { "Loader": "lab", "MinimumCount": 100, "MapFile": "Meta/LABDATA2.json" },
- "Albion/CD/XLDLIBS/MAPDATA1.XLD": { "Loader": "map", "Map": { "0": { "Id": "map.100" } } },
- "Albion/CD/XLDLIBS/MAPDATA2.XLD": { "Loader": "map", "Map": { "0": { "Id": "map.200" } } },
- "Albion/CD/XLDLIBS/MAPDATA3.XLD": { "Loader": "map", "Map": { "0": { "Id": "map.300" } } },
- "Albion/CD/XLDLIBS/ICONDAT0.XLD": {
- "Loader": "tileset",
- "Map": {
- "0": { "Id": "tiledata.1", "UseSmallGraphics": true },
- "1": { "UseSmallGraphics": true },
- "3": { "UseSmallGraphics": true }
- }
+ "itemname.1-462": {
+ "Files": { // Dummy files used for ensuring the language is available on the AssetLoadContext
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
+ "Loader": "stringset",
+ "FirstId": "itemname.1",
+ "Target": "special.ItemNamesSingleLang",
+ "IsReadOnly": true
+ },
- // Monster info
- "Albion/CD/XLDLIBS/MONCHAR0.XLD": { "Loader": "sheet", "Map": { "0": { "Id": "monster.1" } } },
- "Albion/CD/XLDLIBS/MONGRP0.XLD": { "Loader": "mongrp", "Max": 98, "Map": { "1": { "Id": "mongrp.2" } } },
- "Albion/CD/XLDLIBS/MONGRP1.XLD": { "Loader": "mongrp", "MinimumCount": 100, "Map": { "0": { "Id": "mongrp.100" } } },
- "Albion/CD/XLDLIBS/MONGRP2.XLD": { "Loader": "mongrp", "MinimumCount": 100, "Map": { "0": { "Id": "mongrp.200" } } },
+ "stext.0-777": {
+ "Files": { // Dummy files used for ensuring the language is available on the AssetLoadContext
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
+ },
+ "Loader": "stringset",
+ "FirstId": "stext.0",
+ "Target": "special.SystemStrings",
+ "IsReadOnly": true
+ },
- // Palettes
- "Albion/CD/XLDLIBS/PALETTE.000": {
- "Loader": "pal",
- "Container": "raw",
- "Max": 0,
- "Map": { "0": { "Id": "pal.0", "IsCommon": true } }
+ "word.0-499": {
+ "Files": { // Dummy files used for ensuring the language is available on the AssetLoadContext
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
- "Albion/CD/XLDLIBS/PALETTE0.XLD": {
- "Loader": "pal",
- "Map": {
- "0": { "Id": "pal.1", "NightPaletteId": "pal.47", "AnimatedRanges": "0x99-0x9f, 0xb0-0xb4, 0xb5-0xbf" },
- "1": { "NightPaletteId": "pal.47", "AnimatedRanges": "0x99-0x9f, 0xb0-0xb4, 0xb5-0xbf" },
- "2": { "NightPaletteId": "pal.55", "AnimatedRanges": "0x40-0x43, 0x44-0x4f" },
- "3": { "NightPaletteId": "pal.48" },
- "5": { "AnimatedRanges": "0xb0-0xb4, 0xb5-0xbf" },
- "13": { "NightPaletteId": "pal.49", "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
- "14": { "AnimatedRanges": "0x58-0x5f" },
- "24": { "NightPaletteId": "pal.49", "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
- "25": { "AnimatedRanges": "0xb4-0xb7, 0xb8-0xbb, 0xbc-0xbf" },
- "30": { "AnimatedRanges": "0x10-0x4f" },
- "46": { "AnimatedRanges": "0x99-0x9f, 0xb0-0xb4, 0xb5-0xbf" },
- "48": { "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
- "50": { "NightPaletteId": "pal.49", "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
- "54": { "AnimatedRanges": "0x40-0x43, 0x44-0x4f" }
- }
+ "Loader": "stringset",
+ "FirstId": "word.0",
+ "Target": "special.Words1",
+ "IsReadOnly": true
+ },
+
+ "word.500-999": {
+ "Files": { // Dummy files used for ensuring the language is available on the AssetLoadContext
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
+ "Loader": "stringset",
+ "FirstId": "word.0",
+ "Target": "special.Words2",
+ "IsReadOnly": true
+ },
+
+ "word.1000-1499": {
+ "Files": { // Dummy files used for ensuring the language is available on the AssetLoadContext
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
+ },
+ "Loader": "stringset",
+ "FirstId": "word.0",
+ "Target": "special.Words3",
+ "IsReadOnly": true
+ },
+
+ // Items
+ "item.1-462": { "Files": { "Albion/CD/XLDLIBS/ITEMLIST.DAT": { "Loader": "itemdata", "Container": "items" } } },
- // Fonts
- "Albion/CD/XLDLIBS/FONTS0.XLD#33906F62": { // EN+FR
- "Optional": true,
- "Loader": "fixedsize",
- "Width": 8,
- "Height": 8,
- "Max": 1,
- "Map": {
- "0": { "Id": "fontgfx.Regular" },
- "1": { "Id": "fontgfx.Bold" }
+ // Events
+ "eset.1-32": { "Files": { "Albion/CD/XLDLIBS/EVNTSET0.XLD": { "Loader": "eset" } } },
+ "eset.33-99": { "Files": { "Albion/CD/XLDLIBS/EVNTSET0.XLD": { "Loader": "eset" } }, "Optional": true }, // not in original game
+ "eset.100-199": { "Files": { "Albion/CD/XLDLIBS/EVNTSET1.XLD": { "Loader": "eset" } } },
+ "eset.200-299": { "Files": { "Albion/CD/XLDLIBS/EVNTSET2.XLD": { "Loader": "eset" } } },
+ "eset.300-324": { "Files": { "Albion/CD/XLDLIBS/EVNTSET3.XLD": { "Loader": "eset" } } },
+ "eset.900-999": { "Files": { "Albion/CD/XLDLIBS/EVNTSET9.XLD": { "Loader": "eset" } } },
+ "script.1-62": { "Files": { "Albion/CD/XLDLIBS/SCRIPT0.XLD": { "Loader": "script" } } },
+ "script.200-211": { "Files": { "Albion/CD/XLDLIBS/SCRIPT2.XLD": { "Loader": "script" } } },
+
+ // Maps
+ "block.1-11": { "Files": { "Albion/CD/XLDLIBS/BLKLIST0.XLD": { "Loader": "block" } } },
+ "lab.1-9": { "Files": { "Albion/CD/XLDLIBS/LABDATA0.XLD": { "Loader": "lab", "MapFile": "Meta/LABDATA0.json" } } },
+ "lab.10-99": { "Files": { "Albion/CD/XLDLIBS/LABDATA0.XLD": { "Loader": "lab", "MapFile": "Meta/LABDATA0.json" } }, "Optional": true }, // not in original game
+ "lab.100-199": { "Files": { "Albion/CD/XLDLIBS/LABDATA1.XLD": { "Loader": "lab", "MapFile": "Meta/LABDATA1.json" } } },
+ "lab.200-210": { "Files": { "Albion/CD/XLDLIBS/LABDATA2.XLD": { "Loader": "lab", "MapFile": "Meta/LABDATA2.json" } } },
+ "map.100-199": { "Files": { "Albion/CD/XLDLIBS/MAPDATA1.XLD": { "Loader": "map" } } },
+ "map.200-299": { "Files": { "Albion/CD/XLDLIBS/MAPDATA2.XLD": { "Loader": "map" } } },
+ "map.300-399": { "Files": { "Albion/CD/XLDLIBS/MAPDATA3.XLD": { "Loader": "map" } } },
+
+ "tiledata.1-11": {
+ "Files": {
+ "Albion/CD/XLDLIBS/ICONDAT0.XLD": {
+ "Loader": "tileset",
+ "Map": {
+ "tiledata.1": { "UseSmallGraphics": true },
+ "tiledata.2": { "UseSmallGraphics": true },
+ "tiledata.4": { "UseSmallGraphics": true }
+ }
}
- },
- "Albion/CD/XLDLIBS/FONTS0.XLD#A70E9601": { // DE
- "Optional": true,
- "Loader": "fixedsize",
- "Width": 8,
- "Height": 8,
- "Max": 1,
- "Map": {
- "0": { "Id": "fontgfx.GermanRegular" },
- "1": { "Id": "fontgfx.GermanBold" }
+ }
+ },
+
+ // Monster info
+ "monster.1-59": { "Files": { "Albion/CD/XLDLIBS/MONCHAR0.XLD": { "Loader": "sheet" } } },
+ "mongrp.1-99": { "Files": { "Albion/CD/XLDLIBS/MONGRP0.XLD": { "Loader": "mongrp" } } },
+ "mongrp.100-199": { "Files": { "Albion/CD/XLDLIBS/MONGRP1.XLD": { "Loader": "mongrp" } } },
+ "mongrp.200-251": { "Files": { "Albion/CD/XLDLIBS/MONGRP2.XLD": { "Loader": "mongrp" } } },
+
+ // Palettes
+ "pal.0": {
+ "Files": {
+ "Albion/CD/XLDLIBS/PALETTE.000": {
+ "IsCommon": true,
+ "Container": "raw",
+ "Loader": "pal"
}
- },
+ }
+ },
- // Audio
- "Albion/CD/XLDLIBS/SAMPLES0.XLD": { "Loader": "sample", "Max": 98, "Map": { "0": { "Id": "sample.1" } } }, // TODO: Add mapping for NPC sound id -> sample id
- "Albion/CD/XLDLIBS/SAMPLES1.XLD": { "Loader": "sample", "MinimumCount": 100, "Map": { "0": { "Id": "sample.100" } } },
- "Albion/CD/XLDLIBS/SAMPLES2.XLD": { "Loader": "sample", "MinimumCount": 100, "Map": { "1": { "Id": "sample.201" } } },
- "Albion/CD/XLDLIBS/SONGS0.XLD": { "Loader": "song", "Map": { "0": { "Id": "song.1" } } }, // TODO: Add mapping for song -> ambient song id
- "Albion/CD/XLDLIBS/WAVELIB0.XLD": { "Loader": "wavlib", "Map": { "4": { "Id": "wavlib.5" } } },
+ "pal.1-56": {
+ "Files": {
+ "Albion/CD/XLDLIBS/PALETTE0.XLD": {
+ "Loader": "pal",
+ "Map": {
+ "pal.1": { "NightPalette": "pal.47", "AnimatedRanges": "0x99-0x9f, 0xb0-0xb4, 0xb5-0xbf" },
+ "pal.2": { "NightPalette": "pal.47", "AnimatedRanges": "0x99-0x9f, 0xb0-0xb4, 0xb5-0xbf" },
+ "pal.3": { "NightPalette": "pal.55", "AnimatedRanges": "0x40-0x43, 0x44-0x4f" },
+ "pal.4": { "NightPalette": "pal.48" },
+ "pal.6": { "AnimatedRanges": "0xb0-0xb4, 0xb5-0xbf" },
+ "pal.14": { "NightPalette": "pal.49", "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
+ "pal.15": { "AnimatedRanges": "0x58-0x5f" },
+ "pal.25": { "NightPalette": "pal.49", "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
+ "pal.26": { "AnimatedRanges": "0xb4-0xb7, 0xb8-0xbb, 0xbc-0xbf" },
+ "pal.31": { "AnimatedRanges": "0x10-0x4f" },
+ "pal.47": { "AnimatedRanges": "0x99-0x9f, 0xb0-0xb4, 0xb5-0xbf" },
+ "pal.49": { "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
+ "pal.51": { "NightPalette": "pal.49", "AnimatedRanges": "0xb0-0xb3, 0xb4-0xbf" },
+ "pal.55": { "AnimatedRanges": "0x40-0x43, 0x44-0x4f" }
+ }
+ }
+ }
+ },
- // Videos
- "Albion/CD/XLDLIBS/GERMAN/FLICS0.XLD": { "Language": "GERMAN", "Loader": "flic", "Map": { "0": { "Id": "vid.1" } } },
- "Albion/CD/XLDLIBS/ENGLISH/FLICS0.XLD": { "Language": "ENGLISH", "Loader": "flic", "Map": { "0": { "Id": "vid.1" } } },
- "Albion/CD/XLDLIBS/FRENCH/FLICS0.XLD": { "Language": "FRENCH", "Loader": "flic", "Map": { "0": { "Id": "vid.1" } } },
+ // Fonts
+ "fontgfx.1-2": { // English/French fonts, regular & bold
+ "Files": {
+ "Albion/CD/XLDLIBS/FONTS0.XLD#33906F62": { // EN+FR
+ "Loader": "fixedsize",
+ "Optional": true,
+ "Width": 8,
+ "Height": 8
+ }
+ }
+ },
+ "fontgfx.4-5": { // German fonts
+ "Files": {
+ "Albion/CD/XLDLIBS/FONTS0.XLD#A70E9601": { // DE
+ "Loader": "fixedsize",
+ "Optional": true,
+ "Width": 8,
+ "Height": 8
+ }
+ }
+ },
- // Text
- "Albion/CD/XLDLIBS/GERMAN/EVNTTXT0.XLD": { "Language": "GERMAN", "Loader": "stringtable", "Max": 98, "Map": { "0": { "Id": "etext.1" } } },
- "Albion/CD/XLDLIBS/GERMAN/EVNTTXT1.XLD": { "Language": "GERMAN", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.100" } } },
- "Albion/CD/XLDLIBS/GERMAN/EVNTTXT2.XLD": { "Language": "GERMAN", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.200" } } },
- "Albion/CD/XLDLIBS/GERMAN/EVNTTXT3.XLD": { "Language": "GERMAN", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.300" } } },
- "Albion/CD/XLDLIBS/GERMAN/EVNTTXT9.XLD": { "Language": "GERMAN", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.900" } } },
- "Albion/CD/XLDLIBS/GERMAN/MAPTEXT1.XLD": { "Language": "GERMAN", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.100" } } },
- "Albion/CD/XLDLIBS/GERMAN/MAPTEXT2.XLD": { "Language": "GERMAN", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.200" } } },
- "Albion/CD/XLDLIBS/GERMAN/MAPTEXT3.XLD": { "Language": "GERMAN", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.300" } } },
+ // Audio
+ "sample.1-99": { "Files": { "Albion/CD/XLDLIBS/SAMPLES0.XLD": { "Loader": "sample" } } }, // TODO: Add mapping for NPC sound id -> sample id
+ "sample.100-199": { "Files": { "Albion/CD/XLDLIBS/SAMPLES1.XLD": { "Loader": "sample" } } },
+ "sample.200-299": { "Files": { "Albion/CD/XLDLIBS/SAMPLES2.XLD": { "Loader": "sample" } } },
+ "song.1-99": { "Files": { "Albion/CD/XLDLIBS/SONGS0.XLD": { "Loader": "song" } } }, // TODO: Add mapping for song -> ambient song id
+ "wavlib.1-99": { "Files": { "Albion/CD/XLDLIBS/WAVELIB0.XLD": { "Loader": "wavlib" } } },
- "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT0.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "Max": 98, "Map": { "0": { "Id": "etext.1" } } },
- "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT1.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.100" } } },
- "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT2.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.200" } } },
- "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT3.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.300" } } },
- "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT9.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.900" } } },
- "Albion/CD/XLDLIBS/ENGLISH/MAPTEXT1.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.100" } } },
- "Albion/CD/XLDLIBS/ENGLISH/MAPTEXT2.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.200" } } },
- "Albion/CD/XLDLIBS/ENGLISH/MAPTEXT3.XLD": { "Language": "ENGLISH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.300" } } },
+ // Videos
+ "vid.1-99": {
+ "Loader": "flic",
+ "IsReadOnly": true,
+ "Files": {
+ "Albion/CD/XLDLIBS/GERMAN/FLICS0.XLD": { "Language": "GERMAN" },
+ "Albion/CD/XLDLIBS/ENGLISH/FLICS0.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/FLICS0.XLD": { "Language": "FRENCH" }
+ }
+ },
+
+ // Event Text
+ "etext.1-32": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT0.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/EVNTTXT0.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/EVNTTXT0.XLD": { "Language": "GERMAN" }
+ }
+ },
+ "etext.33-99": { // Not in original game
+ "Loader": "stringtable",
+ "Optional": true,
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT0.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/EVNTTXT0.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/EVNTTXT0.XLD": { "Language": "GERMAN" }
+ }
+ },
- "Albion/CD/XLDLIBS/FRENCH/EVNTTXT0.XLD": { "Language": "FRENCH", "Loader": "stringtable", "Max": 98, "Map": { "0": { "Id": "etext.1" } } },
- "Albion/CD/XLDLIBS/FRENCH/EVNTTXT1.XLD": { "Language": "FRENCH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.100" } } },
- "Albion/CD/XLDLIBS/FRENCH/EVNTTXT2.XLD": { "Language": "FRENCH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.200" } } },
- "Albion/CD/XLDLIBS/FRENCH/EVNTTXT3.XLD": { "Language": "FRENCH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.300" } } },
- "Albion/CD/XLDLIBS/FRENCH/EVNTTXT9.XLD": { "Language": "FRENCH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "etext.900" } } },
- "Albion/CD/XLDLIBS/FRENCH/MAPTEXT1.XLD": { "Language": "FRENCH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.100" } } },
- "Albion/CD/XLDLIBS/FRENCH/MAPTEXT2.XLD": { "Language": "FRENCH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.200" } } },
- "Albion/CD/XLDLIBS/FRENCH/MAPTEXT3.XLD": { "Language": "FRENCH", "Loader": "stringtable", "MinimumCount": 100, "Map": { "0": { "Id": "mtext.300" } } },
+ "etext.100-199": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT1.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/EVNTTXT1.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/EVNTTXT1.XLD": { "Language": "GERMAN" }
+ }
+ },
+ "etext.200-299": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT2.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/EVNTTXT2.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/EVNTTXT2.XLD": { "Language": "GERMAN" }
+ }
+ },
+ "etext.300-399": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT3.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/EVNTTXT3.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/EVNTTXT3.XLD": { "Language": "GERMAN" }
+ }
+ },
+ "etext.900-999": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/EVNTTXT9.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/EVNTTXT9.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/EVNTTXT9.XLD": { "Language": "GERMAN" }
+ }
+ },
- "GERMAN/strings.json": {
- "Language": "GERMAN",
- "Loader": "json",
- "Container": "raw",
- "Max": 0,
- "Map": { "0": { "Id": "special.UAlbionStrings" } }
+ // Map Text
+ "mtext.100-199": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/MAPTEXT1.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/MAPTEXT1.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/MAPTEXT1.XLD": { "Language": "GERMAN" }
},
- "ENGLISH/strings.json": {
- "Language": "ENGLISH",
- "Loader": "json",
- "Container": "raw",
- "Max": 0,
- "Map": { "0": { "Id": "special.UAlbionStrings" } }
+ "Optional": true // test maps etc don't have any text so don't be as strict
+ },
+ "mtext.200-299": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/MAPTEXT2.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/MAPTEXT2.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/MAPTEXT2.XLD": { "Language": "GERMAN" }
},
- "FRENCH/strings.json": {
- "Language": "FRENCH",
- "Loader": "json",
- "Container": "raw",
- "Max": 0,
- "Map": { "0": { "Id": "special.UAlbionStrings" } }
+ "Optional": true
+ },
+ "mtext.300-399": {
+ "Loader": "stringtable",
+ "Files": {
+ "Albion/CD/XLDLIBS/ENGLISH/MAPTEXT3.XLD": { "Language": "ENGLISH" },
+ "Albion/CD/XLDLIBS/FRENCH/MAPTEXT3.XLD": { "Language": "FRENCH" },
+ "Albion/CD/XLDLIBS/GERMAN/MAPTEXT3.XLD": { "Language": "GERMAN" }
},
+ "Optional": true
+ },
- "Albion/CD/XLDLIBS/GERMAN/SYSTEXTS": {
- "Language": "GERMAN",
- "Loader": "stext",
- "Container": "raw",
- "Max": 0,
- "Map": { "0": { "Id": "special.SystemStrings" } }
- },
- "Albion/CD/XLDLIBS/ENGLISH/SYSTEXTS": {
- "Language": "ENGLISH",
- "Loader": "stext",
- "Container": "raw",
- "Max": 0,
- "Map": { "0": { "Id": "special.SystemStrings" } }
- },
- "Albion/CD/XLDLIBS/FRENCH/SYSTEXTS": {
- "Language": "FRENCH",
- "Loader": "stext",
- "Container": "raw",
- "Max": 0,
- "Map": { "0": { "Id": "special.SystemStrings" } }
- },
+ // Spells
+ "spell.1-210": { "Files": { "Albion/CD/XLDLIBS/SPELLDAT.DAT": { "Loader": "spell", "Container": "spells", "MapFile": "Meta/SPELLDAT.json" } } },
- "Albion/CD/XLDLIBS/GERMAN/WORDLIS0.XLD": {
- "Language": "GERMAN",
- "Loader": "wordlist",
- "Max": 2,
- "Map": {
- "0": { "Id": "special.Words1" },
- "1": { "Id": "special.Words2" },
- "2": { "Id": "special.Words3" }
- }
- },
- "Albion/CD/XLDLIBS/ENGLISH/WORDLIS0.XLD": {
- "Language": "ENGLISH",
- "Loader": "wordlist",
- "Max": 2,
- "Map": {
- "0": { "Id": "special.Words1" },
- "1": { "Id": "special.Words2" },
- "2": { "Id": "special.Words3" }
- }
- },
- "Albion/CD/XLDLIBS/FRENCH/WORDLIS0.XLD": {
- "Language": "FRENCH",
- "Loader": "wordlist",
- "Max": 2,
- "Map": {
- "0": { "Id": "special.Words1" },
- "1": { "Id": "special.Words2" },
- "2": { "Id": "special.Words3" }
- }
- },
+ // Initial game state data
+ "automap.100-199": { "Files": { "Albion/CD/XLDLIBS/INITIAL/AUTOMAP1.XLD": { "Loader": "automap" } }, "Optional": true }, // Marked as optional as 2D maps won't have automaps and we don't want to spam errors when unpacking
+ "automap.200-299": { "Files": { "Albion/CD/XLDLIBS/INITIAL/AUTOMAP2.XLD": { "Loader": "automap" } }, "Optional": true },
+ "automap.300-399": { "Files": { "Albion/CD/XLDLIBS/INITIAL/AUTOMAP3.XLD": { "Loader": "automap" } }, "Optional": true },
+ "chest.1-2": { "Files": { "Albion/CD/XLDLIBS/INITIAL/CHESTDT0.XLD": { "Loader": "chest" } } },
+ "chest.3-99": { "Files": { "Albion/CD/XLDLIBS/INITIAL/CHESTDT0.XLD": { "Loader": "chest" } }, "Optional": true }, // Not in original game but defined here to allow extension
+ "chest.100-199": { "Files": { "Albion/CD/XLDLIBS/INITIAL/CHESTDT1.XLD": { "Loader": "chest" } } },
+ "chest.200-299": { "Files": { "Albion/CD/XLDLIBS/INITIAL/CHESTDT2.XLD": { "Loader": "chest" } } },
+ "chest.500-574": { "Files": { "Albion/CD/XLDLIBS/INITIAL/CHESTDT5.XLD": { "Loader": "chest" } } },
+ "merchant.1": { "Files": { "Albion/CD/XLDLIBS/INITIAL/MERCHDT0.XLD": { "Loader": "merchant" } } },
+ "merchant.100-109": { "Files": { "Albion/CD/XLDLIBS/INITIAL/MERCHDT1.XLD": { "Loader": "merchant" } } },
+ "merchant.200-210": { "Files": { "Albion/CD/XLDLIBS/INITIAL/MERCHDT2.XLD": { "Loader": "merchant" } } },
+ "npc.1-99": { "Files": { "Albion/CD/XLDLIBS/INITIAL/NPCCHAR0.XLD": { "Loader": "sheet" } } },
+ "npc.100-199": { "Files": { "Albion/CD/XLDLIBS/INITIAL/NPCCHAR1.XLD": { "Loader": "sheet" } } },
+ "npc.200-299": { "Files": { "Albion/CD/XLDLIBS/INITIAL/NPCCHAR2.XLD": { "Loader": "sheet" } } },
+ "psheet.1-59": { "Files": { "Albion/CD/XLDLIBS/INITIAL/PRTCHAR0.XLD": { "Loader": "sheet" } } },
+ "psheet.100-199": { "Files": { "Albion/CD/XLDLIBS/INITIAL/PRTCHAR1.XLD": { "Loader": "sheet" } } },
+ "psheet.200-299": { "Files": { "Albion/CD/XLDLIBS/INITIAL/PRTCHAR2.XLD": { "Loader": "sheet" } } },
- // Spells
- "Albion/CD/XLDLIBS/SPELLDAT.DAT": { "Loader": "spell", "Container": "spells", "MapFile": "Meta/SPELLDAT.json" },
+ // Graphics
+ "floor.1-99": { "Files": { "Albion/CD/XLDLIBS/3DFLOOR0.XLD": { "Loader": "fixedsize", "Width": 64, "Height": 64, "MapFile": "Meta/3DFLOOR0.json" } } },
+ "floor.100-199": { "Files": { "Albion/CD/XLDLIBS/3DFLOOR1.XLD": { "Loader": "fixedsize", "Width": 64, "Height": 64, "MapFile": "Meta/3DFLOOR1.json" } } },
+ "floor.200-299": { "Files": { "Albion/CD/XLDLIBS/3DFLOOR2.XLD": { "Loader": "fixedsize", "Width": 64, "Height": 64, "MapFile": "Meta/3DFLOOR2.json" } } },
+ "combg.1-19": { "Files": { "Albion/CD/XLDLIBS/COMBACK0.XLD": { "Loader": "fixedsize", "Width": 360, "MapFile": "Meta/COMBACK0.json" } } },
+ "comgfx.1-85": { "Files": { "Albion/CD/XLDLIBS/COMGFX0.XLD": { "Loader": "multiheader", "Palette": "pal.23" } } },
+ "pinvgfx.1-10": { "Files": { "Albion/CD/XLDLIBS/FBODPIX0.XLD": { "Loader": "header", "Palette": "pal.19" } } },
+ "mongfx.1-60": { "Files": { "Albion/CD/XLDLIBS/MONGFX0.XLD": { "Loader": "multiheader", "Palette": "pal.24", "MapFile": "Meta/MONGFX0.json" } } },
+ "npclarge.1-99": { "Files": { "Albion/CD/XLDLIBS/NPCGR0.XLD": { "Loader": "header", "MapFile": "Meta/NPCGR0.json" } } },
+ "npclarge.100-199": { "Files": { "Albion/CD/XLDLIBS/NPCGR1.XLD": { "Loader": "header", "MapFile": "Meta/NPCGR1.json" } } },
+ "npcsmall.1-29": { "Files": { "Albion/CD/XLDLIBS/NPCKL0.XLD": { "Loader": "header", "Palette": "pal.1", "Map": { "npcsmall.28": { "Palette": "pal.4" } } } } },
+ "plarge.1-10": { "Files": { "Albion/CD/XLDLIBS/PARTGR0.XLD": { "Loader": "header", "Palette": "pal.20" } } },
+ "psmall.1-10": { "Files": { "Albion/CD/XLDLIBS/PARTKL0.XLD": { "Loader": "header", "Palette": "pal.1" } } },
+ "portrait.1-99": { "Files": { "Albion/CD/XLDLIBS/SMLPORT0.XLD": { "Loader": "fixedsize", "Width": 34 } }, "Palette": "pal.0" },
+ "portrait.100-175": { "Files": { "Albion/CD/XLDLIBS/SMLPORT1.XLD": { "Loader": "fixedsize", "Width": 34 } } },
+ "tacgfx.1-72": { "Files": { "Albion/CD/XLDLIBS/TACTICO0.XLD": { "Loader": "fixedsize", "Width": 32 } }, "Palette": "pal.0" },
+ "pic.1-45": { "Files": { "Albion/CD/XLDLIBS/PICTURE0.XLD": { "Loader": "interlaced", "IsReadOnly": true } } },
+ "3dobj.1-99": { "Files": { "Albion/CD/XLDLIBS/3DOBJEC0.XLD": { "Loader": "fixedsize", "MapFile": "Meta/3DOBJEC0.json" } } },
+ "3dobj.100-199": { "Files": { "Albion/CD/XLDLIBS/3DOBJEC1.XLD": { "Loader": "fixedsize", "MapFile": "Meta/3DOBJEC1.json" } } },
+ "3dobj.200-299": { "Files": { "Albion/CD/XLDLIBS/3DOBJEC2.XLD": { "Loader": "fixedsize", "MapFile": "Meta/3DOBJEC2.json" } } },
+ "3dobj.300-399": { "Files": { "Albion/CD/XLDLIBS/3DOBJEC3.XLD": { "Loader": "fixedsize", "MapFile": "Meta/3DOBJEC3.json" } } },
+ "overlay.1-99": { "Files": { "Albion/CD/XLDLIBS/3DOVERL0.XLD": { "Loader": "fixedsize", "Transposed": true, "MapFile": "Meta/3DOVERL0.json" } } },
+ "overlay.100-199": { "Files": { "Albion/CD/XLDLIBS/3DOVERL1.XLD": { "Loader": "fixedsize", "Transposed": true, "MapFile": "Meta/3DOVERL1.json" } } },
+ "overlay.200-299": { "Files": { "Albion/CD/XLDLIBS/3DOVERL2.XLD": { "Loader": "fixedsize", "Transposed": true, "MapFile": "Meta/3DOVERL2.json" } } },
+ "wall.1-99": { "Files": { "Albion/CD/XLDLIBS/3DWALLS0.XLD": { "Loader": "fixedsize", "Transposed": true, "MapFile": "Meta/3DWALLS0.json" } } },
+ "wall.100-199": { "Files": { "Albion/CD/XLDLIBS/3DWALLS1.XLD": { "Loader": "fixedsize", "Transposed": true, "MapFile": "Meta/3DWALLS1.json" } } },
- // Initial game state data
- "Albion/CD/XLDLIBS/INITIAL/AUTOMAP1.XLD": { "Loader": "automap", "MinimumCount": 100, "Map": { "0": { "Id": "automap.100" } } },
- "Albion/CD/XLDLIBS/INITIAL/AUTOMAP2.XLD": { "Loader": "automap", "MinimumCount": 100, "Map": { "0": { "Id": "automap.200" } } },
- "Albion/CD/XLDLIBS/INITIAL/AUTOMAP3.XLD": { "Loader": "automap", "MinimumCount": 100, "Map": { "0": { "Id": "automap.300" } } },
- "Albion/CD/XLDLIBS/INITIAL/CHESTDT0.XLD": { "Loader": "chest", "Max": 98, "Map": { "0": { "Id": "chest.1" } } },
- "Albion/CD/XLDLIBS/INITIAL/CHESTDT1.XLD": { "Loader": "chest", "MinimumCount": 100, "Map": { "0": { "Id": "chest.100" } } },
- "Albion/CD/XLDLIBS/INITIAL/CHESTDT2.XLD": { "Loader": "chest", "MinimumCount": 100, "Map": { "0": { "Id": "chest.200" } } },
- "Albion/CD/XLDLIBS/INITIAL/CHESTDT5.XLD": { "Loader": "chest", "MinimumCount": 100, "Map": { "0": { "Id": "chest.500" } } },
- "Albion/CD/XLDLIBS/INITIAL/MERCHDT0.XLD": { "Loader": "merchant", "Max": 98, "Map": { "0": { "Id": "merchant.1" } } },
- "Albion/CD/XLDLIBS/INITIAL/MERCHDT1.XLD": { "Loader": "merchant", "MinimumCount": 100, "Map": { "0": { "Id": "merchant.100" } } },
- "Albion/CD/XLDLIBS/INITIAL/MERCHDT2.XLD": { "Loader": "merchant", "MinimumCount": 100, "Map": { "0": { "Id": "merchant.200" } } },
- "Albion/CD/XLDLIBS/INITIAL/NPCCHAR0.XLD": { "Loader": "sheet", "Max": 98, "Map": { "0": { "Id": "npc.1" } } },
- "Albion/CD/XLDLIBS/INITIAL/NPCCHAR1.XLD": { "Loader": "sheet", "MinimumCount": 100, "Map": { "0": { "Id": "npc.100" } } },
- "Albion/CD/XLDLIBS/INITIAL/NPCCHAR2.XLD": { "Loader": "sheet", "MinimumCount": 100, "Map": { "0": { "Id": "npc.200" } } },
- "Albion/CD/XLDLIBS/INITIAL/PRTCHAR0.XLD": { "Loader": "sheet", "Max": 98, "MinimumCount": 58, "Map": { "0": { "Id": "psheet.1" } } },
- "Albion/CD/XLDLIBS/INITIAL/PRTCHAR1.XLD": { "Loader": "sheet", "Map": { "0": { "Id": "psheet.100" } } },
- "Albion/CD/XLDLIBS/INITIAL/PRTCHAR2.XLD": { "Loader": "sheet", "Map": { "0": { "Id": "psheet.200" } } },
+ "3dbg.1-3": {
+ "Files": {
+ "Albion/CD/XLDLIBS/3DBCKGR0.XLD": {
+ "Loader": "header",
+ "Map": {
+ "3dbg.1": { "Palette": "pal.3" },
+ "3dbg.2": { "Palette": "pal.3" },
+ "3dbg.3": { "Palette": "pal.25" }
+ }
+ }
+ }
+ },
- // Graphics
- "Albion/CD/XLDLIBS/3DFLOOR0.XLD": { "Loader": "fixedsize", "Width": 64, "Height": 64, "Max": 98, "MapFile": "Meta/3DFLOOR0.json" },
- "Albion/CD/XLDLIBS/3DFLOOR1.XLD": { "Loader": "fixedsize", "MinimumCount": 100, "Width": 64, "Height": 64, "MapFile": "Meta/3DFLOOR1.json" },
- "Albion/CD/XLDLIBS/3DFLOOR2.XLD": { "Loader": "fixedsize", "MinimumCount": 100, "Width": 64, "Height": 64, "MapFile": "Meta/3DFLOOR2.json" },
- "Albion/CD/XLDLIBS/3DOBJEC0.XLD": { "Loader": "fixedsize", "Max": 98, "MapFile": "Meta/3DOBJEC0.json" },
- "Albion/CD/XLDLIBS/3DOBJEC1.XLD": { "Loader": "fixedsize", "MapFile": "Meta/3DOBJEC1.json" },
- "Albion/CD/XLDLIBS/3DOBJEC2.XLD": { "Loader": "fixedsize", "MapFile": "Meta/3DOBJEC2.json" },
- "Albion/CD/XLDLIBS/3DOBJEC3.XLD": { "Loader": "fixedsize", "MinimumCount": 100, "MapFile": "Meta/3DOBJEC3.json" },
- "Albion/CD/XLDLIBS/3DOVERL0.XLD": { "Transposed": true, "Loader": "fixedsize", "Max": 98, "MapFile": "Meta/3DOVERL0.json" },
- "Albion/CD/XLDLIBS/3DOVERL1.XLD": { "Transposed": true, "Loader": "fixedsize", "MapFile": "Meta/3DOVERL1.json" },
- "Albion/CD/XLDLIBS/3DOVERL2.XLD": { "Transposed": true, "Loader": "fixedsize", "MinimumCount": 100, "MapFile": "Meta/3DOVERL2.json" },
- "Albion/CD/XLDLIBS/3DWALLS0.XLD": { "Transposed": true, "Loader": "fixedsize", "Max": 98, "MapFile": "Meta/3DWALLS0.json" },
- "Albion/CD/XLDLIBS/3DWALLS1.XLD": { "Transposed": true, "Loader": "fixedsize", "MinimumCount": 100, "MapFile": "Meta/3DWALLS1.json" },
- "Albion/CD/XLDLIBS/COMBACK0.XLD": { "Loader": "fixedsize", "Width": 360, "MapFile": "Meta/COMBACK0.json" },
- "Albion/CD/XLDLIBS/COMGFX0.XLD": { "Loader": "multiheader", "PaletteId": 23, "Map": { "0": { "Id": "comgfx.1"} } },
- "Albion/CD/XLDLIBS/FBODPIX0.XLD": { "Loader": "header", "PaletteId": 19, "Map": { "0": { "Id": "pinvgfx.1" } } },
- "Albion/CD/XLDLIBS/MONGFX0.XLD": { "Loader": "multiheader", "PaletteId": 24, "MapFile": "Meta/MONGFX0.json" },
- "Albion/CD/XLDLIBS/NPCGR0.XLD": { "Loader": "header", "Max": 98, "MapFile": "Meta/NPCGR0.json" },
- "Albion/CD/XLDLIBS/NPCGR1.XLD": { "Loader": "header", "MinimumCount": 100, "MapFile": "Meta/NPCGR1.json" },
- "Albion/CD/XLDLIBS/NPCKL0.XLD": { "Loader": "header", "PaletteId": 1, "Map": { "0": { "Id": "npcsmall.1" }, "27": { "PaletteId": 4 } } },
- "Albion/CD/XLDLIBS/PARTGR0.XLD": { "Loader": "header", "PaletteId": 20, "Map": { "0": { "Id": "plarge.1" } } },
- "Albion/CD/XLDLIBS/PARTKL0.XLD": { "Loader": "header", "PaletteId": 1, "Map": { "0": { "Id": "psmall.1" } } },
- "Albion/CD/XLDLIBS/PICTURE0.XLD": { "Loader": "interlaced", "IsReadOnly": true, "Map": { "0": { "Id": "pic.1" } } },
- "Albion/CD/XLDLIBS/SMLPORT0.XLD": { "Loader": "fixedsize", "Width": 34, "Max": 98, "Map": { "0": { "Id": "portrait.1" } } },
- "Albion/CD/XLDLIBS/SMLPORT1.XLD": { "Loader": "fixedsize", "Width": 34, "MinimumCount": 100, "Map": { "0": { "Id": "portrait.100" } } },
- "Albion/CD/XLDLIBS/TACTICO0.XLD": { "Loader": "fixedsize", "Width": 32, "Map": { "0": { "Id": "tacgfx.1" } } },
+ "autotile.1-2": {
+ "Files": {
+ "Albion/CD/XLDLIBS/AUTOGFX0.XLD": {
+ "Post": "atlas",
+ "Loader": "amorphous",
+ "Map": {
+ "autotile.1": { "SubSprites": "(8,8,576) (16,16)", "Palette": "pal.11" },
+ "autotile.2": { "SubSprites": "(8,8,576) (16,16)", "Palette": "pal.30" }
+ }
+ }
+ }
+ },
- "Albion/CD/XLDLIBS/3DBCKGR0.XLD": {
- "Loader": "header",
- "Map": {
- "0": { "Id": "3dbg.1", "PaletteId": 3 },
- "1": { "PaletteId": 3 },
- "2": { "PaletteId": 25 }
- }
- },
- "Albion/CD/XLDLIBS/AUTOGFX0.XLD": {
- "Post": "atlas",
- "Loader": "amorphous",
- "Map": {
- "0": { "Id": "autotile.1", "SubSprites": "(8,8,576) (16,16)", "PaletteId": 11 },
- "1": { "SubSprites": "(8,8,576) (16,16)", "PaletteId": 30 }
+ "tilegfx.1-11": {
+ "Files": {
+ "Albion/CD/XLDLIBS/ICONGFX0.XLD": {
+ "Loader": "tilegfx",
+ "Width": 16,
+ "Height": 16,
+ "Map": {
+ "tilegfx.1": { "Palette": "pal.1" },
+ "tilegfx.2": { "Palette": "pal.2" },
+ "tilegfx.3": { "Palette": "pal.6" },
+ "tilegfx.4": { "Palette": "pal.4" },
+ "tilegfx.5": { "Palette": "pal.5" },
+ "tilegfx.6": { "Palette": "pal.16" },
+ "tilegfx.7": { "Palette": "pal.9" },
+ "tilegfx.8": { "Palette": "pal.26" },
+ "tilegfx.9": { "Palette": "pal.28" },
+ "tilegfx.10": { "Palette": "pal.45" },
+ "tilegfx.11": { "Palette": "pal.56" }
+ }
}
- },
- "Albion/CD/XLDLIBS/ICONGFX0.XLD": {
- "Loader": "tilegfx",
- "Width": 16,
- "Height": 16,
- "Map": {
- "0": { "Id": "tilegfx.1", "PaletteId": 1 },
- "1": { "PaletteId": 2 },
- "2": { "PaletteId": 6 },
- "3": { "PaletteId": 4 },
- "4": { "PaletteId": 5 },
- "5": { "PaletteId": 16 },
- "6": { "PaletteId": 9 },
- "7": { "PaletteId": 26 },
- "8": { "PaletteId": 28 },
- "9": { "PaletteId": 45 },
- "10": { "PaletteId": 56 }
+ }
+ },
+
+ "itemgfx.1": {
+ "Files": {
+ "Albion/CD/XLDLIBS/ITEMGFX": {
+ "Loader": "fixedsize",
+ "Container": "raw",
+ "Palette": "pal.0",
+ "Width": 16,
+ "Height": 16
}
- },
- "Albion/CD/XLDLIBS/ITEMGFX": {
- "Loader": "fixedsize",
- "Container": "raw",
- "Width": 16,
- "Height": 16,
- "Max": 0,
- "Map": { "0": { "Id": "itemgfx.1" } }
- },
- "Albion/CD/XLDLIBS/SLAB": {
- "Loader": "slab",
- "Container": "raw",
- "Width": 360,
- "Max": 0,
- "Map": { "0": { "Id": "uibg.1" } }
- },
- "Albion/MAIN.EXE#476227B0": { // EN GOG Installed Aug 22 1996
- "IsReadOnly": true,
- "Loader": "fixedsize",
- "Container": "binaryoffsets",
- "MapFile": "Meta/MainExe.json"
- },
- "Albion/MAIN.EXE#9FC7ABCF": { // EN Jul 25 1996
- "IsReadOnly": true,
- "Loader": "fixedsize",
- "Container": "binaryoffsets",
- "MapFile": "Meta/MainExe.json"
- },
- "Albion/MAIN.EXE#487DA334": { // FR
- "IsReadOnly": true,
- "Loader": "fixedsize",
- "Container": "binaryoffsets",
- "MapFile": "Meta/MainExe.json"
- },
- "Albion/MAIN.EXE#EC6D6389": { // DE GOG ISO Dec 14 1995
- "IsReadOnly": true,
- "Loader": "fixedsize",
- "Container": "binaryoffsets",
- "MapFile": "Meta/MainExe_DE.json"
}
+ },
+ "uibg.1": { "Files": { "Albion/CD/XLDLIBS/SLAB": { "Loader": "slab", "Container": "raw", "Width": 360 } } },
+
+ "coregfx.0-88": {
+ "Files": {
+ "Albion/MAIN.EXE#476227B0": { "MapFile": "Meta/MainExe.json" }, // EN GOG, built Aug 22 1996
+ "Albion/MAIN.EXE#9FC7ABCF": { "MapFile": "Meta/MainExe.json" }, // EN, built Jul 25 1996
+ "Albion/MAIN.EXE#487DA334": { "MapFile": "Meta/MainExe.json" }, // FR
+ "Albion/MAIN.EXE#EC6D6389": { "MapFile": "Meta/MainExe_DE.json" } // DE GOG ISO, built Dec 14 1995
+ },
+ "Container": "binaryoffsets",
+ "Loader": "fixedsize",
+ "IsReadOnly": true
}
}
// vim: tabstop=2 shiftwidth=2 expandtab
diff --git a/mods/Albion/modinfo.json b/mods/Albion/modinfo.json
index 967afbbe9..9e9201731 100644
--- a/mods/Albion/modinfo.json
+++ b/mods/Albion/modinfo.json
@@ -5,7 +5,7 @@
"Author": "Cam Sinclair et al",
"Version": "0.1.0",
"Dependencies": [ "Base", "Shaders", "Common" ],
- "InheritAssetConfigFrom": "Base",
+ "InheritTypeConfigFrom": "Base",
"AssetConfig": "alb_assets.json",
"SymLinks": { "Albion": "$(ALBION)" }
}
diff --git a/mods/Base/Base.shproj b/mods/Base/Base.shproj
index ae36cb23c..18f2e9d6d 100644
--- a/mods/Base/Base.shproj
+++ b/mods/Base/Base.shproj
@@ -3,7 +3,8 @@
-
+
+
diff --git a/mods/Base/modinfo.json b/mods/Base/modinfo.json
index 83c442418..cbc069b14 100644
--- a/mods/Base/modinfo.json
+++ b/mods/Base/modinfo.json
@@ -5,5 +5,5 @@
"Author": "Cam Sinclair et al",
"Version": "0.1.0",
"Dependencies": [],
- "AssetConfig": "base_assets.json"
+ "TypeConfig": "types.json"
}
diff --git a/mods/Base/base_assets.json b/mods/Base/types.json
similarity index 55%
rename from mods/Base/base_assets.json
rename to mods/Base/types.json
index aaa5273c0..3a1c91d28 100644
--- a/mods/Base/base_assets.json
+++ b/mods/Base/types.json
@@ -1,61 +1,61 @@
{
"IdTypes": {
- "3dbg": { "AssetType": "BackgroundGfx", "EnumType": "UAlbion.Base.DungeonBackground, UAlbion.Base" },
- "3dobj": { "AssetType": "Object3D", "EnumType": "UAlbion.Base.DungeonObject, UAlbion.Base" },
- "automap": { "AssetType": "Automap", "EnumType": "UAlbion.Base.Automap, UAlbion.Base" },
- "autotile": { "AssetType": "AutomapGfx", "EnumType": "UAlbion.Base.AutomapTiles, UAlbion.Base" },
- "block": { "AssetType": "BlockList", "EnumType": "UAlbion.Base.BlockList, UAlbion.Base" },
- "chest": { "AssetType": "Chest", "EnumType": "UAlbion.Base.Chest, UAlbion.Base" },
- "combg": { "AssetType": "CombatBackground", "EnumType": "UAlbion.Base.CombatBackground, UAlbion.Base" },
- "comgfx": { "AssetType": "CombatGfx", "EnumType": "UAlbion.Base.CombatGfx, UAlbion.Base" },
- "coregfx": { "AssetType": "CoreGfx", "EnumType": "UAlbion.Base.CoreGfx, UAlbion.Base" },
- "door": { "AssetType": "Door", "EnumType": "UAlbion.Base.Door, UAlbion.Base" },
- "eset": { "AssetType": "EventSet", "EnumType": "UAlbion.Base.EventSet, UAlbion.Base" },
- "etext": { "AssetType": "EventText", "EnumType": "UAlbion.Base.EventText, UAlbion.Base" },
- "floor": { "AssetType": "Floor", "EnumType": "UAlbion.Base.Floor, UAlbion.Base" },
- "font": { "AssetType": "FontDefinition", "EnumType": "UAlbion.Base.Font, UAlbion.Base" },
- "fontgfx": { "AssetType": "FontGfx", "EnumType": "UAlbion.Base.FontGfx, UAlbion.Base" },
- "ink": { "AssetType": "Ink", "EnumType": "UAlbion.Base.Ink, UAlbion.Base" },
- "item": { "AssetType": "Item", "EnumType": "UAlbion.Base.Item, UAlbion.Base" },
- "itemgfx": { "AssetType": "ItemGfx", "EnumType": "UAlbion.Base.ItemGfx, UAlbion.Base" },
- "itemname": { "AssetType": "ItemName", "EnumType": "UAlbion.Base.ItemName, UAlbion.Base" },
- "lab": { "AssetType": "Labyrinth", "EnumType": "UAlbion.Base.Labyrinth, UAlbion.Base" },
- "map": { "AssetType": "Map", "EnumType": "UAlbion.Base.Map, UAlbion.Base" },
- "merchant": { "AssetType": "Merchant", "EnumType": "UAlbion.Base.Merchant, UAlbion.Base" },
- "mongfx": { "AssetType": "MonsterGfx", "EnumType": "UAlbion.Base.MonsterGfx, UAlbion.Base" },
- "mongrp": { "AssetType": "MonsterGroup", "EnumType": "UAlbion.Base.MonsterGroup, UAlbion.Base" },
- "monster": { "AssetType": "MonsterSheet", "EnumType": "UAlbion.Base.MonsterSheet, UAlbion.Base" },
- "mtext": { "AssetType": "MapText", "EnumType": "UAlbion.Base.MapText, UAlbion.Base" },
- "npc": { "AssetType": "NpcSheet", "EnumType": "UAlbion.Base.NpcSheet, UAlbion.Base" },
- "npclarge": { "AssetType": "NpcLargeGfx", "EnumType": "UAlbion.Base.NpcLargeGfx, UAlbion.Base" },
- "npcsmall": { "AssetType": "NpcSmallGfx", "EnumType": "UAlbion.Base.NpcSmallGfx, UAlbion.Base" },
- "overlay": { "AssetType": "WallOverlay", "EnumType": "UAlbion.Base.WallOverlay, UAlbion.Base" },
- "pal": { "AssetType": "Palette", "EnumType": "UAlbion.Base.Palette, UAlbion.Base" },
- "pic": { "AssetType": "Picture", "EnumType": "UAlbion.Base.Picture, UAlbion.Base" },
- "party": { "AssetType": "PartyMember", "EnumType": "UAlbion.Base.PartyMember, UAlbion.Base" },
- "pinvgfx": { "AssetType": "PartyInventoryGfx", "EnumType": "UAlbion.Base.PartyInventoryGfx, UAlbion.Base" },
- "plarge": { "AssetType": "PartyLargeGfx", "EnumType": "UAlbion.Base.PartyLargeGfx, UAlbion.Base" },
- "psheet": { "AssetType": "PartySheet", "EnumType": "UAlbion.Base.PartySheet, UAlbion.Base" },
- "portrait": { "AssetType": "Portrait", "EnumType": "UAlbion.Base.Portrait, UAlbion.Base" },
- "psmall": { "AssetType": "PartySmallGfx", "EnumType": "UAlbion.Base.PartySmallGfx, UAlbion.Base" },
- "sample": { "AssetType": "Sample", "EnumType": "UAlbion.Base.Sample, UAlbion.Base" },
- "script": { "AssetType": "Script", "EnumType": "UAlbion.Base.Script, UAlbion.Base" },
- "song": { "AssetType": "Song", "EnumType": "UAlbion.Base.Song, UAlbion.Base" },
- "special": { "AssetType": "Special", "EnumType": "UAlbion.Base.Special, UAlbion.Base" },
- "spell": { "AssetType": "Spell", "EnumType": "UAlbion.Base.Spell, UAlbion.Base" },
- "stext": { "AssetType": "Text", "EnumType": "UAlbion.Base.SystemText, UAlbion.Base" },
- "switch": { "AssetType": "Switch", "EnumType": "UAlbion.Base.Switch, UAlbion.Base" },
- "tacgfx": { "AssetType": "TacticalGfx", "EnumType": "UAlbion.Base.TacticalGfx, UAlbion.Base" },
- "target": { "AssetType": "Target", "EnumType": "UAlbion.Base.Target, UAlbion.Base" },
- "ticker": { "AssetType": "Ticker", "EnumType": "UAlbion.Base.Ticker, UAlbion.Base" },
- "tiledata": { "AssetType": "Tileset", "EnumType": "UAlbion.Base.Tileset, UAlbion.Base" },
- "tilegfx": { "AssetType": "TilesetGfx", "EnumType": "UAlbion.Base.TilesetGfx, UAlbion.Base" },
- "uibg": { "AssetType": "Slab", "EnumType": "UAlbion.Base.UiBackground, UAlbion.Base" },
- "utext": { "AssetType": "Text", "EnumType": "UAlbion.Base.UAlbionString, UAlbion.Base" },
- "vid": { "AssetType": "Video", "EnumType": "UAlbion.Base.Video, UAlbion.Base" },
- "wall": { "AssetType": "Wall", "EnumType": "UAlbion.Base.Wall, UAlbion.Base" },
- "wavlib": { "AssetType": "WaveLibrary", "EnumType": "UAlbion.Base.WaveLibrary, UAlbion.Base" },
- "word": { "AssetType": "Word", "EnumType": "UAlbion.Base.Word, UAlbion.Base" }
+ "3dbg": { "AssetType": "BackgroundGfx", "EnumType": "UAlbion.Base.DungeonBackground, UAlbion.Base" },
+ "3dobj": { "AssetType": "Object3D", "EnumType": "UAlbion.Base.DungeonObject, UAlbion.Base" },
+ "automap": { "AssetType": "Automap", "EnumType": "UAlbion.Base.Automap, UAlbion.Base" },
+ "autotile": { "AssetType": "AutomapGfx", "EnumType": "UAlbion.Base.AutomapTiles, UAlbion.Base" },
+ "block": { "AssetType": "BlockList", "EnumType": "UAlbion.Base.BlockList, UAlbion.Base" },
+ "chest": { "AssetType": "Chest", "EnumType": "UAlbion.Base.Chest, UAlbion.Base" },
+ "combg": { "AssetType": "CombatBackground", "EnumType": "UAlbion.Base.CombatBackground, UAlbion.Base" },
+ "comgfx": { "AssetType": "CombatGfx", "EnumType": "UAlbion.Base.CombatGfx, UAlbion.Base" },
+ "coregfx": { "AssetType": "CoreGfx", "EnumType": "UAlbion.Base.CoreGfx, UAlbion.Base" },
+ "door": { "AssetType": "Door", "EnumType": "UAlbion.Base.Door, UAlbion.Base" },
+ "eset": { "AssetType": "EventSet", "EnumType": "UAlbion.Base.EventSet, UAlbion.Base" },
+ "etext": { "AssetType": "EventText", "EnumType": "UAlbion.Base.EventText, UAlbion.Base" },
+ "floor": { "AssetType": "Floor", "EnumType": "UAlbion.Base.Floor, UAlbion.Base" },
+ "font": { "AssetType": "FontDefinition", "EnumType": "UAlbion.Base.Font, UAlbion.Base" },
+ "fontgfx": { "AssetType": "FontGfx", "EnumType": "UAlbion.Base.FontGfx, UAlbion.Base" },
+ "ink": { "AssetType": "Ink", "EnumType": "UAlbion.Base.Ink, UAlbion.Base" },
+ "item": { "AssetType": "Item", "EnumType": "UAlbion.Base.Item, UAlbion.Base" },
+ "itemgfx": { "AssetType": "ItemGfx", "EnumType": "UAlbion.Base.ItemGfx, UAlbion.Base" },
+ "itemname": { "AssetType": "ItemName", "EnumType": "UAlbion.Base.ItemName, UAlbion.Base" },
+ "lab": { "AssetType": "Labyrinth", "EnumType": "UAlbion.Base.Labyrinth, UAlbion.Base" },
+ "map": { "AssetType": "Map", "EnumType": "UAlbion.Base.Map, UAlbion.Base" },
+ "merchant": { "AssetType": "Merchant", "EnumType": "UAlbion.Base.Merchant, UAlbion.Base" },
+ "mongfx": { "AssetType": "MonsterGfx", "EnumType": "UAlbion.Base.MonsterGfx, UAlbion.Base" },
+ "mongrp": { "AssetType": "MonsterGroup", "EnumType": "UAlbion.Base.MonsterGroup, UAlbion.Base" },
+ "monster": { "AssetType": "MonsterSheet", "EnumType": "UAlbion.Base.MonsterSheet, UAlbion.Base" },
+ "mtext": { "AssetType": "MapText", "EnumType": "UAlbion.Base.MapText, UAlbion.Base" },
+ "npc": { "AssetType": "NpcSheet", "EnumType": "UAlbion.Base.NpcSheet, UAlbion.Base" },
+ "npclarge": { "AssetType": "NpcLargeGfx", "EnumType": "UAlbion.Base.NpcLargeGfx, UAlbion.Base" },
+ "npcsmall": { "AssetType": "NpcSmallGfx", "EnumType": "UAlbion.Base.NpcSmallGfx, UAlbion.Base" },
+ "overlay": { "AssetType": "WallOverlay", "EnumType": "UAlbion.Base.WallOverlay, UAlbion.Base" },
+ "pal": { "AssetType": "Palette", "EnumType": "UAlbion.Base.Palette, UAlbion.Base" },
+ "pic": { "AssetType": "Picture", "EnumType": "UAlbion.Base.Picture, UAlbion.Base" },
+ "party": { "AssetType": "PartyMember", "EnumType": "UAlbion.Base.PartyMember, UAlbion.Base" },
+ "pinvgfx": { "AssetType": "PartyInventoryGfx", "EnumType": "UAlbion.Base.PartyInventoryGfx, UAlbion.Base" },
+ "plarge": { "AssetType": "PartyLargeGfx", "EnumType": "UAlbion.Base.PartyLargeGfx, UAlbion.Base" },
+ "psheet": { "AssetType": "PartySheet", "EnumType": "UAlbion.Base.PartySheet, UAlbion.Base" },
+ "portrait": { "AssetType": "Portrait", "EnumType": "UAlbion.Base.Portrait, UAlbion.Base" },
+ "psmall": { "AssetType": "PartySmallGfx", "EnumType": "UAlbion.Base.PartySmallGfx, UAlbion.Base" },
+ "sample": { "AssetType": "Sample", "EnumType": "UAlbion.Base.Sample, UAlbion.Base" },
+ "script": { "AssetType": "Script", "EnumType": "UAlbion.Base.Script, UAlbion.Base" },
+ "song": { "AssetType": "Song", "EnumType": "UAlbion.Base.Song, UAlbion.Base" },
+ "special": { "AssetType": "Special", "EnumType": "UAlbion.Base.Special, UAlbion.Base" },
+ "spell": { "AssetType": "Spell", "EnumType": "UAlbion.Base.Spell, UAlbion.Base" },
+ "stext": { "AssetType": "Text", "EnumType": "UAlbion.Base.SystemText, UAlbion.Base" },
+ "switch": { "AssetType": "Switch", "EnumType": "UAlbion.Base.Switch, UAlbion.Base" },
+ "tacgfx": { "AssetType": "TacticalGfx", "EnumType": "UAlbion.Base.TacticalGfx, UAlbion.Base" },
+ "target": { "AssetType": "Target", "EnumType": "UAlbion.Base.Target, UAlbion.Base" },
+ "ticker": { "AssetType": "Ticker", "EnumType": "UAlbion.Base.Ticker, UAlbion.Base" },
+ "tiledata": { "AssetType": "Tileset", "EnumType": "UAlbion.Base.Tileset, UAlbion.Base" },
+ "tilegfx": { "AssetType": "TilesetGfx", "EnumType": "UAlbion.Base.TilesetGfx, UAlbion.Base" },
+ "uibg": { "AssetType": "Slab", "EnumType": "UAlbion.Base.UiBackground, UAlbion.Base" },
+ "utext": { "AssetType": "Text", "EnumType": "UAlbion.Base.UAlbionString, UAlbion.Base" },
+ "vid": { "AssetType": "Video", "EnumType": "UAlbion.Base.Video, UAlbion.Base" },
+ "wall": { "AssetType": "Wall", "EnumType": "UAlbion.Base.Wall, UAlbion.Base" },
+ "wavlib": { "AssetType": "WaveLibrary", "EnumType": "UAlbion.Base.WaveLibrary, UAlbion.Base" },
+ "word": { "AssetType": "Word", "EnumType": "UAlbion.Base.Word, UAlbion.Base" }
},
"Loaders": {
@@ -73,9 +73,10 @@
"ink": "UAlbion.Formats.Parsers.JsonLoader`1[[UAlbion.Formats.Assets.Ink, UAlbion.Formats]], UAlbion.Formats",
"inputconfig": "UAlbion.Formats.Parsers.InputConfigLoader, UAlbion.Formats",
"interlaced": "UAlbion.Formats.Parsers.InterlacedBitmapLoader, UAlbion.Formats",
- "itemNameCollector": "UAlbion.Formats.Parsers.ItemNameCollector, UAlbion.Formats",
"itemdata": "UAlbion.Formats.Parsers.ItemDataLoader, UAlbion.Formats",
"itemname": "UAlbion.Formats.Parsers.ItemNameLoader, UAlbion.Formats",
+ "itemnameCollector": "UAlbion.Formats.Parsers.ItemNameCollectorLoader, UAlbion.Formats",
+ "itemnameMeta": "UAlbion.Formats.Parsers.ItemNameMetaLoader, UAlbion.Formats",
"json": "UAlbion.Formats.Parsers.JsonStringLoader, UAlbion.Formats",
"jsonEventSet": "UAlbion.Formats.Parsers.JsonLoader`1[[UAlbion.Formats.Assets.EventSet, UAlbion.Formats]], UAlbion.Formats",
"jsonInv": "UAlbion.Formats.Parsers.JsonLoader`1[[UAlbion.Formats.Assets.Inventory, UAlbion.Formats]], UAlbion.Formats",
@@ -102,6 +103,8 @@
"song": "UAlbion.Formats.Parsers.SongLoader, UAlbion.Formats",
"spell": "UAlbion.Formats.Parsers.SpellLoader, UAlbion.Formats",
"stext": "UAlbion.Formats.Parsers.SystemTextLoader, UAlbion.Formats",
+ "stringset": "UAlbion.Formats.Parsers.StringSetStringLoader, UAlbion.Formats",
+ "stringcollector": "UAlbion.Formats.Parsers.StringSetCollectorLoader, UAlbion.Formats",
"stringtable": "UAlbion.Formats.Parsers.AlbionStringTableLoader, UAlbion.Formats",
"tiledMap": "UAlbion.Formats.Exporters.Tiled.TiledMapLoader, UAlbion.Formats",
"tiledStamp": "UAlbion.Formats.Exporters.Tiled.StampLoader, UAlbion.Formats",
@@ -113,7 +116,6 @@
"wav": "UAlbion.Formats.Parsers.WavLoader, UAlbion.Formats",
"wavlib": "UAlbion.Formats.Parsers.WaveLibLoader, UAlbion.Formats",
"wavlib2": "UAlbion.Formats.Parsers.WaveLibWavLoader, UAlbion.Formats",
- "wordCollector": "UAlbion.Formats.Parsers.WordCollector, UAlbion.Formats",
"wordlist": "UAlbion.Formats.Parsers.WordListLoader, UAlbion.Formats",
// These are in Game.Veldrid due to a dependency on ImageSharp
@@ -149,6 +151,11 @@
"atlas": "UAlbion.Formats.Parsers.AtlasPostProcessor, UAlbion.Formats"
},
+ "GlobalPropertyTypes": [
+ "UAlbion.Config.Properties.AssetProps, UAlbion.Config",
+ "UAlbion.Game.Veldrid.Input.CursorManager, UAlbion.Game.Veldrid"
+ ],
+
"VarTypes": [
"UAlbion.Formats.Config.GameVars, UAlbion.Formats",
"UAlbion.Game.Settings.UserVars, UAlbion.Game",
diff --git a/mods/Albion/ENGLISH/strings.json b/mods/Common/ENGLISH/strings.json
similarity index 100%
rename from mods/Albion/ENGLISH/strings.json
rename to mods/Common/ENGLISH/strings.json
diff --git a/mods/Albion/FRENCH/strings.json b/mods/Common/FRENCH/strings.json
similarity index 100%
rename from mods/Albion/FRENCH/strings.json
rename to mods/Common/FRENCH/strings.json
diff --git a/mods/Common/Fonts/0_Regular.json b/mods/Common/Fonts/1_Regular.json
similarity index 100%
rename from mods/Common/Fonts/0_Regular.json
rename to mods/Common/Fonts/1_Regular.json
diff --git a/mods/Common/Fonts/1_Bold.json b/mods/Common/Fonts/2_Bold.json
similarity index 100%
rename from mods/Common/Fonts/1_Bold.json
rename to mods/Common/Fonts/2_Bold.json
diff --git a/mods/Common/Fonts/2_DebugFont6.json b/mods/Common/Fonts/3_DebugFont6.json
similarity index 100%
rename from mods/Common/Fonts/2_DebugFont6.json
rename to mods/Common/Fonts/3_DebugFont6.json
diff --git a/mods/Common/Fonts/3_DebugFont7.json b/mods/Common/Fonts/4_DebugFont7.json
similarity index 100%
rename from mods/Common/Fonts/3_DebugFont7.json
rename to mods/Common/Fonts/4_DebugFont7.json
diff --git a/mods/Common/Fonts/4_DebugFont10.json b/mods/Common/Fonts/5_DebugFont10.json
similarity index 100%
rename from mods/Common/Fonts/4_DebugFont10.json
rename to mods/Common/Fonts/5_DebugFont10.json
diff --git a/mods/Common/Fonts/5_DebugFont11.json b/mods/Common/Fonts/6_DebugFont11.json
similarity index 100%
rename from mods/Common/Fonts/5_DebugFont11.json
rename to mods/Common/Fonts/6_DebugFont11.json
diff --git a/mods/Common/Fonts/6_DebugFont14.json b/mods/Common/Fonts/7_DebugFont14.json
similarity index 100%
rename from mods/Common/Fonts/6_DebugFont14.json
rename to mods/Common/Fonts/7_DebugFont14.json
diff --git a/mods/Common/Fonts/7_DebugFont17.json b/mods/Common/Fonts/8_DebugFont17.json
similarity index 100%
rename from mods/Common/Fonts/7_DebugFont17.json
rename to mods/Common/Fonts/8_DebugFont17.json
diff --git a/mods/Albion/GERMAN/strings.json b/mods/Common/GERMAN/strings.json
similarity index 100%
rename from mods/Albion/GERMAN/strings.json
rename to mods/Common/GERMAN/strings.json
diff --git a/mods/Common/assets.json b/mods/Common/assets.json
index fadf52e74..1cb81b486 100644
--- a/mods/Common/assets.json
+++ b/mods/Common/assets.json
@@ -1,39 +1,61 @@
{
- "Files": {
- "config.json": {
- "Container": "dummy",
- "Loader": "varset",
- "Max": 0,
- "Map": { "0": { "Id": "special.GameConfig" } }
+ "special.GameConfig": {
+ "Files": { "config.json": {} },
+ "Container": "dummy",
+ "Loader": "varset"
+ },
+
+ "special.InputConfig": {
+ "Files": { "input.json": {} },
+ "Container": "dummy",
+ "Loader": "inputconfig"
+ },
+
+ "special.UAlbionStrings": {
+ "Files": {
+ "GERMAN/strings.json": { "Language": "GERMAN" },
+ "ENGLISH/strings.json": { "Language": "ENGLISH" },
+ "FRENCH/strings.json": { "Language": "FRENCH" }
},
- "input.json": {
- "Container": "dummy",
- "Loader": "inputconfig",
- "Max": 0,
- "Map": { "0": { "Id": "special.InputConfig" } }
+ "Loader": "json",
+ "Container": "raw"
+ },
+
+ "utext.0-*": {
+ "Files": { // Dummy files used for ensuring the language is available on the AssetLoadContext
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
- "PartyMembers": {
- "Loader": "jsonParty",
- "Pattern": "{id:00}_{name}.json",
- "Map": { "1": { "Id": "party.1" } }
- },
- "Fonts": {
- "Loader": "font",
- "Pattern": "{id}_{name}.json",
- "Map": { "0": { "Id": "font.Regular" } }
- },
- "Fonts/DebugFonts.png": {
- "Container": "raw",
- "Loader": "png8",
- "Max": 0,
- "Map": { "0": { "Id": "fontgfx.Debug" } }
- },
- "Inks.json": {
- "Container": "jsonObj",
- "Loader": "ink",
- "Max": 99,
- "Map": { "1": { "Id": "ink.White" } }
- }
+ "Loader": "stringset",
+ "FirstId": "utext.0",
+ "Target": "special.UAlbionStrings",
+ "IsReadOnly": true
+ },
+
+ "party.1-*": {
+ "Files": { "PartyMembers": {} },
+ "Loader": "jsonParty",
+ "Pattern": "{id:00}_{name}.json"
+ },
+
+ "font.1-*": {
+ "Files": { "Fonts": {} },
+ "Loader": "font",
+ "Pattern": "{id}_{name}.json"
+ },
+
+ "fontgfx.Debug": {
+ "Files": { "Fonts/DebugFonts.png": {} },
+ "Container": "raw",
+ "Loader": "png8",
+ "Palette": "pal.0"
+ },
+
+ "ink.1-*": {
+ "Files": { "Inks.json": {} },
+ "Container": "jsonObj",
+ "Loader": "ink"
}
}
// vim: tabstop=2 shiftwidth=2 expandtab
diff --git a/mods/Common/modinfo.json b/mods/Common/modinfo.json
index 2d84c7194..c2e3ef02f 100644
--- a/mods/Common/modinfo.json
+++ b/mods/Common/modinfo.json
@@ -5,5 +5,6 @@
"Author": "Cam Sinclair et al",
"Version": "0.1.0",
"Dependencies": [ "Base" ],
- "InheritAssetConfigFrom": "Base"
+ "InheritTypeConfigFrom": "Base",
+ "AssetConfig": "assets.json"
}
diff --git a/mods/ExportPalettes/modinfo.json b/mods/ExportPalettes/modinfo.json
index 965cbc14e..697a21535 100644
--- a/mods/ExportPalettes/modinfo.json
+++ b/mods/ExportPalettes/modinfo.json
@@ -2,6 +2,7 @@
"Name": "UAlbion-ExportPalettes",
"Description": "A simple mod spec for exporting palettes to png",
"Version": "0.1.0",
- "Dependencies": [ "Base", "Shaders", "Common" ],
- "InheritAssetConfigFrom": "Base"
+ "Dependencies": [ "Albion" ],
+ "InheritTypeConfigFrom": "Base",
+ "AssetConfig": "assets.json"
}
diff --git a/mods/Repacked/assets.json b/mods/Repacked/assets.json
deleted file mode 100644
index be5b337e1..000000000
--- a/mods/Repacked/assets.json
+++ /dev/null
@@ -1,9 +0,0 @@
-{
- /*
- Uses identical asset config to 'Albion', but without the symlink
- pointing it to the installed game files. This ensures that when
- exporting to 'Repacked', the original game won't be affected.
- Only the files in the mods/Repacked directory will be updated.
- */
-}
-
diff --git a/mods/Repacked/modinfo.json b/mods/Repacked/modinfo.json
index a4710b183..b82dd16d5 100644
--- a/mods/Repacked/modinfo.json
+++ b/mods/Repacked/modinfo.json
@@ -3,5 +3,6 @@
"Description": "Local location for repacking modified assets for testing with original game",
"Version": "0.1.0",
"Dependencies": [ "Albion" ],
- "InheritAssetConfigFrom": "Albion"
+ "InheritAssetConfigFrom": "Albion",
+ "InheritTypeConfigFrom": "Albion"
}
diff --git a/mods/Shaders/assets.json b/mods/Shaders/assets.json
deleted file mode 100644
index ffcd4415b..000000000
--- a/mods/Shaders/assets.json
+++ /dev/null
@@ -1 +0,0 @@
-{ }
diff --git a/mods/Unpacked/assets.json b/mods/Unpacked/assets.json
index db9a68915..adf906f26 100644
--- a/mods/Unpacked/assets.json
+++ b/mods/Unpacked/assets.json
@@ -1,219 +1,242 @@
{
- "Languages": { // Just used for the options screen
- "ENGLISH": { "DisplayName": "English", "ShortName": "EN" },
- "GERMAN": { "DisplayName": "Deutsch", "ShortName": "DE" },
- "FRENCH": { "DisplayName": "Français", "ShortName": "FR" }
+ // Pattern Variables: 0=SubId in container 1=frame/sub-asset number 2=Asset name 3=PaletteId. Patterns must begin with {id}_ when writing.
+ "special.SoundBank": { "Files": { "Assets/Soundbank.json": { "Container": "raw", "Loader": "jsonSoundbank" } } },
+
+ "special.TiledNpcsLarge": {
+ "Sequence": 1, // Needs to happen before maps are exported
+ "Loader": "tiledNpcTileset",
+ "Container": "raw",
+ "UseDummyRead": true,
+ "Files": { "Assets/Tilesets/LargeNPCs.tsx": { "IsSmall": false, "GraphicsPattern": "Assets/Tilesets/LargeNPCs/{id}.png" } }
+ },
+ "special.TiledNpcsSmall": {
+ "Sequence": 1, // Needs to happen before maps are exported
+ "Loader": "tiledNpcTileset",
+ "Container": "raw",
+ "UseDummyRead": true,
+ "Files": { "Assets/Tilesets/SmallNPCs.tsx": { "IsSmall": true, "GraphicsPattern": "Assets/Tilesets/SmallNPCs/{id}.png" } }
},
- "Files": { // Pattern Variables: 0=SubId in container 1=frame/sub-asset number 2=Asset name 3=PaletteId. Patterns must begin with {id}_ when writing.
- "Assets/3dBackgrounds": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_p{pal}_{name}.png", "Map": { "1": { "Id": "3dbg.1" } } },
- "Assets/3dFloors": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "floor.1" } } },
- "Assets/3dObjects": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "3dobj.1" } } },
- "Assets/3dOverlays": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "overlay.1" } } },
- "Assets/3dWalls": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "wall.1" } } },
- "Assets/CombatBackground": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_p{pal}_{name}.png", "Map": { "1": { "Id": "combg.1" } } },
- "Assets/CombatGraphics": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "comgfx.1" } } },
- "Assets/InvBackgrounds": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "pinvgfx.1" } } },
- "Assets/MonsterGraphics": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "mongfx.1" } } },
- "Assets/NpcGraphicsLarge": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "npclarge.1" } } },
- "Assets/NpcGraphicsSmall": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "npcsmall.1" } } },
- "Assets/PartyGraphicsLarge": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "plarge.1" } } },
- "Assets/PartyGraphicsSmall": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png", "Map": { "1": { "Id": "psmall.1" } } },
- "Assets/Pictures": { "Loader": "png32", "Container": "dir", "Pattern": "{id}_{name}.png", "Map": { "1": { "Id": "pic.1" } } },
- "Assets/Portraits": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{name}.png", "Map": { "1": { "Id": "portrait.1" } } },
- "Assets/Slab": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_{name}.png", "Map": { "1": { "Id": "uibg.1" } } },
- "Assets/TacticalIcons": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_{name}.png", "Map": { "1": { "Id": "tacgfx.1" } } },
- "Assets/CoreGraphics": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_{name}.png", "Map": { "0": { "Id": "coregfx.0" } } },
-
- "Assets/Soundbank.json": {
- "Container": "raw",
- "Loader": "jsonSoundbank",
- "Max": 0,
- "Map": { "0": { "Id": "special.SoundBank" } }
- },
-
- "Assets/Tilesets/LargeNPCs.tsx": {
- "Loader": "tiledNpcTileset",
- "Container": "raw",
- "IsSmall": false,
- "GraphicsPattern": "Assets/Tilesets/LargeNPCs/{id}.png",
- "Max": 0,
- "Map": { "0": { "Id": "special.DummyObject" } }
- },
- "Assets/Tilesets/SmallNPCs.tsx": {
- "Loader": "tiledNpcTileset",
- "Container": "raw",
- "IsSmall": true,
- "GraphicsPattern": "Assets/Tilesets/SmallNPCs/{id}.png",
- "Max": 0,
- "Map": { "0": { "Id": "special.DummyObject" } }
- },
+ "special.ItemNamesMultiLang": { // This is just for repacking back to the binary formats
+ "Loader": "itemnameCollector",
+ "TargetRange": "itemname.1-*",
+ "TargetLanguages": [ "GERMAN", "ENGLISH", "FRENCH" ],
+ "IsReadOnly": true
+ },
- "Assets/Chests": { "Loader": "jsonInv", "Container": "dir", "Pattern": "{id:000}_{name}.json", "Map": { "1": { "Id": "chest.1" } } },
- "Assets/Events": { "Loader": "eventSetScript", "Container": "dir", "Pattern": "{id:000}_{name}.ua", "Map": { "1": { "Id": "eset.1" } } },
- "Assets/Merchants": { "Loader": "jsonInv", "Container": "dir", "Pattern": "{id:000}_{name}.json", "Map": { "1": { "Id": "merchant.1" } } },
- "Assets/MonsterGroups": { "Loader": "jsonMonsterGroup", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "2": { "Id": "mongrp.2" } } },
- "Assets/Monsters": { "Loader": "jsonSheet", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "1": { "Id": "monster.1" } } },
- "Assets/Npcs": { "Loader": "jsonSheet", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "1": { "Id": "npc.1" } } },
- "Assets/Palettes": { "Loader": "jsonPal", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "0": { "Id": "pal.0" } } },
- "Assets/PartyMembers": { "Loader": "jsonSheet", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "1": { "Id": "psheet.1" } } },
- "Assets/Samples": { "Loader": "wav", "Container": "dir", "Pattern": "{id}_{name}.wav", "Map": { "1": { "Id": "sample.1" } } },
- "Assets/Scripts": { "Loader": "script", "Container": "dir", "Pattern": "{id}_{name}.ua", "Map": { "2": { "Id": "script.2" } } },
- "Assets/Songs": { "Loader": "song", "Container": "dir", "Pattern": "{id}_{name}.xmi", "Map": { "1": { "Id": "song.1" } } },
- "Assets/WaveLib": { "Loader": "wavlib2", "Container": "dir", "Pattern": "{id}_{frame}_{name}.wav", "Map": { "5": { "Id": "wavlib.5" } } },
- "Assets/Items.json": { "Loader": "jsonItems", "Container": "jsonObj", "Map": { "1": { "Id": "item.1" } } },
- "Assets/Spells.json": { "Loader": "jsonSpell", "Container": "jsonObj", "Map": { "1": { "Id": "spell.1" } } },
-
- "dummy_item_names": { "Loader": "itemNameCollector", "Container": "dummy", "Max": 0, "Map": { "0": { "Id": "special.ItemNames" } } },
- "Assets/ItemNamesDE.json": { "Language": "GERMAN", "Loader": "utf8", "Container": "jsonStrings", "Map": { "1": { "Id": "itemname.1" } } },
- "Assets/ItemNamesEN.json": { "Language": "ENGLISH", "Loader": "utf8", "Container": "jsonStrings", "Map": { "1": { "Id": "itemname.1" } } },
- "Assets/ItemNamesFR.json": { "Language": "FRENCH", "Loader": "utf8", "Container": "jsonStrings", "Map": { "1": { "Id": "itemname.1" } } },
-
- "Assets/SystemTextDE.json": { "Language": "GERMAN", "Loader": "utf8", "Container": "jsonStrings", "Map": { "0": { "Id": "stext.0" } } },
- "Assets/SystemTextEN.json": { "Language": "ENGLISH", "Loader": "utf8", "Container": "jsonStrings", "Map": { "0": { "Id": "stext.0" } } },
- "Assets/SystemTextFR.json": { "Language": "FRENCH", "Loader": "utf8", "Container": "jsonStrings", "Map": { "0": { "Id": "stext.0" } } },
-
- "Assets/EventTextDE": { "Language": "GERMAN", "Loader": "jsonText", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "1": { "Id": "etext.1" } } },
- "Assets/EventTextEN": { "Language": "ENGLISH", "Loader": "jsonText", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "1": { "Id": "etext.1" } } },
- "Assets/EventTextFR": { "Language": "FRENCH", "Loader": "jsonText", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "1": { "Id": "etext.1" } } },
-
- "Assets/MapTextDE": { "Language": "GERMAN", "Loader": "jsonText", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "100": { "Id": "mtext.100" } } },
- "Assets/MapTextEN": { "Language": "ENGLISH", "Loader": "jsonText", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "100": { "Id": "mtext.100" } } },
- "Assets/MapTextFR": { "Language": "FRENCH", "Loader": "jsonText", "Container": "dir", "Pattern": "{id}_{name}.json", "Map": { "100": { "Id": "mtext.100" } } },
-
- "dummy_words_de": {
- "Language": "GERMAN",
- "Loader": "wordCollector",
- "Container": "dummy",
- "Max": 2,
- "Map": {
- "0": { "Id": "special.Words1" },
- "1": { "Id": "special.Words2" },
- "2": { "Id": "special.Words3" }
- }
- },
- "dummy_words_en": {
- "Language": "ENGLISH",
- "Loader": "wordCollector",
- "Container": "dummy",
- "Max": 2,
- "Map": {
- "0": { "Id": "special.Words1" },
- "1": { "Id": "special.Words2" },
- "2": { "Id": "special.Words3" }
- }
+ "special.Words1": {
+ "Files": {
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
- "dummy_words_fr": {
- "Language": "FRENCH",
- "Loader": "wordCollector",
- "Container": "dummy",
- "Max": 2,
- "Map": {
- "0": { "Id": "special.Words1" },
- "1": { "Id": "special.Words2" },
- "2": { "Id": "special.Words3" }
- }
- },
- "Assets/WordsDE.json": { "Language": "GERMAN", "Loader": "utf8", "Container": "jsonStrings", "Map": { "0": { "Id": "word.0" } } },
- "Assets/WordsEN.json": { "Language": "ENGLISH", "Loader": "utf8", "Container": "jsonStrings", "Map": { "0": { "Id": "word.0" } } },
- "Assets/WordsFR.json": { "Language": "FRENCH", "Loader": "utf8", "Container": "jsonStrings", "Map": { "0": { "Id": "word.0" } } },
-
- "Assets/Automap/1": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame:000}_p{pal}_{name}.png", "Max": 1, "Map": { "1": { "Id": "autotile.1" } } },
- "Assets/Automap/2": { "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame:000}_p{pal}_{name}.png", "Max": 2, "Map": { "2": { "Id": "autotile.2" } } },
- "Assets/Automap": { "Loader": "automap", "Container": "dir", "Pattern": "{id}_{frame}_{name}.dat", "Map": { "100": { "Id": "automap.100" } } },
- "Assets/FontGfx": {
- "Container": "dir",
- "Loader": "pngsheet",
- "Width": 8,
- "Height": 8,
- "Pattern": "{id}_{name}.png",
- "Map": { "1": { "Id": "fontgfx.1" } }
+ "IsReadOnly": true,
+ "Loader": "stringcollector",
+ "FileRange": "word.0-1499",
+ "TargetRange": "word.0-499"
+ },
+ "special.Words2": {
+ "Files": {
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
- "Assets/Items.png": {
- "Loader": "pngsheet",
- "Container": "raw",
- "Pattern": "{id}_{name}.png",
- "Width": 16,
- "Height": 16,
- "Map": { "0": { "Id": "itemgfx.1" } }
+ "IsReadOnly": true,
+ "Loader": "stringcollector",
+ "FileRange": "word.0-1499",
+ "TargetRange": "word.500-999"
+ },
+ "special.Words3": {
+ "Files": {
+ "!GERMAN": { "Language": "GERMAN" },
+ "!ENGLISH": { "Language": "ENGLISH" },
+ "!FRENCH": { "Language": "FRENCH" }
},
+ "IsReadOnly": true,
+ "Loader": "stringcollector",
+ "FileRange": "word.0-1499",
+ "TargetRange": "word.1000-1499"
+ },
- "Assets/Tilesets/1": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 1, "Pattern": "{id}_{frame}.png", "Max": 1, "Map": { "1": { "Id": "tilegfx.1" } } },
- "Assets/Tilesets/2": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 2, "Pattern": "{id}_{frame}.png", "Max": 2, "Map": { "2": { "Id": "tilegfx.2" } } },
- "Assets/Tilesets/3": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 6, "Pattern": "{id}_{frame}.png", "Max": 3, "Map": { "3": { "Id": "tilegfx.3" } } },
- "Assets/Tilesets/4": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 4, "Pattern": "{id}_{frame}.png", "Max": 4, "Map": { "4": { "Id": "tilegfx.4" } } },
- "Assets/Tilesets/5": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 5, "Pattern": "{id}_{frame}.png", "Max": 5, "Map": { "5": { "Id": "tilegfx.5" } } },
- "Assets/Tilesets/6": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 16, "Pattern": "{id}_{frame}.png", "Max": 6, "Map": { "6": { "Id": "tilegfx.6" } } },
- "Assets/Tilesets/7": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 9, "Pattern": "{id}_{frame}.png", "Max": 7, "Map": { "7": { "Id": "tilegfx.7" } } },
- "Assets/Tilesets/8": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 26, "Pattern": "{id}_{frame}.png", "Max": 8, "Map": { "8": { "Id": "tilegfx.8" } } },
- "Assets/Tilesets/9": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 28, "Pattern": "{id}_{frame}.png", "Max": 9, "Map": { "9": { "Id": "tilegfx.9" } } },
- "Assets/Tilesets/10": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 45, "Pattern": "{id}_{frame}.png", "Max": 10, "Map": { "10": { "Id": "tilegfx.10" } } },
- "Assets/Tilesets/11": { "Loader": "pngtile8", "Container": "dir", "PaletteId": 56, "Pattern": "{id}_{frame}.png", "Max": 11, "Map": { "11": { "Id": "tilegfx.11" } } },
-
- "Assets/Tilesets/1/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 1, "Map": { "1": { "Id": "block.1" } } },
- "Assets/Tilesets/2/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 2, "Map": { "2": { "Id": "block.2" } } },
- "Assets/Tilesets/3/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 3, "Map": { "3": { "Id": "block.3" } } },
- "Assets/Tilesets/4/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 4, "Map": { "4": { "Id": "block.4" } } },
- "Assets/Tilesets/5/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 5, "Map": { "5": { "Id": "block.5" } } },
- "Assets/Tilesets/6/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 6, "Map": { "6": { "Id": "block.6" } } },
- "Assets/Tilesets/7/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 7, "Map": { "7": { "Id": "block.7" } } },
- "Assets/Tilesets/8/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 8, "Map": { "8": { "Id": "block.8" } } },
- "Assets/Tilesets/9/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 9, "Map": { "9": { "Id": "block.9" } } },
- "Assets/Tilesets/10/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 10, "Map": { "10": { "Id": "block.10" } } },
- "Assets/Tilesets/11/Stamps": { "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx", "Max": 11, "Map": { "11": { "Id": "block.11" } } },
-
- "Assets/3dTilesets": {
- // "Loader": "jsonLab",
- "Loader": "tiledLabyrinth",
- "Container": "dir",
-
- "Pattern": "{id}_{name}.json",
- "TileWidth": 96,
- "TileHeight": 128,
- "BaseHeight": 68,
- "TilesPerRow": 16,
- "TiledFloorPattern": "Tiled/{id}_{name}_Floors.tsx",
- "TiledCeilingPattern": "Tiled/{id}_{name}_Ceilings.tsx",
- "TiledWallPattern": "Tiled/{id}_{name}_Walls.tsx",
- "TiledContentsPattern": "Tiled/{id}_{name}_Contents.tsx",
-
- "FloorPngPattern": "Tiled/Gfx/{id}_{name}_Floors.png",
- "CeilingPngPattern": "Tiled/Gfx/{id}_{name}_Ceilings.png",
- "WallPngPattern": "Tiled/Gfx/{id}_{name}_Walls.png",
- "ContentsPngPattern": "Tiled/Gfx/{id}_{name}_Contents.png",
-
- "Map": { "1": { "Id": "lab.1" } }
- },
+ "3dbg.1-*": { "Files": { "Assets/3dBackgrounds": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_p{pal}_{name}.png" },
+ "floor.1-*": { "Files": { "Assets/3dFloors": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "3dobj.1-*": { "Files": { "Assets/3dObjects": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "overlay.1-*": { "Files": { "Assets/3dOverlays": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "wall.1-*": { "Files": { "Assets/3dWalls": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "combg.1-*": { "Files": { "Assets/CombatBackground": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_p{pal}_{name}.png" },
+ "comgfx.1-*": { "Files": { "Assets/CombatGraphics": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "pinvgfx.1-*": { "Files": { "Assets/InvBackgrounds": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "mongfx.1-*": { "Files": { "Assets/MonsterGraphics": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "npclarge.1-*": { "Files": { "Assets/NpcGraphicsLarge": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "npcsmall.1-*": { "Files": { "Assets/NpcGraphicsSmall": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "plarge.1-*": { "Files": { "Assets/PartyGraphicsLarge": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "psmall.1-*": { "Files": { "Assets/PartyGraphicsSmall": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_p{pal}_{name}.png" },
+ "pic.1-*": { "Files": { "Assets/Pictures": {} }, "Loader": "png32", "Container": "dir", "Pattern": "{id}_{name}.png" },
+ "portrait.1-*": { "Files": { "Assets/Portraits": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{name}.png", "Palette": "pal.0" },
+ "uibg.1-*": { "Files": { "Assets/Slab": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_{name}.png", "Palette": "pal.0" },
+ "tacgfx.1-*": { "Files": { "Assets/TacticalIcons": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_{name}.png", "Palette": "pal.0" },
+ "coregfx.0-*": { "Files": { "Assets/CoreGraphics": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame}_{name}.png", "Palette": "pal.0" },
+
+ "chest.1-*": { "Files": { "Assets/Chests": {} }, "Loader": "jsonInv", "Container": "dir", "Pattern": "{id:000}_{name}.json" },
+ "eset.1-*": { "Files": { "Assets/Events": {} }, "Loader": "eventSetScript", "Container": "dir", "Pattern": "{id:000}_{name}.ua" },
+ "merchant.1-*": { "Files": { "Assets/Merchants": {} }, "Loader": "jsonInv", "Container": "dir", "Pattern": "{id:000}_{name}.json" },
+ "mongrp.2-*": { "Files": { "Assets/MonsterGroups": {} }, "Loader": "jsonMonsterGroup", "Container": "dir", "Pattern": "{id}_{name}.json" },
+ "monster.1-*": { "Files": { "Assets/Monsters": {} }, "Loader": "jsonSheet", "Container": "dir", "Pattern": "{id}_{name}.json" },
+ "npc.1-*": { "Files": { "Assets/Npcs": {} }, "Loader": "jsonSheet", "Container": "dir", "Pattern": "{id}_{name}.json" },
+ "pal.0-*": { "Files": { "Assets/Palettes": {} }, "Loader": "jsonPal", "Container": "dir", "Pattern": "{id}_{name}.json" },
+ "psheet.1-*": { "Files": { "Assets/PartyMembers": {} }, "Loader": "jsonSheet", "Container": "dir", "Pattern": "{id}_{name}.json" },
+ "sample.1-*": { "Files": { "Assets/Samples": {} }, "Loader": "wav", "Container": "dir", "Pattern": "{id}_{name}.wav" },
+ "script.2-*": { "Files": { "Assets/Scripts": {} }, "Loader": "script", "Container": "dir", "Pattern": "{id}_{name}.ua" },
+ "song.1-*": { "Files": { "Assets/Songs": {} }, "Loader": "song", "Container": "dir", "Pattern": "{id}_{name}.xmi" },
+ "wavlib.5-*": { "Files": { "Assets/WaveLib": {} }, "Loader": "wavlib2", "Container": "dir", "Pattern": "{id}_{frame}_{name}.wav" },
+ "item.1-*": { "Files": { "Assets/Items.json": {} }, "Loader": "jsonItems", "Container": "jsonObj" },
+ "spell.1-*": { "Files": { "Assets/Spells.json": {} }, "Loader": "jsonSpell", "Container": "jsonObj" },
+
+ "itemname.1-*": {
+ "Loader": "utf8",
+ "Container": "jsonStrings",
+ "Files": {
+ "Assets/ItemNamesDE.json": { "Language": "GERMAN" },
+ "Assets/ItemNamesEN.json": { "Language": "ENGLISH" },
+ "Assets/ItemNamesFR.json": { "Language": "FRENCH" }
+ }
+ },
- "Assets/Tilesets": {
- "Loader": "tiledTileset", // "jsonTileset"
- "Container": "dir",
- "Pattern": "{id}_{name}.tsx", // "{id}_{name}.json",
- "GraphicsPattern": "{id}/{id}_{frame}.png",
- "BlankTilePath": "../../Blank.png",
- "Map": { "1": { "Id": "tiledata.1" } }
- },
+ "stext.0-*": {
+ "Loader": "utf8",
+ "Container": "jsonStrings",
+ "Files": {
+ "Assets/SystemTextDE.json": { "Language": "GERMAN" },
+ "Assets/SystemTextEN.json": { "Language": "ENGLISH" },
+ "Assets/SystemTextFR.json": { "Language": "FRENCH" }
+ }
+ },
- "Assets/Maps": {
- "Loader": "tiledMap",
- "Container": "dir",
- "Pattern": "{id}_{name}.tmx",
- "ScriptPattern": "{id}_{name}.ua",
-
- "TilesetPattern": "../Tilesets/{id}_{name}.tsx",
- "SmallNpcs": "../Tilesets/SmallNPCs.tsx",
- "LargeNpcs": "../Tilesets/LargeNPCs.tsx",
-
- "TileWidth": 96,
- "TileHeight": 128,
- "BaseHeight": 68,
- "TiledFloorPattern": "../3dTilesets/Tiled/{id}_{name}_Floors.tsx",
- "TiledCeilingPattern": "../3dTilesets/Tiled/{id}_{name}_Ceilings.tsx",
- "TiledWallPattern": "../3dTilesets/Tiled/{id}_{name}_Walls.tsx",
- "TiledContentsPattern": "../3dTilesets/Tiled/{id}_{name}_Contents.tsx",
-
- "Map": { "100": { "Id": "map.100" } }
+ "etext.1-*": {
+ "Loader": "jsonText",
+ "Container": "dir",
+ "Pattern": "{id}_{name}.json",
+ "Files": {
+ "Assets/EventTextDE": { "Language": "GERMAN" },
+ "Assets/EventTextEN": { "Language": "ENGLISH" },
+ "Assets/EventTextFR": { "Language": "FRENCH" }
}
+ },
+
+ "mtext.100-*": {
+ "Loader": "jsonText",
+ "Container": "dir",
+ "Optional": true, // Not every map has text
+ "Pattern": "{id}_{name}.json",
+ "Files": {
+ "Assets/MapTextDE": { "Language": "GERMAN" },
+ "Assets/MapTextEN": { "Language": "ENGLISH" },
+ "Assets/MapTextFR": { "Language": "FRENCH" }
+ }
+ },
+
+ "word.0-*": {
+ "Loader": "utf8",
+ "Container": "jsonStrings",
+ "Files": {
+ "Assets/WordsDE.json": { "Language": "GERMAN" },
+ "Assets/WordsEN.json": { "Language": "ENGLISH" },
+ "Assets/WordsFR.json": { "Language": "FRENCH" }
+ }
+ },
+
+ "autotile.1": { "Files": { "Assets/Automap/1": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame:000}_p{pal}_{name}.png" },
+ "autotile.2": { "Files": { "Assets/Automap/2": {} }, "Loader": "png8", "Container": "dir", "Pattern": "{id}_{frame:000}_p{pal}_{name}.png" },
+ "automap.100-*": { "Files": { "Assets/Automap": {} }, "Loader": "automap", "Container": "dir", "Pattern": "{id}_{frame}_{name}.dat", "Optional": true },
+
+ "fontgfx.1-*": {
+ "Files": { "Assets/FontGfx": { } },
+ "Container": "dir",
+ "Loader": "pngsheet",
+ "Width": 8,
+ "Height": 8,
+ "Pattern": "{id}_{name}.png"
+ },
+
+ "itemgfx.1-*": {
+ "Files": { "Assets/Items.png": {} },
+ "Loader": "pngsheet",
+ "Container": "raw",
+ "Pattern": "{id}_{name}.png",
+ "Width": 16, "Height": 16
+ },
+
+ "tilegfx.1": { "Files": { "Assets/Tilesets/1": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.1", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.2": { "Files": { "Assets/Tilesets/2": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.2", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.3": { "Files": { "Assets/Tilesets/3": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.6", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.4": { "Files": { "Assets/Tilesets/4": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.4", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.5": { "Files": { "Assets/Tilesets/5": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.5", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.6": { "Files": { "Assets/Tilesets/6": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.16", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.7": { "Files": { "Assets/Tilesets/7": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.9", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.8": { "Files": { "Assets/Tilesets/8": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.26", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.9": { "Files": { "Assets/Tilesets/9": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.28", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.10": { "Files": { "Assets/Tilesets/10": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.45", "Pattern": "{id}_{frame}.png" },
+ "tilegfx.11": { "Files": { "Assets/Tilesets/11": {} }, "Loader": "pngtile8", "Container": "dir", "Palette": "pal.56", "Pattern": "{id}_{frame}.png" },
+
+ "block.1": { "Files": { "Assets/Tilesets/1/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.2": { "Files": { "Assets/Tilesets/2/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.3": { "Files": { "Assets/Tilesets/3/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.4": { "Files": { "Assets/Tilesets/4/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.5": { "Files": { "Assets/Tilesets/5/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.6": { "Files": { "Assets/Tilesets/6/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.7": { "Files": { "Assets/Tilesets/7/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.8": { "Files": { "Assets/Tilesets/8/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.9": { "Files": { "Assets/Tilesets/9/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.10": { "Files": { "Assets/Tilesets/10/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+ "block.11": { "Files": { "Assets/Tilesets/11/Stamps": {} }, "Loader": "tiledStamp", "Container": "dir", "Pattern": "{id}_{frame:000}.stamp", "TilesetPattern": "../../{id}_{name}.tsx" },
+
+ "lab.1-*": {
+ "Files": { "Assets/3dTilesets": {} },
+ "Loader": "tiledLabyrinth",
+ "Container": "dir",
+
+ "Pattern": "{id}_{name}.json",
+ "TileWidth": 96,
+ "TileHeight": 128,
+ "BaseHeight": 68,
+ "TilesPerRow": 16,
+ "TiledFloorPattern": "Tiled/{id}_{name}_Floors.tsx",
+ "TiledCeilingPattern": "Tiled/{id}_{name}_Ceilings.tsx",
+ "TiledWallPattern": "Tiled/{id}_{name}_Walls.tsx",
+ "TiledContentsPattern": "Tiled/{id}_{name}_Contents.tsx",
+
+ "FloorPngPattern": "Tiled/Gfx/{id}_{name}_Floors.png",
+ "CeilingPngPattern": "Tiled/Gfx/{id}_{name}_Ceilings.png",
+ "WallPngPattern": "Tiled/Gfx/{id}_{name}_Walls.png",
+ "ContentsPngPattern": "Tiled/Gfx/{id}_{name}_Contents.png"
+ },
+
+ "tiledata.1-*": {
+ "Files": { "Assets/Tilesets": {} },
+ "Loader": "tiledTileset", // "jsonTileset"
+ "Container": "dir",
+ "Pattern": "{id}_{name}.tsx", // "{id}_{name}.json",
+ "GraphicsPattern": "{id}/{id}_{frame}.png",
+ "BlankTilePath": "../../Blank.png"
+ },
+
+ "map.100-*": {
+ "Files": { "Assets/Maps": {} },
+ "Loader": "tiledMap",
+ "Container": "dir",
+ "Pattern": "{id}_{name}.tmx",
+ "ScriptPattern": "{id}_{name}.ua",
+
+ "TilesetPattern": "../Tilesets/{id}_{name}.tsx",
+ "SmallNpcs": "../Tilesets/SmallNPCs.tsx",
+ "LargeNpcs": "../Tilesets/LargeNPCs.tsx",
+
+ "TileWidth": 96,
+ "BaseHeight": 68,
+ "TiledFloorPattern": "../3dTilesets/Tiled/{id}_{name}_Floors.tsx",
+ "TiledCeilingPattern": "../3dTilesets/Tiled/{id}_{name}_Ceilings.tsx",
+ "TiledWallPattern": "../3dTilesets/Tiled/{id}_{name}_Walls.tsx",
+ "TiledContentsPattern": "../3dTilesets/Tiled/{id}_{name}_Contents.tsx"
}
}
// vim: tabstop=2 shiftwidth=2 expandtab
diff --git a/mods/Unpacked/modinfo.json b/mods/Unpacked/modinfo.json
index a5c234903..b3eb5eaac 100644
--- a/mods/Unpacked/modinfo.json
+++ b/mods/Unpacked/modinfo.json
@@ -3,5 +3,6 @@
"Description": "Local location for unpacking/modifying and repacking assets",
"Version": "0.1.0",
"Dependencies": [ "Base", "Shaders", "Common" ],
- "InheritAssetConfigFrom": "Base"
+ "InheritTypeConfigFrom": "Base",
+ "AssetConfig": "assets.json"
}
diff --git a/src/Api/Eventing/EventConstructorAttribute.cs b/src/Api/Eventing/EventConstructorAttribute.cs
new file mode 100644
index 000000000..ee91f0a54
--- /dev/null
+++ b/src/Api/Eventing/EventConstructorAttribute.cs
@@ -0,0 +1,11 @@
+using System;
+
+namespace UAlbion.Api.Eventing;
+
+///
+/// Used to specify which constructor should be used when parsing an event from text using its reflection metadata.
+///
+[AttributeUsage(AttributeTargets.Constructor)]
+public sealed class EventConstructorAttribute : Attribute
+{
+}
\ No newline at end of file
diff --git a/src/Api/Eventing/EventMetadata.cs b/src/Api/Eventing/EventMetadata.cs
index bfa423d94..7652380ff 100644
--- a/src/Api/Eventing/EventMetadata.cs
+++ b/src/Api/Eventing/EventMetadata.cs
@@ -143,7 +143,7 @@ public static void SerializePart(IScriptBuilder builder, EventPartMetadata part,
Func BuildParser(ParameterExpression partsParameter)
{
- var constructor = Type.GetConstructors().Single();
+ var constructor = GetConstructor();
var parameters = constructor.GetParameters();
if (parameters.Length != Parts.Count)
{
@@ -157,4 +157,29 @@ Func BuildParser(ParameterExpression partsParameter)
Expression.New(constructor, Parts.Select(x => x.Parser)), typeof(IEvent)),
partsParameter).Compile();
}
+
+ ConstructorInfo GetConstructor()
+ {
+ var constructors = Type.GetConstructors();
+ ConstructorInfo constructor = null;
+
+ if (constructors.Length == 1)
+ return constructors[0];
+
+ foreach (var x in constructors)
+ {
+ if (x.GetCustomAttribute() == null)
+ continue;
+
+ if (constructor != null)
+ throw new FormatException($"\"{Type}\" has multiple constructors with the {nameof(EventConstructorAttribute)}!");
+
+ constructor = x;
+ }
+
+ if (constructor == null)
+ throw new FormatException($"\"{Type}\" has multiple constructors, but none of them are annotated with an {nameof(EventConstructorAttribute)} to indicate which should be used for constructing parsed events");
+
+ return constructor;
+ }
}
\ No newline at end of file
diff --git a/src/Api/FileSystem.cs b/src/Api/FileSystem.cs
index 8a5f67efc..7b5c27677 100644
--- a/src/Api/FileSystem.cs
+++ b/src/Api/FileSystem.cs
@@ -35,7 +35,8 @@ public string CurrentDirectory
public IEnumerable ReadAllLines(string path) => File.ReadAllLines(ToAbsolutePath(path));
public byte[] ReadAllBytes(string path) => File.ReadAllBytes(ToAbsolutePath(path));
public void WriteAllBytes(string path, byte[] bytes) => File.WriteAllBytes(ToAbsolutePath(path), bytes);
- public IEnumerable EnumerateDirectory(string path, string filter = null)
+ public IEnumerable EnumerateFiles(string path, string filter = null)
=> filter == null ? Directory.EnumerateFiles(ToAbsolutePath(path)) : Directory.EnumerateFiles(ToAbsolutePath(path), filter);
+ public IEnumerable EnumerateDirectories(string path) => Directory.EnumerateDirectories(ToAbsolutePath(path));
public string ToAbsolutePath(string path) => ApiUtil.CombinePaths(_currentDirectory, path);
}
\ No newline at end of file
diff --git a/src/Api/IFileSystem.cs b/src/Api/IFileSystem.cs
index 14a619b5a..fb4f1eba8 100644
--- a/src/Api/IFileSystem.cs
+++ b/src/Api/IFileSystem.cs
@@ -10,7 +10,8 @@ public interface IFileSystem
IFileSystem Duplicate(string currentDirectory);
bool FileExists(string path);
bool DirectoryExists(string path);
- IEnumerable EnumerateDirectory(string path, string filter = null);
+ IEnumerable EnumerateFiles(string path, string filter = null);
+ IEnumerable EnumerateDirectories(string path);
void CreateDirectory(string path);
Stream OpenRead(string path);
Stream OpenWriteTruncate(string path);
diff --git a/src/Api/Json/DictionaryConverterUtil.cs b/src/Api/Json/DictionaryConverterUtil.cs
index 3406d1cee..b7fa6cced 100644
--- a/src/Api/Json/DictionaryConverterUtil.cs
+++ b/src/Api/Json/DictionaryConverterUtil.cs
@@ -27,7 +27,8 @@ public static Dictionary Read(
if (reader.TokenType != JsonTokenType.PropertyName)
throw new JsonException($"Expected property name when reading {typeToConvert}, but was {reader.TokenType}");
- var key = parser(reader.GetString());
+ var keyString = reader.GetString();
+ var key = parser(keyString);
TValue v;
if (valueConverter != null)
diff --git a/src/Api/ReadOnlyFileSystem.cs b/src/Api/ReadOnlyFileSystem.cs
index 3acfbfc2a..d6b48f9c3 100644
--- a/src/Api/ReadOnlyFileSystem.cs
+++ b/src/Api/ReadOnlyFileSystem.cs
@@ -8,8 +8,9 @@ public class ReadOnlyFileSystem : IFileSystem
{
string _currentDirectory;
public ReadOnlyFileSystem(string currentDirectory) => CurrentDirectory = currentDirectory;
- public IEnumerable EnumerateDirectory(string path, string filter = null)
+ public IEnumerable EnumerateFiles(string path, string filter = null)
=> filter == null ? Directory.EnumerateFiles(path) : Directory.EnumerateFiles(path, filter);
+ public IEnumerable EnumerateDirectories(string path) => Directory.EnumerateDirectories(path);
public bool IsReadOnly => true;
public string CurrentDirectory
diff --git a/src/Api/RedirectionFileSystemDecorator.cs b/src/Api/RedirectionFileSystemDecorator.cs
index 2b3741560..8d7627c0f 100644
--- a/src/Api/RedirectionFileSystemDecorator.cs
+++ b/src/Api/RedirectionFileSystemDecorator.cs
@@ -24,7 +24,8 @@ public RedirectionFileSystemDecorator(IFileSystem disk, string prefix, string ta
public IFileSystem Duplicate(string currentDirectory) => _disk.Duplicate(currentDirectory);
public bool FileExists(string path) => _disk.FileExists(ToAbsolutePath(path));
public bool DirectoryExists(string path) => _disk.DirectoryExists(ToAbsolutePath(path));
- public IEnumerable EnumerateDirectory(string path, string filter = null) => _disk.EnumerateDirectory(ToAbsolutePath(path), filter);
+ public IEnumerable EnumerateFiles(string path, string filter = null) => _disk.EnumerateFiles(ToAbsolutePath(path), filter);
+ public IEnumerable EnumerateDirectories(string path) => _disk.EnumerateDirectories(ToAbsolutePath(path));
public void CreateDirectory(string path) => _disk.CreateDirectory(ToAbsolutePath(path));
public Stream OpenRead(string path) => _disk.OpenRead(ToAbsolutePath(path));
public Stream OpenWriteTruncate(string path) => _disk.OpenWriteTruncate(ToAbsolutePath(path));
diff --git a/src/Base/EventSet.cs b/src/Base/EventSet.cs
index d93c01f36..bec080bd4 100644
--- a/src/Base/EventSet.cs
+++ b/src/Base/EventSet.cs
@@ -231,4 +231,6 @@ public enum EventSet : ushort
Khunag2 = 989,
Siobhan2 = 990,
+
+ Empty999 = 999
}
diff --git a/src/Base/EventText.cs b/src/Base/EventText.cs
index c376ea615..10e9e2dee 100644
--- a/src/Base/EventText.cs
+++ b/src/Base/EventText.cs
@@ -231,4 +231,6 @@ public enum EventText : ushort
Khunag2 = 989,
Siobhan2 = 990,
+
+ Empty999 = 999
}
diff --git a/src/Base/FontGfx.cs b/src/Base/FontGfx.cs
index 032061182..7dc8560ba 100644
--- a/src/Base/FontGfx.cs
+++ b/src/Base/FontGfx.cs
@@ -1,3 +1,5 @@
+using UAlbion.Config;
+
namespace UAlbion.Base;
public enum FontGfx : byte
diff --git a/src/Base/ItemGfx.cs b/src/Base/ItemGfx.cs
index 096cb88f8..11b670f0f 100644
--- a/src/Base/ItemGfx.cs
+++ b/src/Base/ItemGfx.cs
@@ -1,4 +1,4 @@
-// ReSharper disable InconsistentNaming
+ // ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
namespace UAlbion.Base;
diff --git a/src/Base/MapText.cs b/src/Base/MapText.cs
index 671c31d48..84ba6c138 100644
--- a/src/Base/MapText.cs
+++ b/src/Base/MapText.cs
@@ -1,5 +1,6 @@
// ReSharper disable InconsistentNaming
// ReSharper disable UnusedMember.Global
+
namespace UAlbion.Base;
public enum MapText : ushort
diff --git a/src/Base/Song.cs b/src/Base/Song.cs
index 2e3ecbd17..ae0f9b49b 100644
--- a/src/Base/Song.cs
+++ b/src/Base/Song.cs
@@ -117,7 +117,7 @@ public enum Song : byte
// Unknown44 = 44,
// Unknown45 = 45,
// ShortOptimisticGlissando = 46,
- Invalid51 = 51,
- Invalid53 = 53,
- Invalid58 = 58,
+ // Invalid51 = 51,
+ // Invalid53 = 53,
+ // Invalid58 = 58,
}
diff --git a/src/Base/Special.cs b/src/Base/Special.cs
index c89e87140..4bc49baa9 100644
--- a/src/Base/Special.cs
+++ b/src/Base/Special.cs
@@ -5,13 +5,16 @@ namespace UAlbion.Base;
public enum Special : ushort
{
SoundBank = 0,
- ItemNames = 1,
- SystemStrings = 2,
- UAlbionStrings = 3,
- Words1 = 4,
- Words2 = 5,
- Words3 = 6,
- DummyObject = 7,
- GameConfig = 8,
- InputConfig = 9,
+ SystemStrings,
+ UAlbionStrings,
+ Words1,
+ Words2,
+ Words3,
+ DummyObject,
+ GameConfig,
+ InputConfig,
+ ItemNamesMultiLang,
+ ItemNamesSingleLang,
+ TiledNpcsLarge,
+ TiledNpcsSmall
}
\ No newline at end of file
diff --git a/src/Config/AssetConfig.cs b/src/Config/AssetConfig.cs
index fc35f6685..b002e6f72 100644
--- a/src/Config/AssetConfig.cs
+++ b/src/Config/AssetConfig.cs
@@ -1,9 +1,5 @@
using System;
using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Text.Json.Serialization;
-using UAlbion.Api;
namespace UAlbion.Config;
@@ -12,274 +8,38 @@ namespace UAlbion.Config;
///
public class AssetConfig : IAssetConfig
{
- ///
- /// A set of aliases for enums to be used as asset ids
- ///
- [JsonIgnore] public IReadOnlyDictionary IdTypes { get; private set; }
- ///
- /// A set of mappings between asset ids and string ids
- ///
- [JsonIgnore] public IReadOnlyDictionary StringMappings { get; private set; }
- ///
- /// A set of aliases for .NET types (deriving from IAssetLoader) to be used for loading assets
- ///
- [JsonIgnore] public IReadOnlyDictionary Loaders { get; private set; }
- ///
- /// A set of aliases for .NET types (deriving from IAssetContainer) to be used for extracting individual assets from container formats.
- ///
- [JsonIgnore] public IReadOnlyDictionary Containers { get; private set; }
- ///
- /// A set of aliases for .NET types (deriving from IAssetPostProcessor) to be used for additional post-load asset processing.
- ///
- [JsonIgnore] public IReadOnlyDictionary PostProcessors { get; private set; }
- ///
- /// A set of supported natural languages that the player can choose to play the game in.
- ///
- [JsonIgnore] public IReadOnlyDictionary Languages { get; private set; }
- ///
- /// The collection of files comprising the mod, paths are relative to the mod directory by default.
- ///
- [JsonIgnore] public IReadOnlyDictionary Files { get; private set; }
-
- ///
- /// The collection of types containing static IVar instances to be registered
- ///
- [JsonInclude, JsonPropertyName("VarTypes")] public List VarTypes { get; private set; } = new();
-
- // Dictionaries containing only the details defined in this particular mod, and not in any that this mod inherits from.
- [JsonInclude, JsonPropertyName("IdTypes")] public Dictionary RawIdTypes { get; private set; } = new();
- [JsonInclude, JsonPropertyName("StringMappings")] public Dictionary RawStringMappings { get; private set; } = new();
- [JsonInclude, JsonPropertyName("Loaders")] public Dictionary RawLoaders { get; private set; } = new();
- [JsonInclude, JsonPropertyName("Containers")] public Dictionary RawContainers { get; private set; } = new();
- [JsonInclude, JsonPropertyName("PostProcessors")] public Dictionary RawPostProcessors { get; private set; } = new();
- [JsonInclude, JsonPropertyName("Languages")] public Dictionary RawLanguages { get; private set; } = new();
- [JsonInclude, JsonPropertyName("Files")] public Dictionary RawFiles { get; private set; } = new();
-
- Dictionary _assetLookup;
- AssetMapping _mapping;
-
- public static AssetConfig Parse(
- byte[] configText,
- AssetConfig parent,
- AssetMapping mapping,
- IJsonUtil jsonUtil)
+ public AssetConfig(string modName, RangeLookup ranges)
{
- if (jsonUtil == null) throw new ArgumentNullException(nameof(jsonUtil));
- var config = jsonUtil.Deserialize(configText);
- if (config == null)
- return null;
-
- if (parent != null)
- {
- config.IdTypes = new FallbackDictionary (config.RawIdTypes, parent.IdTypes);
- config.StringMappings = new FallbackDictionary (config.RawStringMappings, parent.StringMappings);
- config.Loaders = new FallbackDictionary (config.RawLoaders, parent.Loaders);
- config.Containers = new FallbackDictionary (config.RawContainers, parent.Containers);
- config.PostProcessors = new FallbackDictionary (config.RawPostProcessors, parent.PostProcessors);
- config.Languages = new FallbackDictionary(config.RawLanguages, parent.Languages);
- config.Files = new FallbackDictionary (config.RawFiles, parent.Files);
- }
- else
- {
- config.IdTypes = config.RawIdTypes;
- config.StringMappings = config.RawStringMappings;
- config.Loaders = config.RawLoaders;
- config.Containers = config.RawContainers;
- config.PostProcessors = config.RawPostProcessors;
- config.Languages = config.RawLanguages;
- config.Files = config.RawFiles;
- }
-
- config.PostLoad(mapping);
- return config;
+ ModName = modName;
+ Ranges = ranges ?? throw new ArgumentNullException(nameof(ranges));
}
- public static AssetConfig Load(
- string configPath,
- AssetConfig parent,
- AssetMapping mapping,
- IFileSystem disk,
- IJsonUtil jsonUtil)
- {
- if (disk == null) throw new ArgumentNullException(nameof(disk));
- if (jsonUtil == null) throw new ArgumentNullException(nameof(jsonUtil));
- if (!disk.FileExists(configPath))
- throw new FileNotFoundException($"Could not open asset config from {configPath}");
-
- var configText = disk.ReadAllBytes(configPath);
- var config = Parse(configText, parent, mapping, jsonUtil);
- if(config == null)
- throw new FileLoadException($"Could not load asset config from \"{configPath}\"");
- return config;
- }
-
- public void Save(string configPath, IFileSystem disk, IJsonUtil jsonUtil)
- {
- if (disk == null) throw new ArgumentNullException(nameof(disk));
- if (jsonUtil == null) throw new ArgumentNullException(nameof(jsonUtil));
- var json = jsonUtil.Serialize(this);
- disk.WriteAllText(configPath, json);
- }
+ public string ModName { get; } // The mod name
- public AssetInfo[] GetAssetInfo(AssetId id)
- => _assetLookup.TryGetValue(id, out var info)
- ? info
- : Array.Empty();
+ ///
+ /// The collection of asset ranges that are provided by the mod.
+ ///
+ public RangeLookup Ranges { get; }
- void PostLoad(AssetMapping mapping)
+ public IEnumerable GetAssetInfo(AssetId id)
{
- _mapping = mapping ?? throw new ArgumentNullException(nameof(mapping));
- foreach (var kvp in IdTypes)
- kvp.Value.Alias = kvp.Key;
-
- foreach (var kvp in Languages)
- kvp.Value.Id = kvp.Key;
+ var range = Ranges.TryFindAssetRangeInfo(id);
+ if (range == null)
+ yield break;
- foreach (var kvp in Files)
+ if (range.Files == null || range.Files.Count == 0)
{
- kvp.Value.Config = this;
- int index = kvp.Key.IndexOf('#', StringComparison.Ordinal);
- kvp.Value.Filename = index == -1 ? kvp.Key : kvp.Key[..index];
- if (index != -1)
- kvp.Value.Sha256Hash = kvp.Key[(index + 1)..];
-
- // Resolve type aliases
- if (kvp.Value.Loader != null && Loaders.TryGetValue(kvp.Value.Loader, out var typeName)) kvp.Value.Loader = typeName;
- if (kvp.Value.Container != null && Containers.TryGetValue(kvp.Value.Container, out typeName)) kvp.Value.Container = typeName;
- if (kvp.Value.Post != null && PostProcessors.TryGetValue(kvp.Value.Post, out typeName)) kvp.Value.Post = typeName;
-
- foreach (var asset in kvp.Value.Map)
- {
- asset.Value.Index = asset.Key;
- asset.Value.File = kvp.Value;
- }
+ yield return range.Node;
}
- }
-
- public delegate IList<(int RangeStart, int RangeLength)> GetSubItemCountMethod(AssetFileInfo info);
- public delegate byte[] ReadAllBytesMethod(string path);
- public void PopulateAssetIds(
- IJsonUtil jsonUtil,
- GetSubItemCountMethod getSubItemCountForFile,
- ReadAllBytesMethod readAllBytesFunc)
- {
- if (jsonUtil == null) throw new ArgumentNullException(nameof(jsonUtil));
-
- var temp = new Dictionary>();
- foreach (var file in Files)
+ else
{
- file.Value.PopulateAssetIds(jsonUtil, getSubItemCountForFile, readAllBytesFunc);
-
- foreach (var asset in file.Value.Map.Values)
+ foreach (var file in range.Files)
{
- if (!temp.TryGetValue(asset.AssetId, out var list))
- {
- list = new List();
- temp[asset.AssetId] = list;
- }
-
- list.Add(asset);
+ if (file.Map != null && file.Map.TryGetValue(id, out var assetInfo))
+ yield return assetInfo.Node;
+ else
+ yield return file.Node;
}
}
-
- _assetLookup = temp.ToDictionary(x => x.Key, x => x.Value.ToArray());
- }
-
- public void RegisterStringRedirects(AssetMapping mapping)
- {
- if (mapping == null) throw new ArgumentNullException(nameof(mapping));
- foreach (var kvp in StringMappings)
- {
- var (type, range) = SplitId(kvp.Key, '.');
- var enumType = ResolveIdType(type);
- var (targetStr, offsetStr) = SplitId(kvp.Value, ':');
- if (!int.TryParse(offsetStr, out var offset))
- offset = 0;
-
- var target = ResolveId(targetStr);
- var (min, max) = ParseRange(range);
- mapping.RegisterStringRedirect(enumType, target, min, max, offset);
- }
- }
-
- static IEnumerable Validate(IEnumerable types, string category, string assetConfigPath)
- {
- foreach (var type in types)
- {
- var enumType = Type.GetType(type);
- if (enumType == null)
- yield return $"Could not load {category} type \"{type}\" defined in \"{assetConfigPath}\"";
- }
- }
-
- public void Validate(string assetConfigPath)
- {
- var errors = new List();
- errors.AddRange(Validate(IdTypes.Values.Select(x => x.EnumType), "enum", assetConfigPath));
- errors.AddRange(Validate(Loaders.Values, "loader", assetConfigPath));
- errors.AddRange(Validate(Containers.Values, "container", assetConfigPath));
- errors.AddRange(Validate(PostProcessors.Values, "post-processor", assetConfigPath));
- if (errors.Count > 0)
- {
- var combined = string.Join(Environment.NewLine, errors);
- throw new InvalidOperationException(combined);
- }
- }
-
- static (int, int) ParseRange(string s)
- {
- if (s == "*")
- return (0, int.MaxValue);
-
- int index = s.IndexOf('-', StringComparison.Ordinal);
- if (index == -1)
- {
- if(!int.TryParse(s, out var asInt))
- throw new FormatException($"Invalid id range \"{s}\"");
-
- return (asInt, asInt);
- }
-
- var from = s[..index];
- var to = s[(index + 1)..];
- if(!int.TryParse(from, out var min))
- throw new FormatException($"Invalid id range \"{s}\"");
-
- if(!int.TryParse(to, out var max))
- throw new FormatException($"Invalid id range \"{s}\"");
-
- return (min, max);
- }
-
- static (string, string) SplitId(string id, char separator)
- {
- int index = id.IndexOf(separator, StringComparison.Ordinal);
- if (index == -1)
- return (id, null);
-
- var type = id[..index];
- var val = id[(index + 1)..];
- return (type, val);
- }
-
- Type ResolveIdType(string type)
- {
- if (!IdTypes.TryGetValue(type, out var assetType))
- throw new FormatException($"Could not resolve asset id alias \"{type}\"");
-
- var enumType = Type.GetType(assetType.EnumType);
- if (enumType == null)
- throw new FormatException($"Could not resolve type \"{assetType.EnumType}\" (alias \"{assetType.Alias}\")");
-
- return enumType;
- }
-
- internal AssetId ResolveId(string id)
- {
- var (type, val) = SplitId(id, '.');
- if (val == null)
- throw new FormatException("Asset IDs should consist of an alias type and value, separated by a '.' character");
- var enumType = ResolveIdType(type);
- return _mapping.EnumToId(enumType, val);
}
-}
+}
\ No newline at end of file
diff --git a/src/Config/AssetConfigLoadException.cs b/src/Config/AssetConfigLoadException.cs
new file mode 100644
index 000000000..f902fd709
--- /dev/null
+++ b/src/Config/AssetConfigLoadException.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Runtime.Serialization;
+
+namespace UAlbion.Config;
+
+[Serializable]
+public class AssetConfigLoadException : Exception
+{
+ public AssetConfigLoadException() { }
+ public AssetConfigLoadException(string message) : base(message) { }
+ public AssetConfigLoadException(string message, Exception exception) : base(message, exception) { }
+ protected AssetConfigLoadException(SerializationInfo info, StreamingContext context) : base(info, context) { }
+}
\ No newline at end of file
diff --git a/src/Config/AssetConfigLoader.cs b/src/Config/AssetConfigLoader.cs
new file mode 100644
index 000000000..da6d55a6b
--- /dev/null
+++ b/src/Config/AssetConfigLoader.cs
@@ -0,0 +1,167 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using UAlbion.Api;
+using UAlbion.Config.Properties;
+
+namespace UAlbion.Config;
+
+public class AssetConfigLoader
+{
+ readonly IJsonUtil _jsonUtil;
+ readonly IFileSystem _disk;
+ readonly IPathResolver _pathResolver;
+ readonly TypeConfig _typeConfig;
+
+ public AssetConfigLoader(
+ IFileSystem disk,
+ IJsonUtil jsonUtil,
+ IPathResolver pathResolver,
+ TypeConfig typeConfig)
+ {
+ _jsonUtil = jsonUtil;
+ _disk = disk;
+ _pathResolver = pathResolver;
+ _typeConfig = typeConfig;
+ }
+
+ public AssetConfig Load(string configPath, string modName, AssetConfig parent)
+ {
+ if (!_disk.FileExists(configPath))
+ throw new FileNotFoundException($"Could not open asset config from {configPath}");
+
+ var configText = _disk.ReadAllBytes(configPath);
+ try
+ {
+ var config = Parse(configText, modName, parent);
+ if (config == null)
+ throw new FileLoadException($"Could not load asset config from \"{configPath}\"");
+
+ return config;
+ }
+ catch (Exception ex)
+ {
+ var message = $@"Error loading asset config ""{configPath}"":
+ {ex.Message}";
+ throw new AssetConfigLoadException(message, ex);
+ }
+ }
+
+ public AssetConfig Parse(byte[] configText, string modName, AssetConfig parent)
+ {
+ var raw = _jsonUtil.Deserialize>(configText);
+ if (raw == null)
+ return null;
+
+ var ranges = BuildRanges(raw, parent);
+ var assetConfig = new AssetConfig(modName, ranges);
+ return assetConfig;
+ }
+
+ RangeLookup BuildRanges(Dictionary raw, AssetConfig parent)
+ {
+ var rangeInfos = new List();
+ foreach (var kvp in raw)
+ rangeInfos.Add(BuildRange(kvp.Key, kvp.Value));
+
+ return new RangeLookup(parent?.Ranges, rangeInfos);
+ }
+
+ AssetRangeInfo BuildRange(string key, LoadAssetRangeInfo load)
+ {
+ AssetRange range = default;
+ try
+ {
+ range = _typeConfig.ParseIdRange(key);
+ var rangeInfo = new AssetRangeInfo(range, load.Sequence ?? int.MaxValue);
+
+ if (load.Properties != null)
+ rangeInfo.Node.SetProperties(load.Properties, _typeConfig, "range", range);
+
+ foreach (var fileKvp in load.Files)
+ rangeInfo.Files.Add(BuildFile(rangeInfo, fileKvp.Key, fileKvp.Value));
+
+ return rangeInfo;
+ }
+ catch (Exception ex)
+ {
+ var message = $@"Error loading info for range {key} ({range}):
+ {ex.Message}";
+ throw new AssetConfigLoadException(message, ex);
+ }
+ }
+
+ AssetFileInfo BuildFile(AssetRangeInfo rangeInfo, string key, LoadAssetFileInfo load)
+ {
+ try
+ {
+ int index = key.IndexOf('#', StringComparison.Ordinal);
+ var filename = index == -1 ? key : key[..index];
+ var hash = index != -1
+ ? key[(index + 1)..]
+ : null;
+
+ var fileInfo = new AssetFileInfo(rangeInfo);
+
+ fileInfo.Node.SetProperty(AssetProps.Filename, filename);
+ if (hash != null)
+ fileInfo.Node.SetProperty(AssetProps.Sha256Hash, hash);
+
+ if (load.Properties != null) // Do this before loading any asset mapping or the loader/container might not be set
+ fileInfo.Node.SetProperties(load.Properties, _typeConfig, "file", key);
+
+ if (load.Map != null)
+ {
+ foreach (var kvp in load.Map)
+ {
+ var info = BuildAssetInfo(_typeConfig, kvp.Key, fileInfo, kvp.Value);
+ fileInfo.Map.Add(info.Id, info);
+ }
+ }
+
+ if (load.MapFile != null)
+ {
+ var fullPath = _pathResolver.ResolvePath(load.MapFile);
+ if (!_disk.FileExists(fullPath))
+ throw new FileNotFoundException($"Could not find mapping file \"{load.MapFile}\" ({fullPath}) specified in mod \"{_typeConfig.ModName}\"");
+
+ var mappingJson = _disk.ReadAllBytes(fullPath);
+ var mapping = _jsonUtil.Deserialize>(mappingJson);
+ foreach (var kvp in mapping)
+ {
+ var info = BuildAssetInfo(_typeConfig, kvp.Key, fileInfo, kvp.Value);
+ fileInfo.Map.Add(info.Id, info);
+ }
+ }
+
+ return fileInfo;
+ }
+ catch (Exception ex)
+ {
+ var message = $@"Error loading info for file {key}:
+ {ex.Message}";
+ throw new AssetConfigLoadException(message, ex);
+ }
+ }
+
+ static AssetInfo BuildAssetInfo(TypeConfig typeConfig, string key, AssetFileInfo parent, LoadAssetInfo load)
+ {
+ AssetId id = AssetId.None;
+ try
+ {
+ id = typeConfig.ResolveId(key);
+ var result = new AssetInfo(id, parent);
+
+ if (load.Properties != null)
+ result.Node.SetProperties(load.Properties, typeConfig, "asset", id);
+
+ return result;
+ }
+ catch (Exception ex)
+ {
+ var message = $@"Error loading info for asset {key} ({id}):
+ {ex.Message}";
+ throw new AssetConfigLoadException(message, ex);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Config/AssetFileInfo.cs b/src/Config/AssetFileInfo.cs
index 279f4839d..e180fa5f4 100644
--- a/src/Config/AssetFileInfo.cs
+++ b/src/Config/AssetFileInfo.cs
@@ -1,219 +1,20 @@
using System;
using System.Collections.Generic;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using UAlbion.Api;
namespace UAlbion.Config;
-///
-/// Represents all information about a given file on disk that is required by the asset loading / saving system.
-///
public class AssetFileInfo
{
- /// The filename, relative to the mod directory
- [JsonIgnore] public string Filename { get; set; } // Just mirrors the dictionary key
+ public AssetRangeInfo Range { get; }
+ public AssetNode Node { get; }
- /// The first 32-bits of the file's SHA256 hash (if specified)
- [JsonIgnore] public string Sha256Hash { get; set; }
-
- /// The alias of the IAssetContainer to use for loading the file
- public string Container { get; set; }
-
- /// The alias of the IAssetLoad to use for loading assets in this file
- public string Loader { get; set; }
- /// The alias of the IAssetPostProcessor to run on assets in this file after loading
- public string Post { get; set; }
-
- /// The maximum container-index to load from this file.
- [JsonInclude] public int? Max { get; private set; }
-
- /// The mapping from container indices to assets
- [JsonInclude] public Dictionary Map { get; private set; } = new();
-
- /// Path to an optional JSON file containing the mapping (for cases where the mapping is complicated and would clutter the main assets.json file)
- public string MapFile { get; set; }
-
- ///
- /// The set of additional properties that relate to assets in the file
- ///
- [JsonInclude]
- [JsonExtensionData]
- public Dictionary Properties { get; private set; }
-
- ///
- /// The default width, in pixels, of frames in images inside the file
- ///
- public int? Width // For sprites only
- {
- get => Get(AssetProperty.Width, (int?)null);
- set => Set(AssetProperty.Width, value);
- }
-
- ///
- /// The default height, in pixels, of frames in images inside the file
- ///
- public int? Height // For sprites only
- {
- get => Get(AssetProperty.Height, (int?)null);
- set => Set(AssetProperty.Height, value);
- }
-
- internal AssetConfig Config { get; set; }
-
- public override string ToString() => $"AssetFile: {Filename}{(string.IsNullOrEmpty(Sha256Hash) ? "" : $"#{Sha256Hash}")} ({Map.Count})";
-
- ///
- /// Retrieve a property's value by name
- ///
- /// The type to interpret the property value as
- /// The property name
- /// The value to use if the property does not exist, or cannot be parsed as the requested type
- /// The parsed value, or defaultValue if no value existed or could be parsed.
- public T Get(string property, T defaultValue)
- {
- if (Properties == null || !Properties.TryGetValue(property, out var token))
- return defaultValue;
-
- if (token is JsonElement elem)
- {
- if (typeof(T) == typeof(string)) return (T)(object)elem.GetString();
- if (typeof(T) == typeof(int)) return (T)(object)elem.GetInt32();
- if (typeof(T) == typeof(long)) return (T)(object)elem.GetInt64();
- if (typeof(T) == typeof(bool)) return (T)(object)elem.GetBoolean();
- }
- //if (token is double asDouble)
- //{
- // if (typeof(T) == typeof(int))
- // return (T)(object)Convert.ToInt32(asDouble);
-
- // if (typeof(T) == typeof(int?))
- // return (T)(object)Convert.ToInt32(asDouble);
- //}
-
- if (typeof(T).IsAssignableFrom(typeof(AssetId)))
- {
- var id = (string)token;
- return CastHelper.Cast(ResolveId(id));
- }
-
- if (typeof(T).IsEnum)
- return (T)Enum.Parse(typeof(T), (string)token);
-
- return (T)token;
- }
-
- ///
- /// Set's a property by name
- ///
- /// The type of value to set
- /// The property name
- /// The value to set the property to
- public void Set(string property, T value)
- {
- if (value == null)
- {
- if (Properties == null)
- return;
-
- Properties.Remove(property);
- if (Properties.Count == 0)
- Properties = null;
- }
- else
- {
- Properties ??= new Dictionary();
- Properties[property] = value;
- }
- }
-
- void MergeMapping(Dictionary mapping)
+ public AssetFileInfo(AssetRangeInfo range)
{
- foreach (var kvp in mapping)
- {
- if (Map.TryGetValue(kvp.Key, out var info))
- {
- kvp.Value.File = this;
- info.Id ??= kvp.Value.Id;
- if (kvp.Value.Properties != null)
- foreach (var prop in kvp.Value.Properties)
- info.Set(prop.Key, prop.Value);
- }
- else
- {
- info = kvp.Value;
- Map[kvp.Key] = info;
- }
-
- info.Index = kvp.Key;
- info.File = this;
- }
+ Range = range ?? throw new ArgumentNullException(nameof(range));
+ Node = new AssetNode(range.Node);
}
- ///
- /// Uses the given callbacks to determine which assets are actually present in the file in the current file system.
- ///
- /// The JSON parsing utility
- /// A method which takes an AssetFileInfo and returns the list of container id ranges (offsets + lengths) that the file contains.
- /// A method which takes a relative filename and returns the file contents as a byte array
- ///
- ///
- public void PopulateAssetIds(
- IJsonUtil jsonUtil,
- AssetConfig.GetSubItemCountMethod getSubItemCountForFile,
- AssetConfig.ReadAllBytesMethod readAllBytesFunc)
- {
- if (jsonUtil == null) throw new ArgumentNullException(nameof(jsonUtil));
- if (getSubItemCountForFile == null) throw new ArgumentNullException(nameof(getSubItemCountForFile));
- if (readAllBytesFunc == null) throw new ArgumentNullException(nameof(readAllBytesFunc));
-
- if (!string.IsNullOrEmpty(MapFile))
- {
- var mappingJson = readAllBytesFunc(MapFile);
- var mapping = jsonUtil.Deserialize>(mappingJson);
- MergeMapping(mapping);
- MapFile = null;
- }
-
- AssetInfo last = null;
- var ranges = getSubItemCountForFile(this);
- if (ranges == null)
- return;
-
- foreach (var asset in Map.Values)
- {
- last ??= asset; // Let last start off as the first mapped info, in case the range doesn't overlap with the mapped ids.
- if (asset.Id == null || !asset.AssetId.IsNone) continue;
- asset.AssetId = ResolveId(asset.Id);
- }
-
- foreach (var range in ranges)
- {
- for (int i = range.RangeStart; i < range.RangeStart + range.RangeLength; i++)
- {
- if (last != null && i < last.Index) // Don't add any assets below the mapped range
- break;
-
- if (!Map.TryGetValue(i, out var asset))
- {
- if (last == null)
- continue;
-
- asset = new AssetInfo();
- Map[i] = asset;
- }
-
- if(last == null && asset.Id == null)
- throw new FormatException("The first sub-item in a file's asset mapping must have its Id property set");
-
- asset.File = this;
- asset.Index = i;
- if (asset.Id == null && last != null)
- asset.AssetId = new AssetId(last.AssetId.Type, i - last.Index + last.AssetId.Id);
- last = asset;
- }
- }
- }
+ public Dictionary Map { get; } = new();
- internal AssetId ResolveId(string id) => Config.ResolveId(id);
+ public override string ToString() => $"AssetFile: {Node.Filename}{(string.IsNullOrEmpty(Node.Sha256Hash) ? "" : $"#{Node.Sha256Hash}")}";
}
\ No newline at end of file
diff --git a/src/Config/AssetInfo.cs b/src/Config/AssetInfo.cs
index 996e93d71..c7ba6083a 100644
--- a/src/Config/AssetInfo.cs
+++ b/src/Config/AssetInfo.cs
@@ -1,98 +1,17 @@
using System;
-using System.Collections.Generic;
-using System.Text.Json;
-using System.Text.Json.Serialization;
-using UAlbion.Api;
-#pragma warning disable CA2227 // Collection properties should be read only
namespace UAlbion.Config;
public class AssetInfo
{
- public string Id { get; set; } // Id of this asset in the mapped enum type.
- [JsonInclude, JsonExtensionData] public Dictionary Properties { get; private set; } // Supported: string, bool, int
- [JsonIgnore] public AssetId AssetId { get; set; }
- [JsonIgnore] public int Index { get; set; } // Sub-asset offset in the container file (or 0 if not inside a container)
- [JsonIgnore] public AssetFileInfo File { get; set; }
+ public AssetId Id { get; }
+ public AssetFileInfo File { get; }
+ public AssetNode Node { get; }
- public int Width // For sprites only
+ public AssetInfo(AssetId id, AssetFileInfo file)
{
- get => Get(AssetProperty.Width, File?.Width ?? 0);
- set => Set(AssetProperty.Width, value == 0 ? (object)null : value);
+ Id = id;
+ File = file ?? throw new ArgumentNullException(nameof(file));
+ Node = new AssetNode(file.Node);
}
-
- public int Height // For sprites only
- {
- get => Get(AssetProperty.Height, File?.Height ?? 0);
- set => Set(AssetProperty.Height, value == 0 ? (object)null : value);
- }
-
- public AssetInfo() { }
- public AssetInfo(Dictionary properties)
- {
- if (properties == null) throw new ArgumentNullException(nameof(properties));
- foreach (var property in properties)
- Set(property.Key, property.Value);
- }
-
- public override string ToString()
- {
- var hashPart = (string.IsNullOrEmpty(File.Sha256Hash) ? "" : $"#{File.Sha256Hash}");
- return $"I:{AssetId} ({File.Filename}{hashPart}.{Index})";
- }
-
- public AssetPathPattern GetPattern(string property, string defaultValue)
- {
- var pattern = Get(property, defaultValue);
- return AssetPathPattern.Build(pattern);
- }
-
- public T Get(string property, T defaultValue)
- {
- if (Properties == null || !Properties.TryGetValue(property, out var token))
- return File != null ? File.Get(property, defaultValue) : defaultValue;
-
- if (token is JsonElement elem)
- {
- if (typeof(T) == typeof(string)) return (T)(object)elem.GetString();
- if (typeof(T) == typeof(int)) return (T)(object)elem.GetInt32();
- if (typeof(T) == typeof(long)) return (T)(object)elem.GetInt64();
- if (typeof(T) == typeof(bool)) return (T)(object)elem.GetBoolean();
-
- if (typeof(T).IsAssignableTo(typeof(IAssetId)))
- {
- var id = elem.GetString();
- return CastHelper.Cast(File.ResolveId(id));
- }
-
- if (typeof(T).IsEnum)
- return (T)Enum.Parse(typeof(T), elem.GetString() ?? "");
- }
- //else if (token is double asDouble)
- //{
- // if (typeof(T) == typeof(int)) return (T)(object)Convert.ToInt32(asDouble);
- // if (typeof(T) == typeof(int?)) return (T)(object)Convert.ToInt32(asDouble);
- //}
-
- return (T)token;
- }
-
- public void Set(string property, T value)
- {
- if (value == null)
- {
- if (Properties == null)
- return;
-
- Properties.Remove(property);
- if (Properties.Count == 0)
- Properties = null;
- }
- else
- {
- Properties ??= new Dictionary();
- Properties[property] = value;
- }
- }
-}
-#pragma warning restore CA2227 // Collection properties should be read only
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/src/Config/AssetLoadContext.cs b/src/Config/AssetLoadContext.cs
new file mode 100644
index 000000000..9d178ce19
--- /dev/null
+++ b/src/Config/AssetLoadContext.cs
@@ -0,0 +1,39 @@
+using UAlbion.Api;
+using UAlbion.Config.Properties;
+
+namespace UAlbion.Config;
+
+public record AssetLoadContext(
+ AssetId AssetId,
+ AssetNode Node,
+ ModContext ModContext,
+ string Language = null)
+{
+ public T GetProperty(IAssetProperty assetProperty)
+ => Node.GetProperty(assetProperty);
+ public T GetProperty(IAssetProperty assetProperty, T defaultValue)
+ => Node.GetProperty(assetProperty, defaultValue);
+ public void SetProperty(IAssetProperty assetProperty, T value)
+ => Node.SetProperty(assetProperty, value);
+
+ public int Index => Node.GetIndex(AssetId);
+ public string Filename => Node.Filename;
+ public string Sha256Hash => Node.Sha256Hash;
+ public string ModName => ModContext.ModName;
+ public IJsonUtil Json => ModContext.Json;
+ public IFileSystem Disk => ModContext.Disk;
+ public AssetMapping Mapping => ModContext.Mapping;
+ public AssetPath BuildAssetPath(int subAsset = 0, string overrideName = null)
+ => new(AssetId, subAsset, Node.GetProperty(AssetProps.Palette).Id, overrideName);
+
+ // Common loader / container specific properties
+ public int Width => Node.Width; // The default width, in pixels, of frames in images inside the file. For sprites only.
+ public int Height => Node.Height; // The default height, in pixels, of frames in images inside the file. For sprites only.
+ public AssetId PaletteId => Node.PaletteId; //for providing context when exporting 8-bit images to true-colour PNGs
+
+ public override string ToString()
+ {
+ var hashPart = (string.IsNullOrEmpty(Sha256Hash) ? "" : $"#{Sha256Hash}");
+ return $"I:{AssetId} ({Filename}{hashPart}.{Index})";
+ }
+}
\ No newline at end of file
diff --git a/src/Config/AssetMapping.cs b/src/Config/AssetMapping.cs
index d6d8ffabe..7287303f5 100644
--- a/src/Config/AssetMapping.cs
+++ b/src/Config/AssetMapping.cs
@@ -46,16 +46,13 @@ static T GetAttribute(object x) where T : Attribute
// Always built dynamically based on the current set of active mods
public static AssetMapping Global => GlobalIsThreadLocal ? ThreadLocalGlobal.Value : TrueGlobal;
public static bool GlobalIsThreadLocal { get; set; } // Set to true for unit tests.
- readonly Dictionary _nameCache = new();
+ readonly Dictionary _idToNameCache = new();
readonly struct Range
{
- [JsonConstructor]
- public Range(int from, int to) { From = from; To = to; }
- [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
- public int From { get; }
- [JsonIgnore(Condition = JsonIgnoreCondition.Never)]
- public int To { get; }
+ [JsonConstructor] public Range(int from, int to) { From = from; To = to; }
+ [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public int From { get; }
+ [JsonIgnore(Condition = JsonIgnoreCondition.Never)] public int To { get; }
public override string ToString() => $"{From}:{To}";
}
@@ -122,8 +119,7 @@ public EnumInfo(string typeString, AssetType assetType, int? lastMax)
.ToArray(); // Keyed by AssetType, a byte enum
readonly Dictionary _byEnumType = new();
- readonly Dictionary> _byName = new();
- readonly Dictionary _stringLookup = new();
+ readonly Dictionary> _byName = new();
public AssetMapping() { }
AssetMapping(Dictionary byEnumType)
@@ -217,7 +213,7 @@ public string IdToName(AssetId id)
if (id == AssetId.None) // Special case to keep things tidy
return "None";
- if (_nameCache.TryGetValue(id, out var name))
+ if (_idToNameCache.TryGetValue(id, out var name))
return name;
var (enumType, enumValue) = IdToEnum(id);
@@ -233,7 +229,7 @@ public string IdToName(AssetId id)
: enumType.Name + "." + enumName;
}
- _nameCache[id] = name;
+ _idToNameCache[id] = name;
return name;
}
@@ -263,7 +259,7 @@ public AssetId EnumToId(T id) where T : unmanaged, Enum
}
}
- public AssetId EnumToId((Type, int) value) => EnumToId(value.Item1, value.Item2);
+ public AssetId EnumToId((Type Type, int Value) value) => EnumToId(value.Type, value.Value);
public AssetId EnumToId(Type enumType, int enumValue)
{
if (enumType == null)
@@ -297,16 +293,16 @@ public AssetId EnumToId(Type enumType, string value)
throw new FormatException($"Could not parse a value of type \"{enumType}\", as it has not been registered in the asset mapping");
if (int.TryParse(value, out int intValue))
- return new AssetId(enumInfo.AssetType, intValue);
+ return new AssetId(enumInfo.AssetType, enumInfo.Offset + intValue);
if (!_byName.TryGetValue(value.ToUpperInvariant(), out var matches))
throw new FormatException($"Could not parse id \"{value}\" as \"{enumType}\": no such value");
- var match = matches.FirstOrDefault(x => x.Item1 == enumInfo);
+ var match = matches.FirstOrDefault(x => x.Info == enumInfo);
if (match == (null, 0))
throw new FormatException($"Could not parse id \"{value}\" as \"{enumType}\": no such value");
- return new AssetId(match.Item1.AssetType, match.Item2);
+ return new AssetId(match.Info.AssetType, match.Value);
}
public AssetMapping Clear()
@@ -358,26 +354,13 @@ void RegisterNames(EnumInfo info)
var key = value.Item1.ToUpperInvariant();
if (!_byName.TryGetValue(key, out var entries))
{
- entries = new List<(EnumInfo, int)>();
+ entries = new List<(EnumInfo Info, int Value)>();
_byName[key] = entries;
}
entries.Add((info, value.Item2 + info.Offset));
}
}
- public AssetMapping RegisterStringRedirect(Type enumType, AssetId target, int min, int max, int offset)
- {
- foreach (var id in EnumerateAssetsOfType(enumType))
- {
- var (_, numeric) = IdToEnum(id);
- if (numeric < min || numeric > max)
- continue;
-
- _stringLookup[id] = (target, (ushort)(offset + numeric - min));
- }
- return this;
- }
-
public void ConsistencyCheck()
{
(string, string) Describe(AssetType assetType)
@@ -421,11 +404,6 @@ public void ConsistencyCheck()
}
}
- public (AssetId, ushort)? TextIdToStringId(AssetId id)
- => _stringLookup.ContainsKey(id)
- ? _stringLookup[id]
- : ((AssetId, ushort)?)null;
-
public IEnumerable EnumerateAssetsOfType(AssetType type)
{
foreach (var info in _byAssetType[(byte)type]) // Nested for-loops go brrr
@@ -475,9 +453,6 @@ public void MergeFrom(AssetMapping other)
if (!_byEnumType.ContainsKey(info.EnumType))
RegisterAssetType(info.EnumTypeString, info.AssetType);
}
-
- foreach (var redirect in other._stringLookup)
- _stringLookup[redirect.Key] = redirect.Value;
}
public AssetId Parse(string s, AssetType[] validTypes) // pass null for validTypes to allow any type
@@ -499,17 +474,17 @@ public void MergeFrom(AssetMapping other)
: ParseNumeric(s, typeName, valueName, validTypes);
}
- static AssetId ParseTextual(string s, string typeName, IList<(EnumInfo, int)> matches, AssetType[] validTypes)
+ static AssetId ParseTextual(string s, string typeName, IList<(EnumInfo Info, int Value)> matches, AssetType[] validTypes)
{
AssetId result = new AssetId(AssetType.Unknown);
foreach (var match in matches)
{
- if (validTypes != null && !validTypes.Contains(match.Item1.AssetType))
+ if (validTypes != null && !validTypes.Contains(match.Info.AssetType))
continue;
if (!string.IsNullOrEmpty(typeName)
- && !match.Item1.EnumType.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase)
- && !match.Item1.AssetType.ToString().Equals(typeName, StringComparison.OrdinalIgnoreCase))
+ && !match.Info.EnumType.Name.Equals(typeName, StringComparison.OrdinalIgnoreCase)
+ && !match.Info.AssetType.ToString().Equals(typeName, StringComparison.OrdinalIgnoreCase))
{
continue;
}
@@ -518,13 +493,13 @@ static AssetId ParseTextual(string s, string typeName, IList<(EnumInfo, int)> ma
{
var candidates = string.Join(", ",
matches
- .Where(x => validTypes == null || validTypes.Contains(x.Item1.AssetType))
- .Select(x => x.Item1.EnumType.Name));
+ .Where(x => validTypes == null || validTypes.Contains(x.Info.AssetType))
+ .Select(x => x.Info.EnumType.Name));
throw new FormatException($"Could not unambiguously parse \"{s}\" as an asset id. Candidate types: {candidates}");
}
- result = new AssetId(match.Item1.AssetType, match.Item2);
+ result = new AssetId(match.Info.AssetType, match.Value);
}
if (result.Type == AssetType.Unknown)
@@ -562,4 +537,14 @@ static AssetId ParseTextual(string s, string typeName, IList<(EnumInfo, int)> ma
return result;
}
+
+ public AssetId MaxIdForType(Type type)
+ {
+ if (type == null) throw new ArgumentNullException(nameof(type));
+ if (!_byEnumType.TryGetValue(type, out var result))
+ throw new FormatException($"Could not get max id for unmapped type \"{type.FullName}\"");
+
+ var max = result.EnumMax;
+ return EnumToId(type, max);
+ }
}
\ No newline at end of file
diff --git a/src/Config/AssetNode.cs b/src/Config/AssetNode.cs
new file mode 100644
index 000000000..c2423d896
--- /dev/null
+++ b/src/Config/AssetNode.cs
@@ -0,0 +1,151 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using UAlbion.Config.Properties;
+
+namespace UAlbion.Config;
+
+public class AssetNode
+{
+ readonly AssetId _startOfRangeId;
+ readonly AssetNode _parent;
+ bool _frozen;
+
+ public AssetNode(AssetId startOfRangeId) => _startOfRangeId = startOfRangeId;
+ public AssetNode(AssetNode parent)
+ {
+ _parent = parent ?? throw new ArgumentNullException(nameof(parent));
+ _startOfRangeId = parent._startOfRangeId;
+ }
+
+ ///
+ /// The set of additional properties that relate to assets in the file
+ ///
+ [JsonInclude]
+ [JsonExtensionData]
+ public Dictionary Properties { get; private set; }
+
+ public int GetIndex(AssetId id)
+ {
+ if (id.Type != _startOfRangeId.Type)
+ throw new InvalidOperationException($"AssetId ({id}) of incorrect type passed to AssetRangeInfo.GetIndex (range {this})");
+
+ return id.Id - _startOfRangeId.Id;
+ }
+
+ ///
+ /// Retrieve a property's value
+ ///
+ /// The type to interpret the property value as
+ /// The property to retrieve
+ /// The parsed value, or defaultValue if no value existed or could be parsed.
+ public T GetProperty(IAssetProperty assetProperty)
+ {
+ if (assetProperty == null) throw new ArgumentNullException(nameof(assetProperty));
+ return GetProperty(assetProperty, assetProperty.DefaultValue);
+ }
+
+ ///
+ /// Retrieve a property's value
+ ///
+ /// The type to interpret the property value as
+ /// The property to retrieve
+ /// The default value to use when the property is not set
+ /// The parsed value, or defaultValue if no value existed or could be parsed.
+ public T GetProperty(IAssetProperty assetProperty, T defaultValue)
+ {
+ if (assetProperty == null) throw new ArgumentNullException(nameof(assetProperty));
+ var name = assetProperty.Name;
+
+ object token = null;
+ Properties?.TryGetValue(name, out token);
+
+ if (token == null)
+ {
+ return _parent != null
+ ? _parent.GetProperty(assetProperty)
+ : defaultValue;
+ }
+
+ return (T)token;
+ }
+
+ ///
+ /// Set's a property by name
+ ///
+ /// The property
+ /// The value to set the property to
+ /// The type config
+ public void SetProperty(IAssetProperty assetProperty, JsonElement value, TypeConfig typeConfig)
+ {
+ if (assetProperty == null) throw new ArgumentNullException(nameof(assetProperty));
+ if (_frozen) throw new InvalidOperationException("Tried to modify asset node after it was frozen. Asset nodes are immutable after mods have been loaded.");
+
+ try
+ {
+ Properties ??= new Dictionary();
+ Properties[assetProperty.Name] = assetProperty.FromJson(value, typeConfig);
+ }
+ catch (Exception ex)
+ {
+ var message = $@"Error setting property {assetProperty.Name} to {value} ({assetProperty.GetType().Name}):
+ {ex.Message}";
+ throw new AssetConfigLoadException(message, ex);
+ }
+ }
+
+ public void SetProperty(IAssetProperty assetProperty, T value)
+ {
+ if (assetProperty == null) throw new ArgumentNullException(nameof(assetProperty));
+ if (_frozen) throw new InvalidOperationException("Tried to modify asset node after it was frozen. Asset nodes are immutable after mods have been loaded.");
+ Properties ??= new Dictionary();
+ Properties[assetProperty.Name] = value;
+ }
+
+ public void SetProperties(IReadOnlyDictionary dict, TypeConfig typeConfig, string contextName, object context)
+ {
+ if (dict == null) throw new ArgumentNullException(nameof(dict));
+ if (typeConfig == null) throw new ArgumentNullException(nameof(typeConfig));
+
+ // The loader and container can change the set of valid properties, so we have to make sure those are set first.
+ foreach (var kvp in dict)
+ {
+ if (kvp.Key != AssetProps.Loader.Name && kvp.Key != AssetProps.Container.Name)
+ continue;
+
+ var assetProperty = typeConfig.GetAssetProperty(kvp.Key, this);
+ if (assetProperty == null)
+ throw new AssetConfigLoadException($"Unexpected property \"{kvp.Key}\" encountered when loading {contextName} \"{context}\" - did not match any registered global property or any exposed by the asset's loader/container");
+
+ SetProperty(assetProperty, kvp.Value, typeConfig);
+ }
+
+ foreach (var kvp in dict)
+ {
+ if (kvp.Key == AssetProps.Loader.Name || kvp.Key == AssetProps.Container.Name)
+ continue;
+
+ var assetProperty = typeConfig.GetAssetProperty(kvp.Key, this);
+ if (assetProperty == null)
+ throw new AssetConfigLoadException($"Unexpected property \"{kvp.Key}\" encountered when loading {contextName} \"{context}\" - did not match any registered global property or any exposed by the asset's loader/container");
+
+ SetProperty(assetProperty, kvp.Value, typeConfig);
+ }
+
+ _frozen = true;
+ }
+
+ // Asset loading control props
+ public string Filename => GetProperty(AssetProps.Filename);
+ public string Sha256Hash => GetProperty(AssetProps.Sha256Hash);
+ public Type Container => GetProperty(AssetProps.Container); // The alias of the IAssetContainer to use for loading the file
+ public Type Loader => GetProperty(AssetProps.Loader); // The alias of the IAssetLoader to use for loading assets in this file
+ public Type PostProcessor => GetProperty(AssetProps.Post); // The alias of the IAssetPostProcessor to use for loading assets in this file
+ public bool IsReadOnly => GetProperty(AssetProps.IsReadOnly); // To prevent zeroing out files when repacking formats that don't have writing code yet, e.g. ILBM images
+
+ // Common loader / container specific properties
+ public int Width => GetProperty(AssetProps.Width); // The default width, in pixels, of frames in images inside the file. For sprites only.
+ public int Height => GetProperty(AssetProps.Height); // The default height, in pixels, of frames in images inside the file. For sprites only.
+ public AssetId PaletteId => GetProperty(AssetProps.Palette); // for providing context when exporting 8-bit images to true-colour PNGs
+}
\ No newline at end of file
diff --git a/src/Config/AssetPath.cs b/src/Config/AssetPath.cs
index 38e8d9426..87bcda409 100644
--- a/src/Config/AssetPath.cs
+++ b/src/Config/AssetPath.cs
@@ -4,38 +4,26 @@ namespace UAlbion.Config;
public readonly struct AssetPath : IEquatable
{
- public int Index { get; }
+ public AssetId AssetId { get; }
public int SubAsset { get; }
public int? PaletteId { get; }
public int? PaletteFrame { get; }
public string Name { get; }
- public override string ToString() => $"{Index}:{SubAsset}{(PaletteId==null ? "" : " P"+PaletteId)} {Name}";
- public AssetPath(int index, int subAsset = 0, int? paletteId = null, string overrideName = null, int? paletteFrame = null)
+ public override string ToString() => $"{AssetId.Id}:{SubAsset}{(PaletteId == null ? "" : " P" + PaletteId)} {Name}";
+
+ public AssetPath(AssetId id, int subAsset = 0, int? paletteId = null, string overrideName = null, int? paletteFrame = null)
{
- Index = index;
+ AssetId = id;
+ Name = overrideName ?? ConfigUtil.AssetName(id);
SubAsset = subAsset;
PaletteId = paletteId;
- Name = overrideName;
PaletteFrame = paletteFrame;
}
- public AssetPath(AssetInfo info, int subAsset = 0, string overrideName = null)
- {
- if (info == null) throw new ArgumentNullException(nameof(info));
- Index = info.Index;
- SubAsset = subAsset;
- Name = string.IsNullOrEmpty(overrideName) ? ConfigUtil.AssetName(info.AssetId) : overrideName;
- PaletteId = info.Get(AssetProperty.PaletteId, -1);
- if (PaletteId == -1)
- PaletteId = null;
-
- PaletteFrame = null;
- }
-
public override bool Equals(object obj) => obj is AssetPath other && Equals(other);
- public bool Equals(AssetPath other) => Index == other.Index && SubAsset == other.SubAsset && PaletteId == other.PaletteId && Name == other.Name;
+ public bool Equals(AssetPath other) => AssetId == other.AssetId && SubAsset == other.SubAsset && PaletteId == other.PaletteId && Name == other.Name;
public static bool operator ==(AssetPath left, AssetPath right) => left.Equals(right);
public static bool operator !=(AssetPath left, AssetPath right) => !(left == right);
- public override int GetHashCode() => HashCode.Combine(Index, SubAsset, PaletteId, Name);
+ public override int GetHashCode() => HashCode.Combine(AssetId, SubAsset, PaletteId, Name);
}
\ No newline at end of file
diff --git a/src/Config/AssetPathPattern.cs b/src/Config/AssetPathPattern.cs
index 253dd6ae0..dd15fae21 100644
--- a/src/Config/AssetPathPattern.cs
+++ b/src/Config/AssetPathPattern.cs
@@ -16,8 +16,8 @@ public class AssetPathPattern
enum PartType
{
+ Id,
Text,
- Index,
SubAsset,
Name,
Palette,
@@ -38,9 +38,8 @@ public Part(string name, string value)
Type =
name.ToUpperInvariant() switch
{
- "0" => PartType.Index,
- "ID" => PartType.Index,
- "INDEX" => PartType.Index,
+ "0" => PartType.Id,
+ "ID" => PartType.Id,
"1" => PartType.SubAsset,
"FRAME" => PartType.SubAsset,
@@ -144,13 +143,13 @@ public static AssetPathPattern Build(string pattern)
{
switch (part.Type)
{
- case PartType.Text: sb.Append(Regex.Escape(part.Value)); break;
- case PartType.Index: sb.Append(@"(?\d+)"); break;
- case PartType.SubAsset: sb.Append(@"(?\d+)"); break;
- case PartType.Name: sb.Append(@"(?\w+)"); break;
- case PartType.Palette: sb.Append(@"(?\d+)"); break;
+ case PartType.Id: sb.Append(@"(?\d+)"); break;
+ case PartType.Text: sb.Append(Regex.Escape(part.Value)); break;
+ case PartType.SubAsset: sb.Append(@"(?\d+)"); break;
+ case PartType.Name: sb.Append(@"(?\w+)"); break;
+ case PartType.Palette: sb.Append(@"(?\d+)"); break;
case PartType.PaletteFrame: sb.Append(@"(?\d+)"); break;
- case PartType.IgnoreNum: sb.Append(@"\d+"); break;
+ case PartType.IgnoreNum: sb.Append(@"\d+"); break;
}
}
@@ -162,7 +161,6 @@ static string FormatInt(int v, string format) =>
? v.ToString(format, CultureInfo.InvariantCulture)
: v.ToString(CultureInfo.InvariantCulture);
- public string Format(AssetInfo info) => Format(new AssetPath(info));
public string Format(in AssetPath path)
{
var sb = new StringBuilder();
@@ -170,9 +168,9 @@ public string Format(in AssetPath path)
{
switch (part.Type)
{
- case PartType.Text: sb.Append(part.Value); break;
- case PartType.Index: sb.Append(FormatInt(path.Index, part.Value)); break;
+ case PartType.Id: sb.Append(FormatInt(path.AssetId.Id, part.Value)); break;
case PartType.SubAsset: sb.Append(FormatInt(path.SubAsset, part.Value)); break;
+ case PartType.Text: sb.Append(part.Value); break;
case PartType.Name: sb.Append(path.Name); break;
case PartType.IgnoreNum: sb.Append('0'); break;
case PartType.Palette:
@@ -189,7 +187,7 @@ public string Format(in AssetPath path)
return sb.ToString();
}
- public bool TryParse(string filename, out AssetPath path)
+ public bool TryParse(string filename, AssetType type, out AssetPath path)
{
var m = _regex.Match(filename);
if (!m.Success)
@@ -198,28 +196,28 @@ public bool TryParse(string filename, out AssetPath path)
return false;
}
- var indexGroup = m.Groups["Index"];
+ var idGroup = m.Groups["Id"];
var subAssetGroup = m.Groups["SubAsset"];
var paletteGroup = m.Groups["Palette"];
var pframeGroup = m.Groups["PFrame"];
- int index = indexGroup.Success ? int.Parse(indexGroup.Value) : -1;
+ int id = idGroup.Success ? int.Parse(idGroup.Value) : -1;
int subAsset = subAssetGroup.Success ? int.Parse(subAssetGroup.Value) : 0;
int? paletteId = paletteGroup.Success ? (int?)int.Parse(paletteGroup.Value) : null;
int? paletteFrame = pframeGroup.Success ? (int?)int.Parse(pframeGroup.Value) : null;
- path = new AssetPath(index, subAsset, paletteId, m.Groups["Name"].Value, paletteFrame);
+ path = new AssetPath(new AssetId(type, id), subAsset, paletteId, m.Groups["Name"].Value, paletteFrame);
return true;
}
- public string WilcardForIndex(int index)
+ public string WilcardForId(AssetId id)
{
var sb = new StringBuilder();
foreach (var part in _parts)
{
switch (part.Type)
{
+ case PartType.Id: sb.Append(FormatInt(id.Id, part.Value)); break;
case PartType.Text: sb.Append(part.Value); break;
- case PartType.Index: sb.Append(FormatInt(index, part.Value)); break;
case PartType.SubAsset: sb.Append('*'); break;
case PartType.Name: sb.Append('*'); break;
case PartType.IgnoreNum: sb.Append('*'); break;
diff --git a/src/Config/AssetProperties.cs b/src/Config/AssetProperties.cs
new file mode 100644
index 000000000..e4ca1a3f8
--- /dev/null
+++ b/src/Config/AssetProperties.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+
+namespace UAlbion.Config;
+
+public class AssetProperties
+{
+ readonly Dictionary> _properties = new(); // loader/container specific properties
+ readonly Dictionary _globalProperties = new();
+ readonly AssetProperties _parent;
+
+ public AssetProperties(AssetProperties parent)
+ => _parent = parent;
+
+ public IAssetProperty GetGlobalProperty(string name)
+ {
+ _globalProperties.TryGetValue(name, out var globalProperty);
+ return globalProperty;
+ }
+
+ public IAssetProperty GetProperty(string name, Type context)
+ {
+ if (context == null)
+ return null;
+
+ _properties.TryGetValue(context, out var dict);
+ if (dict == null)
+ return null;
+
+ dict.TryGetValue(name, out var assetProperty);
+ return assetProperty;
+ }
+
+ public void LoadAssetPropertiesFromType(bool loadGlobal, Type type)
+ {
+ if (type == null) throw new ArgumentNullException(nameof(type));
+ var properties = type.GetProperties(BindingFlags.Static | BindingFlags.Public);
+ foreach (var property in properties)
+ {
+ if (!property.PropertyType.IsAssignableTo(typeof(IAssetProperty))) continue;
+ var instance = (IAssetProperty)property.GetValue(null);
+ if (instance == null) continue;
+
+ if (loadGlobal)
+ AddGlobalProperty(instance);
+ else
+ AddProperty(type, instance);
+ }
+
+ var fields = type.GetFields(BindingFlags.Static | BindingFlags.Public);
+ foreach (var field in fields)
+ {
+ if (!field.FieldType.IsAssignableTo(typeof(IAssetProperty))) continue;
+ var instance = (IAssetProperty)field.GetValue(null);
+ if (instance == null) continue;
+
+ if (loadGlobal)
+ AddGlobalProperty(instance);
+ else
+ AddProperty(type, instance);
+ }
+ }
+
+ void AddProperty(Type type, IAssetProperty assetProperty)
+ {
+ _properties.TryGetValue(type, out var dict);
+ if (dict == null)
+ {
+ dict = new Dictionary();
+ _properties[type] = dict;
+ }
+
+ if (dict.ContainsKey(assetProperty.Name))
+ throw new InvalidOperationException($"Tried to registry property \"{assetProperty.Name}\" for type {type}, but another property is already registered with that name");
+
+ if (_parent?.GetProperty(assetProperty.Name, type) != null)
+ throw new InvalidOperationException($"Tried to registry property \"{assetProperty.Name}\" for type {type}, but another property is already registered with that name in an inherited mod's type config");
+
+ dict[assetProperty.Name] = assetProperty;
+ }
+
+ void AddGlobalProperty(IAssetProperty assetProperty)
+ {
+ if (_globalProperties.ContainsKey(assetProperty.Name))
+ throw new InvalidOperationException($"Tried to registry property \"{assetProperty.Name}\" globally, but another property is already registered with that name");
+
+ if (_parent?._globalProperties.ContainsKey(assetProperty.Name) == true)
+ throw new InvalidOperationException($"Tried to registry property \"{assetProperty.Name}\" globally, but another property is already registered with that name in an inherited mod's type config");
+
+ _globalProperties[assetProperty.Name] = assetProperty;
+ }
+}
\ No newline at end of file
diff --git a/src/Config/AssetProperty.cs b/src/Config/AssetProperty.cs
deleted file mode 100644
index 9c65914d0..000000000
--- a/src/Config/AssetProperty.cs
+++ /dev/null
@@ -1,64 +0,0 @@
-namespace UAlbion.Config;
-
-public static class AssetProperty
-{
- // General
- public const string Language = "Language"; // string
- public const string Offset = "Offset"; // int, used for BinaryOffsetContainer, e.g. MAIN.EXE
- public const string Pattern = "Pattern"; // string, mostly for DirectoryContainer
- public const string MinimumCount = "MinimumCount"; // Just used to get closer to 1:1 round-tripping of XLDs
- public const string IsReadOnly = "IsReadOnly"; // To prevent zeroing out files when repacking formats that don't have writing code yet, e.g. ILBM images
- public const string Optional = "Optional"; // bool, will suppress missing-asset warnings when true
-
- // Textures
- public const string Width = "Width"; // int
- public const string Height = "Height"; // int
- public const string PaletteId = "PaletteId"; // int, for providing context when exporting 8-bit images to true-colour PNGs
- public const string SubSprites = "SubSprites"; // string
- public const string Transposed = "Transposed"; // bool, for various textures in the 3D world that are stored with rows/columns flipped
- public const string ExtraBytes = "ExtraBytes"; // int, used to suppress assertions when loading original assets that have incorrect sizes
-
- // Palette
- public const string IsCommon = "IsCommon"; // bool
- public const string AnimatedRanges = "AnimatedRanges"; // string (e.g. "0x1-0xf, 0x12-0x1a")
-
- // 32-bit tileset gfx
- public const string DayPath = "DayPath"; // string
- public const string NightPath = "NightPath"; // string
-
- // 2D Tilesets
- public const string BlankTilePath = "BlankTilePath"; // string
- public const string GraphicsPattern = "GraphicsPattern"; // string
- public const string UseSmallGraphics = "UseSmallGraphics"; // bool
-
- // Maps
- public const string LargeNpcs = "LargeNpcs"; // string
- public const string SmallNpcs = "SmallNpcs"; // string
- public const string TilesetPattern = "TilesetPattern"; // string
- public const string ScriptPattern = "ScriptPattern"; // string
-
- // NPC tileset
- public const string IsSmall = "IsSmall"; // bool
-
- // Isometric tileset/map properties
- public const string BaseHeight = "BaseHeight"; // int
- public const string CeilingPngPattern = "CeilingPngPattern"; // string
- public const string ContentsPngPattern = "ContentsPngPattern"; // string
- public const string FloorPngPattern = "FloorPngPattern"; // string
- public const string TileHeight = "TileHeight"; // int
- public const string TileWidth = "TileWidth"; // int
- public const string TiledCeilingPattern = "TiledCeilingPattern"; // string
- public const string TiledContentsPattern = "TiledContentsPattern"; // string
- public const string TiledFloorPattern = "TiledFloorPattern"; // string
- public const string TiledWallPattern = "TiledWallPattern"; // string
- public const string TilesPerRow = "TilesPerRow"; // int
- public const string WallPngPattern = "WallPngPattern"; // string
-
- // Spells
- public const string Name = "Name"; // StringId to use in game
- public const string MagicSchool = "School"; // SpellClass enum
- public const string SpellNumber = "SpellNumber"; // offset into school, used for save-game serialization
-
- // Songs
- public const string WaveLib = "WaveLib";
-}
\ No newline at end of file
diff --git a/src/Config/AssetRange.cs b/src/Config/AssetRange.cs
new file mode 100644
index 000000000..c0219d2e6
--- /dev/null
+++ b/src/Config/AssetRange.cs
@@ -0,0 +1,37 @@
+using System.Collections;
+using System.Collections.Generic;
+
+namespace UAlbion.Config;
+
+public readonly record struct AssetRange(AssetId From, AssetId To) : IEnumerable
+{
+ public override string ToString() => $"{From}-{To} [{From.Id}-{To.Id}]";
+ public IEnumerator GetEnumerator() => new RangeEnumerator(this);
+ IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
+
+ class RangeEnumerator : IEnumerator
+ {
+ readonly AssetRange _range;
+ public RangeEnumerator(AssetRange range) => _range = range;
+
+ public void Reset() => Current = AssetId.None;
+ public AssetId Current { get; private set; }
+ object IEnumerator.Current => Current;
+ public void Dispose() { }
+
+ public bool MoveNext()
+ {
+ if (Current >= _range.To)
+ return false;
+
+ if (Current.IsNone)
+ {
+ Current = _range.From;
+ return true;
+ }
+
+ Current = new AssetId(Current.Type, Current.Id + 1);
+ return true;
+ }
+ }
+};
\ No newline at end of file
diff --git a/src/Config/AssetRangeInfo.cs b/src/Config/AssetRangeInfo.cs
new file mode 100644
index 000000000..560eac4dc
--- /dev/null
+++ b/src/Config/AssetRangeInfo.cs
@@ -0,0 +1,19 @@
+using System.Collections.Generic;
+
+namespace UAlbion.Config;
+
+public class AssetRangeInfo
+{
+ public AssetRange Range { get; }
+ public AssetNode Node { get; }
+ public int Sequence { get; }
+ public List Files { get; } = new();
+ public AssetRangeInfo(AssetRange range, int sequence)
+ {
+ Range = range;
+ Sequence = sequence;
+ Node = new AssetNode(range.From);
+ }
+
+ public override string ToString() => $"{Range} ({Files.Count} files)";
+}
\ No newline at end of file
diff --git a/src/Config/AssetType.cs b/src/Config/AssetType.cs
index 103de3e4c..aa2b31046 100644
--- a/src/Config/AssetType.cs
+++ b/src/Config/AssetType.cs
@@ -13,6 +13,7 @@ public enum AssetType : byte
{
[Unmapped] None = 0, // Must be 0 so default(AssetId) will equate to AssetId.None
+ // Various kinds of SpriteId
AutomapGfx,
BackgroundGfx,
CombatBackground,
@@ -36,31 +37,39 @@ public enum AssetType : byte
Wall,
WallOverlay,
+ // Text rendering
Ink,
FontDefinition,
[Unmapped] MetaFont,
+ // Environmental objects that are setup on new game and have their state tracked in the save files
Chest,
Merchant,
Door,
+ // Scripts
EventSet,
Script,
+ // Inventory items
[Unmapped] Gold,
[Unmapped] Rations,
Item,
+ // 3D template
Labyrinth,
+ // Actual map data
Map,
[IsomorphicTo(Map)] Automap,
+ // Character definitions
PartyMember,
[IsomorphicTo(PartyMember)] PartySheet,
MonsterSheet,
NpcSheet,
+ // Misc
MonsterGroup,
[Unmapped] ObjectGroup,
Palette,
@@ -74,16 +83,21 @@ public enum AssetType : byte
[IsomorphicTo(Tileset)] BlockList,
[Localised] Video,
- [Localised] [IsomorphicTo(EventSet)] EventText,
- [Localised] [IsomorphicTo(Map)] MapText,
+ // Individual strings
[Localised] [IsomorphicTo(Item)] ItemName,
[Localised] Text,
[Localised] Word,
- [Unmapped] MapTextIndex = 250, // Used for NPCs with the SimpleMsg flag
- [Unmapped] PromptNumber = 251, // Used for DialogueLine actions
- [Unmapped] LocalNpc = 252, // For identifying NPCs in a map by their slot number
- Target = 253, // For targeting DataChangeEvents etc
- Special = 254, // For various types that only have a single value
+ // String sets
+ [Localised] [IsomorphicTo(EventSet)] EventText,
+ [Localised] [IsomorphicTo(Map)] MapText,
+
+ Special, // For various types that only have a single value, can be a string set
+
+ [Unmapped] MapTextIndex, // Used for NPCs with the SimpleMsg flag
+ [Unmapped] PromptNumber, // Used for DialogueLine actions
+ [Unmapped] LocalNpc, // For identifying NPCs in a map by their slot number
+ Target, // For targeting DataChangeEvents etc
+
[Unmapped] Unknown = 255
}
\ No newline at end of file
diff --git a/src/Config/ConfigUtil.cs b/src/Config/ConfigUtil.cs
index 553ba2902..9f0c7ea34 100644
--- a/src/Config/ConfigUtil.cs
+++ b/src/Config/ConfigUtil.cs
@@ -8,7 +8,7 @@ namespace UAlbion.Config;
public static class ConfigUtil
{
- static readonly string ProbePath = Path.Combine("mods", "Base", "base_assets.json");
+ static readonly string ProbePath = Path.Combine("mods", "Base", "types.json");
public static string FindBasePath(IFileSystem disk) // Should roughly match UAlbion.Scripting.Tests.TestUtil
{
if (disk == null) throw new ArgumentNullException(nameof(disk));
diff --git a/src/Config/IAssetConfig.cs b/src/Config/IAssetConfig.cs
index 83f2f065e..d251bd0e4 100644
--- a/src/Config/IAssetConfig.cs
+++ b/src/Config/IAssetConfig.cs
@@ -1,6 +1,8 @@
-namespace UAlbion.Config;
+using System.Collections.Generic;
+
+namespace UAlbion.Config;
public interface IAssetConfig
{
- AssetInfo[] GetAssetInfo(AssetId id);
+ IEnumerable GetAssetInfo(AssetId id);
}
\ No newline at end of file
diff --git a/src/Formats/Containers/IAssetContainer.cs b/src/Config/IAssetContainer.cs
similarity index 54%
rename from src/Formats/Containers/IAssetContainer.cs
rename to src/Config/IAssetContainer.cs
index b03b3cdad..55a9c6b4f 100644
--- a/src/Formats/Containers/IAssetContainer.cs
+++ b/src/Config/IAssetContainer.cs
@@ -1,8 +1,7 @@
using System.Collections.Generic;
using SerdesNet;
-using UAlbion.Config;
-namespace UAlbion.Formats.Containers;
+namespace UAlbion.Config;
///
/// Abstraction over container files/directories containing assets
@@ -15,10 +14,9 @@ public interface IAssetContainer
/// Open a serializer for one of the assets inside a container
///
/// The path to the container file/directory
- /// The config metadata for the asset
/// The loader context, containing the JSON serialiser, file system access object etc
///
- ISerializer Read(string path, AssetInfo info, SerdesContext context);
+ ISerializer Read(string path, AssetLoadContext context);
///
/// Write all assets inside a container
@@ -26,14 +24,5 @@ public interface IAssetContainer
/// The path to the container file/directory
/// A list of pairs containing asset metadata and the corresponding raw bytes of the asset
/// The loader context, containing the JSON serialiser, file system access object etc
- void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context);
-
- ///
- /// Open the container and return the sub-item ranges that are present inside it.
- ///
- /// The path to the container file/directory
- /// The config metadata for the container
- /// The loader context, containing the JSON serialiser, file system access object etc
- /// A list of range pairs: (subItemId of start of range, count of ids in range)
- List<(int num, int count)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context);
+ void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context);
}
\ No newline at end of file
diff --git a/src/Config/IAssetLoader.cs b/src/Config/IAssetLoader.cs
new file mode 100644
index 000000000..6afa33627
--- /dev/null
+++ b/src/Config/IAssetLoader.cs
@@ -0,0 +1,13 @@
+using SerdesNet;
+
+namespace UAlbion.Config;
+
+public interface IAssetLoader
+{
+ object Serdes(object existing, ISerializer s, AssetLoadContext context);
+}
+
+public interface IAssetLoader : IAssetLoader where T : class
+{
+ T Serdes(T existing, ISerializer s, AssetLoadContext context); // SerDes = Serialise / Deserialise.
+}
\ No newline at end of file
diff --git a/src/Config/IAssetPostProcessor.cs b/src/Config/IAssetPostProcessor.cs
new file mode 100644
index 000000000..6d0e3f852
--- /dev/null
+++ b/src/Config/IAssetPostProcessor.cs
@@ -0,0 +1,6 @@
+namespace UAlbion.Config;
+
+public interface IAssetPostProcessor
+{
+ object Process(object asset, AssetLoadContext context);
+}
\ No newline at end of file
diff --git a/src/Config/IAssetProperty.cs b/src/Config/IAssetProperty.cs
new file mode 100644
index 000000000..4e654b92d
--- /dev/null
+++ b/src/Config/IAssetProperty.cs
@@ -0,0 +1,14 @@
+using System.Text.Json;
+
+namespace UAlbion.Config;
+
+public interface IAssetProperty
+{
+ string Name { get; }
+ object FromJson(JsonElement elem, TypeConfig config);
+}
+
+public interface IAssetProperty : IAssetProperty
+{
+ T DefaultValue { get; }
+}
\ No newline at end of file
diff --git a/src/Config/LoadAssetFileInfo.cs b/src/Config/LoadAssetFileInfo.cs
new file mode 100644
index 000000000..cd3b1bc37
--- /dev/null
+++ b/src/Config/LoadAssetFileInfo.cs
@@ -0,0 +1,14 @@
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace UAlbion.Config;
+
+public class LoadAssetFileInfo
+{
+ public string MapFile { get; set; }
+ public Dictionary Map { get; set; }
+
+ [JsonInclude, JsonExtensionData]
+ public Dictionary Properties { get; private set; }
+}
\ No newline at end of file
diff --git a/src/Config/LoadAssetInfo.cs b/src/Config/LoadAssetInfo.cs
new file mode 100644
index 000000000..433b3c09d
--- /dev/null
+++ b/src/Config/LoadAssetInfo.cs
@@ -0,0 +1,11 @@
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace UAlbion.Config;
+
+public class LoadAssetInfo
+{
+ [JsonInclude, JsonExtensionData]
+ public Dictionary Properties { get; private set; }
+}
\ No newline at end of file
diff --git a/src/Config/LoadAssetRangeInfo.cs b/src/Config/LoadAssetRangeInfo.cs
new file mode 100644
index 000000000..e8d1ca3f5
--- /dev/null
+++ b/src/Config/LoadAssetRangeInfo.cs
@@ -0,0 +1,12 @@
+using System.Collections.Generic;
+using System.Text.Json;
+using System.Text.Json.Serialization;
+
+namespace UAlbion.Config;
+
+public class LoadAssetRangeInfo
+{
+ public int? Sequence { get; set; }
+ public Dictionary Files { get; set; } = new();
+ [JsonInclude] [JsonExtensionData] public Dictionary Properties { get; private set; }
+}
\ No newline at end of file
diff --git a/src/Config/ModConfig.cs b/src/Config/ModConfig.cs
index 8bb463907..3171e6bb9 100644
--- a/src/Config/ModConfig.cs
+++ b/src/Config/ModConfig.cs
@@ -15,8 +15,10 @@ public class ModConfig
public string Author { get; set; }
public Version Version { get; set; }
public string ShaderPath { get; set; }
- public string AssetConfig { get; set; } = "assets.json";
+ public string AssetConfig { get; set; }
+ public string TypeConfig { get; set; }
public string InheritAssetConfigFrom { get; set; }
+ public string InheritTypeConfigFrom { get; set; }
[JsonInclude] public List Dependencies { get; private set; } = new();
[JsonInclude] public Dictionary SymLinks { get; private set; } = new();
diff --git a/src/Formats/SerdesContext.cs b/src/Config/ModContext.cs
similarity index 72%
rename from src/Formats/SerdesContext.cs
rename to src/Config/ModContext.cs
index 7e6b86cb4..d0d94bc58 100644
--- a/src/Formats/SerdesContext.cs
+++ b/src/Config/ModContext.cs
@@ -1,17 +1,16 @@
using System;
using UAlbion.Api;
-using UAlbion.Config;
-namespace UAlbion.Formats;
+namespace UAlbion.Config;
-public class SerdesContext
+public class ModContext
{
- public SerdesContext(string modName, IJsonUtil json, AssetMapping mapping, IFileSystem disk)
+ public ModContext(string modName, IJsonUtil json, IFileSystem disk, AssetMapping mapping)
{
ModName = modName;
Json = json ?? throw new ArgumentNullException(nameof(json));
- Mapping = mapping ?? throw new ArgumentNullException(nameof(mapping));
Disk = disk ?? throw new ArgumentNullException(nameof(disk));
+ Mapping = mapping ?? throw new ArgumentNullException(nameof(mapping));
}
public string ModName { get; }
diff --git a/src/Config/PathResolver.cs b/src/Config/PathResolver.cs
index 1cfd3fcaa..7d3ea0ea3 100644
--- a/src/Config/PathResolver.cs
+++ b/src/Config/PathResolver.cs
@@ -78,14 +78,13 @@ static string GetConfigBaseDir()
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var configHome = Environment.GetEnvironmentVariable("XDG_CONFIG_HOME");
if (configHome == null)
{
- var home = Environment.GetEnvironmentVariable("HOME");
- if (home != null)
- configHome = Path.Combine(home, ".config");
+ var home = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
+ configHome = Path.Combine(home, ".config");
}
if (configHome == null)
@@ -97,6 +96,12 @@ static string GetConfigBaseDir()
return configHome;
}
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
+ {
+ var home = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
+ return Path.Combine(home, "Library", "Application Support");
+ }
+
throw new NotSupportedException();
}
@@ -105,7 +110,7 @@ static string GetCacheBaseDir()
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
- if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
+ if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux) || RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
var cacheHome = Environment.GetEnvironmentVariable("XDG_CACHE_HOME");
if (cacheHome == null)
diff --git a/src/Config/Properties/AssetIdAssetProperty.cs b/src/Config/Properties/AssetIdAssetProperty.cs
new file mode 100644
index 000000000..8d01442b8
--- /dev/null
+++ b/src/Config/Properties/AssetIdAssetProperty.cs
@@ -0,0 +1,40 @@
+using System;
+using System.Text.Json;
+using UAlbion.Api;
+
+namespace UAlbion.Config.Properties;
+
+public class AssetIdAssetProperty : IAssetProperty
+{
+ public AssetIdAssetProperty(string name) => Name = name;
+ public string Name { get; }
+ public AssetId DefaultValue => AssetId.None;
+ public object FromJson(JsonElement elem, TypeConfig config)
+ {
+ if (config == null) throw new ArgumentNullException(nameof(config));
+ var asString = elem.GetString();
+ return config.ResolveId(asString);
+ }
+}
+
+public class AssetIdAssetProperty : IAssetProperty where T : IAssetId
+{
+ readonly Func _converter;
+
+ public AssetIdAssetProperty(string name, T defaultValue, Func converter)
+ {
+ _converter = converter;
+ Name = name;
+ DefaultValue = defaultValue;
+ }
+
+ public string Name { get; }
+ public T DefaultValue { get; }
+ public object FromJson(JsonElement elem, TypeConfig config)
+ {
+ if (config == null) throw new ArgumentNullException(nameof(config));
+ var asString = elem.GetString();
+ AssetId id = config.ResolveId(asString);
+ return _converter(id);
+ }
+}
\ No newline at end of file
diff --git a/src/Config/Properties/AssetProps.cs b/src/Config/Properties/AssetProps.cs
new file mode 100644
index 000000000..43724c9ce
--- /dev/null
+++ b/src/Config/Properties/AssetProps.cs
@@ -0,0 +1,30 @@
+namespace UAlbion.Config.Properties;
+
+public static class AssetProps
+{
+ // General
+ public static readonly StringAssetProperty Filename = new("Filename"); // Not specified explicitly - this is loaded from the dictionary key of the file
+ public static readonly StringAssetProperty Sha256Hash = new("Sha256Hash"); // Not specified explicitly - this is loaded from the dictionary key of the file
+ public static readonly PathPatternProperty Pattern = new("Pattern"); // Mostly for DirectoryContainer - used to specify complex file names based on the asset's id and metadata
+
+ // How to load the asset. Container is used to pull one asset out of a file containing many, loader
+ // is used to actually load the asset and the post-processor can perform any extra steps required after
+ // loading (to maintain simplicity, use of post-processors should be minimised wherever possible)
+ public static readonly TypeAliasAssetProperty Container = new("Container", "container", x => x.Containers);
+ public static readonly TypeAliasAssetProperty Loader = new("Loader", "loader", x => x.Loaders);
+ public static readonly TypeAliasAssetProperty Post = new("Post", "post-processor", x => x.PostProcessors);
+
+ // When to load the asset. Language will cause the asset to only be loaded in that language's context,
+ // IsReadOnly will cause the asset to be ignored when converting / saving, UseDummyRead will skip the
+ // loading step when converting and Optional will suppress error messages about missing assets (e.g. when some languages are not available etc).
+ public static readonly StringAssetProperty Language = new("Language");
+ public static readonly BoolAssetProperty IsReadOnly = new("IsReadOnly"); // To prevent zeroing out files when repacking formats that don't have writing code yet, e.g. ILBM images
+ public static readonly BoolAssetProperty UseDummyRead = new("UseDummyRead"); // For asset conversion, indicates that no asset should be loaded from the source mod, instead the target mod loader should be called directly with a dummy object
+ public static readonly BoolAssetProperty Optional = new("Optional"); // Will suppress missing-asset warnings when true
+
+ // Common texture-specific properties
+ public static readonly IntAssetProperty Width = new("Width");
+ public static readonly IntAssetProperty Height = new("Height");
+ public static readonly AssetIdAssetProperty Palette = new("Palette"); // For providing context when exporting 8-bit images to true-colour PNGs and reimporting the true-colour PNGs back to 8-bit images.
+}
+
diff --git a/src/Config/Properties/AssetRangeAssetProperty.cs b/src/Config/Properties/AssetRangeAssetProperty.cs
new file mode 100644
index 000000000..afde32455
--- /dev/null
+++ b/src/Config/Properties/AssetRangeAssetProperty.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class AssetRangeAssetProperty : IAssetProperty
+{
+ public AssetRangeAssetProperty(string name) => Name = name;
+ public string Name { get; }
+ public AssetRange DefaultValue => new(AssetId.None, AssetId.None);
+ public object FromJson(JsonElement elem, TypeConfig config)
+ {
+ if (config == null) throw new ArgumentNullException(nameof(config));
+ var asString = elem.GetString();
+ return config.ParseIdRange(asString);
+ }
+}
\ No newline at end of file
diff --git a/src/Config/Properties/BoolAssetProperty.cs b/src/Config/Properties/BoolAssetProperty.cs
new file mode 100644
index 000000000..b709176b8
--- /dev/null
+++ b/src/Config/Properties/BoolAssetProperty.cs
@@ -0,0 +1,11 @@
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class BoolAssetProperty : IAssetProperty
+{
+ public BoolAssetProperty(string name) => Name = name;
+ public string Name { get; }
+ public bool DefaultValue => false;
+ public object FromJson(JsonElement elem, TypeConfig config) => elem.GetBoolean();
+}
\ No newline at end of file
diff --git a/src/Config/Properties/EnumAssetProperty.cs b/src/Config/Properties/EnumAssetProperty.cs
new file mode 100644
index 000000000..4382a4066
--- /dev/null
+++ b/src/Config/Properties/EnumAssetProperty.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class EnumAssetProperty : IAssetProperty where T : struct, Enum
+{
+ public EnumAssetProperty(string name, T defaultValue)
+ {
+ Name = name;
+ DefaultValue = defaultValue;
+ }
+
+ public string Name { get; }
+ public T DefaultValue { get; }
+ public object FromJson(JsonElement elem, TypeConfig config)
+ {
+ var asString = elem.GetString();
+ if (asString == null)
+ throw new FormatException($"Null is an invalid value for the \"{Name}\" property (must be {typeof(T).Name})");
+
+ return Enum.Parse(asString);
+ }
+}
\ No newline at end of file
diff --git a/src/Config/Properties/IntAssetProperty.cs b/src/Config/Properties/IntAssetProperty.cs
new file mode 100644
index 000000000..41fd28d97
--- /dev/null
+++ b/src/Config/Properties/IntAssetProperty.cs
@@ -0,0 +1,11 @@
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class IntAssetProperty : IAssetProperty
+{
+ public IntAssetProperty(string name) => Name = name;
+ public string Name { get; }
+ public int DefaultValue => 0;
+ public object FromJson(JsonElement elem, TypeConfig config) => elem.GetInt32();
+}
\ No newline at end of file
diff --git a/src/Config/Properties/PathPatternProperty.cs b/src/Config/Properties/PathPatternProperty.cs
new file mode 100644
index 000000000..fd1690a13
--- /dev/null
+++ b/src/Config/Properties/PathPatternProperty.cs
@@ -0,0 +1,26 @@
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class PathPatternProperty : IAssetProperty
+{
+ public PathPatternProperty(string name)
+ {
+ Name = name;
+ DefaultValue = AssetPathPattern.Build("");
+ }
+
+ public PathPatternProperty(string name, string defaultPath)
+ {
+ Name = name;
+ DefaultValue = AssetPathPattern.Build(defaultPath);
+ }
+
+ public string Name { get; }
+ public AssetPathPattern DefaultValue { get; }
+ public object FromJson(JsonElement elem, TypeConfig config)
+ {
+ var asString = elem.GetString();
+ return AssetPathPattern.Build(asString);
+ }
+}
\ No newline at end of file
diff --git a/src/Config/Properties/StringAssetProperty.cs b/src/Config/Properties/StringAssetProperty.cs
new file mode 100644
index 000000000..766022646
--- /dev/null
+++ b/src/Config/Properties/StringAssetProperty.cs
@@ -0,0 +1,11 @@
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class StringAssetProperty : IAssetProperty
+{
+ public StringAssetProperty(string name) => Name = name;
+ public string Name { get; }
+ public string DefaultValue => null;
+ public object FromJson(JsonElement elem, TypeConfig config) => elem.GetString();
+}
\ No newline at end of file
diff --git a/src/Config/Properties/StringListAssetProperty.cs b/src/Config/Properties/StringListAssetProperty.cs
new file mode 100644
index 000000000..e59cb6093
--- /dev/null
+++ b/src/Config/Properties/StringListAssetProperty.cs
@@ -0,0 +1,24 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class StringListAssetProperty : IAssetProperty>
+{
+ public StringListAssetProperty(string name) => Name = name;
+ public string Name { get; }
+ public List DefaultValue => new();
+ public object FromJson(JsonElement elem, TypeConfig config)
+ {
+ if (elem.ValueKind != JsonValueKind.Array)
+ throw new FormatException($"Property \"{Name}\" expects an array of strings");
+
+ var list = new List();
+ foreach (var s in elem.EnumerateArray())
+ list.Add(s.GetString());
+
+ return list;
+ }
+
+}
\ No newline at end of file
diff --git a/src/Config/Properties/TypeAliasAssetProperty.cs b/src/Config/Properties/TypeAliasAssetProperty.cs
new file mode 100644
index 000000000..a180b6c39
--- /dev/null
+++ b/src/Config/Properties/TypeAliasAssetProperty.cs
@@ -0,0 +1,33 @@
+using System;
+using System.Collections.Generic;
+using System.Text.Json;
+
+namespace UAlbion.Config.Properties;
+
+public class TypeAliasAssetProperty : IAssetProperty
+{
+ readonly string _description;
+ readonly Func> _dictSelector;
+
+ public TypeAliasAssetProperty(string name, string description, Func> dictSelector)
+ {
+ if (string.IsNullOrEmpty(name)) throw new ArgumentException("Value cannot be null or empty.", nameof(name));
+ if (string.IsNullOrEmpty(description)) throw new ArgumentException("Value cannot be null or empty.", nameof(description));
+
+ Name = name;
+ _description = description;
+ _dictSelector = dictSelector ?? throw new ArgumentNullException(nameof(dictSelector));
+ }
+
+ public string Name { get; }
+ public Type DefaultValue => null;
+ public object FromJson(JsonElement elem, TypeConfig config)
+ {
+ var dict = _dictSelector(config);
+ var s = elem.GetString();
+ if (s != null && dict.TryGetValue(s, out var type))
+ return type;
+
+ throw new FormatException($"Could not resolve {_description} alias \"{s}\" to a type name");
+ }
+}
\ No newline at end of file
diff --git a/src/Config/RangeLookup.cs b/src/Config/RangeLookup.cs
new file mode 100644
index 000000000..5c95eb4e5
--- /dev/null
+++ b/src/Config/RangeLookup.cs
@@ -0,0 +1,71 @@
+using System.Collections.Generic;
+using System.Linq;
+
+namespace UAlbion.Config;
+
+public class RangeLookup // Note: it is assumed that id ranges in a given config are disjoint, i.e. there should be no AssetId which satisfies multiple ranges in a single assets.json
+{
+ readonly AssetRangeInfo[][] _byType = new AssetRangeInfo[256][];
+ readonly RangeLookup _parent;
+
+ public RangeLookup() { } // Empty range for mods without an asset config
+ public RangeLookup(RangeLookup parent, IEnumerable ranges)
+ {
+ _parent = parent;
+
+ var groups = ranges
+ .GroupBy(x => x.Range.From.Type)
+ .Select(x => (x.Key, x.OrderBy(x => x.Range.From).ToArray()));
+
+ foreach (var (type, group) in groups)
+ _byType[(int)type] = group;
+ }
+
+ public IEnumerable AllRanges =>
+ _byType
+ .Where(x => x != null)
+ .SelectMany(x => x)
+ .OrderBy(x => x.Sequence)
+ .ThenBy(x => x.Range.From.ToString());
+
+ public AssetRangeInfo TryFindAssetRangeInfo(AssetId id)
+ {
+ var rangesForType = _byType[(int)id.Type];
+ if (rangesForType == null)
+ return _parent?.TryFindAssetRangeInfo(id);
+
+ int index = FindNearest(rangesForType, id);
+ if (index < 0 || index >= rangesForType.Length)
+ return _parent?.TryFindAssetRangeInfo(id);
+
+ var rangeInfo = rangesForType[index];
+ var range = rangeInfo.Range;
+ return range.From <= id && range.To >= id
+ ? rangeInfo
+ : _parent?.TryFindAssetRangeInfo(id);
+ }
+
+ static int FindNearest(AssetRangeInfo[] collection, AssetId id) // Binary search
+ {
+ int first = 0;
+ int last = collection.Length - 1;
+ int mid;
+
+ do
+ {
+ mid = first + (last - first) / 2;
+ if (id > collection[mid].Range.To)
+ first = mid + 1;
+ else
+ last = mid - 1;
+
+ if (collection[mid].Range.From <= id && collection[mid].Range.To >= id)
+ return mid;
+ } while (first <= last);
+
+ if (collection[mid].Range.From > id && mid != 0)
+ mid--;
+
+ return mid;
+ }
+}
\ No newline at end of file
diff --git a/src/Config/TypeConfig.cs b/src/Config/TypeConfig.cs
new file mode 100644
index 000000000..63a0bd7dd
--- /dev/null
+++ b/src/Config/TypeConfig.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+
+namespace UAlbion.Config;
+
+public class TypeConfig // Defines the vocabulary to be used in assets.json files / AssetConfig
+{
+ readonly AssetMapping _mapping;
+
+ public TypeConfig(string modName, AssetMapping mapping)
+ {
+ ModName = modName;
+ _mapping = mapping ?? throw new ArgumentNullException(nameof(mapping));
+ }
+
+ ///
+ /// The name of the mod that this type config came from
+ ///
+ public string ModName { get; }
+
+ ///
+ /// A set of aliases for enums to be used as asset ids
+ ///
+ public IReadOnlyDictionary IdTypes { get; init; }
+
+ ///
+ /// A set of supported natural languages that the player can choose to play the game in.
+ ///
+ public IReadOnlyDictionary Languages { get; init; }
+
+ ///
+ /// A set of aliases for .NET types (deriving from IAssetLoader) to be used for loading assets
+ ///
+ public IReadOnlyDictionary Loaders { get; init; }
+
+ ///
+ /// A set of aliases for .NET types (deriving from IAssetContainer) to be used for extracting individual assets from container formats.
+ ///
+ public IReadOnlyDictionary Containers { get; init; }
+
+ ///
+ /// A set of aliases for .NET types (deriving from IAssetPostProcessor) to be used for additional post-load asset processing.
+ ///
+ public IReadOnlyDictionary PostProcessors { get; init; }
+
+ ///
+ /// The collection of types containing static IAssetProperty members to be registered
+ ///
+ public AssetProperties PropertyTypes { get; init; }
+
+ ///
+ /// The collection of types containing vars
+ ///
+ public List VarTypes { get; init; } = new();
+
+ public IAssetProperty GetAssetProperty(string name, AssetNode node)
+ {
+ var loader = node?.Loader;
+ if (loader != null)
+ {
+ var loaderProperty = PropertyTypes.GetProperty(name, loader);
+ if (loaderProperty != null)
+ return loaderProperty;
+ }
+
+ var container = node?.Container;
+ if (container != null)
+ {
+ var containerProperty = PropertyTypes.GetProperty(name, container);
+ if (containerProperty != null)
+ return containerProperty;
+ }
+
+ return PropertyTypes.GetGlobalProperty(name);
+ }
+
+ public AssetId ResolveId(string id)
+ {
+ if (string.IsNullOrEmpty(id))
+ return AssetId.None;
+
+ var (type, val) = SplitId(id, '.');
+ if (val == null)
+ throw new FormatException($"Asset IDs should consist of an alias type and value, separated by a '.' character (string was \"{id}\")");
+
+ var enumType = ResolveIdType(type);
+ return _mapping.EnumToId(enumType, val);
+ }
+
+ static (string, string) SplitId(string id, char separator)
+ {
+ int index = id.IndexOf(separator, StringComparison.Ordinal);
+ if (index == -1)
+ return (id, null);
+
+ var type = id[..index];
+ var val = id[(index + 1)..];
+ return (type, val);
+ }
+
+ Type ResolveIdType(string type)
+ {
+ if (!IdTypes.TryGetValue(type, out var assetType))
+ throw new FormatException($"Could not resolve asset id alias \"{type}\"");
+
+ var enumType = Type.GetType(assetType.EnumType);
+ if (enumType == null)
+ throw new FormatException($"Could not resolve type \"{assetType.EnumType}\" (alias \"{assetType.Alias}\")");
+
+ return enumType;
+ }
+
+ public AssetRange ParseIdRange(string s)
+ {
+ if (string.IsNullOrWhiteSpace(s))
+ throw new ArgumentNullException(nameof(s));
+
+ int hyphenIndex = s.IndexOf('-', StringComparison.Ordinal);
+ if (hyphenIndex == -1)
+ {
+ var id = ResolveId(s);
+ return new AssetRange(id, id);
+ }
+
+ var first = s[..hyphenIndex];
+ var dotIndex = first.IndexOf('.', StringComparison.Ordinal);
+ if (dotIndex == -1)
+ throw new FormatException("Expected '.' in first section of range specifier \"{s}\"");
+
+ var firstId = ResolveId(first);
+
+ var typePart = first[..dotIndex];
+ var secondPart = s[(hyphenIndex + 1)..];
+ AssetId secondId;
+ if (secondPart == "*")
+ {
+ var (type, _) = _mapping.IdToEnum(firstId);
+ secondId = _mapping.MaxIdForType(type);
+ }
+ else
+ {
+ var second = $"{typePart}.{secondPart}";
+ secondId = ResolveId(second);
+ }
+
+ return new AssetRange(firstId, secondId);
+ }
+}
\ No newline at end of file
diff --git a/src/Config/TypeConfigLoader.cs b/src/Config/TypeConfigLoader.cs
new file mode 100644
index 000000000..bec647201
--- /dev/null
+++ b/src/Config/TypeConfigLoader.cs
@@ -0,0 +1,134 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Text.Json.Serialization;
+using UAlbion.Api;
+
+namespace UAlbion.Config;
+
+public class TypeConfigLoader
+{
+ readonly IJsonUtil _jsonUtil;
+ public TypeConfigLoader(IJsonUtil jsonUtil)
+ => _jsonUtil = jsonUtil ?? throw new ArgumentNullException(nameof(jsonUtil));
+
+#pragma warning disable CA1812 // 'AssetConfigLoader.RawTypeConfig' is an internal class that is apparently never instantiated. If so, remove the code from the assembly. If this class is intended to contain only static members, make it 'static' (Module in Visual Basic).
+ class RawTypeConfig
+ {
+ [JsonInclude, JsonPropertyName("Languages")] public Dictionary Languages { get; private set; } = new();
+ [JsonInclude, JsonPropertyName("IdTypes")] public Dictionary IdTypes { get; private set; } = new();
+ [JsonInclude, JsonPropertyName("Containers")] public Dictionary Containers { get; private set; } = new();
+ [JsonInclude, JsonPropertyName("Loaders")] public Dictionary Loaders { get; private set; } = new();
+ [JsonInclude, JsonPropertyName("PostProcessors")] public Dictionary PostProcessors { get; private set; } = new();
+ [JsonInclude, JsonPropertyName("GlobalPropertyTypes")] public List GlobalPropertyTypes { get; private set; } = new();
+ [JsonInclude, JsonPropertyName("VarTypes")] public List VarTypes { get; private set; } = new();
+ }
+#pragma warning restore CA1812 // 'AssetConfigLoader.RawTypeConfig' is an internal class that is apparently never instantiated. If so, remove the code from the assembly. If this class is intended to contain only static members, make it 'static' (Module in Visual Basic).
+
+ public TypeConfig Load(string configPath, string modName, TypeConfig parent, AssetMapping mapping, IFileSystem disk)
+ {
+ if (disk == null) throw new ArgumentNullException(nameof(disk));
+ if (!disk.FileExists(configPath))
+ throw new FileNotFoundException($"Could not open asset config from {configPath}");
+
+ var configText = disk.ReadAllBytes(configPath);
+ var config = Parse(configText, modName, parent, mapping);
+ if (config == null)
+ throw new FileLoadException($"Could not load asset config from \"{configPath}\"");
+
+ return config;
+ }
+
+ public IReadOnlyDictionary LoadIdTypesOnly(string configPath, IFileSystem disk)
+ {
+ if (disk == null) throw new ArgumentNullException(nameof(disk));
+ if (!disk.FileExists(configPath))
+ throw new FileNotFoundException($"Could not open asset config from {configPath}");
+
+ var configText = disk.ReadAllBytes(configPath);
+ var raw = _jsonUtil.Deserialize(configText);
+ if (raw == null)
+ return null;
+
+ foreach (var kvp in raw.IdTypes)
+ kvp.Value.Alias = kvp.Key;
+
+ return raw.IdTypes;
+ }
+
+ public TypeConfig Parse(byte[] configText, string modName, TypeConfig parent, AssetMapping mapping)
+ {
+ var raw = _jsonUtil.Deserialize(configText);
+ if (raw == null)
+ return null;
+
+ foreach (var kvp in raw.IdTypes)
+ kvp.Value.Alias = kvp.Key;
+
+ foreach (var kvp in raw.Languages)
+ kvp.Value.Id = kvp.Key;
+
+ var loaders = GetTypes(raw.Loaders);
+ var containers = GetTypes(raw.Containers);
+ var postProcessors = GetTypes(raw.PostProcessors);
+
+ var config = new TypeConfig(modName, mapping)
+ {
+ IdTypes = parent != null ? new FallbackDictionary(raw.IdTypes, parent.IdTypes) : raw.IdTypes,
+ Loaders = parent != null ? new FallbackDictionary(loaders, parent.Loaders) : loaders,
+ Containers = parent != null ? new FallbackDictionary(containers, parent.Containers) : containers,
+ PostProcessors = parent != null ? new FallbackDictionary(postProcessors, parent.PostProcessors) : postProcessors,
+ Languages = parent != null ? new FallbackDictionary(raw.Languages, parent.Languages) : raw.Languages,
+ PropertyTypes = LoadPropertyTypes(modName, parent, raw),
+ VarTypes = raw.VarTypes
+ };
+
+ return config;
+ }
+
+ static AssetProperties LoadPropertyTypes(string modName, TypeConfig parent, RawTypeConfig raw)
+ {
+ var properties = new AssetProperties(parent?.PropertyTypes);
+
+ foreach (var kvp in raw.Loaders)
+ {
+ var type = Type.GetType(kvp.Value);
+ if (type == null)
+ throw new InvalidOperationException($"Could not load type \"{kvp.Value}\" as property container from mod {modName}");
+
+ properties.LoadAssetPropertiesFromType(false, type);
+ }
+
+ foreach (var kvp in raw.Containers)
+ {
+ var type = Type.GetType(kvp.Value);
+ if (type == null)
+ throw new InvalidOperationException($"Could not load type \"{kvp.Value}\" as property container from mod {modName}");
+
+ properties.LoadAssetPropertiesFromType(false, type);
+ }
+
+ foreach (var typeName in raw.GlobalPropertyTypes)
+ {
+ var type = Type.GetType(typeName);
+ if (type == null)
+ throw new InvalidOperationException($"Could not load type \"{typeName}\" as property container from mod {modName}");
+
+ properties.LoadAssetPropertiesFromType(true, type);
+ }
+
+ return properties;
+ }
+
+ static Dictionary GetTypes(Dictionary typeNames)
+ {
+ var results = new Dictionary();
+ foreach (var kvp in typeNames)
+ {
+ var type = Type.GetType(kvp.Value);
+ results[kvp.Key] = type;
+ }
+
+ return results;
+ }
+}
\ No newline at end of file
diff --git a/src/Core.Veldrid/ShaderCache.cs b/src/Core.Veldrid/ShaderCache.cs
index 8d6940502..0842d1c1d 100644
--- a/src/Core.Veldrid/ShaderCache.cs
+++ b/src/Core.Veldrid/ShaderCache.cs
@@ -152,7 +152,7 @@ CacheEntry BuildShaderPair(GraphicsBackend backend, ShaderInfo vertex, ShaderInf
}
void RemoveOldFiles(string name, string goodHash)
{
- foreach (var path in _disk.EnumerateDirectory(_shaderCachePath, $"{name}.*"))
+ foreach (var path in _disk.EnumerateFiles(_shaderCachePath, $"{name}.*"))
{
var filename = Path.GetFileName(path);
var parts = filename[(name.Length + 1)..].Split('.');
diff --git a/src/Formats/AssetConversionOptions.cs b/src/Formats/AssetConversionOptions.cs
new file mode 100644
index 000000000..bea3baf07
--- /dev/null
+++ b/src/Formats/AssetConversionOptions.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text.RegularExpressions;
+using UAlbion.Config;
+
+namespace UAlbion.Formats;
+
+public record AssetConversionOptions(
+ AssetLoaderMethod LoaderFunc,
+ Action FlushCacheFunc,
+ ISet Ids,
+ ISet AssetTypes,
+ string[] Languages,
+ Regex FilePattern
+);
\ No newline at end of file
diff --git a/src/Formats/AssetIdTypes.json b/src/Formats/AssetIdTypes.json
index 5047805f8..6cb44f14c 100644
--- a/src/Formats/AssetIdTypes.json
+++ b/src/Formats/AssetIdTypes.json
@@ -73,22 +73,23 @@
"VideoId": [ "Video" ],
"WaveLibraryId": [ "WaveLibrary" ],
- "EventTextId": [ "EventText" ],
- "MapTextId": [ "MapText" ],
"WordId": [ "Word" ],
- "TextId": [
+ "StringSetId": [
"EventText",
- "ItemName",
"MapText",
- "Special",
+ "Special"
+ ],
+
+ "TextId": [
+ "ItemName",
"Text",
"Word"
]
},
"Extras": {
- "EventSetId": [ " public readonly TextId ToEventText() => new TextId(AssetType.EventText, Id);" ],
- "MapId": [ " public readonly TextId ToMapText() => new TextId(AssetType.MapText, Id);" ],
+ "EventSetId": [ " public readonly StringSetId ToEventText() => new StringSetId(AssetType.EventText, Id);" ],
+ "MapId": [ " public readonly StringSetId ToMapText() => new StringSetId(AssetType.MapText, Id);" ],
"ItemId": [ " public readonly TextId ToName() => new TextId(AssetType.ItemName, Id);" ],
"TilesetId": [
" public readonly BlockListId ToBlockList() => new BlockListId(AssetType.BlockList, Id);",
diff --git a/src/Formats/AssetLoadResult.cs b/src/Formats/AssetLoadResult.cs
new file mode 100644
index 000000000..3721bc18d
--- /dev/null
+++ b/src/Formats/AssetLoadResult.cs
@@ -0,0 +1,5 @@
+using UAlbion.Config;
+
+namespace UAlbion.Formats;
+
+public record AssetLoadResult(AssetId AssetId, object Asset, AssetNode Node);
\ No newline at end of file
diff --git a/src/Formats/AssetLoaderMethod.cs b/src/Formats/AssetLoaderMethod.cs
new file mode 100644
index 000000000..9badbf19e
--- /dev/null
+++ b/src/Formats/AssetLoaderMethod.cs
@@ -0,0 +1,5 @@
+using UAlbion.Config;
+
+namespace UAlbion.Formats;
+
+public delegate AssetLoadResult AssetLoaderMethod(AssetId id, string language);
\ No newline at end of file
diff --git a/src/Formats/Assets/AlbionPalette.cs b/src/Formats/Assets/AlbionPalette.cs
index d89bf350e..86806a587 100644
--- a/src/Formats/Assets/AlbionPalette.cs
+++ b/src/Formats/Assets/AlbionPalette.cs
@@ -7,6 +7,7 @@
using UAlbion.Api;
using UAlbion.Api.Visual;
using UAlbion.Config;
+using UAlbion.Formats.Parsers;
namespace UAlbion.Formats.Assets;
@@ -178,12 +179,12 @@ public uint[] GetUnambiguousPalette()
public ReadOnlySpan GetPaletteAtTime(int i) => _texture.GetLayerBuffer(0).GetRow(i % _texture.Height);
public override string ToString() { return string.IsNullOrEmpty(Name) ? $"Palette {Id}" : $"{Name} ({Id})"; }
- public static AlbionPalette Serdes(AlbionPalette p, AssetInfo info, ISerializer s)
+ public static AlbionPalette Serdes(AlbionPalette p, AssetLoadContext context, ISerializer s)
{
if (s == null) throw new ArgumentNullException(nameof(s));
- if (info == null) throw new ArgumentNullException(nameof(info));
+ if (context == null) throw new ArgumentNullException(nameof(context));
- bool isCommon = info.Get(AssetProperty.IsCommon, false);
+ bool isCommon = context.GetProperty(PaletteLoader.IsCommon);
long entryCount = isCommon ? CommonEntries : VariableEntries;
if (p == null)
@@ -191,12 +192,13 @@ public static AlbionPalette Serdes(AlbionPalette p, AssetInfo info, ISerializer
if (s.IsWriting()) throw new ArgumentNullException(nameof(p));
// AssetId is None when loading palettes from raw data in ImageReverser
+ int index = context.Index;
p = new AlbionPalette
{
- Id = info.AssetId.IsNone ? (uint)info.Index : info.AssetId.ToUInt32(),
- Name = info.AssetId.IsNone
- ? info.Index.ToString()
- : info.AssetId.ToString()
+ Id = context.AssetId.IsNone ? (uint)index : context.AssetId.ToUInt32(),
+ Name = context.AssetId.IsNone
+ ? index.ToString()
+ : context.AssetId.ToString()
};
}
@@ -216,13 +218,13 @@ public static AlbionPalette Serdes(AlbionPalette p, AssetInfo info, ISerializer
}
if (s.IsReading())
- p.Ranges = ParseRanges(info);
+ p.Ranges = ParseRanges(context);
return p;
}
- static IEnumerable<(byte, byte)> ParseRanges(AssetInfo info) =>
- info.Get(AssetProperty.AnimatedRanges, null)?.Split(',').Select(x =>
+ static IEnumerable<(byte, byte)> ParseRanges(AssetLoadContext context) =>
+ context.GetProperty(PaletteLoader.AnimatedRanges)?.Split(',').Select(x =>
{
var parts = x.Trim().Split('-');
if (parts.Length != 2)
diff --git a/src/Formats/Assets/AssetIdStringDictionary.cs b/src/Formats/Assets/AssetIdStringDictionary.cs
deleted file mode 100644
index 05942321d..000000000
--- a/src/Formats/Assets/AssetIdStringDictionary.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Collections.Generic;
-using UAlbion.Config;
-
-namespace UAlbion.Formats.Assets;
-
-public class AssetIdStringDictionary : Dictionary, IStringSet
-{
- public string GetString(StringId id, string language) => this.GetValueOrDefault(id.Id);
-}
\ No newline at end of file
diff --git a/src/Formats/Assets/EventSet.cs b/src/Formats/Assets/EventSet.cs
index 91c281cde..9581c84df 100644
--- a/src/Formats/Assets/EventSet.cs
+++ b/src/Formats/Assets/EventSet.cs
@@ -16,7 +16,7 @@ public class EventSet : IEventSet
{
ushort[] _chainMapping;
AssetId IEventSet.Id => Id;
- [JsonIgnore] public TextId TextId => Id.ToEventText();
+ [JsonIgnore] public StringSetId StringSetId => Id.ToEventText();
[JsonInclude] public EventSetId Id { get; private init; }
[JsonInclude] public IList Chains { get; private set; }
[JsonIgnore] public IList ExtraEntryPoints => null;
@@ -70,18 +70,23 @@ public static EventSet Serdes(EventSetId id, EventSet set, AssetMapping mapping,
foreach (var e in set.Events)
e.Unswizzle(set.Events);
- // TODO: Unify this with the code in BaseMapData
- var sortedChains = set.Chains
+ set.BuildChainMapping();
+ return set;
+ }
+
+ // TODO: Unify this with the code in BaseMapData
+ void BuildChainMapping()
+ {
+ var sortedChains = Chains
.Select((eventId, chainId) => (eventId, chainId))
.OrderBy(x => x)
.ToArray();
- set._chainMapping = new ushort[set.Events.Count];
- for (int i = 0, j = 0; i < set.Events.Count; i++)
+ _chainMapping = new ushort[Events.Count];
+ for (int i = 0, j = 0; i < Events.Count; i++)
{
while (sortedChains.Length > j + 1 && sortedChains[j].eventId < i) j++;
- set._chainMapping[i] = (ushort)sortedChains[j].chainId;
+ _chainMapping[i] = (ushort)sortedChains[j].chainId;
}
- return set;
}
}
\ No newline at end of file
diff --git a/src/Formats/Assets/IEventSet.cs b/src/Formats/Assets/IEventSet.cs
index f8833390d..4aad12d5c 100644
--- a/src/Formats/Assets/IEventSet.cs
+++ b/src/Formats/Assets/IEventSet.cs
@@ -9,7 +9,7 @@ namespace UAlbion.Formats.Assets;
public interface IEventSet
{
AssetId Id { get; }
- TextId TextId { get; }
+ StringSetId StringSetId { get; }
IList Events { get; }
IList Chains { get; }
IList ExtraEntryPoints { get; }
diff --git a/src/Formats/Assets/IFFChunkType.cs b/src/Formats/Assets/IFFChunkType.cs
index f9bc3300c..0df3e54ae 100644
--- a/src/Formats/Assets/IFFChunkType.cs
+++ b/src/Formats/Assets/IFFChunkType.cs
@@ -1,6 +1,6 @@
namespace UAlbion.Formats.Assets;
-public static class IFFChunkType
+public static class IffChunkType
{
public const string Format = "FORM";
public const string PackedBitmap = "PBM ";
diff --git a/src/Formats/Assets/IStringSet.cs b/src/Formats/Assets/IStringSet.cs
index 712fffc5a..51a6522e1 100644
--- a/src/Formats/Assets/IStringSet.cs
+++ b/src/Formats/Assets/IStringSet.cs
@@ -3,5 +3,6 @@
public interface IStringSet
{
int Count { get; }
- string GetString(StringId id, string language = null);
+ string GetString(StringId id);
+ void SetString(StringId id, string value);
}
\ No newline at end of file
diff --git a/src/Formats/Assets/IntStringDictionary.cs b/src/Formats/Assets/IntStringDictionary.cs
index dc4872ea7..6eb29f686 100644
--- a/src/Formats/Assets/IntStringDictionary.cs
+++ b/src/Formats/Assets/IntStringDictionary.cs
@@ -4,5 +4,6 @@ namespace UAlbion.Formats.Assets;
public class IntStringDictionary : Dictionary, IStringSet
{
- public string GetString(StringId id, string language) => this.GetValueOrDefault(id.SubId);
+ public string GetString(StringId id) => this.GetValueOrDefault(id.SubId);
+ public void SetString(StringId id, string value) => this[id.SubId] = value;
}
\ No newline at end of file
diff --git a/src/Formats/Assets/InterlacedBitmap.cs b/src/Formats/Assets/InterlacedBitmap.cs
index 089c9a4fd..b98f25674 100644
--- a/src/Formats/Assets/InterlacedBitmap.cs
+++ b/src/Formats/Assets/InterlacedBitmap.cs
@@ -33,12 +33,12 @@ public static InterlacedBitmap Serdes(InterlacedBitmap img, ISerializer s)
if (s == null) throw new ArgumentNullException(nameof(s));
img ??= new InterlacedBitmap();
- var formatChunk = IffChunk.Serdes(0, new IffChunk(IFFChunkType.Format, 0), s);
- if (formatChunk.TypeId != IFFChunkType.Format)
+ var formatChunk = IffChunk.Serdes(0, new IffChunk(IffChunkType.Format, 0), s);
+ if (formatChunk.TypeId != IffChunkType.Format)
throw new NotSupportedException($"Invalid IFF header, expected \"FORM\", found \"{formatChunk.TypeId}\"");
- var formatId = s.FixedLengthString("FormatId", IFFChunkType.PackedBitmap, 4);
- if (formatId != IFFChunkType.PackedBitmap)
+ var formatId = s.FixedLengthString("FormatId", IffChunkType.PackedBitmap, 4);
+ if (formatId != IffChunkType.PackedBitmap)
throw new NotSupportedException($"Invalid IFF header, expected \"PBM \", found \"{formatId}\"");
if (s.IsReading())
@@ -49,17 +49,17 @@ public static InterlacedBitmap Serdes(InterlacedBitmap img, ISerializer s)
var chunk = IffChunk.Serdes(i, null, s);
switch (chunk.TypeId)
{
- case IFFChunkType.BitmapHeader: img.SerdesHeader(s, chunk.Length); break;
- case IFFChunkType.ColorMapping: img.SerdesPalette(s, chunk.Length); break;
- case IFFChunkType.Hotspot: img.SerdesHotspot(s, chunk.Length); break;
+ case IffChunkType.BitmapHeader: img.SerdesHeader(s, chunk.Length); break;
+ case IffChunkType.ColorMapping: img.SerdesPalette(s, chunk.Length); break;
+ case IffChunkType.Hotspot: img.SerdesHotspot(s, chunk.Length); break;
- case IFFChunkType.ColorRanges:
+ case IffChunkType.ColorRanges:
img.ColorRanges ??= new List();
img.ColorRanges.Add(ColorRange.Serdes(img.ColorRanges.Count, null, s));
break;
- case IFFChunkType.Thumbnail: img.SerdesThumbnail(s, chunk.Length); break;
- case IFFChunkType.Body: img.SerdesPixels(s, chunk.Length); break;
+ case IffChunkType.Thumbnail: img.SerdesThumbnail(s, chunk.Length); break;
+ case IffChunkType.Body: img.SerdesPixels(s, chunk.Length); break;
default:
s.Bytes("Unk", null, chunk.Length);
break;
@@ -70,12 +70,12 @@ public static InterlacedBitmap Serdes(InterlacedBitmap img, ISerializer s)
}
else
{
- WriteChunk(s, IFFChunkType.BitmapHeader, (x, n) => img.SerdesHeader(x, n));
- WriteChunk(s, IFFChunkType.ColorMapping, (x, n) => img.SerdesPalette(x, n));
- WriteChunk(s, IFFChunkType.Hotspot, (x, n) => img.SerdesHotspot(x, n));
+ WriteChunk(s, IffChunkType.BitmapHeader, (x, n) => img.SerdesHeader(x, n));
+ WriteChunk(s, IffChunkType.ColorMapping, (x, n) => img.SerdesPalette(x, n));
+ WriteChunk(s, IffChunkType.Hotspot, (x, n) => img.SerdesHotspot(x, n));
s.List(nameof(img.ColorRanges), img.ColorRanges, img.ColorRanges.Count, ColorRange.Serdes);
- WriteChunk(s, IFFChunkType.Thumbnail, (x, n) => img.SerdesThumbnail(x, n));
- WriteChunk(s, IFFChunkType.Body, (x, n) => img.SerdesPixels(x, n));
+ WriteChunk(s, IffChunkType.Thumbnail, (x, n) => img.SerdesThumbnail(x, n));
+ WriteChunk(s, IffChunkType.Body, (x, n) => img.SerdesPixels(x, n));
}
formatChunk.WriteLength(s);
diff --git a/src/Formats/Assets/ItemData.cs b/src/Formats/Assets/ItemData.cs
index 0611180c5..aae3b5234 100644
--- a/src/Formats/Assets/ItemData.cs
+++ b/src/Formats/Assets/ItemData.cs
@@ -12,7 +12,7 @@ public sealed class ItemData
{
public const int SizeOnDisk = 0x28;
public ItemData(ItemId id) => Id = id;
- [JsonIgnore] public StringId Name => Id.ToName();
+ [JsonIgnore] public StringId Name => new(Id.ToName());
public ItemId Id { get; }
public byte Unknown { get; set; } // 0 Always 0
public ItemType TypeId { get; set; } // 1 Item type
@@ -132,13 +132,12 @@ public override string ToString()
return sb.ToString();
}
- public static ItemData Serdes(AssetInfo info, ItemData item, ISerializer s, ISpellManager spellManager)
+ public static ItemData Serdes(AssetId id, ItemData item, ISerializer s, ISpellManager spellManager)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (s == null) throw new ArgumentNullException(nameof(s));
if (spellManager == null) throw new ArgumentNullException(nameof(spellManager));
- item ??= new ItemData(info.AssetId);
+ item ??= new ItemData(id);
item.Unknown = s.UInt8(nameof(item.Unknown), item.Unknown); // 0
item.TypeId = s.EnumU8(nameof(item.TypeId), item.TypeId); // 1
item.SlotType = ((PersistedItemSlotId)s.UInt8(nameof(item.SlotType), (byte)item.SlotType.ToPersisted())).ToMemory(); // 2
diff --git a/src/Formats/Assets/Labyrinth/LabyrinthData.cs b/src/Formats/Assets/Labyrinth/LabyrinthData.cs
index 96cc0e6e0..d4285d994 100644
--- a/src/Formats/Assets/Labyrinth/LabyrinthData.cs
+++ b/src/Formats/Assets/Labyrinth/LabyrinthData.cs
@@ -71,11 +71,10 @@ public int FrameCountForObjectGroup(int i) =>
.Where(x => x is { ObjectInfoNumber: >= 0 } && x.ObjectInfoNumber < Objects.Count)
.Select(x => (long)Objects[x.ObjectInfoNumber].FrameCount));
- public static LabyrinthData Serdes(LabyrinthData d, AssetInfo info, AssetMapping mapping, ISerializer s)
+ public static LabyrinthData Serdes(LabyrinthData d, AssetId id, AssetMapping mapping, ISerializer s)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (s == null) throw new ArgumentNullException(nameof(s));
- d ??= new LabyrinthData { Id = info.AssetId };
+ d ??= new LabyrinthData { Id = id };
if (d.ObjectGroups.Count > WallOffset) throw new InvalidOperationException($"A labyrinth specification can only contain a maximum of {WallOffset} object groups, but {d.Id} contains {d.ObjectGroups.Count}");
if (d.Walls.Count > MaxWalls) throw new InvalidOperationException($"A labyrinth specification can only contain a maximum of {WallOffset} walls, but {d.Id} contains {d.Walls.Count}");
diff --git a/src/Formats/Assets/ListStringSet.cs b/src/Formats/Assets/ListStringSet.cs
index 0eaa777df..455d0d3b5 100644
--- a/src/Formats/Assets/ListStringSet.cs
+++ b/src/Formats/Assets/ListStringSet.cs
@@ -5,15 +5,26 @@ namespace UAlbion.Formats.Assets;
public class ListStringSet : List, IStringSet
{
public ListStringSet() { }
+ public ListStringSet(int capacity) : base(capacity) { }
public ListStringSet(IList existing)
{
Clear();
if (existing != null)
+ {
+ Capacity = existing.Count;
foreach (var s in existing)
Add(s);
+ }
}
- public string GetString(StringId id, string language) => Count > id.SubId ? this[id.SubId] : null;
+ public string GetString(StringId id) => Count > id.SubId ? this[id.SubId] : null;
+ public void SetString(StringId id, string value)
+ {
+ while (Count <= id.SubId)
+ Add(null);
+
+ this[id.SubId] = value;
+ }
public int FindOrAdd(string text)
{
diff --git a/src/Formats/Assets/Maps/BaseMapData.cs b/src/Formats/Assets/Maps/BaseMapData.cs
index 0aaaefbac..5df2c57c3 100644
--- a/src/Formats/Assets/Maps/BaseMapData.cs
+++ b/src/Formats/Assets/Maps/BaseMapData.cs
@@ -22,7 +22,7 @@ public abstract class BaseMapData : IMapData, IJsonPostDeserialise
AssetId IEventSet.Id => Id;
[JsonInclude] public MapId Id { get; protected set; }
- [JsonIgnore] public TextId TextId => Id.ToMapText();
+ [JsonIgnore] public StringSetId StringSetId => Id.ToMapText();
public abstract MapType MapType { get; }
[JsonInclude] public MapFlags Flags { get; set; } // Wait/Rest, Light-Environment, NPC converge range
[JsonInclude] public int Width { get; protected set; }
@@ -269,7 +269,7 @@ protected void SerdesNpcWaypoints(ISerializer s)
}
}
- public static IMapData Serdes(AssetInfo info, IMapData existing, AssetMapping mapping, ISerializer s)
+ public static IMapData Serdes(AssetId id, IMapData existing, AssetMapping mapping, ISerializer s)
{
if (s == null) throw new ArgumentNullException(nameof(s));
if (s.BytesRemaining == 0)
@@ -290,8 +290,8 @@ public static IMapData Serdes(AssetInfo info, IMapData existing, AssetMapping ma
return mapType switch
{
// Indoor/outdoor maps aren't distinguished on disk - it has to be inferred from the tileset
- MapType.TwoD => MapData2D.Serdes(info, (MapData2D)existing, mapping, s),
- MapType.ThreeD => MapData3D.Serdes(info, (MapData3D)existing, mapping, s),
+ MapType.TwoD => MapData2D.Serdes(id, (MapData2D)existing, mapping, s),
+ MapType.ThreeD => MapData3D.Serdes(id, (MapData3D)existing, mapping, s),
_ => throw new NotImplementedException($"Unrecognised map type {mapType} found.")
};
}
diff --git a/src/Formats/Assets/Maps/MapData2D.cs b/src/Formats/Assets/Maps/MapData2D.cs
index 38f452a1d..d5c8a01f5 100644
--- a/src/Formats/Assets/Maps/MapData2D.cs
+++ b/src/Formats/Assets/Maps/MapData2D.cs
@@ -69,14 +69,13 @@ public MapData2D(MapId id, PaletteId paletteId, TilesetId tilesetId, byte width,
Tiles = new MapTile[width * height];
}
- public static MapData2D Serdes(AssetInfo info, MapData2D existing, AssetMapping mapping, ISerializer s)
+ public static MapData2D Serdes(AssetId id, MapData2D existing, AssetMapping mapping, ISerializer s)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (mapping == null) throw new ArgumentNullException(nameof(mapping));
if (s == null) throw new ArgumentNullException(nameof(s));
var startOffset = s.Offset;
- var map = existing ?? new MapData2D { Id = info.AssetId };
+ var map = existing ?? new MapData2D { Id = id };
map.Flags = s.EnumU16(nameof(Flags), map.Flags); // 0
_ = s.UInt8("MapType", (byte)MapType.TwoD); // 2 (always Map2D to start with, may shift to outdoors once we assign the tileset)
diff --git a/src/Formats/Assets/Maps/MapData3D.cs b/src/Formats/Assets/Maps/MapData3D.cs
index ff9594cb2..905b528da 100644
--- a/src/Formats/Assets/Maps/MapData3D.cs
+++ b/src/Formats/Assets/Maps/MapData3D.cs
@@ -70,12 +70,11 @@ public MapData3D(MapId id, PaletteId paletteId, LabyrinthId labyrinthId, int wid
AutomapGraphics = new byte[AutomapGraphicsSize];
}
- public static MapData3D Serdes(AssetInfo info, MapData3D existing, AssetMapping mapping, ISerializer s)
+ public static MapData3D Serdes(AssetId id, MapData3D existing, AssetMapping mapping, ISerializer s)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (s == null) throw new ArgumentNullException(nameof(s));
- var map = existing ?? new MapData3D { Id = info.AssetId };
+ var map = existing ?? new MapData3D { Id = id };
map.Flags = s.EnumU16(nameof(Flags), map.Flags); // 0
var _ = s.UInt8("MapType", (byte)map.MapType); // 2
diff --git a/src/Formats/Assets/Maps/TilesetData.cs b/src/Formats/Assets/Maps/TilesetData.cs
index ba40ab806..e68666343 100644
--- a/src/Formats/Assets/Maps/TilesetData.cs
+++ b/src/Formats/Assets/Maps/TilesetData.cs
@@ -4,6 +4,7 @@
using SerdesNet;
using UAlbion.Config;
using UAlbion.Formats.Ids;
+using UAlbion.Formats.Parsers;
namespace UAlbion.Formats.Assets.Maps;
@@ -16,15 +17,15 @@ public TilesetData() { }
public bool UseSmallGraphics { get; set; } // Careful if renaming: needs to match up to asset property in assets.json
[JsonInclude] public List Tiles { get; private set; } = new();
- public static TilesetData Serdes(TilesetData td, ISerializer s, AssetInfo info)
+ public static TilesetData Serdes(TilesetData td, ISerializer s, AssetLoadContext context)
{
const int dummyTileCount = 1;
if (s == null) throw new ArgumentNullException(nameof(s));
- if (info == null) throw new ArgumentNullException(nameof(info));
+ if (context == null) throw new ArgumentNullException(nameof(context));
int tileCount = td?.Tiles.Count ?? (int)(s.BytesRemaining / 8) + dummyTileCount;
- td ??= new TilesetData(info.AssetId);
- td.UseSmallGraphics = info.Get(AssetProperty.UseSmallGraphics, td.UseSmallGraphics);
+ td ??= new TilesetData(context.AssetId);
+ td.UseSmallGraphics = context.GetProperty(TilesetLoader.UseSmallGraphicsProperty, td.UseSmallGraphics);
if (td.Tiles.Count == 0)
{
diff --git a/src/Formats/Assets/MultiLanguageStringDictionary.cs b/src/Formats/Assets/MultiLanguageStringDictionary.cs
deleted file mode 100644
index 838ceaa50..000000000
--- a/src/Formats/Assets/MultiLanguageStringDictionary.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Collections.Generic;
-
-namespace UAlbion.Formats.Assets;
-
-public class MultiLanguageStringDictionary : Dictionary, IStringSet
-{
- public string GetString(StringId id, string language)
- => TryGetValue(language, out var collection) ? collection.GetString(id, language) : null;
-}
\ No newline at end of file
diff --git a/src/Formats/Assets/ScriptEventSet.cs b/src/Formats/Assets/ScriptEventSet.cs
index 034c07c57..3b04bb181 100644
--- a/src/Formats/Assets/ScriptEventSet.cs
+++ b/src/Formats/Assets/ScriptEventSet.cs
@@ -10,15 +10,15 @@ namespace UAlbion.Formats.Assets;
public class ScriptEventSet : IEventSet
{
- public ScriptEventSet(AssetId id, TextId textId, IList events)
+ public ScriptEventSet(AssetId id, StringSetId stringSetId, IList events)
{
Id = id;
- TextId = textId;
+ StringSetId = stringSetId;
Events = events?.ToArray() ?? throw new ArgumentNullException(nameof(events));
}
public AssetId Id { get; }
- public TextId TextId { get; }
+ public StringSetId StringSetId { get; }
public IList Events { get; }
public IList Chains { get; } = Array.Empty();
public IList ExtraEntryPoints { get; } = Array.Empty();
diff --git a/src/Formats/Assets/SpellData.cs b/src/Formats/Assets/SpellData.cs
index e1e7b0052..b4a8813f7 100644
--- a/src/Formats/Assets/SpellData.cs
+++ b/src/Formats/Assets/SpellData.cs
@@ -3,6 +3,7 @@
using SerdesNet;
using UAlbion.Config;
using UAlbion.Formats.Ids;
+using UAlbion.Formats.Parsers;
namespace UAlbion.Formats.Assets;
@@ -20,7 +21,7 @@ public SpellData(SpellId id, SpellClass school, byte number) // For tests
}
[JsonIgnore] public SpellId Id { get; } // Setters needed for JSON
- public StringId Name { get; set; }
+ public AssetId Name { get; set; }
public SpellClass Class { get; set; }
public byte OffsetInClass { get; set; }
public SpellEnvironments Environments { get; set; }
@@ -28,21 +29,20 @@ public SpellData(SpellId id, SpellClass school, byte number) // For tests
public byte LevelRequirement { get; set; }
public SpellTargets Targets { get; set; }
public byte Unused { get; set; } // Always 0 except for unused spells in school 6
-
- public static SpellData Serdes(SpellData d, AssetInfo info, ISerializer s)
+ public static SpellData Serdes(SpellData d, AssetLoadContext context, ISerializer s)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
+ if (context == null) throw new ArgumentNullException(nameof(context));
if (s == null) throw new ArgumentNullException(nameof(s));
- d ??= new SpellData(info.AssetId);
+ d ??= new SpellData(context.AssetId);
d.Environments = s.EnumU8(nameof(Environments), d.Environments);
d.Cost = s.UInt8(nameof(Cost), d.Cost);
d.LevelRequirement = s.UInt8(nameof(LevelRequirement), d.LevelRequirement);
d.Targets = s.EnumU8(nameof(Targets), d.Targets);
d.Unused = s.UInt8(nameof(Unused), d.Unused);
- d.Name = info.Get(AssetProperty.Name, (TextId)AssetId.None);
- d.Class = info.Get(AssetProperty.MagicSchool, SpellClass.DjiKas);
- d.OffsetInClass = (byte)info.Get(AssetProperty.SpellNumber, 0);
+ d.Name = context.GetProperty(SpellLoader.SpellName);
+ d.Class = context.GetProperty(SpellLoader.MagicSchool);
+ d.OffsetInClass = (byte)context.GetProperty(SpellLoader.SpellNumber);
return d;
}
}
\ No newline at end of file
diff --git a/src/Formats/Assets/StringId.cs b/src/Formats/Assets/StringId.cs
index f6b1d53a2..9a2af6065 100644
--- a/src/Formats/Assets/StringId.cs
+++ b/src/Formats/Assets/StringId.cs
@@ -4,16 +4,14 @@
namespace UAlbion.Formats.Assets;
-public struct StringId : System.IEquatable
+public struct StringId : IEquatable
{
- public StringId(TextId id, ushort subId) { Id = id; SubId = subId; }
+ public StringId(TextId id) { Id = id; SubId = 0; }
+ public StringId(StringSetId id, ushort subId) { Id = id; SubId = subId; }
public override string ToString() => $"{Id}:{SubId}";
public AssetId Id { get; }
public ushort SubId { get; }
- public static implicit operator StringId(TextId id) => ToStringId(id);
- public static StringId ToStringId(TextId id) => FormatUtil.ResolveTextId(id);
-
public override bool Equals(object obj) => obj is StringId other && Equals(other);
public bool Equals(StringId other) => Id == other.Id && SubId == other.SubId;
public static bool operator ==(StringId left, StringId right) => left.Equals(right);
@@ -26,11 +24,17 @@ public static StringId Parse(string s)
throw new ArgumentNullException(nameof(s));
int index = s.IndexOf(':', StringComparison.Ordinal);
- if (index == -1)
- throw new FormatException($"Expected ':' in StringId: \"{s}\"");
- var textId = TextId.Parse(s[..index]);
- var subId = ushort.Parse(s[(index + 1)..]);
- return new StringId(textId, subId);
+ if (index == -1)
+ {
+ var id = TextId.Parse(s);
+ return new StringId(id);
+ }
+ else
+ {
+ var id = StringSetId.Parse(s[..index]);
+ var subId = ushort.Parse(s[(index + 1)..]);
+ return new StringId(id, subId);
+ }
}
}
\ No newline at end of file
diff --git a/src/Formats/Assets/TextIdStringDictionary.cs b/src/Formats/Assets/TextIdStringDictionary.cs
deleted file mode 100644
index a474795b9..000000000
--- a/src/Formats/Assets/TextIdStringDictionary.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Collections.Generic;
-using UAlbion.Formats.Ids;
-
-namespace UAlbion.Formats.Assets;
-
-public class TextIdStringDictionary : Dictionary, IStringSet
-{
- public string GetString(StringId id, string language) => this.GetValueOrDefault(id.Id);
-}
\ No newline at end of file
diff --git a/src/Formats/Assets/WaveLibSample.cs b/src/Formats/Assets/WaveLibSample.cs
index e25ab9cb5..98e5ae8a6 100644
--- a/src/Formats/Assets/WaveLibSample.cs
+++ b/src/Formats/Assets/WaveLibSample.cs
@@ -1,5 +1,4 @@
using System;
-using System.Diagnostics.CodeAnalysis;
using System.Linq;
using SerdesNet;
using UAlbion.Api;
diff --git a/src/Formats/Containers/BinaryOffsetContainer.cs b/src/Formats/Containers/BinaryOffsetContainer.cs
index 102721e0a..42aca3358 100644
--- a/src/Formats/Containers/BinaryOffsetContainer.cs
+++ b/src/Formats/Containers/BinaryOffsetContainer.cs
@@ -1,10 +1,10 @@
using System;
using System.Collections.Generic;
using System.IO;
-using System.Linq;
using SerdesNet;
using UAlbion.Api;
using UAlbion.Config;
+using UAlbion.Config.Properties;
namespace UAlbion.Formats.Containers;
@@ -13,22 +13,21 @@ namespace UAlbion.Formats.Containers;
///
public class BinaryOffsetContainer : IAssetContainer
{
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ public static readonly IntAssetProperty Offset = new("Offset"); // int, used for BinaryOffsetContainer, e.g. MAIN.EXE
+ public static readonly StringAssetProperty Hotspot = new("Hotspot"); // for cursors, formatted like "5 -2"
+
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
using var stream = context.Disk.OpenRead(path);
using var br = new BinaryReader(stream);
- stream.Position = info.Get(AssetProperty.Offset, 0);
- var bytes = br.ReadBytes(info.Width * info.Height);
+ stream.Position = context.GetProperty(Offset);
+ var bytes = br.ReadBytes(context.Node.Width * context.Node.Height);
var ms = new MemoryStream(bytes);
return new AlbionReader(new BinaryReader(ms));
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
=> ApiUtil.Assert("Binary offset containers do not currently support saving");
-
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context) // All sub-items must be given explicitly for binary offset containers
- => FormatUtil.SortedIntsToRanges(info?.Map.Keys.OrderBy(x => x));
}
\ No newline at end of file
diff --git a/src/Formats/Containers/DirectoryContainer.cs b/src/Formats/Containers/DirectoryContainer.cs
index 73c83d964..e5759001f 100644
--- a/src/Formats/Containers/DirectoryContainer.cs
+++ b/src/Formats/Containers/DirectoryContainer.cs
@@ -5,6 +5,8 @@
using System.Text;
using SerdesNet;
using UAlbion.Config;
+using UAlbion.Config.Properties;
+using UAlbion.Formats.Ids;
using UAlbion.Formats.Parsers;
namespace UAlbion.Formats.Containers;
@@ -14,27 +16,31 @@ namespace UAlbion.Formats.Containers;
///
public class DirectoryContainer : IAssetContainer
{
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ static readonly AssetPathPattern DefaultPattern = AssetPathPattern.Build("{0}_{1}_{2}.dat");
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
var subAssets = new Dictionary(); // path and name
// Pattern vars: 0=Index 1=SubItem 2=Name 3=Palette
- var pattern = info.GetPattern(AssetProperty.Pattern, "{0}_{1}_{2}.dat");
+ var pattern = context.GetProperty(AssetProps.Pattern, DefaultPattern);
if (context.Disk.DirectoryExists(path))
{
- foreach (var filePath in context.Disk.EnumerateDirectory(path, pattern.WilcardForIndex(info.Index)))
+ var wildcardPattern = pattern.WilcardForId(context.AssetId);
+ foreach (var filePath in context.Disk.EnumerateFiles(path, wildcardPattern))
{
var filename = Path.GetFileName(filePath);
- if (!pattern.TryParse(filename, out var assetPath))
+ if (!pattern.TryParse(filename, context.AssetId.Type, out var assetPath))
continue;
if (assetPath.PaletteId.HasValue)
- info.Set(AssetProperty.PaletteId, assetPath.PaletteId);
+ {
+ var palId = new PaletteId(assetPath.PaletteId.Value);
+ context.SetProperty(AssetProps.Palette, palId);
+ }
- if (assetPath.Index != info.Index)
+ if (assetPath.AssetId != context.AssetId)
continue;
subAssets[assetPath.SubAsset] = (filePath, assetPath.Name);
@@ -61,10 +67,11 @@ public ISerializer Read(string path, AssetInfo info, SerdesContext context)
});
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
{
if (assets == null) throw new ArgumentNullException(nameof(assets));
if (context == null) throw new ArgumentNullException(nameof(context));
+
if (context.Disk.FileExists(path))
throw new InvalidOperationException($"Cannot save directory container at \"{path}\", as there is already a file with that name.");
@@ -83,12 +90,12 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
using var s = new AlbionReader(br);
var subAssets = PackedChunks.Unpack(s).ToList();
- var pattern = info.GetPattern(AssetProperty.Pattern, "{0}_{1}_{2}.dat");
+ var pattern = info.GetProperty(AssetProps.Pattern, AssetPathPattern.Build("{0}_{1}_{2}.dat"));
if (subAssets.Count == 1)
{
var (subAssetBytes, name) = subAssets[0];
- var filename = name ?? pattern.Format(new AssetPath(info));
+ var filename = name ?? pattern.Format(info.BuildAssetPath());
context.Disk.WriteAllBytes(Path.Combine(path, filename), subAssetBytes);
}
else
@@ -102,7 +109,7 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
if (string.IsNullOrWhiteSpace(name))
name = null;
- var filename = name ?? pattern.Format(new AssetPath(info, i));
+ var filename = name ?? pattern.Format(info.BuildAssetPath(i));
var fullPath = Path.Combine(path, filename);
var dir = Path.GetDirectoryName(fullPath);
@@ -114,26 +121,4 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
}
}
}
-
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
- var subIds = new List();
- if (!context.Disk.DirectoryExists(path))
- return new List<(int, int)> { (0, 1) };
-
- foreach (var filePath in context.Disk.EnumerateDirectory(path))
- {
- var file = Path.GetFileName(filePath);
- int index = file.IndexOf('_', StringComparison.Ordinal);
- var part = index == -1 ? file : file.Substring(0, index);
- if (!int.TryParse(part, out var asInt))
- continue;
-
- subIds.Add(asInt);
- }
-
- subIds.Sort();
- return FormatUtil.SortedIntsToRanges(subIds);
- }
}
diff --git a/src/Formats/Containers/DummyContainer.cs b/src/Formats/Containers/DummyContainer.cs
index 50c030d36..aacfcbefb 100644
--- a/src/Formats/Containers/DummyContainer.cs
+++ b/src/Formats/Containers/DummyContainer.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
+using System.Collections.Generic;
using SerdesNet;
using UAlbion.Config;
@@ -9,11 +7,6 @@ namespace UAlbion.Formats.Containers;
public class DummyContainer : IAssetContainer
{
static readonly EmptySerializer Empty = new();
- public ISerializer Read(string path, AssetInfo info, SerdesContext context) => Empty;
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context) { }
- public List<(int num, int count)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- {
- if (info == null) throw new ArgumentNullException(nameof(info));
- return FormatUtil.SortedIntsToRanges(info.Map.Keys.OrderBy(x => x));
- }
+ public ISerializer Read(string path, AssetLoadContext context) => Empty;
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context) { }
}
\ No newline at end of file
diff --git a/src/Formats/Containers/ItemListContainer.cs b/src/Formats/Containers/ItemListContainer.cs
index 476651c6b..2c160ace3 100644
--- a/src/Formats/Containers/ItemListContainer.cs
+++ b/src/Formats/Containers/ItemListContainer.cs
@@ -14,17 +14,16 @@ namespace UAlbion.Formats.Containers;
///
public class ItemListContainer : IAssetContainer
{
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
var stream = context.Disk.OpenRead(path);
var br = new BinaryReader(stream);
- stream.Position = info.Index * ItemData.SizeOnDisk;
+ stream.Position = context.Index * ItemData.SizeOnDisk;
return new AlbionReader(br, ItemData.SizeOnDisk);
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -41,14 +40,4 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
bw.Write(bytes);
}
}
-
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
- if (!context.Disk.FileExists(path))
- return new List<(int, int)>();
-
- using var f = context.Disk.OpenRead(path);
- return new List<(int, int)> { (0, (int)f.Length / ItemData.SizeOnDisk) };
- }
}
\ No newline at end of file
diff --git a/src/Formats/Containers/JsonObjectContainer.cs b/src/Formats/Containers/JsonObjectContainer.cs
index b6f2310c4..3c67d4026 100644
--- a/src/Formats/Containers/JsonObjectContainer.cs
+++ b/src/Formats/Containers/JsonObjectContainer.cs
@@ -16,15 +16,14 @@ namespace UAlbion.Formats.Containers;
public class JsonObjectContainer : IAssetContainer
{
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The serializer will handle it")]
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
if (!context.Disk.FileExists(path))
return null;
var dict = Load(path, context);
- if (!dict.TryGetValue(info.AssetId, out var token))
+ if (!dict.TryGetValue(context.AssetId, out var token))
return null;
var ms = new MemoryStream(Encoding.UTF8.GetBytes(context.Json.Serialize(token)));
@@ -37,7 +36,7 @@ public ISerializer Read(string path, AssetInfo info, SerdesContext context)
() => { br.Dispose(); ms.Dispose(); });
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
{
if (assets == null) throw new ArgumentNullException(nameof(assets));
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -57,18 +56,7 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
context.Disk.WriteAllText(path, fullText);
}
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
-
- if (!context.Disk.FileExists(path))
- return null;
-
- var dict = Load(path, context);
- return FormatUtil.SortedIntsToRanges(dict.Keys.Select(x => x.Id).OrderBy(x => x));
- }
-
- static IDictionary Load(string path, SerdesContext context)
+ static IDictionary Load(string path, AssetLoadContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
diff --git a/src/Formats/Containers/JsonStringContainer.cs b/src/Formats/Containers/JsonStringContainer.cs
index 7b190e326..d3dc99f74 100644
--- a/src/Formats/Containers/JsonStringContainer.cs
+++ b/src/Formats/Containers/JsonStringContainer.cs
@@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
-using System.Linq;
using System.Text;
using SerdesNet;
using UAlbion.Api;
@@ -16,16 +15,15 @@ namespace UAlbion.Formats.Containers;
public class JsonStringContainer : IAssetContainer
{
[SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The serializer will handle it")]
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
if (!context.Disk.FileExists(path))
return null;
var dict = Load(path, context);
- if (!dict.TryGetValue(info.AssetId, out var value))
+ if (!dict.TryGetValue(context.AssetId, out var value))
return null;
var ms = new MemoryStream(Encoding.UTF8.GetBytes(value));
@@ -38,7 +36,7 @@ public ISerializer Read(string path, AssetInfo info, SerdesContext context)
() => { br.Dispose(); ms.Dispose(); });
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
{
if (assets == null) throw new ArgumentNullException(nameof(assets));
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -55,24 +53,16 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
context.Disk.WriteAllText(path, fullText);
}
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
-
- if (!context.Disk.FileExists(path))
- return null;
-
- var dict = Load(path, context);
- return FormatUtil.SortedIntsToRanges(dict.Keys.Select(x => x.Id).OrderBy(x => x));
- }
-
- static IDictionary Load(string path, SerdesContext context)
+ static IDictionary Load(string path, AssetLoadContext context)
{
var text = context.Disk.ReadAllBytes(path);
var dict = context.Json.Deserialize>(text);
if (dict == null)
throw new FileLoadException($"Could not deserialize \"{path}\"");
- return dict.ToDictionary(x => AssetId.Parse(x.Key), x => x.Value);
+ var dictionary = new Dictionary();
+ foreach (var pair in dict)
+ dictionary.Add(AssetId.Parse(pair.Key), pair.Value);
+ return dictionary;
}
}
\ No newline at end of file
diff --git a/src/Formats/Containers/RawContainer.cs b/src/Formats/Containers/RawContainer.cs
index 396f3dbf4..5b27fd2d9 100644
--- a/src/Formats/Containers/RawContainer.cs
+++ b/src/Formats/Containers/RawContainer.cs
@@ -13,11 +13,10 @@ namespace UAlbion.Formats.Containers;
///
public class RawContainer : IAssetContainer
{
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
- ApiUtil.Assert(info.Index == 0, "SubItem should always be 0 when accessing a non-container file");
+ ApiUtil.Assert(context.Index == 0, "SubItem should always be 0 when accessing a non-container file");
if (!context.Disk.FileExists(path))
return null;
@@ -27,7 +26,7 @@ public ISerializer Read(string path, AssetInfo info, SerdesContext context)
return new AlbionReader(br);
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
{
if (assets == null) throw new ArgumentNullException(nameof(assets));
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -48,7 +47,4 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
var (_, bytes) = assets.Single();
context.Disk.WriteAllBytes(path, bytes);
}
-
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- => new() { (0, 1) };
}
\ No newline at end of file
diff --git a/src/Formats/Containers/SpellListContainer.cs b/src/Formats/Containers/SpellListContainer.cs
index 66cd64b53..012d60564 100644
--- a/src/Formats/Containers/SpellListContainer.cs
+++ b/src/Formats/Containers/SpellListContainer.cs
@@ -15,18 +15,17 @@ namespace UAlbion.Formats.Containers;
public class SpellListContainer : IAssetContainer
{
static readonly byte[] Blank = { 0, 0, 0, 0, 0 };
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
var stream = context.Disk.OpenRead(path);
var br = new BinaryReader(stream);
- stream.Position = info.Index * SpellData.SizeOnDisk;
+ stream.Position = context.Index * SpellData.SizeOnDisk;
return new AlbionReader(br, SpellData.SizeOnDisk);
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
{
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -51,15 +50,4 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
bw.Write(bytes);
}
}
-
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
-
- if (!context.Disk.FileExists(path))
- return new List<(int, int)>();
-
- using var f = context.Disk.OpenRead(path);
- return new List<(int, int)> { (0, (int)f.Length / SpellData.SizeOnDisk) };
- }
}
\ No newline at end of file
diff --git a/src/Formats/Containers/XldContainer.cs b/src/Formats/Containers/XldContainer.cs
index 7471f6979..d3f42aa91 100644
--- a/src/Formats/Containers/XldContainer.cs
+++ b/src/Formats/Containers/XldContainer.cs
@@ -5,6 +5,7 @@
using SerdesNet;
using UAlbion.Api;
using UAlbion.Config;
+using UAlbion.Config.Properties;
using UAlbion.Formats.Assets.Save;
namespace UAlbion.Formats.Containers;
@@ -15,19 +16,25 @@ namespace UAlbion.Formats.Containers;
public class XldContainer : IAssetContainer
{
const string MagicString = "XLD0I";
+ static readonly IntAssetProperty MinimumCount = new("MinimumCount");
static int HeaderSize(int itemCount) => MagicString.Length + 3 + 4 * itemCount;
- public ISerializer Read(string path, AssetInfo info, SerdesContext context)
+ public ISerializer Read(string path, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
+ if (!context.Disk.FileExists(path))
+ return null;
+
using var s = new AlbionReader(new BinaryReader(context.Disk.OpenRead(path)));
- var bytes = LoadAsset(info.Index, s);
+ var bytes = LoadAsset(context.Index, s);
+ if (bytes == null)
+ return null;
+
var ms = new MemoryStream(bytes);
return new AlbionReader(new BinaryReader(ms));
}
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context)
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
{
if (assets == null) throw new ArgumentNullException(nameof(assets));
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -43,7 +50,7 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
foreach (var (info, bytes) in assets)
byIndex[info.Index] = bytes;
- int minCount = assets[0].Item1.File.Get(AssetProperty.MinimumCount, 0);
+ int minCount = assets[0].Item1.GetProperty(MinimumCount);
int count = byIndex
.OrderBy(x => x.Key)
.Last(x => x.Value.Length > 0)
@@ -66,28 +73,11 @@ public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext
s.Bytes(null, buffer, buffer.Length);
}
- public List<(int num, int count)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
-
- if (!context.Disk.FileExists(path))
- return new List<(int, int)>();
-
- using var s = new AlbionReader(new BinaryReader(context.Disk.OpenRead(path)));
- var lengths = HeaderSerdes(null, s);
- int i = 0;
- for (; i < lengths.Length; i++)
- if (lengths[i] > 0)
- break;
-
- return new List<(int, int)> { (i, lengths.Length - i) };
- }
-
static byte[] LoadAsset(int subItem, ISerializer s)
{
var lengths = HeaderSerdes(null, s);
if (subItem >= lengths.Length)
- throw new ArgumentOutOfRangeException($"Tried to load subItem {subItem} from XLD, but it only contains {lengths.Length} items.");
+ return null;
long offset = s.Offset;
offset += lengths.Where((_, i) => i < subItem).Sum();
diff --git a/src/Formats/Containers/ZipContainer.cs b/src/Formats/Containers/ZipContainer.cs
index ba08cb420..bf5b4f56c 100644
--- a/src/Formats/Containers/ZipContainer.cs
+++ b/src/Formats/Containers/ZipContainer.cs
@@ -9,7 +9,7 @@ namespace UAlbion.Formats.Containers;
///
public class ZipContainer : IAssetContainer
{
- public ISerializer Read(string path, AssetInfo info, SerdesContext context) => throw new System.NotImplementedException();
- public void Write(string path, IList<(AssetInfo, byte[])> assets, SerdesContext context) => throw new System.NotImplementedException();
- public List<(int, int)> GetSubItemRanges(string path, AssetFileInfo info, SerdesContext context) => throw new System.NotImplementedException();
+ public ISerializer Read(string path, AssetLoadContext context) => throw new System.NotImplementedException();
+ public void Write(string path, IList<(AssetLoadContext, byte[])> assets, ModContext context)
+ => throw new System.NotImplementedException();
}
\ No newline at end of file
diff --git a/src/Formats/EventFormatter.cs b/src/Formats/EventFormatter.cs
index 494740a13..dd819e1b4 100644
--- a/src/Formats/EventFormatter.cs
+++ b/src/Formats/EventFormatter.cs
@@ -12,10 +12,10 @@ namespace UAlbion.Formats;
public class EventFormatter : IEventFormatter
{
- readonly Func _stringLoadFunc;
+ readonly Func _stringLoadFunc;
readonly AssetId _textSourceId;
- public EventFormatter(Func stringLoadFunc, AssetId textSourceId)
+ public EventFormatter(Func stringLoadFunc, AssetId textSourceId)
{
_stringLoadFunc = stringLoadFunc;
_textSourceId = textSourceId;
@@ -30,7 +30,7 @@ public void Format(IScriptBuilder builder, IEventNode e, int idOffset = 0)
if (e.Event is TextEvent textEvent && _stringLoadFunc != null)
{
var text =
- _stringLoadFunc(textEvent.ToId(_textSourceId))
+ _stringLoadFunc(textEvent.ToId(_textSourceId), null)
.Replace("\"", "\\\"", StringComparison.Ordinal);
builder.Add(ScriptPartType.Comment, $" ; \"{text}\"");
@@ -46,7 +46,7 @@ public void Format(IScriptBuilder builder, IEvent e)
if (e is TextEvent textEvent && _stringLoadFunc != null)
{
var text =
- _stringLoadFunc(textEvent.ToId(_textSourceId))
+ _stringLoadFunc(textEvent.ToId(_textSourceId), null)
.Replace("\"", "\\\"", StringComparison.Ordinal);
builder.Add(ScriptPartType.Comment, $" ; \"{text}\"");
@@ -160,7 +160,7 @@ public void FormatChain(IScriptBuilder builder, IEventNode firstEvent, int inden
}
}
- public void FormatEventSet(IScriptBuilder builder, IList events, int indent = 0) where T : IEventNode
+ void FormatEventSet(IScriptBuilder builder, IList events, int indent = 0) where T : IEventNode
{
if (builder == null) throw new ArgumentNullException(nameof(builder));
if (events == null) return;
diff --git a/src/Formats/Exporters/Tiled/MapImport.cs b/src/Formats/Exporters/Tiled/MapImport.cs
index 191f004cd..e9435a636 100644
--- a/src/Formats/Exporters/Tiled/MapImport.cs
+++ b/src/Formats/Exporters/Tiled/MapImport.cs
@@ -8,10 +8,9 @@ namespace UAlbion.Formats.Exporters.Tiled;
public static class MapImport
{
- public static BaseMapData ToAlbion(this Map map, AssetInfo info, string script)
+ public static BaseMapData ToAlbion(this Map map, AssetId assetId, string script)
{
if (map == null) throw new ArgumentNullException(nameof(map));
- if (info == null) throw new ArgumentNullException(nameof(info));
// Check width/height <= 255
if (map.Width > 256) throw new FormatException($"Map widths above 256 are not currently supported (was {map.Width})");
@@ -26,7 +25,8 @@ public static BaseMapData ToAlbion(this Map map, AssetInfo info, string script)
List markers = new();
List markerTiles = new();
ObjectGroupMapping.LoadObjectGroups(
- info, map,
+ assetId,
+ map,
is3d ? map.TileHeight : map.TileWidth,
map.TileHeight,
eventLayout, triggers, npcs, zones,
@@ -38,7 +38,7 @@ public static BaseMapData ToAlbion(this Map map, AssetInfo info, string script)
if (is3d)
{
var labId = MapperUtil.PropId(map, MapMapping.Prop.Labyrinth, true);
- var map3d = new MapData3D(info.AssetId, paletteId, labId, (byte)map.Width, (byte)map.Height, eventLayout.Events, eventLayout.Chains, npcs, zones);
+ var map3d = new MapData3D(assetId, paletteId, labId, (byte)map.Width, (byte)map.Height, eventLayout.Events, eventLayout.Chains, npcs, zones);
LayerMapping3D.ReadLayers(map3d, map.Layers);
for (int i = 0; i < markerTiles.Count; i++)
@@ -53,7 +53,7 @@ public static BaseMapData ToAlbion(this Map map, AssetInfo info, string script)
{
var tilesetId = MapperUtil.PropId(map, MapMapping.Prop.Tileset, true);
var tiles = LayerMapping2D.ReadMapLayers(map);
- var albionMap2d = new MapData2D(info.AssetId, paletteId, tilesetId, map.Width, map.Height, eventLayout.Events, eventLayout.Chains, npcs, zones);
+ var albionMap2d = new MapData2D(assetId, paletteId, tilesetId, map.Width, map.Height, eventLayout.Events, eventLayout.Chains, npcs, zones);
Array.Copy(tiles, albionMap2d.Tiles, albionMap2d.Tiles.Length);
albionMap = albionMap2d;
}
diff --git a/src/Formats/Exporters/Tiled/ObjectGroupMapping.cs b/src/Formats/Exporters/Tiled/ObjectGroupMapping.cs
index eb3adb190..c3104355a 100644
--- a/src/Formats/Exporters/Tiled/ObjectGroupMapping.cs
+++ b/src/Formats/Exporters/Tiled/ObjectGroupMapping.cs
@@ -39,7 +39,8 @@ public static List BuildObjectGroups(
}
- public static void LoadObjectGroups(AssetInfo info,
+ public static void LoadObjectGroups(
+ AssetId assetId,
Map map,
int tileWidth,
int tileHeight,
@@ -50,7 +51,6 @@ public static void LoadObjectGroups(AssetInfo info,
List markers,
List markerTiles)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (map == null) throw new ArgumentNullException(nameof(map));
if (triggers == null) throw new ArgumentNullException(nameof(triggers));
if (npcs == null) throw new ArgumentNullException(nameof(npcs));
@@ -86,6 +86,6 @@ ushort ResolveEntryPoint(string name)
}
}
- TriggerMapping.LoadZones(zones, info.AssetId, triggers, map);
+ TriggerMapping.LoadZones(zones, assetId, triggers, map);
}
}
\ No newline at end of file
diff --git a/src/Formats/Exporters/Tiled/StampLoader.cs b/src/Formats/Exporters/Tiled/StampLoader.cs
index f4f7159ba..4a8ade8f4 100644
--- a/src/Formats/Exporters/Tiled/StampLoader.cs
+++ b/src/Formats/Exporters/Tiled/StampLoader.cs
@@ -2,6 +2,7 @@
using System.Text;
using SerdesNet;
using UAlbion.Config;
+using UAlbion.Config.Properties;
using UAlbion.Formats.Assets;
using UAlbion.Formats.Ids;
using UAlbion.Formats.Parsers;
@@ -10,9 +11,9 @@ namespace UAlbion.Formats.Exporters.Tiled;
public class StampLoader : IAssetLoader
{
- public BlockList Serdes(BlockList existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public static readonly PathPatternProperty TilesetPattern = new("TilesetPattern", "../Tilesets/{0}_{2}.tsx");
+ public BlockList Serdes(BlockList existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (s == null) throw new ArgumentNullException(nameof(s));
if (context == null) throw new ArgumentNullException(nameof(context));
@@ -20,11 +21,11 @@ public BlockList Serdes(BlockList existing, AssetInfo info, ISerializer s, Serde
{
if (existing == null) throw new ArgumentNullException(nameof(existing));
- var blockListId = (BlockListId)info.AssetId;
+ var blockListId = (BlockListId)context.AssetId;
var tilesetId = blockListId.ToTileset();
- var tilesetPattern = info.GetPattern(AssetProperty.TilesetPattern, "../Tilesets/{0}_{2}.tsx");
- var tilesetPath = tilesetPattern.Format(new AssetPath(tilesetId.Id, 0, null, ConfigUtil.AssetName(tilesetId)));
+ var tilesetPattern = context.GetProperty(TilesetPattern);
+ var tilesetPath = tilesetPattern.Format(new AssetPath(tilesetId, 0, null, ConfigUtil.AssetName(tilesetId)));
var tileset = new Tileset
{
@@ -58,8 +59,8 @@ public BlockList Serdes(BlockList existing, AssetInfo info, ISerializer s, Serde
return list;
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((BlockList) existing, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((BlockList) existing, s, context);
/* .stamp file
{
diff --git a/src/Formats/Exporters/Tiled/TileMapping.cs b/src/Formats/Exporters/Tiled/TileMapping.cs
index fc7ba385d..e6014db4e 100644
--- a/src/Formats/Exporters/Tiled/TileMapping.cs
+++ b/src/Formats/Exporters/Tiled/TileMapping.cs
@@ -4,6 +4,7 @@
using UAlbion.Config;
using UAlbion.Formats.Assets.Labyrinth;
using UAlbion.Formats.Assets.Maps;
+using UAlbion.Formats.Ids;
using static UAlbion.Formats.Exporters.Tiled.MapperUtil;
namespace UAlbion.Formats.Exporters.Tiled;
@@ -33,7 +34,7 @@ static class Prop
public const string UseUnderlayFlags = "UseUnderlayFlags";
}
- public static Tile BuildTile(int id, int index, ushort? imageNumber, List tileProperties, Tilemap2DProperties properties, AssetPathPattern graphicsPattern)
+ public static Tile BuildTile(TilesetId id, int index, ushort? imageNumber, List tileProperties, Tilemap2DProperties properties, AssetPathPattern graphicsPattern)
{
if (properties == null) throw new ArgumentNullException(nameof(properties));
if (graphicsPattern == null) throw new ArgumentNullException(nameof(graphicsPattern));
@@ -116,7 +117,7 @@ static ushort SourceStringToImageNumber(string source, Tilemap2DProperties prope
{
if (string.IsNullOrEmpty(source)) return 0;
if (source == properties.BlankTilePath) return 0xffff;
- if (!graphicsPattern.TryParse(source, out var assetPath)) return 0xffff;
+ if (!graphicsPattern.TryParse(source, AssetType.Unknown, out var assetPath)) return 0xffff;
return (ushort)assetPath.SubAsset;
}
diff --git a/src/Formats/Exporters/Tiled/TiledMapLoader.cs b/src/Formats/Exporters/Tiled/TiledMapLoader.cs
index 56e8a23e8..d0a23664a 100644
--- a/src/Formats/Exporters/Tiled/TiledMapLoader.cs
+++ b/src/Formats/Exporters/Tiled/TiledMapLoader.cs
@@ -3,72 +3,84 @@
using SerdesNet;
using UAlbion.Api.Eventing;
using UAlbion.Config;
+using UAlbion.Config.Properties;
using UAlbion.Formats.Assets.Maps;
namespace UAlbion.Formats.Exporters.Tiled;
public class TiledMapLoader : Component, IAssetLoader
{
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((BaseMapData) existing, info, s, context);
-
- public BaseMapData Serdes(BaseMapData existing, AssetInfo info, ISerializer s, SerdesContext context)
+ // Isometric tileset/map properties
+ public static readonly IntAssetProperty BaseHeight = new("BaseHeight");
+ public static readonly IntAssetProperty TileWidth = new("TileWidth");
+ public static readonly PathPatternProperty TiledCeilingPattern = new("TiledCeilingPattern");
+ public static readonly PathPatternProperty TiledContentsPattern = new("TiledContentsPattern");
+ public static readonly PathPatternProperty TiledFloorPattern = new("TiledFloorPattern");
+ public static readonly PathPatternProperty TiledWallPattern = new("TiledWallPattern");
+ public static readonly StringAssetProperty LargeNpcs = new("LargeNpcs"); // string
+ public static readonly StringAssetProperty SmallNpcs = new("SmallNpcs"); // string
+ public static readonly PathPatternProperty TilesetPattern = new("TilesetPattern", "../Tilesets/{0}_{2}.tsx"); // string
+ public static readonly PathPatternProperty ScriptPattern = new("ScriptPattern"); // string
+
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((BaseMapData) existing, s, context);
+
+ public BaseMapData Serdes(BaseMapData existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (s == null) throw new ArgumentNullException(nameof(s));
if (context == null) throw new ArgumentNullException(nameof(context));
if (!s.IsWriting())
- return Read(info, s, context);
+ return Read(s, context);
- Write(existing, info, s, context);
+ Write(existing, s, context);
return existing;
}
- static string GetScriptFilename(AssetInfo info)
+ static string GetScriptFilename(AssetLoadContext context)
{
- var scriptPattern = info.GetPattern(AssetProperty.ScriptPattern, "");
- return scriptPattern.Format(info);
+ var scriptPattern = context.GetProperty(ScriptPattern);
+ return scriptPattern.Format(context.BuildAssetPath());
}
- void Write(BaseMapData existing, AssetInfo info, ISerializer s, SerdesContext context)
+ void Write(BaseMapData existing, ISerializer s, AssetLoadContext context)
{
(byte[] bytes, string script) = existing switch
{
- MapData2D map2d => Write2D(map2d, info, context),
- MapData3D map3d => Write3D(map3d, info),
+ MapData2D map2d => Write2D(map2d, context),
+ MapData3D map3d => Write3D(map3d, context),
_ => (null, null)
};
if (bytes != null)
s.Bytes(null, bytes, bytes.Length);
else
- Warn($"No bytes were generated when saving map {info.Id}");
+ Warn($"No bytes were generated when saving map {context.AssetId}");
if (script == null)
{
- Warn($"No script for map {info.Id}, aborting script output");
+ Warn($"No script for map {context.AssetId}, aborting script output");
return;
}
- var scriptPath = GetScriptFilename(info);
+ var scriptPath = GetScriptFilename(context);
if (string.IsNullOrEmpty(scriptPath))
{
- Warn($"No script path was set for map {info.Id}, aborting script output");
+ Warn($"No script path was set for map {context.AssetId}, aborting script output");
return;
}
- var assetDir = GetAssetDir(info);
+ var assetDir = GetAssetDir(context);
if (!context.Disk.DirectoryExists(assetDir))
context.Disk.CreateDirectory(assetDir);
context.Disk.WriteAllText(Path.Combine(assetDir, scriptPath), script);
}
- BaseMapData Read(AssetInfo info, ISerializer s, SerdesContext context)
+ BaseMapData Read(ISerializer s, AssetLoadContext context)
{
- var assetDir = GetAssetDir(info);
- var scriptPath = Path.Combine(assetDir, GetScriptFilename(info));
+ var assetDir = GetAssetDir(context);
+ var scriptPath = Path.Combine(assetDir, GetScriptFilename(context));
string script = null;
if (!string.IsNullOrEmpty(scriptPath) && context.Disk.FileExists(scriptPath))
script = context.Disk.ReadAllText(scriptPath);
@@ -76,10 +88,10 @@ BaseMapData Read(AssetInfo info, ISerializer s, SerdesContext context)
var bytes = s.Bytes(null, null, (int)s.BytesRemaining);
using var ms = new MemoryStream(bytes);
var map = Map.Parse(ms);
- return map.ToAlbion(info, script);
+ return map.ToAlbion(context.AssetId, script);
}
- (byte[], string) Write2D(MapData2D map, AssetInfo info, SerdesContext context)
+ (byte[], string) Write2D(MapData2D map, AssetLoadContext context)
{
var assets = Resolve();
TilesetData tileset = assets.LoadTileData(map.TilesetId);
@@ -89,66 +101,66 @@ BaseMapData Read(AssetInfo info, ISerializer s, SerdesContext context)
return (null, null);
}
- var tilesetPattern = info.GetPattern(AssetProperty.TilesetPattern, "../Tilesets/{0}_{2}.tsx");
- var tilesetPath = tilesetPattern.Format(new AssetPath(map.TilesetId.Id, 0, null, ConfigUtil.AssetName(map.TilesetId)));
+ var tilesetPattern = context.GetProperty(TilesetPattern);
+ var tilesetPath = tilesetPattern.Format(new AssetPath(map.TilesetId, 0, null, ConfigUtil.AssetName(map.TilesetId)));
var npcTilesetPath = map.MapType == MapType.TwoDOutdoors
- ? info.Get(AssetProperty.SmallNpcs, "../Tilesets/SmallNPCs.tsx")
- : info.Get(AssetProperty.LargeNpcs, "../Tilesets/LargeNPCs.tsx");
+ ? context.GetProperty(SmallNpcs, "../Tilesets/SmallNPCs.tsx")
+ : context.GetProperty(LargeNpcs, "../Tilesets/LargeNPCs.tsx");
- var assetDir = GetAssetDir(info);
+ var assetDir = GetAssetDir(context);
var npcTileset = Tileset.Load(Path.Combine(assetDir, npcTilesetPath), context.Disk);
npcTileset.Filename = npcTilesetPath; // The path in the map file should be relative to the map path, not to the mod dir so replace it here.
var properties = new Tilemap2DProperties { TileWidth = 16, TileHeight = 16 };
- var formatter = new EventFormatter(assets.LoadString, map.Id.ToMapText());
+ var formatter = new EventFormatter(assets.LoadStringSafe, map.Id.ToMapText());
var (tiledMap, script) = MapExport.FromAlbionMap2D(map, tileset, properties, tilesetPath, npcTileset, formatter);
var mapBytes = FormatUtil.BytesFromTextWriter(tiledMap.Serialize);
return (mapBytes, script);
}
- (byte[], string) Write3D(MapData3D map, AssetInfo info)
+ (byte[], string) Write3D(MapData3D map, AssetLoadContext context)
{
var assets = Resolve();
var destModApplier = Resolve();
- var floorPattern = info.GetPattern(AssetProperty.TiledFloorPattern, "");
- var ceilingPattern = info.GetPattern(AssetProperty.TiledCeilingPattern, "");
- var wallPattern = info.GetPattern(AssetProperty.TiledWallPattern, "");
- var contentsPattern = info.GetPattern(AssetProperty.TiledContentsPattern, "");
+ var floorPattern = context.GetProperty(TiledFloorPattern);
+ var ceilingPattern = context.GetProperty(TiledCeilingPattern);
+ var wallPattern = context.GetProperty(TiledWallPattern);
+ var contentsPattern = context.GetProperty(TiledContentsPattern);
if (floorPattern.IsEmpty || ceilingPattern.IsEmpty || wallPattern.IsEmpty || contentsPattern.IsEmpty)
return (Array.Empty(), null);
- var labInfo = destModApplier.GetAssetInfo(map.LabDataId, null);
+ var labInfo = destModApplier.GetAssetInfo(map.LabDataId);
if (labInfo == null)
{
Error($"Could not load asset info for lab {map.LabDataId} in map {map.Id}");
return (Array.Empty(), null);
}
- var assetPath = new AssetPath(labInfo);
+ var assetPath = new AssetPath(map.LabDataId, 0, labInfo.PaletteId.Id);
var properties = new Tilemap3DProperties
{
- TileWidth = info.Get(AssetProperty.TileWidth, 0),
- TileHeight = info.Get(AssetProperty.BaseHeight, 0),
+ TileWidth = context.GetProperty(TileWidth, 0),
+ TileHeight = context.GetProperty(BaseHeight),
FloorPath = floorPattern.Format(assetPath),
CeilingPath = ceilingPattern.Format(assetPath),
WallPath = wallPattern.Format(assetPath),
ContentsPath = contentsPattern.Format(assetPath),
};
- var formatter = new EventFormatter(assets.LoadString, map.Id.ToMapText());
+ var formatter = new EventFormatter(assets.LoadStringSafe, map.Id.ToMapText());
var (tiledMap, script) = MapExport.FromAlbionMap3D(map, properties, formatter);
var mapBytes = FormatUtil.BytesFromTextWriter(tiledMap.Serialize);
return (mapBytes, script);
}
- string GetAssetDir(AssetInfo info)
+ string GetAssetDir(AssetLoadContext context)
{
var pathResolver = Resolve();
- var destPath = pathResolver.ResolvePath(info.File.Filename);
+ var destPath = pathResolver.ResolvePath(context.Filename);
return destPath;
}
}
diff --git a/src/Formats/Exporters/Tiled/TiledTilesetLoader.cs b/src/Formats/Exporters/Tiled/TiledTilesetLoader.cs
index 7641ce705..0ba0d575b 100644
--- a/src/Formats/Exporters/Tiled/TiledTilesetLoader.cs
+++ b/src/Formats/Exporters/Tiled/TiledTilesetLoader.cs
@@ -3,22 +3,25 @@
using SerdesNet;
using UAlbion.Api.Eventing;
using UAlbion.Config;
+using UAlbion.Config.Properties;
using UAlbion.Formats.Assets.Maps;
namespace UAlbion.Formats.Exporters.Tiled;
public class TiledTilesetLoader : Component, IAssetLoader
{
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((TilesetData)existing, info, s, context);
+ public static readonly StringAssetProperty BlankTilePathProperty = new("BlankTilePath");
+ public static readonly PathPatternProperty GraphicsPattern = new("GraphicsPattern");
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((TilesetData)existing, s, context);
- public TilesetData Serdes(TilesetData existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public TilesetData Serdes(TilesetData existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (s == null) throw new ArgumentNullException(nameof(s));
+ if (context == null) throw new ArgumentNullException(nameof(context));
- var graphicsTemplate = info.Get(AssetProperty.GraphicsPattern, "{0}/{0}_{1}.png");
- var blankTilePath = info.Get(AssetProperty.BlankTilePath, "Blank.png");
+ var graphicsTemplate = context.GetProperty(GraphicsPattern, AssetPathPattern.Build("{0}/{0}_{1}.png"));
+ var blankTilePath = context.GetProperty(BlankTilePathProperty, "Blank.png");
var properties = new Tilemap2DProperties
{
@@ -28,15 +31,17 @@ public TilesetData Serdes(TilesetData existing, AssetInfo info, ISerializer s, S
TileHeight = 16
};
- return s.IsWriting() ? Save(existing, properties, s) : Load(info, properties, s);
+ return s.IsWriting()
+ ? Save(existing, properties, s)
+ : Load(context, properties, s);
}
- static TilesetData Load(AssetInfo info, Tilemap2DProperties properties, ISerializer serializer)
+ static TilesetData Load(AssetLoadContext context, Tilemap2DProperties properties, ISerializer serializer)
{
var xmlBytes = serializer.Bytes(null, null, (int)serializer.BytesRemaining);
using var ms = new MemoryStream(xmlBytes);
var tileset = Tileset.Parse(ms);
- return TilesetMapping.ToAlbion(tileset, info.AssetId, properties);
+ return TilesetMapping.ToAlbion(tileset, context.AssetId, properties);
}
static TilesetData Save(TilesetData tileset, Tilemap2DProperties properties, ISerializer s)
diff --git a/src/Formats/Exporters/Tiled/TilemapProperties.cs b/src/Formats/Exporters/Tiled/TilemapProperties.cs
index b2ee6cb76..ba565c6ec 100644
--- a/src/Formats/Exporters/Tiled/TilemapProperties.cs
+++ b/src/Formats/Exporters/Tiled/TilemapProperties.cs
@@ -1,4 +1,5 @@
-using UAlbion.Formats.Assets.Labyrinth;
+using UAlbion.Config;
+using UAlbion.Formats.Assets.Labyrinth;
namespace UAlbion.Formats.Exporters.Tiled;
@@ -12,7 +13,7 @@ public class TilemapProperties
public class Tilemap2DProperties : TilemapProperties
{
- public string GraphicsTemplate { get; set; }
+ public AssetPathPattern GraphicsTemplate { get; set; }
}
public class Tilemap3DProperties : TilemapProperties
diff --git a/src/Formats/Exporters/Tiled/TilesetMapping.cs b/src/Formats/Exporters/Tiled/TilesetMapping.cs
index 552940638..dccbaa229 100644
--- a/src/Formats/Exporters/Tiled/TilesetMapping.cs
+++ b/src/Formats/Exporters/Tiled/TilesetMapping.cs
@@ -22,13 +22,13 @@ public static Tileset FromAlbion(TilesetData tileset, Tilemap2DProperties proper
if (tileset == null) throw new ArgumentNullException(nameof(tileset));
if (properties == null) throw new ArgumentNullException(nameof(properties));
- var graphicsPattern = AssetPathPattern.Build(properties.GraphicsTemplate);
+ var graphicsPattern = properties.GraphicsTemplate;
List tiles =
tileset.Tiles
.Where(x => !x.IsBlank)
.Select(x =>
TileMapping.BuildTile(
- tileset.Id.Id,
+ tileset.Id,
x.Index,
x.FrameCount > 0 ? x.ImageNumber : null,
TileMapping.BuildTileProperties(x),
@@ -50,7 +50,7 @@ public static Tileset FromAlbion(TilesetData tileset, Tilemap2DProperties proper
for (int f = 1; f < sourceTile.FrameCount; f++)
{
tiles.Add(TileMapping.BuildTile(
- tileset.Id.Id,
+ tileset.Id,
nextId,
(ushort)(sourceTile.ImageNumber + f),
new List { new(Prop.Frame, true) },
@@ -86,7 +86,7 @@ public static TilesetData ToAlbion(Tileset tileset, TilesetId id, Tilemap2DPrope
if (properties == null) throw new ArgumentNullException(nameof(properties));
var t = new TilesetData(id);
- var graphicsPattern = AssetPathPattern.Build(properties.GraphicsTemplate);
+ var graphicsPattern = properties.GraphicsTemplate;
var tileLookup =
tileset.Tiles
.Select(x => TileMapping.InterpretTile(x, properties, graphicsPattern))
diff --git a/src/Formats/Exporters/Tiled/TriggerMapping.cs b/src/Formats/Exporters/Tiled/TriggerMapping.cs
index 867cc027b..a49f19fdd 100644
--- a/src/Formats/Exporters/Tiled/TriggerMapping.cs
+++ b/src/Formats/Exporters/Tiled/TriggerMapping.cs
@@ -94,6 +94,19 @@ static List BuildTriggerProperties(ZoneKey zone, Dictionary $"#{GetHashForString(s) & 0x00ffffff:x}";
+ static int GetHashForString(string s)
+ {
+ if (string.IsNullOrEmpty(s)) return 0;
+ int result = 0;
+ foreach (var c in s)
+ {
+ result *= 17;
+ result ^= char.ToUpperInvariant(c);
+ }
+ return result;
+ }
+
static ObjectGroup BuildTriggerObjectGroup(
int objectGroupId,
string name,
@@ -121,7 +134,7 @@ from r in polygons
{
Id = objectGroupId,
Name = name,
- Color = "#" + (name.GetHashCode(StringComparison.InvariantCulture) & 0x00ffffff).ToString("x"),
+ Color = GetColorForString(name),
Opacity = 0.5f,
Objects = zonePolygons.ToList(),
};
diff --git a/src/Formats/FormatUtil.cs b/src/Formats/FormatUtil.cs
index 18d8e4980..f3eb19d7a 100644
--- a/src/Formats/FormatUtil.cs
+++ b/src/Formats/FormatUtil.cs
@@ -6,9 +6,6 @@
using System.Text;
using SerdesNet;
using UAlbion.Api;
-using UAlbion.Config;
-using UAlbion.Formats.Assets;
-using UAlbion.Formats.Ids;
using UAlbion.Formats.MapEvents;
namespace UAlbion.Formats;
@@ -121,14 +118,6 @@ public static byte[] HexStringToBytes(string s)
return ranges;
}
- public static StringId ResolveTextId(TextId id)
- {
- var result = AssetMapping.Global.TextIdToStringId(id);
- return result.HasValue
- ? new StringId(result.Value.Item1, result.Value.Item2)
- : new StringId(id, 0);
- }
-
public static bool Compare(QueryOperation operation, int value, int immediate) =>
operation switch
{
diff --git a/src/Formats/IAssetLoader.cs b/src/Formats/IAssetLoader.cs
deleted file mode 100644
index bb9032f21..000000000
--- a/src/Formats/IAssetLoader.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using SerdesNet;
-using UAlbion.Config;
-
-namespace UAlbion.Formats;
-
-public interface IAssetLoader
-{
- object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context);
-}
-
-public interface IAssetLoader : IAssetLoader where T : class
-{
- T Serdes(T existing, AssetInfo info, ISerializer s, SerdesContext context); // SerDes = Serialise / Deserialise.
-}
\ No newline at end of file
diff --git a/src/Formats/IAssetManager.cs b/src/Formats/IAssetManager.cs
index 95c74fcd4..7afdffb35 100644
--- a/src/Formats/IAssetManager.cs
+++ b/src/Formats/IAssetManager.cs
@@ -16,7 +16,7 @@ namespace UAlbion.Formats;
public interface IAssetManager : ITextureLoader
{
- AssetInfo GetAssetInfo(AssetId id, string language = null);
+ AssetNode GetAssetInfo(AssetId id, string language = null);
ITexture LoadTexture(SpriteId id);
ITileGraphics LoadTileGraphics(TilesetGfxId id);
object LoadMapObject(MapObjectId id); // Might be an ITexture or a Mesh
@@ -27,10 +27,11 @@ public interface IAssetManager : ITextureLoader
LabyrinthData LoadLabyrinthData(LabyrinthId id);
bool IsStringDefined(TextId id, string language);
bool IsStringDefined(StringId id, string language);
- string LoadString(TextId id);
- string LoadString(StringId id);
- string LoadString(TextId id, string language);
- string LoadString(StringId id, string language);
+ string LoadStringSafe(TextId id, string language = null); // never returns null - will give a "missing string" string instead
+ string LoadStringSafe(StringId id, string language = null); // never returns null - will give a "missing string" string instead
+ string LoadStringRaw(TextId id, string language = null); // can return null
+ string LoadStringRaw(StringId id, string language = null); // can return null
+ IStringSet LoadStringSet(StringSetId id, string language);
ISample LoadSample(SampleId id);
WaveLib LoadWaveLib(WaveLibraryId waveLibraryId);
FlicFile LoadVideo(VideoId id);
diff --git a/src/Formats/IAssetPostProcessor.cs b/src/Formats/IAssetPostProcessor.cs
deleted file mode 100644
index 0f8d80e69..000000000
--- a/src/Formats/IAssetPostProcessor.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using UAlbion.Config;
-
-namespace UAlbion.Formats;
-
-public interface IAssetPostProcessor
-{
- object Process(object asset, AssetInfo info);
-}
\ No newline at end of file
diff --git a/src/Formats/IAssetPostProcessorRegistry.cs b/src/Formats/IAssetPostProcessorRegistry.cs
index a83940d41..e922518b1 100644
--- a/src/Formats/IAssetPostProcessorRegistry.cs
+++ b/src/Formats/IAssetPostProcessorRegistry.cs
@@ -1,6 +1,9 @@
-namespace UAlbion.Formats;
+using System;
+using UAlbion.Config;
+
+namespace UAlbion.Formats;
public interface IAssetPostProcessorRegistry
{
- IAssetPostProcessor GetPostProcessor(string postProcessorName);
+ IAssetPostProcessor GetPostProcessor(Type postProcessorType);
}
\ No newline at end of file
diff --git a/src/Formats/IModApplier.cs b/src/Formats/IModApplier.cs
index f78ae0845..ce9f238ff 100644
--- a/src/Formats/IModApplier.cs
+++ b/src/Formats/IModApplier.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.Text.RegularExpressions;
+using System.Collections.Generic;
using UAlbion.Api.Eventing;
using UAlbion.Config;
using UAlbion.Formats.Assets.Save;
@@ -9,21 +7,17 @@ namespace UAlbion.Formats;
public interface IModApplier : IComponent
{
- void LoadMods(AssetMapping mapping, IPathResolver pathResolver, IReadOnlyList mods);
- AssetInfo GetAssetInfo(AssetId key, string language);
- object LoadAsset(AssetId id);
- object LoadAsset(AssetId id, string language);
- object LoadAssetCached(AssetId assetId);
- string LoadAssetAnnotated(AssetId id, string language);
- SavedGame LoadSavedGame(string path);
IReadOnlyDictionary Languages { get; }
IEnumerable ShaderPaths { get; }
- delegate (object asset, AssetInfo info) AssetLoader(AssetId id, string language);
- void SaveAssets(
- AssetLoader loaderFunc,
- Action flushCacheFunc,
- ISet ids,
- ISet assetTypes,
- Regex filePattern);
+ void LoadMods(AssetMapping mapping, IPathResolver pathResolver, IReadOnlyList mods);
+ SavedGame LoadSavedGame(string path);
+ AssetNode GetAssetInfo(AssetId key, string language = null);
+
+ object LoadAsset(AssetId id, string language = null);
+ object LoadAssetCached(AssetId id, string language = null);
+ string LoadAssetAnnotated(AssetId id, string language = null);
+
+ AssetLoadResult LoadAssetAndNode(AssetId assetId, string language = null);
+ void SaveAssets(AssetConversionOptions options);
}
diff --git a/src/Formats/Ids/EventSetId.g.cs b/src/Formats/Ids/EventSetId.g.cs
index a1da90159..742aa5214 100644
--- a/src/Formats/Ids/EventSetId.g.cs
+++ b/src/Formats/Ids/EventSetId.g.cs
@@ -131,7 +131,7 @@ public static EventSetId SerdesU16BE(string name, EventSetId id, AssetMapping ma
public override bool Equals(object obj) => obj is IAssetId other && other.ToUInt32() == _value;
public int CompareTo(object obj) => (obj is IAssetId other) ? _value.CompareTo(other.ToUInt32()) : -1;
public override int GetHashCode() => unchecked((int)_value);
- public readonly TextId ToEventText() => new TextId(AssetType.EventText, Id);
+ public readonly StringSetId ToEventText() => new StringSetId(AssetType.EventText, Id);
}
public class EventSetIdConverter : TypeConverter
diff --git a/src/Formats/Ids/MapId.g.cs b/src/Formats/Ids/MapId.g.cs
index dc877bf85..97b195361 100644
--- a/src/Formats/Ids/MapId.g.cs
+++ b/src/Formats/Ids/MapId.g.cs
@@ -131,7 +131,7 @@ public static MapId SerdesU16BE(string name, MapId id, AssetMapping mapping, ISe
public override bool Equals(object obj) => obj is IAssetId other && other.ToUInt32() == _value;
public int CompareTo(object obj) => (obj is IAssetId other) ? _value.CompareTo(other.ToUInt32()) : -1;
public override int GetHashCode() => unchecked((int)_value);
- public readonly TextId ToMapText() => new TextId(AssetType.MapText, Id);
+ public readonly StringSetId ToMapText() => new StringSetId(AssetType.MapText, Id);
}
public class MapIdConverter : TypeConverter
diff --git a/src/Formats/Ids/MapTextId.g.cs b/src/Formats/Ids/MapTextId.g.cs
deleted file mode 100644
index 31104e9f2..000000000
--- a/src/Formats/Ids/MapTextId.g.cs
+++ /dev/null
@@ -1,148 +0,0 @@
-// Note: This file was automatically generated using Tools/CodeGenerator.
-// No changes should be made to this file by hand. Instead, the relevant json
-// files should be modified and then GenerateEnums should be used to regenerate
-// the various types.
-using System;
-using System.ComponentModel;
-using System.Globalization;
-using System.Text.Json.Serialization;
-using SerdesNet;
-using UAlbion.Api;
-using UAlbion.Config;
-
-namespace UAlbion.Formats.Ids;
-
-[JsonConverter(typeof(ToStringJsonConverter))]
-[TypeConverter(typeof(MapTextIdConverter))]
-public readonly struct MapTextId : IEquatable, IEquatable, IComparable, IAssetId
-{
- readonly uint _value;
- public MapTextId(AssetType type, int id = 0)
- {
- if (!(type == AssetType.None || type == AssetType.MapText))
- throw new ArgumentOutOfRangeException($"Tried to construct a MapTextId with a type of {type}");
-#if DEBUG
- if (id < 0 || id > 0xffffff)
- throw new ArgumentOutOfRangeException($"Tried to construct a MapTextId with out of range id {id}");
-#endif
- _value = (uint)type << 24 | (uint)id;
- }
-
- public MapTextId(int id)
- {
-#if DEBUG
- if (id < 0 || id > 0xffffff)
- throw new ArgumentOutOfRangeException($"Tried to construct a MapTextId with out of range id {id}");
-#endif
- _value = (uint)AssetType.MapText << 24 | (uint)id;
- }
-
- MapTextId(uint id)
- {
- _value = id;
- if (!(Type == AssetType.None || Type == AssetType.MapText))
- throw new ArgumentOutOfRangeException($"Tried to construct a MapTextId with a type of {Type}");
- }
-
- public MapTextId(IAssetId id)
- {
- _value = id.ToUInt32();
- if (!(Type == AssetType.None || Type == AssetType.MapText))
- throw new ArgumentOutOfRangeException($"Tried to construct a MapTextId with a type of {Type}");
- }
-
- public static MapTextId From(T id) where T : unmanaged, Enum => (MapTextId)AssetMapping.Global.EnumToId(id);
-
- public int ToDisk(AssetMapping mapping)
- {
- if (mapping == null) throw new ArgumentNullException(nameof(mapping));
- var (enumType, enumValue) = AssetMapping.Global.IdToEnum(this);
- return mapping.EnumToId(enumType, enumValue).Id;
- }
-
- public static MapTextId FromDisk(int disk, AssetMapping mapping)
- {
- if (mapping == null) throw new ArgumentNullException(nameof(mapping));
- var (enumType, enumValue) = mapping.IdToEnum(new MapTextId(AssetType.MapText, disk));
- return (MapTextId)AssetMapping.Global.EnumToId(enumType, enumValue);
- }
-
- public static MapTextId SerdesU8(string name, MapTextId id, AssetMapping mapping, ISerializer s)
- {
- if (s == null) throw new ArgumentNullException(nameof(s));
-
- byte diskValue = (byte)id.ToDisk(mapping);
- diskValue = s.UInt8(name, diskValue);
- id = FromDisk(diskValue, mapping);
- if (s.IsCommenting()) s.Comment(id.ToString(), true);
- return id;
- }
-
- public static MapTextId SerdesU16(string name, MapTextId id, AssetMapping mapping, ISerializer s)
- {
- if (s == null) throw new ArgumentNullException(nameof(s));
-
- ushort diskValue = (ushort)id.ToDisk(mapping);
- diskValue = s.UInt16(name, diskValue);
- id = FromDisk(diskValue, mapping);
- if (s.IsCommenting()) s.Comment(id.ToString(), true);
- return id;
- }
-
- public static MapTextId SerdesU16BE(string name, MapTextId id, AssetMapping mapping, ISerializer s)
- {
- if (s == null) throw new ArgumentNullException(nameof(s));
-
- ushort diskValue = (ushort)id.ToDisk(mapping);
- diskValue = s.UInt16BE(name, diskValue);
- id = FromDisk(diskValue, mapping);
- if (s.IsCommenting()) s.Comment(id.ToString(), true);
- return id;
- }
-
- public readonly AssetType Type => (AssetType)((_value & 0xff00_0000) >> 24);
- public readonly int Id => (int)(_value & 0xffffff);
- public static MapTextId None => new MapTextId(AssetType.None);
- public bool IsNone => Type == AssetType.None;
-
- public override string ToString() => AssetMapping.Global.IdToName(this);
- public string ToStringNumeric() => Id.ToString();
- public static AssetType[] ValidTypes = { AssetType.MapText };
- public static MapTextId Parse(string s) => AssetMapping.Global.Parse(s, ValidTypes);
-
- public static implicit operator AssetId(MapTextId id) => AssetId.FromUInt32(id._value);
- public static implicit operator MapTextId(AssetId id) => new MapTextId(id.ToUInt32());
- public static implicit operator TextId(MapTextId id) => TextId.FromUInt32(id._value);
- public static explicit operator MapTextId(TextId id) => new MapTextId(id.ToUInt32());
- public static implicit operator MapTextId(UAlbion.Base.MapText id) => MapTextId.From(id);
-
- public readonly int ToInt32() => unchecked((int)_value);
- public readonly uint ToUInt32() => _value;
- public static MapTextId FromInt32(int id) => new MapTextId(unchecked((uint)id));
- public static MapTextId FromUInt32(uint id) => new MapTextId(id);
- public static bool operator ==(MapTextId x, MapTextId y) => x.Equals(y);
- public static bool operator !=(MapTextId x, MapTextId y) => !(x == y);
- public static bool operator ==(MapTextId x, AssetId y) => x.Equals(y);
- public static bool operator !=(MapTextId x, AssetId y) => !(x == y);
- public static bool operator <(MapTextId x, MapTextId y) => x.CompareTo(y) == -1;
- public static bool operator >(MapTextId x, MapTextId y) => x.CompareTo(y) == 1;
- public static bool operator <=(MapTextId x, MapTextId y) => x.CompareTo(y) != 1;
- public static bool operator >=(MapTextId x, MapTextId y) => x.CompareTo(y) != -1;
- public bool Equals(MapTextId other) => _value == other._value;
- public bool Equals(AssetId other) => _value == other.ToUInt32();
- public override bool Equals(object obj) => obj is IAssetId other && other.ToUInt32() == _value;
- public int CompareTo(object obj) => (obj is IAssetId other) ? _value.CompareTo(other.ToUInt32()) : -1;
- public override int GetHashCode() => unchecked((int)_value);
-}
-
-public class MapTextIdConverter : TypeConverter
-{
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- => sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType);
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- => value is string s ? MapTextId.Parse(s) : base.ConvertFrom(context, culture, value);
-
- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
- => destinationType == typeof(string) ? value.ToString() : base.ConvertTo(context, culture, value, destinationType);
-}
\ No newline at end of file
diff --git a/src/Formats/Ids/SpecialId.g.cs b/src/Formats/Ids/SpecialId.g.cs
index d1f024107..23295ffa4 100644
--- a/src/Formats/Ids/SpecialId.g.cs
+++ b/src/Formats/Ids/SpecialId.g.cs
@@ -112,8 +112,8 @@ public static SpecialId SerdesU16BE(string name, SpecialId id, AssetMapping mapp
public static implicit operator AssetId(SpecialId id) => AssetId.FromUInt32(id._value);
public static implicit operator SpecialId(AssetId id) => new SpecialId(id.ToUInt32());
- public static implicit operator TextId(SpecialId id) => TextId.FromUInt32(id._value);
- public static explicit operator SpecialId(TextId id) => new SpecialId(id.ToUInt32());
+ public static implicit operator StringSetId(SpecialId id) => StringSetId.FromUInt32(id._value);
+ public static explicit operator SpecialId(StringSetId id) => new SpecialId(id.ToUInt32());
public static implicit operator SpecialId(UAlbion.Base.Special id) => SpecialId.From(id);
public readonly int ToInt32() => unchecked((int)_value);
diff --git a/src/Formats/Ids/EventTextId.g.cs b/src/Formats/Ids/StringSetId.g.cs
similarity index 54%
rename from src/Formats/Ids/EventTextId.g.cs
rename to src/Formats/Ids/StringSetId.g.cs
index f929b4334..55b405f06 100644
--- a/src/Formats/Ids/EventTextId.g.cs
+++ b/src/Formats/Ids/StringSetId.g.cs
@@ -12,46 +12,37 @@
namespace UAlbion.Formats.Ids;
-[JsonConverter(typeof(ToStringJsonConverter))]
-[TypeConverter(typeof(EventTextIdConverter))]
-public readonly struct EventTextId : IEquatable, IEquatable, IComparable, IAssetId
+[JsonConverter(typeof(ToStringJsonConverter))]
+[TypeConverter(typeof(StringSetIdConverter))]
+public readonly struct StringSetId : IEquatable, IEquatable, IComparable, IAssetId
{
readonly uint _value;
- public EventTextId(AssetType type, int id = 0)
+ public StringSetId(AssetType type, int id = 0)
{
- if (!(type == AssetType.None || type == AssetType.EventText))
- throw new ArgumentOutOfRangeException($"Tried to construct a EventTextId with a type of {type}");
+ if (!(type == AssetType.None || type >= AssetType.EventText && type <= AssetType.Special))
+ throw new ArgumentOutOfRangeException($"Tried to construct a StringSetId with a type of {type}");
#if DEBUG
if (id < 0 || id > 0xffffff)
- throw new ArgumentOutOfRangeException($"Tried to construct a EventTextId with out of range id {id}");
+ throw new ArgumentOutOfRangeException($"Tried to construct a StringSetId with out of range id {id}");
#endif
_value = (uint)type << 24 | (uint)id;
}
- public EventTextId(int id)
- {
-#if DEBUG
- if (id < 0 || id > 0xffffff)
- throw new ArgumentOutOfRangeException($"Tried to construct a EventTextId with out of range id {id}");
-#endif
- _value = (uint)AssetType.EventText << 24 | (uint)id;
- }
-
- EventTextId(uint id)
+ StringSetId(uint id)
{
_value = id;
- if (!(Type == AssetType.None || Type == AssetType.EventText))
- throw new ArgumentOutOfRangeException($"Tried to construct a EventTextId with a type of {Type}");
+ if (!(Type == AssetType.None || Type >= AssetType.EventText && Type <= AssetType.Special))
+ throw new ArgumentOutOfRangeException($"Tried to construct a StringSetId with a type of {Type}");
}
- public EventTextId(IAssetId id)
+ public StringSetId(IAssetId id)
{
_value = id.ToUInt32();
- if (!(Type == AssetType.None || Type == AssetType.EventText))
- throw new ArgumentOutOfRangeException($"Tried to construct a EventTextId with a type of {Type}");
+ if (!(Type == AssetType.None || Type >= AssetType.EventText && Type <= AssetType.Special))
+ throw new ArgumentOutOfRangeException($"Tried to construct a StringSetId with a type of {Type}");
}
- public static EventTextId From(T id) where T : unmanaged, Enum => (EventTextId)AssetMapping.Global.EnumToId(id);
+ public static StringSetId From(T id) where T : unmanaged, Enum => (StringSetId)AssetMapping.Global.EnumToId(id);
public int ToDisk(AssetMapping mapping)
{
@@ -60,88 +51,91 @@ public int ToDisk(AssetMapping mapping)
return mapping.EnumToId(enumType, enumValue).Id;
}
- public static EventTextId FromDisk(int disk, AssetMapping mapping)
+ public static StringSetId FromDisk(AssetType type, int disk, AssetMapping mapping)
{
if (mapping == null) throw new ArgumentNullException(nameof(mapping));
- var (enumType, enumValue) = mapping.IdToEnum(new EventTextId(AssetType.EventText, disk));
- return (EventTextId)AssetMapping.Global.EnumToId(enumType, enumValue);
+ if (!(type == AssetType.None || type >= AssetType.EventText && type <= AssetType.Special))
+ throw new ArgumentOutOfRangeException($"Tried to construct a StringSetId with a type of {type}");
+
+ var (enumType, enumValue) = mapping.IdToEnum(new StringSetId(type, disk));
+ return (StringSetId)AssetMapping.Global.EnumToId(enumType, enumValue);
}
- public static EventTextId SerdesU8(string name, EventTextId id, AssetMapping mapping, ISerializer s)
+ public static StringSetId SerdesU8(string name, StringSetId id, AssetType type, AssetMapping mapping, ISerializer s)
{
if (s == null) throw new ArgumentNullException(nameof(s));
byte diskValue = (byte)id.ToDisk(mapping);
diskValue = s.UInt8(name, diskValue);
- id = FromDisk(diskValue, mapping);
+ id = FromDisk(type, diskValue, mapping);
if (s.IsCommenting()) s.Comment(id.ToString(), true);
return id;
}
- public static EventTextId SerdesU16(string name, EventTextId id, AssetMapping mapping, ISerializer s)
+ public static StringSetId SerdesU16(string name, StringSetId id, AssetType type, AssetMapping mapping, ISerializer s)
{
if (s == null) throw new ArgumentNullException(nameof(s));
ushort diskValue = (ushort)id.ToDisk(mapping);
diskValue = s.UInt16(name, diskValue);
- id = FromDisk(diskValue, mapping);
+ id = FromDisk(type, diskValue, mapping);
if (s.IsCommenting()) s.Comment(id.ToString(), true);
return id;
}
- public static EventTextId SerdesU16BE(string name, EventTextId id, AssetMapping mapping, ISerializer s)
+ public static StringSetId SerdesU16BE(string name, StringSetId id, AssetType type, AssetMapping mapping, ISerializer s)
{
if (s == null) throw new ArgumentNullException(nameof(s));
ushort diskValue = (ushort)id.ToDisk(mapping);
diskValue = s.UInt16BE(name, diskValue);
- id = FromDisk(diskValue, mapping);
+ id = FromDisk(type, diskValue, mapping);
if (s.IsCommenting()) s.Comment(id.ToString(), true);
return id;
}
public readonly AssetType Type => (AssetType)((_value & 0xff00_0000) >> 24);
public readonly int Id => (int)(_value & 0xffffff);
- public static EventTextId None => new EventTextId(AssetType.None);
+ public static StringSetId None => new StringSetId(AssetType.None);
public bool IsNone => Type == AssetType.None;
public override string ToString() => AssetMapping.Global.IdToName(this);
public string ToStringNumeric() => Id.ToString();
- public static AssetType[] ValidTypes = { AssetType.EventText };
- public static EventTextId Parse(string s) => AssetMapping.Global.Parse(s, ValidTypes);
+ public static AssetType[] ValidTypes = { AssetType.EventText, AssetType.MapText, AssetType.Special };
+ public static StringSetId Parse(string s) => AssetMapping.Global.Parse(s, ValidTypes);
- public static implicit operator AssetId(EventTextId id) => AssetId.FromUInt32(id._value);
- public static implicit operator EventTextId(AssetId id) => new EventTextId(id.ToUInt32());
- public static implicit operator TextId(EventTextId id) => TextId.FromUInt32(id._value);
- public static explicit operator EventTextId(TextId id) => new EventTextId(id.ToUInt32());
- public static implicit operator EventTextId(UAlbion.Base.EventText id) => EventTextId.From(id);
+ public static implicit operator AssetId(StringSetId id) => AssetId.FromUInt32(id._value);
+ public static implicit operator StringSetId(AssetId id) => new StringSetId(id.ToUInt32());
+ public static implicit operator StringSetId(UAlbion.Base.EventText id) => StringSetId.From(id);
+ public static implicit operator StringSetId(UAlbion.Base.MapText id) => StringSetId.From(id);
+ public static implicit operator StringSetId(UAlbion.Base.Special id) => StringSetId.From(id);
public readonly int ToInt32() => unchecked((int)_value);
public readonly uint ToUInt32() => _value;
- public static EventTextId FromInt32(int id) => new EventTextId(unchecked((uint)id));
- public static EventTextId FromUInt32(uint id) => new EventTextId(id);
- public static bool operator ==(EventTextId x, EventTextId y) => x.Equals(y);
- public static bool operator !=(EventTextId x, EventTextId y) => !(x == y);
- public static bool operator ==(EventTextId x, AssetId y) => x.Equals(y);
- public static bool operator !=(EventTextId x, AssetId y) => !(x == y);
- public static bool operator <(EventTextId x, EventTextId y) => x.CompareTo(y) == -1;
- public static bool operator >(EventTextId x, EventTextId y) => x.CompareTo(y) == 1;
- public static bool operator <=(EventTextId x, EventTextId y) => x.CompareTo(y) != 1;
- public static bool operator >=(EventTextId x, EventTextId y) => x.CompareTo(y) != -1;
- public bool Equals(EventTextId other) => _value == other._value;
+ public static StringSetId FromInt32(int id) => new StringSetId(unchecked((uint)id));
+ public static StringSetId FromUInt32(uint id) => new StringSetId(id);
+ public static bool operator ==(StringSetId x, StringSetId y) => x.Equals(y);
+ public static bool operator !=(StringSetId x, StringSetId y) => !(x == y);
+ public static bool operator ==(StringSetId x, AssetId y) => x.Equals(y);
+ public static bool operator !=(StringSetId x, AssetId y) => !(x == y);
+ public static bool operator <(StringSetId x, StringSetId y) => x.CompareTo(y) == -1;
+ public static bool operator >(StringSetId x, StringSetId y) => x.CompareTo(y) == 1;
+ public static bool operator <=(StringSetId x, StringSetId y) => x.CompareTo(y) != 1;
+ public static bool operator >=(StringSetId x, StringSetId y) => x.CompareTo(y) != -1;
+ public bool Equals(StringSetId other) => _value == other._value;
public bool Equals(AssetId other) => _value == other.ToUInt32();
public override bool Equals(object obj) => obj is IAssetId other && other.ToUInt32() == _value;
public int CompareTo(object obj) => (obj is IAssetId other) ? _value.CompareTo(other.ToUInt32()) : -1;
public override int GetHashCode() => unchecked((int)_value);
}
-public class EventTextIdConverter : TypeConverter
+public class StringSetIdConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
=> sourceType == typeof(string) ? true : base.CanConvertFrom(context, sourceType);
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- => value is string s ? EventTextId.Parse(s) : base.ConvertFrom(context, culture, value);
+ => value is string s ? StringSetId.Parse(s) : base.ConvertFrom(context, culture, value);
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
=> destinationType == typeof(string) ? value.ToString() : base.ConvertTo(context, culture, value, destinationType);
diff --git a/src/Formats/Ids/TextId.g.cs b/src/Formats/Ids/TextId.g.cs
index dabb98a8f..79f6e6ce7 100644
--- a/src/Formats/Ids/TextId.g.cs
+++ b/src/Formats/Ids/TextId.g.cs
@@ -19,7 +19,7 @@ namespace UAlbion.Formats.Ids;
readonly uint _value;
public TextId(AssetType type, int id = 0)
{
- if (!(type == AssetType.None || type >= AssetType.EventText && type <= AssetType.Word || type == AssetType.Special))
+ if (!(type == AssetType.None || type >= AssetType.ItemName && type <= AssetType.Word))
throw new ArgumentOutOfRangeException($"Tried to construct a TextId with a type of {type}");
#if DEBUG
if (id < 0 || id > 0xffffff)
@@ -31,14 +31,14 @@ public TextId(AssetType type, int id = 0)
TextId(uint id)
{
_value = id;
- if (!(Type == AssetType.None || Type >= AssetType.EventText && Type <= AssetType.Word || Type == AssetType.Special))
+ if (!(Type == AssetType.None || Type >= AssetType.ItemName && Type <= AssetType.Word))
throw new ArgumentOutOfRangeException($"Tried to construct a TextId with a type of {Type}");
}
public TextId(IAssetId id)
{
_value = id.ToUInt32();
- if (!(Type == AssetType.None || Type >= AssetType.EventText && Type <= AssetType.Word || Type == AssetType.Special))
+ if (!(Type == AssetType.None || Type >= AssetType.ItemName && Type <= AssetType.Word))
throw new ArgumentOutOfRangeException($"Tried to construct a TextId with a type of {Type}");
}
@@ -54,7 +54,7 @@ public int ToDisk(AssetMapping mapping)
public static TextId FromDisk(AssetType type, int disk, AssetMapping mapping)
{
if (mapping == null) throw new ArgumentNullException(nameof(mapping));
- if (!(type == AssetType.None || type >= AssetType.EventText && type <= AssetType.Word || type == AssetType.Special))
+ if (!(type == AssetType.None || type >= AssetType.ItemName && type <= AssetType.Word))
throw new ArgumentOutOfRangeException($"Tried to construct a TextId with a type of {type}");
var (enumType, enumValue) = mapping.IdToEnum(new TextId(type, disk));
@@ -101,17 +101,12 @@ public static TextId SerdesU16BE(string name, TextId id, AssetType type, AssetMa
public override string ToString() => AssetMapping.Global.IdToName(this);
public string ToStringNumeric() => Id.ToString();
- public static AssetType[] ValidTypes = {
- AssetType.EventText, AssetType.ItemName, AssetType.MapText, AssetType.Special,
- AssetType.Text, AssetType.Word };
+ public static AssetType[] ValidTypes = { AssetType.ItemName, AssetType.Text, AssetType.Word };
public static TextId Parse(string s) => AssetMapping.Global.Parse(s, ValidTypes);
public static implicit operator AssetId(TextId id) => AssetId.FromUInt32(id._value);
public static implicit operator TextId(AssetId id) => new TextId(id.ToUInt32());
- public static implicit operator TextId(UAlbion.Base.EventText id) => TextId.From(id);
public static implicit operator TextId(UAlbion.Base.ItemName id) => TextId.From(id);
- public static implicit operator TextId(UAlbion.Base.MapText id) => TextId.From(id);
- public static implicit operator TextId(UAlbion.Base.Special id) => TextId.From(id);
public static implicit operator TextId(UAlbion.Base.SystemText id) => TextId.From(id);
public static implicit operator TextId(UAlbion.Base.UAlbionString id) => TextId.From(id);
public static implicit operator TextId(UAlbion.Base.Word id) => TextId.From(id);
diff --git a/src/Formats/MapEvents/TextEvent.cs b/src/Formats/MapEvents/TextEvent.cs
index 5859680a6..423941802 100644
--- a/src/Formats/MapEvents/TextEvent.cs
+++ b/src/Formats/MapEvents/TextEvent.cs
@@ -11,27 +11,27 @@ namespace UAlbion.Formats.MapEvents;
public class TextEvent : MapEvent, IAsyncEvent // Relies on event chain context to resolve TextId to an enum type / AssetId
{
TextEvent() { }
- public TextEvent(ushort subId, TextLocation location, SheetId SheetId)
+ public TextEvent(ushort subId, TextLocation location, SheetId sheetId)
{
SubId = subId;
Location = location;
var expectedType = AssetTypeForTextLocation(location);
- if (SheetId.Type != expectedType && !SheetId.IsNone)
+ if (sheetId.Type != expectedType && !sheetId.IsNone)
{
throw new FormatException(
"Tried to construct a text event with location " +
- $"{location} and a character id of type {SheetId.Type}, but a {expectedType} was expected");
+ $"{location} and a character id of type {sheetId.Type}, but a {expectedType} was expected");
}
- Speaker = SheetId;
+ Speaker = sheetId;
}
[EventPart("id")] public ushort SubId { get; private set; }
[EventPart("location", true, TextLocation.NoPortrait)] public TextLocation Location { get; private set; }
[EventPart("speaker", true, "None")] public SheetId Speaker { get; private set; }
public override MapEventType EventType => MapEventType.Text;
- public StringId ToId(TextId textId) => new(textId, SubId);
+ public StringId ToId(StringSetId textId) => new(textId, SubId);
public static TextEvent Parse(string[] parts)
{
diff --git a/src/Formats/Parsers/AlbionStringTableLoader.cs b/src/Formats/Parsers/AlbionStringTableLoader.cs
index f8533e182..dfca7b003 100644
--- a/src/Formats/Parsers/AlbionStringTableLoader.cs
+++ b/src/Formats/Parsers/AlbionStringTableLoader.cs
@@ -8,7 +8,7 @@ namespace UAlbion.Formats.Parsers;
public class AlbionStringTableLoader : IAssetLoader
{
- public ListStringSet Serdes(ListStringSet existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public ListStringSet Serdes(ListStringSet existing, ISerializer s, AssetLoadContext context)
{
if (s == null) throw new ArgumentNullException(nameof(s));
if (s.IsReading())
@@ -41,6 +41,6 @@ public ListStringSet Serdes(ListStringSet existing, AssetInfo info, ISerializer
}
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes(existing as ListStringSet, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes(existing as ListStringSet, s, context);
}
diff --git a/src/Formats/Parsers/AmorphousSpriteLoader.cs b/src/Formats/Parsers/AmorphousSpriteLoader.cs
index 94a6a13f2..e9117e6cf 100644
--- a/src/Formats/Parsers/AmorphousSpriteLoader.cs
+++ b/src/Formats/Parsers/AmorphousSpriteLoader.cs
@@ -4,11 +4,13 @@
using SerdesNet;
using UAlbion.Api.Visual;
using UAlbion.Config;
+using UAlbion.Config.Properties;
namespace UAlbion.Formats.Parsers;
public class AmorphousSpriteLoader : IAssetLoader>
{
+ public static readonly StringAssetProperty SubSpritesProperty = new("SubSprites");
static readonly Regex SizesRegex = new(@"
\(\s*
(?'width'\d+),\s*
@@ -40,16 +42,16 @@ public class AmorphousSpriteLoader : IAssetLoader>
}
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((IReadOnlyTexture)existing, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((IReadOnlyTexture)existing, s, context);
- public IReadOnlyTexture Serdes(IReadOnlyTexture existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public IReadOnlyTexture Serdes(IReadOnlyTexture existing, ISerializer s, AssetLoadContext context)
{
if (s == null) throw new ArgumentNullException(nameof(s));
- if (info == null) throw new ArgumentNullException(nameof(info));
+ if (context == null) throw new ArgumentNullException(nameof(context));
return s.IsWriting()
? Write(existing, s)
- : Read(info, s);
+ : Read(context, s);
}
static IReadOnlyTexture Write(IReadOnlyTexture existing, ISerializer s)
@@ -78,9 +80,9 @@ static IReadOnlyTexture Write(IReadOnlyTexture existing, ISerializer
return existing;
}
- static IReadOnlyTexture Read(AssetInfo info, ISerializer s)
+ static IReadOnlyTexture Read(AssetLoadContext context, ISerializer s)
{
- var sizes = ParseSpriteSizes(info.Get(AssetProperty.SubSprites, null));
+ var sizes = ParseSpriteSizes(context.Node.GetProperty(SubSpritesProperty));
int totalWidth = 0;
int totalHeight = 0;
@@ -101,7 +103,7 @@ static IReadOnlyTexture Read(AssetInfo info, ISerializer s)
totalWidth = width;
}
- var result = new SimpleTexture(info.AssetId, totalWidth, totalHeight);
+ var result = new SimpleTexture(context.AssetId, totalWidth, totalHeight);
for (int n = 0; n < frames.Count; n++)
{
diff --git a/src/Formats/Parsers/AtlasPostProcessor.cs b/src/Formats/Parsers/AtlasPostProcessor.cs
index b26f6246d..94128e9de 100644
--- a/src/Formats/Parsers/AtlasPostProcessor.cs
+++ b/src/Formats/Parsers/AtlasPostProcessor.cs
@@ -11,18 +11,18 @@ public class AtlasPostProcessor : IAssetPostProcessor
{
const int MarginPixels = 0;
- public object Process(object asset, AssetInfo info) => Process((IReadOnlyTexture)asset, info);
- public static SimpleTexture Process(IReadOnlyTexture sprite, AssetInfo info)
+ public object Process(object asset, AssetLoadContext context) => Process((IReadOnlyTexture)asset, context);
+ public static SimpleTexture Process(IReadOnlyTexture sprite, AssetLoadContext context)
{
if (sprite == null) throw new ArgumentNullException(nameof(sprite));
- if (info == null) throw new ArgumentNullException(nameof(info));
+ if (context == null) throw new ArgumentNullException(nameof(context));
var layout = SpriteSheetUtil.ArrangeSpriteSheet(sprite.Regions.Count, 1, sprite.GetRegionBuffer);
if (layout.Layers > 1)
throw new InvalidOperationException("Could not layout atlas onto one layer");
var texture = new SimpleTexture(
- info.AssetId, sprite.Id.ToString(),
+ context.AssetId, sprite.Id.ToString(),
layout.Width, layout.Height);
var pixelData = texture.GetMutableLayerBuffer(0).Buffer;
diff --git a/src/Formats/Parsers/AutomapLoader.cs b/src/Formats/Parsers/AutomapLoader.cs
index 299ab8fc0..11dd54703 100644
--- a/src/Formats/Parsers/AutomapLoader.cs
+++ b/src/Formats/Parsers/AutomapLoader.cs
@@ -6,7 +6,8 @@ namespace UAlbion.Formats.Parsers;
public class AutomapLoader : IAssetLoader
{
- public Automap Serdes(Automap existing, AssetInfo info, ISerializer s, SerdesContext context) => Automap.Serdes(existing, s);
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((Automap)existing, info, s, context);
+ public Automap Serdes(Automap existing, ISerializer s, AssetLoadContext context)
+ => Automap.Serdes(existing, s);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((Automap)existing, s, context);
}
diff --git a/src/Formats/Parsers/BlockListLoader.cs b/src/Formats/Parsers/BlockListLoader.cs
index d45414775..79b1af4bf 100644
--- a/src/Formats/Parsers/BlockListLoader.cs
+++ b/src/Formats/Parsers/BlockListLoader.cs
@@ -6,9 +6,9 @@ namespace UAlbion.Formats.Parsers;
public class BlockListLoader : IAssetLoader
{
- public BlockList Serdes(BlockList existing, AssetInfo info, ISerializer s, SerdesContext context)
- => BlockList.Serdes(info?.AssetId.Id ?? 0, existing, s);
+ public BlockList Serdes(BlockList existing, ISerializer s, AssetLoadContext context)
+ => BlockList.Serdes(context?.AssetId.Id ?? 0, existing, s);
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes(existing as BlockList, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes(existing as BlockList, s, context);
}
diff --git a/src/Formats/Parsers/CharacterSheetLoader.cs b/src/Formats/Parsers/CharacterSheetLoader.cs
index 1684379e4..03415d9e0 100644
--- a/src/Formats/Parsers/CharacterSheetLoader.cs
+++ b/src/Formats/Parsers/CharacterSheetLoader.cs
@@ -8,13 +8,12 @@ namespace UAlbion.Formats.Parsers;
public class CharacterSheetLoader : Component, IAssetLoader
{
- public CharacterSheet Serdes(CharacterSheet existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public CharacterSheet Serdes(CharacterSheet existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
- return CharacterSheet.Serdes(info.AssetId, existing, context.Mapping, s, Resolve());
+ return CharacterSheet.Serdes(context.AssetId, existing, context.Mapping, s, Resolve());
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes(existing as CharacterSheet, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes(existing as CharacterSheet, s, context);
}
\ No newline at end of file
diff --git a/src/Formats/Parsers/ChestLoader.cs b/src/Formats/Parsers/ChestLoader.cs
index 437a0b820..9ae77459c 100644
--- a/src/Formats/Parsers/ChestLoader.cs
+++ b/src/Formats/Parsers/ChestLoader.cs
@@ -7,13 +7,12 @@ namespace UAlbion.Formats.Parsers;
public class ChestLoader : IAssetLoader
{
- public Inventory Serdes(Inventory existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public Inventory Serdes(Inventory existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
- return Inventory.SerdesChest(info.AssetId.ToInt32(), existing, context.Mapping, s);
+ return Inventory.SerdesChest(context.AssetId.ToInt32(), existing, context.Mapping, s);
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes(existing as Inventory, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes(existing as Inventory, s, context);
}
diff --git a/src/Formats/Parsers/DummyLoader.cs b/src/Formats/Parsers/DummyLoader.cs
index 6152ebc3f..f5a6c93bb 100644
--- a/src/Formats/Parsers/DummyLoader.cs
+++ b/src/Formats/Parsers/DummyLoader.cs
@@ -5,6 +5,6 @@ namespace UAlbion.Formats.Parsers;
public class DummyLoader : IAssetLoader
{
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
=> existing ?? new object();
}
diff --git a/src/Formats/Parsers/EventSetLoader.cs b/src/Formats/Parsers/EventSetLoader.cs
index d45700f51..fde28b457 100644
--- a/src/Formats/Parsers/EventSetLoader.cs
+++ b/src/Formats/Parsers/EventSetLoader.cs
@@ -7,13 +7,12 @@ namespace UAlbion.Formats.Parsers;
public class EventSetLoader : IAssetLoader
{
- public EventSet Serdes(EventSet existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public EventSet Serdes(EventSet existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
- return EventSet.Serdes(info.AssetId, existing, context.Mapping, s);
+ return EventSet.Serdes(context.AssetId, existing, context.Mapping, s);
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes(existing as EventSet, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes(existing as EventSet, s, context);
}
diff --git a/src/Formats/Parsers/EventSetScriptLoader.cs b/src/Formats/Parsers/EventSetScriptLoader.cs
index ed2918736..2cf627141 100644
--- a/src/Formats/Parsers/EventSetScriptLoader.cs
+++ b/src/Formats/Parsers/EventSetScriptLoader.cs
@@ -10,13 +10,12 @@ namespace UAlbion.Formats.Parsers;
public class EventSetScriptLoader : Component, IAssetLoader
{
- public EventSet Serdes(EventSet existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public EventSet Serdes(EventSet existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (s == null) throw new ArgumentNullException(nameof(s));
if (context == null) throw new ArgumentNullException(nameof(context));
- var id = (EventSetId)info.AssetId;
+ var id = (EventSetId)context.AssetId;
if (s.IsWriting())
{
if (existing == null) throw new ArgumentNullException(nameof(existing));
@@ -30,7 +29,7 @@ public EventSet Serdes(EventSet existing, AssetInfo info, ISerializer s, SerdesC
var bytes = s.Bytes(null, null, (int)s.BytesRemaining);
var script = Encoding.UTF8.GetString(bytes);
var eventLayout = AlbionCompiler.Compile(script);
- return new EventSet(info.AssetId, eventLayout.Events, eventLayout.Chains);
+ return new EventSet(context.AssetId, eventLayout.Events, eventLayout.Chains);
}
return existing;
@@ -38,10 +37,10 @@ public EventSet Serdes(EventSet existing, AssetInfo info, ISerializer s, SerdesC
static string Decompile(EventSetId id, EventSet set, IAssetManager assets)
{
- var eventFormatter = new EventFormatter(assets.LoadString, id.ToEventText());
+ var eventFormatter = new EventFormatter(assets.LoadStringSafe, id.ToEventText());
return eventFormatter.Decompile(set.Events, set.Chains, null).Script;
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((EventSet)existing, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((EventSet)existing, s, context);
}
\ No newline at end of file
diff --git a/src/Formats/Parsers/FixedSizeSpriteLoader.cs b/src/Formats/Parsers/FixedSizeSpriteLoader.cs
index 587cede13..07b888876 100644
--- a/src/Formats/Parsers/FixedSizeSpriteLoader.cs
+++ b/src/Formats/Parsers/FixedSizeSpriteLoader.cs
@@ -4,31 +4,35 @@
using UAlbion.Api;
using UAlbion.Api.Visual;
using UAlbion.Config;
+using UAlbion.Config.Properties;
namespace UAlbion.Formats.Parsers;
public class FixedSizeSpriteLoader : IAssetLoader>
{
public const string TypeString = "UAlbion.Formats.Parsers.FixedSizeSpriteLoader, UAlbion.Formats";
+ public static readonly BoolAssetProperty TransposedProperty = new("Transposed"); // For various textures in the 3D world that are stored with rows/columns flipped
+ public static readonly IntAssetProperty ExtraBytesProperty = new("ExtraBytes"); // Used to suppress assertions when loading original assets that have incorrect sizes
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((IReadOnlyTexture) existing, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((IReadOnlyTexture) existing, s, context);
- public IReadOnlyTexture Serdes(IReadOnlyTexture existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public IReadOnlyTexture Serdes(IReadOnlyTexture existing, ISerializer s, AssetLoadContext context)
{
if (s == null) throw new ArgumentNullException(nameof(s));
- if (info == null) throw new ArgumentNullException(nameof(info));
+ if (context == null) throw new ArgumentNullException(nameof(context));
return s.IsWriting()
- ? Write(existing, info, s)
- : Read(info, s);
+ ? Write(existing, context, s)
+ : Read(context, s);
}
- static IReadOnlyTexture Read(AssetInfo info, ISerializer s)
+ static IReadOnlyTexture Read(AssetLoadContext context, ISerializer s)
{
var streamLength = s.BytesRemaining;
if (streamLength == 0)
return null;
+ var info = context.Node;
int width = info.Width;
int height = info.Height;
@@ -42,10 +46,10 @@ static IReadOnlyTexture Read(AssetInfo info, ISerializer s)
byte[] pixelData = s.Bytes(null, null, (int)streamLength);
int expectedPixelCount = width * height * spriteCount;
- int extra = info.Get(AssetProperty.ExtraBytes, 0);
+ int extra = info.GetProperty(ExtraBytesProperty);
ApiUtil.Assert((expectedPixelCount + extra) == (int)streamLength,
- $"Extra pixels found when loading fixed size sprite {info.AssetId} " +
+ $"Extra pixels found when loading fixed size sprite {context.AssetId} " +
$"({streamLength} bytes for a {width}x{height}x{spriteCount} image, expected {expectedPixelCount}");
var frames = new Region[spriteCount];
@@ -53,17 +57,17 @@ static IReadOnlyTexture Read(AssetInfo info, ISerializer s)
frames[n] = new Region(0, height * n, width, height, width, totalHeight, 0);
var sprite = new SimpleTexture(
- info.AssetId,
- info.AssetId.ToString(),
+ context.AssetId,
+ context.AssetId.ToString(),
width,
height * spriteCount,
pixelData.AsSpan(0, expectedPixelCount), // May be less than the streamlength
frames);
- return info.Get(AssetProperty.Transposed, false) ? Transpose(sprite) : sprite;
+ return info.GetProperty(TransposedProperty) ? Transpose(sprite) : sprite;
}
- static IReadOnlyTexture Write(IReadOnlyTexture existing, AssetInfo info, ISerializer s)
+ static IReadOnlyTexture Write(IReadOnlyTexture existing, AssetLoadContext context, ISerializer s)
{
if (existing == null) throw new ArgumentNullException(nameof(existing));
@@ -74,7 +78,7 @@ static IReadOnlyTexture Write(IReadOnlyTexture existing, AssetInfo i
ApiUtil.Assert(f.Height == frame.Height, "FixedSizeSpriteLoader tried to serialise sprite with non-uniform frames");
}
- var sprite = info.Get(AssetProperty.Transposed, false)
+ var sprite = context.GetProperty(TransposedProperty)
? Transpose(existing)
: existing;
diff --git a/src/Formats/Parsers/FlicLoader.cs b/src/Formats/Parsers/FlicLoader.cs
index e55cebf59..4e5676772 100644
--- a/src/Formats/Parsers/FlicLoader.cs
+++ b/src/Formats/Parsers/FlicLoader.cs
@@ -6,5 +6,5 @@ namespace UAlbion.Formats.Parsers;
public class FlicLoader : IAssetLoader
{
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context) => new FlicFile(s);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context) => new FlicFile(s);
}
diff --git a/src/Formats/Parsers/InputConfigLoader.cs b/src/Formats/Parsers/InputConfigLoader.cs
index 3a6f46926..1d3bc82ba 100644
--- a/src/Formats/Parsers/InputConfigLoader.cs
+++ b/src/Formats/Parsers/InputConfigLoader.cs
@@ -7,20 +7,18 @@ namespace UAlbion.Formats.Parsers;
public class InputConfigLoader : IAssetLoader
{
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((InputConfig)existing, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((InputConfig)existing, s, context);
- public InputConfig Serdes(InputConfig existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public InputConfig Serdes(InputConfig existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
if (context == null) throw new ArgumentNullException(nameof(context));
if (!s.IsWriting())
- return InputConfig.Load(info.File.Filename, context.Disk, context.Json);
+ return InputConfig.Load(context.Filename, context.Disk, context.Json);
if (existing == null) throw new ArgumentNullException(nameof(existing));
- existing.Save(info.File.Filename, context.Disk, context.Json);
+ existing.Save(context.Filename, context.Disk, context.Json);
return existing;
-
}
}
\ No newline at end of file
diff --git a/src/Formats/Parsers/InterlacedBitmapLoader.cs b/src/Formats/Parsers/InterlacedBitmapLoader.cs
index 300aba163..a29b4caf1 100644
--- a/src/Formats/Parsers/InterlacedBitmapLoader.cs
+++ b/src/Formats/Parsers/InterlacedBitmapLoader.cs
@@ -8,21 +8,21 @@ namespace UAlbion.Formats.Parsers;
public class InterlacedBitmapLoader : IAssetLoader>
{
- public IReadOnlyTexture Serdes(IReadOnlyTexture existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public IReadOnlyTexture Serdes(IReadOnlyTexture existing, ISerializer s, AssetLoadContext context)
{
- if (info == null) throw new ArgumentNullException(nameof(info));
+ if (context == null) throw new ArgumentNullException(nameof(context));
if (s.IsWriting()) // TODO: Implement writing if required. May require palette generation, which can get complicated.
return existing;
var ilbm = InterlacedBitmap.Serdes(null, s);
- return s.IsWriting() ? existing : ConvertIlbmToTexture(ilbm, info);
+ return s.IsWriting() ? existing : ConvertIlbmToTexture(ilbm, context);
}
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((IReadOnlyTexture)existing, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((IReadOnlyTexture)existing, s, context);
- static IReadOnlyTexture ConvertIlbmToTexture(InterlacedBitmap bitmap, AssetInfo info)
+ static IReadOnlyTexture ConvertIlbmToTexture(InterlacedBitmap bitmap, AssetLoadContext info)
{
var texture = new SimpleTexture(info.AssetId, bitmap.Width, bitmap.Height);
texture.AddRegion(0, 0, bitmap.Width, bitmap.Height);
diff --git a/src/Formats/Parsers/ItemDataLoader.cs b/src/Formats/Parsers/ItemDataLoader.cs
index 8aac61429..499c2f400 100644
--- a/src/Formats/Parsers/ItemDataLoader.cs
+++ b/src/Formats/Parsers/ItemDataLoader.cs
@@ -1,4 +1,5 @@
-using SerdesNet;
+using System;
+using SerdesNet;
using UAlbion.Api.Eventing;
using UAlbion.Config;
using UAlbion.Formats.Assets;
@@ -7,8 +8,12 @@ namespace UAlbion.Formats.Parsers;
public class ItemDataLoader : Component, IAssetLoader
{
- public ItemData Serdes(ItemData existing, AssetInfo info, ISerializer s, SerdesContext context)
- => ItemData.Serdes(info, existing, s, Resolve());
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes(existing as ItemData, info, s, context);
+ public ItemData Serdes(ItemData existing, ISerializer s, AssetLoadContext context)
+ {
+ if (context == null) throw new ArgumentNullException(nameof(context));
+ return ItemData.Serdes(context.AssetId, existing, s, Resolve());
+ }
+
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes(existing as ItemData, s, context);
}
\ No newline at end of file
diff --git a/src/Formats/Parsers/ItemNameCollector.cs b/src/Formats/Parsers/ItemNameCollector.cs
deleted file mode 100644
index 892a0ab05..000000000
--- a/src/Formats/Parsers/ItemNameCollector.cs
+++ /dev/null
@@ -1,55 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using SerdesNet;
-using UAlbion.Api.Eventing;
-using UAlbion.Config;
-using UAlbion.Formats.Assets;
-
-namespace UAlbion.Formats.Parsers;
-
-public class ItemNameCollector : Component, IAssetLoader
-{
- public MultiLanguageStringDictionary Serdes(MultiLanguageStringDictionary existing, AssetInfo info, ISerializer s, SerdesContext context)
- {
- if (context == null) throw new ArgumentNullException(nameof(context));
- if (s.IsWriting()) return existing;
-
- var assets = Resolve();
- var ids =
- context.Mapping.EnumerateAssetsOfType(AssetType.ItemName)
- // make sure TextId->StringId resolution won't happen
- // and get stuck in infinite recursion
- .Select(x => new StringId(x, 0))
- .ToArray();
-
- var german = ids.ToDictionary(x => x.Id.Id, x => assets.LoadString(x, Base.Language.German));
- var english = ids.ToDictionary(x => x.Id.Id, x => assets.LoadString(x, Base.Language.English));
- var french = ids.ToDictionary(x => x.Id.Id, x => assets.LoadString(x, Base.Language.French));
-
- static void Add(ListStringSet collection, int i, string value)
- {
- while (collection.Count <= i)
- collection.Add(null);
- collection[i] = value;
- }
-
- static ListStringSet Build(IDictionary dict)
- {
- var list = new ListStringSet();
- foreach (var kvp in dict)
- Add(list, kvp.Key, kvp.Value);
- return list;
- }
-
- return new MultiLanguageStringDictionary
- {
- [Base.Language.German] = Build(german),
- [Base.Language.English] = Build(english),
- [Base.Language.French] = Build(french)
- };
- }
-
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((MultiLanguageStringDictionary)existing, info, s, context);
-}
\ No newline at end of file
diff --git a/src/Formats/Parsers/ItemNameCollectorLoader.cs b/src/Formats/Parsers/ItemNameCollectorLoader.cs
new file mode 100644
index 000000000..d9852d9be
--- /dev/null
+++ b/src/Formats/Parsers/ItemNameCollectorLoader.cs
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using SerdesNet;
+using UAlbion.Api.Eventing;
+using UAlbion.Config;
+using UAlbion.Config.Properties;
+using UAlbion.Formats.Assets;
+using UAlbion.Formats.Ids;
+
+namespace UAlbion.Formats.Parsers;
+
+public class ItemNameCollectorLoader : Component, IAssetLoader>
+{
+ public static readonly AssetRangeAssetProperty TargetRange = new("TargetRange");
+ public static readonly StringListAssetProperty TargetLanguages = new("TargetLanguages");
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((Dictionary)existing, s, context);
+
+ public Dictionary Serdes(
+ Dictionary existing,
+ ISerializer s,
+ AssetLoadContext context)
+ {
+ if (context == null) throw new ArgumentNullException(nameof(context));
+
+ if (existing != null)
+ throw new NotSupportedException($"{nameof(StringSetStringLoader)} is read-only");
+
+ var range = context.GetProperty(TargetRange);
+ var languages = context.GetProperty(TargetLanguages);
+
+ var results = new Dictionary();
+ var assets = Resolve();
+ foreach (var language in languages)
+ {
+ if (!results.TryGetValue(language, out var list))
+ {
+ list = new ListStringSet();
+ results[language] = list;
+ }
+
+ var firstId = range.From.Id;
+ foreach (var id in range)
+ {
+ var textId = (TextId)id;
+ var value = assets.LoadStringSafe(textId, language);
+ list.SetString(new StringId(context.AssetId, (ushort)(id.Id - firstId)), value);
+ }
+ }
+
+ return results;
+ }
+}
\ No newline at end of file
diff --git a/src/Formats/Parsers/ItemNameLoader.cs b/src/Formats/Parsers/ItemNameLoader.cs
index 0cebf7138..c2a270c96 100644
--- a/src/Formats/Parsers/ItemNameLoader.cs
+++ b/src/Formats/Parsers/ItemNameLoader.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.Linq;
using SerdesNet;
using UAlbion.Api;
using UAlbion.Config;
@@ -6,56 +8,84 @@
namespace UAlbion.Formats.Parsers;
-public class ItemNameLoader : IAssetLoader
+public class ItemNameLoader : IAssetLoader>
{
const int StringSize = 20;
- public object Serdes(object existing, AssetInfo info, ISerializer s, SerdesContext context)
- => Serdes((MultiLanguageStringDictionary)existing, info, s, context);
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((Dictionary)existing, s, context);
- public MultiLanguageStringDictionary Serdes(MultiLanguageStringDictionary existing, AssetInfo info, ISerializer s, SerdesContext context)
+ public Dictionary Serdes(
+ Dictionary existing,
+ ISerializer s,
+ AssetLoadContext context)
{
if (s == null) throw new ArgumentNullException(nameof(s));
- if (s.IsWriting() && existing == null) throw new ArgumentNullException(nameof(existing));
+ if (context == null) throw new ArgumentNullException(nameof(context));
- existing ??= new MultiLanguageStringDictionary();
- if (!existing.ContainsKey(Base.Language.German)) existing[Base.Language.German] = new ListStringSet();
- if (!existing.ContainsKey(Base.Language.English)) existing[Base.Language.English] = new ListStringSet();
- if (!existing.ContainsKey(Base.Language.French)) existing[Base.Language.French] = new ListStringSet();
+ if (s.IsReading())
+ return Read(s);
+
+ if (existing == null)
+ throw new ArgumentNullException(nameof(existing));
+
+ WriteAll(existing, s);
+ return existing;
+ }
- static void Inner(IStringSet collection, int i, ISerializer s2)
+ static Dictionary Read(ISerializer s)
+ {
+ var german = new ListStringSet();
+ var english = new ListStringSet();
+ var french = new ListStringSet();
+
+ var results = new Dictionary
+ {
+ { Base.Language.German, german },
+ { Base.Language.English, english },
+ { Base.Language.French, french }
+ };
+
+ var streamLength = s.BytesRemaining;
+ ApiUtil.Assert(streamLength % StringSize == 0, "Expected item name file length to be a whole multiple of the string size");
+
+ long end = s.Offset + streamLength;
+ while (s.Offset < end)
{
- var concrete = (ListStringSet)collection;
- while (collection.Count <= i)
- concrete.Add(null);
- concrete[i] = s2.FixedLengthString(null, concrete[i], StringSize);
+ german.Add(s.FixedLengthString(null, null, StringSize));
+ english.Add(s.FixedLengthString(null, null, StringSize));
+ french.Add(s.FixedLengthString(null, null, StringSize));
}
- if (s.IsReading())
+ return results;
+ }
+
+ static void WriteAll(Dictionary existing, ISerializer s)
+ {
+ existing.TryGetValue(Base.Language.German, out var german);
+ existing.TryGetValue(Base.Language.English, out var english);
+ existing.TryGetValue(Base.Language.French, out var french);
+
+ var maxCount = new[]
{
- var streamLength = s.BytesRemaining;
- ApiUtil.Assert(streamLength % StringSize == 0, "Expected item name file length to be a whole multiple of the string size");
+ german?.Count,
+ english?.Count,
+ french?.Count,
+ }.Max();
- int i = 1;
- long end = s.Offset + streamLength;
- while (s.Offset < end)
- {
- Inner(existing[Base.Language.German], i, s);
- Inner(existing[Base.Language.English], i, s);
- Inner(existing[Base.Language.French], i, s);
- i++;
- }
- }
- else
+ if (maxCount == null)
+ throw new InvalidOperationException($"No strings for base languages in dictionary given to {nameof(ItemNameLoader)}");
+
+ for (int i = 0; i < maxCount.Value; i++)
{
- var stringCount = existing[Base.Language.German].Count;
- for (int i = 1; i < stringCount; i++)
- {
- Inner(existing[Base.Language.German], i, s);
- Inner(existing[Base.Language.English], i, s);
- Inner(existing[Base.Language.French], i, s);
- }
+ Write(german, s, i);
+ Write(english, s, i);
+ Write(french, s, i);
}
+ }
- return existing;
+ static void Write(ListStringSet set, ISerializer s, int i)
+ {
+ var text = set.Count <= i ? "" : set[i];
+ s.FixedLengthString(null, text, StringSize);
}
}
diff --git a/src/Formats/Parsers/ItemNameMetaLoader.cs b/src/Formats/Parsers/ItemNameMetaLoader.cs
new file mode 100644
index 000000000..cbc740894
--- /dev/null
+++ b/src/Formats/Parsers/ItemNameMetaLoader.cs
@@ -0,0 +1,37 @@
+using System;
+using System.Collections.Generic;
+using SerdesNet;
+using UAlbion.Api.Eventing;
+using UAlbion.Config;
+using UAlbion.Config.Properties;
+using UAlbion.Formats.Assets;
+
+namespace UAlbion.Formats.Parsers;
+
+public class ItemNameMetaLoader : Component, IAssetLoader
+{
+ public static readonly AssetIdAssetProperty TargetProperty = new("Target");
+ public ListStringSet Serdes(ListStringSet existing, ISerializer s, AssetLoadContext context)
+ {
+ if (context == null) throw new ArgumentNullException(nameof(context));
+ var targetId = context.GetProperty(TargetProperty);
+ if (targetId == AssetId.None)
+ return null;
+
+ if (existing != null)
+ throw new NotSupportedException($"{nameof(ItemNameMetaLoader)} is read-only");
+
+ var applier = Resolve();
+ var target = applier.LoadAssetCached(targetId, null);
+
+ if (target is not Dictionary dict)
+ throw new FormatException($"Expected target \"{targetId}\" to be a {nameof(Dictionary)} but it was {target?.GetType()}");
+
+ return dict.TryGetValue(context.Language, out var list)
+ ? list
+ : null;
+ }
+
+ public object Serdes(object existing, ISerializer s, AssetLoadContext context)
+ => Serdes((ListStringSet)existing, s, context);
+}
\ No newline at end of file
diff --git a/src/Formats/Parsers/JsonLoader.cs b/src/Formats/Parsers/JsonLoader.cs
index 465ea1f1b..b040bbd2f 100644
--- a/src/Formats/Parsers/JsonLoader.cs
+++ b/src/Formats/Parsers/JsonLoader.cs
@@ -7,7 +7,7 @@ namespace UAlbion.Formats.Parsers;
public class JsonLoader