|
import os |
|
import json |
|
import struct |
|
import UnityPy |
|
|
|
current_dir = os.path.abspath(os.path.dirname(__file__)) |
|
|
|
romfs_dir = f"{current_dir}/romfs" |
|
data = { |
|
"XLSXContent_FieldEncountTable": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Dpr/scriptableobjects/gamesettings", |
|
"path_id": -9035030829162387677, |
|
}, |
|
"XLSXContent_TrainerTable": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Dpr/masterdatas", |
|
"path_id": 676024375065692598, |
|
}, |
|
"fld_item": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Dpr/ev_script", |
|
"path_id": -4074276362271022109, |
|
}, |
|
"hide_item": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Dpr/ev_script", |
|
"path_id": 4463973245290848484, |
|
}, |
|
"XLSXContent_EvolveTable": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Pml/personal_masterdatas", |
|
"path_id": 5139195221601552760, |
|
}, |
|
"XLSXContent_GrowTable": {}, |
|
"XLSXContent_ItemTable": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Pml/personal_masterdatas", |
|
"path_id": 252928009371549925, |
|
}, |
|
# "XLSXContent_ItemTable": { |
|
# "file_path": "Data/StreamingAssets/AssetAssistant/Pml/personal_masterdatas", |
|
# "path": "assets/pml/data/itemtable.asset", |
|
# }, |
|
"XLSXContent_UgItemTable": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Pml/personal_masterdatas", |
|
"path_id": -5431921521366313060, |
|
}, |
|
"english": { |
|
"file_path": "Data/StreamingAssets/AssetAssistant/Message", |
|
"path_id": 8474889802433302621, |
|
}, |
|
} |
|
|
|
|
|
def read(table: str): |
|
conf = data[table] |
|
file_path = conf["file_path"] |
|
if "path_id" in conf: |
|
path_id = conf["path_id"] |
|
env = UnityPy.load(f"{romfs_dir}/{file_path}") |
|
obj = [obj for obj in env.objects if obj.path_id == path_id][0] |
|
else: |
|
path = conf["path"] |
|
env = UnityPy.load(f"{romfs_dir}/{file_path}", path) # FIXME |
|
obj = env.objects[0] |
|
return obj.read_typetree() |
|
|
|
|
|
def check_evolve(table): |
|
for entry in table["Evolve"]: |
|
if len(entry["ar"]) > 0: |
|
# ar.0 |
|
# 1 = frienship |
|
# 2 = High Friendship (Day) |
|
# 3 = High Friendship (Night) |
|
# 4 = Lvl |
|
# 5 = traide |
|
# 6 = traide + object |
|
# 8 = stone |
|
# 9 = Lvl + (Atk > Def) |
|
# 10 = Lvl + (Atk = Def) |
|
# 11 = Lvl + (Atk < Def) |
|
# 12 = Random |
|
# 13 = Random |
|
# 14 = Pokeball and space in the party -> Shedinja |
|
# 16 = High Beauty Condition |
|
# 17 = Lvl + male |
|
# 18 = Lvl + female |
|
# 19 = Day + object |
|
# 20 = night + object |
|
# 21 = attack (ar.1) |
|
# 22 = Lvl + Pokemon in party |
|
# 23 = Lvl + male |
|
# 24 = Lvl + female |
|
# 25 = Mt. Coronet |
|
# ar.1 object id or attack id or pokemon id ? |
|
# ar.2 next id?monsno |
|
# ar.3 form ? |
|
# ar.4 level |
|
assert not entry["ar"][0] in [18, 7, 15, 17, 26], f"condition {entry}" |
|
if len(entry["ar"]) > 5: |
|
assert not entry["ar"][5] in [18, 7, 15, 17, 26], f"condition {entry}" |
|
assert len(entry["ar"]) <= 10, f"size {entry}" |
|
|
|
|
|
def build_item_table(table, itemnames): |
|
for script in table["Scripts"]: |
|
print(script["Label"]) |
|
for cmd in script["Commands"]: |
|
for arg in cmd["Arg"]: |
|
if arg["argType"] == 1: |
|
f_data = struct.unpack('!f', arg["data"].to_bytes(4, "big"))[0] |
|
arg["data"] = f_data |
|
|
|
job, args = cmd["Arg"][0]["data"], cmd["Arg"][1:] |
|
if job in [41, 187, 194]: |
|
idx = int(args[0]["data"]) |
|
itemname = itemnames[idx] |
|
print("WTF", job, args[0], script["Label"], itemname) |
|
|
|
return table |
|
|
|
|
|
def build_evolve_table(table): |
|
def is_lvl_evolve(cond): |
|
return cond in [24, 23, 22, 18, 17, 11, 10, 9, 4] |
|
|
|
default = { |
|
"prevmons": 0, |
|
"prevlvl": 0, |
|
"condition": 0, |
|
} |
|
evolve_table = [default.copy() for x in range(0, 493)] |
|
for entry in table["Evolve"]: |
|
curmon = entry["id"] |
|
count = len(entry["ar"]) / 5 |
|
for idx in range(0, int(count)): |
|
offset = idx * 5 |
|
condition = entry["ar"][0 + offset] |
|
# element_id = entry["ar"][1+offset] |
|
nextmons = entry["ar"][2 + offset] |
|
# formno = entry["ar"][3+offset] |
|
level = entry["ar"][4 + offset] |
|
|
|
child = evolve_table[nextmons - 1] |
|
child["condition"] = condition |
|
|
|
if is_lvl_evolve(condition) and level > 0: |
|
child["prevlvl"] = level |
|
# assert curmon != 412, f"{entry}" |
|
assert curmon < 493 or child["prevmons"] > 0, f"{entry}" |
|
if curmon > 493: |
|
continue |
|
child["prevmons"] = curmon |
|
|
|
# current = evolve_table[curmon-1]["level"] = level |
|
# current["level"] = level |
|
# child["prevmons"] = curmon |
|
|
|
for entry in evolve_table: |
|
parent = entry["prevmons"] |
|
level = entry["prevlvl"] |
|
condition = entry["condition"] |
|
real_level = level |
|
while parent != 0: |
|
current = evolve_table[parent - 1] |
|
if level and is_lvl_evolve(condition): |
|
real_level = level |
|
break |
|
level = current["prevlvl"] |
|
condition = current["condition"] |
|
parent = current["prevmons"] |
|
|
|
entry["prevlvl"] = real_level |
|
return evolve_table |
|
|
|
|
|
def format_evolve_table(table): |
|
for idx, entry in enumerate(table): |
|
print( |
|
"{ .prevmons = %d, .prevlvl = %d }, // Pokémon: %d" |
|
% (entry["prevmons"], entry["prevlvl"], idx + 1) |
|
) |
|
|
|
|
|
# out = read("XLSXContent_FieldEncountTable") |
|
# out = read("XLSXContent_TrainerTable") |
|
# items = read("XLSXContent_ItemTable") |
|
# ugitems = read("XLSXContent_UgItemTable") |
|
def get_str(wordDataArray): |
|
if len(wordDataArray) <=0: |
|
return None |
|
return wordDataArray[0]["str"] |
|
itemnames = [ |
|
get_str(label["wordDataArray"]) for label in read("english")["labelDataArray"] |
|
] |
|
|
|
# out = read("hide_item") |
|
out = read("fld_item") |
|
out = build_item_table(out, itemnames) |
|
|
|
# out = read("XLSXContent_EvolveTable") |
|
# out = build_evolve_table(out) |
|
# format_evolve_table(out) |
|
print(json.dumps(out, indent=2)) |