From ee404253935db840bba952454e5c29a92ad6aae8 Mon Sep 17 00:00:00 2001 From: Martin Michelsen Date: Thu, 7 May 2026 22:33:15 -0700 Subject: [PATCH] add ItemParameterTable binary serialization; make JSON the default format --- README.md | 61 +- TODO.md | 2 - src/ItemNameIndex.cc | 10 +- src/ItemParameterTable.cc | 1180 +++++++++++++---- src/ItemParameterTable.hh | 13 +- src/ItemTranslationTable.cc | 8 +- src/Main.cc | 33 +- src/SendCommands.cc | 58 +- src/ServerState.cc | 42 +- src/ServerState.hh | 14 +- src/ShellCommands.cc | 3 + system/blueburst/ItemPMT.prs | 1 - system/item-tables/ItemPMT-bb-v4.prs | Bin 21068 -> 0 bytes system/item-tables/ItemPMT-dc-11-2000.prs | Bin 4833 -> 0 bytes system/item-tables/ItemPMT-dc-nte.prs | Bin 4600 -> 0 bytes system/item-tables/ItemPMT-dc-v1.prs | Bin 5755 -> 0 bytes system/item-tables/ItemPMT-dc-v2.prs | 1 - system/item-tables/ItemPMT-gc-ep3-nte.prs | 1 - system/item-tables/ItemPMT-gc-ep3.prs | 1 - system/item-tables/ItemPMT-gc-nte.prs | Bin 5674 -> 0 bytes system/item-tables/ItemPMT-gc-v3.prs | Bin 15673 -> 0 bytes system/item-tables/ItemPMT-pc-nte.prs | 1 - system/item-tables/ItemPMT-pc-v2.prs | Bin 8454 -> 0 bytes system/item-tables/ItemPMT-xb-v3.prs | Bin 15685 -> 0 bytes system/item-tables/translation-table.json | 48 +- tests/item-parameter-table.test.sh | 73 + .../item-parameter-tables/bb-v4.expected.bin | Bin 0 -> 86880 bytes .../dc-11-2000.expected.bin | Bin 0 -> 12608 bytes .../item-parameter-tables/dc-nte.expected.bin | Bin 0 -> 12480 bytes .../item-parameter-tables/dc-v1.expected.bin | Bin 0 -> 13696 bytes .../item-parameter-tables/dc-v2.expected.bin | Bin 0 -> 24928 bytes .../gc-ep3-nte.expected.bin | Bin 0 -> 63680 bytes .../item-parameter-tables/gc-ep3.expected.bin | Bin 0 -> 63680 bytes .../item-parameter-tables/gc-nte.expected.bin | Bin 0 -> 30144 bytes .../item-parameter-tables/gc-v3.expected.bin | Bin 0 -> 63680 bytes .../item-parameter-tables/pc-nte.expected.bin | Bin 0 -> 24928 bytes .../item-parameter-tables/pc-v2.expected.bin | Bin 0 -> 24928 bytes .../item-parameter-tables/xb-v3.expected.bin | Bin 0 -> 63680 bytes 38 files changed, 1156 insertions(+), 394 deletions(-) delete mode 120000 system/blueburst/ItemPMT.prs delete mode 100644 system/item-tables/ItemPMT-bb-v4.prs delete mode 100644 system/item-tables/ItemPMT-dc-11-2000.prs delete mode 100644 system/item-tables/ItemPMT-dc-nte.prs delete mode 100644 system/item-tables/ItemPMT-dc-v1.prs delete mode 120000 system/item-tables/ItemPMT-dc-v2.prs delete mode 120000 system/item-tables/ItemPMT-gc-ep3-nte.prs delete mode 120000 system/item-tables/ItemPMT-gc-ep3.prs delete mode 100644 system/item-tables/ItemPMT-gc-nte.prs delete mode 100644 system/item-tables/ItemPMT-gc-v3.prs delete mode 120000 system/item-tables/ItemPMT-pc-nte.prs delete mode 100644 system/item-tables/ItemPMT-pc-v2.prs delete mode 100644 system/item-tables/ItemPMT-xb-v3.prs create mode 100755 tests/item-parameter-table.test.sh create mode 100644 tests/item-parameter-tables/bb-v4.expected.bin create mode 100644 tests/item-parameter-tables/dc-11-2000.expected.bin create mode 100644 tests/item-parameter-tables/dc-nte.expected.bin create mode 100644 tests/item-parameter-tables/dc-v1.expected.bin create mode 100644 tests/item-parameter-tables/dc-v2.expected.bin create mode 100644 tests/item-parameter-tables/gc-ep3-nte.expected.bin create mode 100644 tests/item-parameter-tables/gc-ep3.expected.bin create mode 100644 tests/item-parameter-tables/gc-nte.expected.bin create mode 100644 tests/item-parameter-tables/gc-v3.expected.bin create mode 100644 tests/item-parameter-tables/pc-nte.expected.bin create mode 100644 tests/item-parameter-tables/pc-v2.expected.bin create mode 100644 tests/item-parameter-tables/xb-v3.expected.bin diff --git a/README.md b/README.md index dcd7e2d7..52e051ee 100644 --- a/README.md +++ b/README.md @@ -780,36 +780,37 @@ newserv has many CLI options, which can be used to access functionality other th The data formats that newserv can convert to/from are: -| Format | Encode/compress action | Decode/extract action | -|-------------------------------------|---------------------------|------------------------------| -| PRS compression | `compress-prs` | `decompress-prs` | -| PR2/PRC compression | `compress-pr2` | `decompress-pr2` | -| BC0 compression | `compress-bc0` | `decompress-bc0` | -| Raw encrypted data | `encrypt-data` | `decrypt-data` | -| Episode 3 command mask | `encrypt-trivial-data` | `decrypt-trivial-data` | -| Challenge Mode rank text | `encrypt-challenge-data` | `decrypt-challenge-data` | -| PSO DC quest file (.vms) | None | `decode-vms` | -| PSO GC quest file (.gci) | None | `decode-gci` | -| Download quest file (.dlq) | None | `decode-dlq` | -| Server quest file (.qst) | `encode-qst` | `decode-qst` | -| PSO DC save file (.vms) | `encrypt-vms-save` | `decrypt-vms-save` | -| PSO PC save file | `encrypt-pc-save` | `decrypt-pc-save` | -| PSO GC save file (.gci) | `encrypt-gci-save` | `decrypt-gci-save` | -| PSO Xbox save file | None | `decrypt-xbox-save` | -| PSO GC snapshot file | None | `decode-gci-snapshot` | -| Quest script (.bin) | `assemble-quest-script` | `disassemble-quest-script` | -| Quest map (.dat) | None | `disassemble-quest-map` | -| AFS archive (.afs) | None | `extract-afs` | -| BML archive (.bml) | None | `extract-bml` | -| PPK archive (.ppk) | None | `extract-ppk` | -| GSL archive (.gsl) | `generate-gsl` | `extract-gsl` | -| GVM texture (.gvm) | `encode-gvm` | None | -| Bitmap font (.fon) | `encode-bitmap-font` | `decode-bitmap-font` | -| Text archive | `encode-text-archive` | `decode-text-archive` | -| Unicode text set | `encode-unicode-text-set` | `decode-unicode-text-set` | -| Word Select data set | None | `decode-word-select-set` | -| Set data table | None | `disassemble-set-data-table` | -| Rare item table (AFS/GSL/JSON/HTML) | `convert-rare-item-set` | `convert-rare-item-set` | +| Format | Encode/compress action | Decode/extract action | +|-------------------------------------|-------------------------------|-------------------------------| +| PRS compression | `compress-prs` | `decompress-prs` | +| PR2/PRC compression | `compress-pr2` | `decompress-pr2` | +| BC0 compression | `compress-bc0` | `decompress-bc0` | +| Raw encrypted data | `encrypt-data` | `decrypt-data` | +| Episode 3 command mask | `encrypt-trivial-data` | `decrypt-trivial-data` | +| Challenge Mode rank text | `encrypt-challenge-data` | `decrypt-challenge-data` | +| PSO DC quest file (.vms) | None | `decode-vms` | +| PSO GC quest file (.gci) | None | `decode-gci` | +| Download quest file (.dlq) | None | `decode-dlq` | +| Server quest file (.qst) | `encode-qst` | `decode-qst` | +| PSO DC save file (.vms) | `encrypt-vms-save` | `decrypt-vms-save` | +| PSO PC save file | `encrypt-pc-save` | `decrypt-pc-save` | +| PSO GC save file (.gci) | `encrypt-gci-save` | `decrypt-gci-save` | +| PSO Xbox save file | None | `decrypt-xbox-save` | +| PSO GC snapshot file | None | `decode-gci-snapshot` | +| Quest script (.bin) | `assemble-quest-script` | `disassemble-quest-script` | +| Quest map (.dat) | None | `disassemble-quest-map` | +| AFS archive (.afs) | None | `extract-afs` | +| BML archive (.bml) | None | `extract-bml` | +| PPK archive (.ppk) | None | `extract-ppk` | +| GSL archive (.gsl) | `generate-gsl` | `extract-gsl` | +| GVM texture (.gvm) | `encode-gvm` | None (use resource_dasm) | +| Bitmap font (.fon) | `encode-bitmap-font` | `decode-bitmap-font` | +| Text archive | `encode-text-archive` | `decode-text-archive` | +| Unicode text set | `encode-unicode-text-set` | `decode-unicode-text-set` | +| Word Select data set | None | `decode-word-select-set` | +| Set data table | None | `disassemble-set-data-table` | +| Rare item table (AFS/GSL/JSON/HTML) | `convert-rare-item-set` | `convert-rare-item-set` | +| Item definitions (ItemPMT) | `encode-item-parameter-table` | `decode-item-parameter-table` | There are several actions that don't fit well into the table above, which let you do other things: diff --git a/TODO.md b/TODO.md index 67d10977..63eb3710 100644 --- a/TODO.md +++ b/TODO.md @@ -30,8 +30,6 @@ ## PSOBB -- Figure out why Pouilly Slime EXP doesn't work - Make server-specified rare enemies work with maps loaded by the proxy -- Implement serialization for various table types (ItemPMT, ItemPT, etc.) - Record some BB tests - Add all necessary Guild Card number rewrites in BB commands on the proxy diff --git a/src/ItemNameIndex.cc b/src/ItemNameIndex.cc index ad3d66bf..1c79c9bf 100644 --- a/src/ItemNameIndex.cc +++ b/src/ItemNameIndex.cc @@ -1086,7 +1086,7 @@ void ItemNameIndex::print_table(FILE* stream) const { phosg::fwrite_fmt(stream, "ITEM COMBINATIONS\n"); phosg::fwrite_fmt(stream, " ---USE + -EQUIP => RESULT MLV GND LVL CLS\n"); - for (const auto& combo_list_it : pmt->all_item_combinations()) { + for (const auto& combo_list_it : pmt->item_combinations_index()) { for (const auto& combo : combo_list_it.second) { phosg::fwrite_fmt(stream, " {:02X}{:02X}{:02X} + {:02X}{:02X}{:02X} => {:02X}{:02X}{:02X}", combo.used_item[0], combo.used_item[1], combo.used_item[2], @@ -1222,22 +1222,22 @@ void ItemNameIndex::print_table(FILE* stream) const { phosg::fwrite_fmt(stream, "SOUND REMAPS\n"); phosg::fwrite_fmt(stream, " -SOUND1- => RT:[...] CC:[...]\n"); - for (const auto& [sound_id, remaps] : pmt->get_all_sound_remaps()) { + for (const auto& remap : pmt->get_all_sound_remaps()) { std::string rt_str; - for (uint32_t rt_sound_id : remaps.by_rt_index) { + for (uint32_t rt_sound_id : remap.by_rt_index) { if (!rt_str.empty()) { rt_str += ","; } rt_str += std::format("{:08X}", rt_sound_id); } std::string cc_str; - for (uint32_t cc_sound_id : remaps.by_char_class) { + for (uint32_t cc_sound_id : remap.by_char_class) { if (!cc_str.empty()) { cc_str += ","; } cc_str += std::format("{:08X}", cc_sound_id); } - phosg::fwrite_fmt(stream, " {:08X} => RT:[{}] CC:[{}]\n", sound_id, rt_str, cc_str); + phosg::fwrite_fmt(stream, " {:08X} => RT:[{}] CC:[{}]\n", remap.sound_id, rt_str, cc_str); } phosg::fwrite_fmt(stream, "TECH BOOSTS\n"); diff --git a/src/ItemParameterTable.cc b/src/ItemParameterTable.cc index fcfebd02..8788762f 100644 --- a/src/ItemParameterTable.cc +++ b/src/ItemParameterTable.cc @@ -4,6 +4,77 @@ using namespace std; +/* General notes on the ItemPMT formats: + * + * Sega apparently serialized the fields in this order, so we do the same in BinaryItemParameterTableT::serialize. + * There's likely no reason for this order, though it appears they made an effort to place fields that don't + * contain pointers before fields that do. + * DCTE 112K V1 V2 GCTE GCV3 XBV3 V4 R + * 0000 0000 0000 0008 0040 0040 0040 00040 armor_table[0][1] + * 030C 030C ---- ---- ---- ---- ---- ----- * shield_stat_boost_index_table // -> uint8_t[armor_table[1].count] + * 0334 0334 03A8 0590 0874 0EE8 0EE8 01500 armor_table[0][0] + * 0668 0668 ---- ---- ---- ---- ---- ----- * armor_stat_boost_index_table // -> uint8_t[armor_table[0].count] + * 0694 0694 0780 0AA0 0E5C 14D0 14D0 02020 unit_table[0] + * 08B4 08B4 0AB0 0DDC 12DC 1960 1960 02804 mag_table[0] + * 0B74 0B74 0D70 1264 16B4 1FA8 1FA8 03118 tool_table[0][0] (the rest follow immediately) + * 0E54 0F24 1120 1874 1B3C 2C8C 2C8C 04348 weapon_table[0][0] (the rest follow immediately) + * 1908 199C ---- ---- ---- ---- ---- ----- * weapon_stat_boost_index_table // -> uint8_t[max(weapon.id : weapon_table) - (ItemStarsFirstID - 1)] + * 1994 1A28 1DB0 2E4C 37A4 A7FC A7FC 0DE7C * photon_color_table // -> PhotonColorEntry[...] + * 1C64 1CF8 2080 32CC 3A74 AACC AACC 0E194 * weapon_range_table // -> WeaponRange[...] (indexed by data1_1, but also by RangedSpecial::weapon_range_index + a version-dependent constant, and also by the result of a vfunc call on some TItemWeapons) + * 1F98 202C 23C8 3DF8 47BC B88C B8A0 0F4B8 * weapon_kind_table // -> uint8_t[...] + * 1FBF 2053 23F0 3E84 484C B938 B94C 0F5A8 * weapon_sale_divisor_table // -> uint8_t[...] on DC protos; float[...] on all other versions + * 1FE6 207A 248C 40A8 4A80 BBCC BBE0 0F83C * non_weapon_sale_divisor_table // -> NonWeaponSaleDivisors + * 1FE9 20D5 249C 40B8 4A90 BBDC BBF0 0F84C mag_feed_table (data) + * 22A9 233D 275C 4378 4D50 BE9C BEB0 0FB0C * star_value_table // -> uint8_t[...] (indexed by .id from weapon, armor, etc.) + * 23EE 2484 28A2 ---- ---- ---- ---- ----- * unknown_a1 // TODO + * 275E 27F4 2C12 4540 4F72 C100 C114 0FE3C * special_table // -> Special[...] + * 2804 2898 2CB8 45E4 5018 C1A4 C1B8 0FEE0 * weapon_effect_table // -> WeaponEffect[...] + * ---- ---- ---- 5704 61B8 D6E4 D6F8 11C80 * shield_effect_table // -> ShieldEffect[...] (indexed by data1[2]) + * ---- ---- ---- ---- 68B0 DE48 DE5C 12754 * sound_remap_table // -> {count, offset -> {sound_id, by_rt_index_offset -> uint32_t[SoundRemapRTTableSize], by_char_class_offset -> uint32_t[12]}} // Leaves first, then array refs going up the tree; forward order on the leaves (as if it matters); everything just before this offset + * 2CE4 2D78 3198 58DC 68B8 DE50 DE64 1275C * stat_boost_table // -> StatBoost[...] + * ---- ---- ---- ---- 69D8 DF88 DF9C 12894 * max_tech_level_table // -> MaxTechniqueLevels + * ---- ---- ---- ---- 6ABC E06C E080 12978 combination_table[0] + * ---- ---- ---- ---- 6B1C EB8C EBA0 14278 * tech_boost_table // -> TechBoostEntry[...] + * ---- ---- ---- ---- ---- EEBC EED0 14698 unwrap_table[0][0] (the rest follow immediately) + * ---- ---- ---- ---- ---- EF24 EF38 14700 unsealable_table[0] + * ---- ---- ---- ---- ---- EF28 EF3C 14710 ranged_special_table[0] + * 2D94 2E28 3258 5A5C 6E4C EF90 EF9C 1478C * armor_table // -> {count, offset -> ArmorOrShieldV*[count]}][2] + * 2DA4 2E38 3268 5A6C 6E5C EFA0 EFAC 1479C * unit_table // -> {count, offset -> UnitV*[count]} (last if out of range) + * 2DAC 2E40 3270 5A74 6E64 EFA8 EFB4 147A4 * mag_table // -> {count, offset -> MagV*[count]} + * 2DB4 2E48 3278 5A7C 6E6C EFB0 EFBC 147AC * tool_table // -> {count, offset -> ToolV*[count]}[...] (last if out of range) + * 2E1C 2EB8 32E8 5AFC 6F0C F078 F084 14884 * weapon_table // -> {count, offset -> WeaponV*[count]}[...] + * ---- ---- ---- ---- 737C F5D0 F5DC 14FF4 * combination_table // -> {count, offset -> ItemCombination[count]} + * ---- ---- ---- ---- ---- F5D8 F5E4 14FFC unwrap_table[0] (the rest follow immediately) + * ---- ---- ---- ---- ---- F5F0 F5FC 15014 * unwrap_table // -> {count, offset -> {count, offset -> EventItem[count]}[count] + * ---- ---- ---- ---- ---- F5F8 F604 1501C * unsealable_table // -> {count, offset -> UnsealableItem[count]} + * ---- ---- ---- ---- ---- F600 F60C 15024 * ranged_special_table // -> {count, offset -> RangedSpecial[count]} + * 2F54 2FF0 3420 5F4C 7384 F608 F614 1502C * mag_feed_table (offsets) // -> MagFeedResultsTable + * + * Some hardcoded constants are different across versions. Our parser/serializer doesn't use some of them, but + * these constants are (all values in hex): + * DCTE / 112K / V1 / V2 / GCTE / GCV3 / XBV3 / V4 + * Weapon class count: 27 / 27 / 27 / 89 / 8D / AA / AA / ED + * Tool class count: 0D / 0E / 0E / 10 / 13 / 18 / 18 / 1B + * Item stars first ID: 22 / 26 / 26 / 4E / 76 / 94 / 94 / B1 + * Item stars last ID: 168 / 16C / 16C / 215 / 298 / 2F7 / 2F7 / 437 + * Special stars start index: AA / AE / AE / 138 / 1A3 / 1CB / 1CB / 256 + * Special count: 28 / 28 / 29 / 29 / 29 / 29 / 29 / 29 + * Photon color count: 14 / 14 / 14 / 20 / 20 / 20 / 20 / 20 + * Sound RT table size: 00 / 00 / 00 / 00 / 4F / 58 / 58 / 6A + * + * Oddities discovered in the various formats: + * - DC NTE through DC V1: + * - The mag count is wrong; there are 0x2C mags defined in the file but the ArrayRef has a count of only 0x28. + * - A few of the tool table entries are encoded out of order. This isn't a bug, just a curiosity. + * - A few of the weapon table entries are encoded out of order as well. + * - One of the weapon classes has an incorrect count, so it also includes the first weapon of the next class. + * - V2: + * - All of the quirks from V1, except the mag count is now correct. + * - The placeholder entries were added in most of the item tables (weapon, armor, shield, unit and mag, but not + * tool). The counts (major count, for weapons) are off by one for this reason, hence HasImplicitPlaceholders. + * - V3 and later: All of the oddities from V2 and earlier are gone. + */ + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Utilities @@ -90,10 +161,10 @@ ItemParameterTable::Weapon ItemParameterTable::Weapon::from_json(const phosg::JS ret.trail2_x = json.get_int("Trail2X"); ret.trail2_y = json.get_int("Trail2Y"); ret.color = json.get_int("Color"); - const auto& unknown_a1 = json.get_list("UnknownA1"); - ret.unknown_a1[0] = unknown_a1[0]->as_int(); - ret.unknown_a1[1] = unknown_a1[1]->as_int(); - ret.unknown_a1[2] = unknown_a1[2]->as_int(); + uint32_t unknown_a1 = json.get_int("UnknownA1"); + ret.unknown_a1[0] = unknown_a1 >> 16; + ret.unknown_a1[1] = unknown_a1 >> 8; + ret.unknown_a1[2] = unknown_a1; ret.unknown_a4 = json.get_int("UnknownA4"); ret.unknown_a5 = json.get_int("UnknownA5"); ret.tech_boost_entry_index = json.get_int("TechBoostEntryIndex"); @@ -120,7 +191,7 @@ phosg::JSON ItemParameterTable::Weapon::json() const { ret.emplace("Trail2X", this->trail2_x); ret.emplace("Trail2Y", this->trail2_y); ret.emplace("Color", this->color); - ret.emplace("UnknownA1", phosg::JSON::list({this->unknown_a1[0], this->unknown_a1[1], this->unknown_a1[2]})); + ret.emplace("UnknownA1", (this->unknown_a1[0] << 16) | (this->unknown_a1[1] << 8) | this->unknown_a1[2]); ret.emplace("UnknownA4", this->unknown_a4); ret.emplace("UnknownA5", this->unknown_a5); ret.emplace("TechBoostEntryIndex", this->tech_boost_entry_index); @@ -315,13 +386,13 @@ ItemParameterTable::TechBoost ItemParameterTable::TechBoost::from_json(const pho ItemParameterTable::TechBoost ret; ret.tech_num1 = json.get_int("TechNum1"); ret.flags1 = json.get_int("Flags1"); - ret.amount1 = json.get_int("Amount1"); + ret.amount1 = json.get_float("Amount1"); ret.tech_num2 = json.get_int("TechNum2"); ret.flags2 = json.get_int("Flags2"); - ret.amount2 = json.get_int("Amount2"); + ret.amount2 = json.get_float("Amount2"); ret.tech_num3 = json.get_int("TechNum3"); ret.flags3 = json.get_int("Flags3"); - ret.amount3 = json.get_int("Amount3"); + ret.amount3 = json.get_float("Amount3"); return ret; } phosg::JSON ItemParameterTable::TechBoost::json() const { @@ -392,14 +463,14 @@ ItemParameterTable::PhotonColorEntry ItemParameterTable::PhotonColorEntry::from_ ret.unknown_a1 = json.get_int("UnknownA1"); const auto& unknown_a2 = json.get_list("UnknownA2"); const auto& unknown_a3 = json.get_list("UnknownA3"); - ret.unknown_a2.x = unknown_a2.at(0)->as_int(); - ret.unknown_a2.y = unknown_a2.at(1)->as_int(); - ret.unknown_a2.z = unknown_a2.at(2)->as_int(); - ret.unknown_a2.t = unknown_a2.at(3)->as_int(); - ret.unknown_a3.x = unknown_a3.at(0)->as_int(); - ret.unknown_a3.y = unknown_a3.at(1)->as_int(); - ret.unknown_a3.z = unknown_a3.at(2)->as_int(); - ret.unknown_a3.t = unknown_a3.at(3)->as_int(); + ret.unknown_a2.x = unknown_a2.at(0)->as_float(); + ret.unknown_a2.y = unknown_a2.at(1)->as_float(); + ret.unknown_a2.z = unknown_a2.at(2)->as_float(); + ret.unknown_a2.t = unknown_a2.at(3)->as_float(); + ret.unknown_a3.x = unknown_a3.at(0)->as_float(); + ret.unknown_a3.y = unknown_a3.at(1)->as_float(); + ret.unknown_a3.z = unknown_a3.at(2)->as_float(); + ret.unknown_a3.t = unknown_a3.at(3)->as_float(); return ret; } phosg::JSON ItemParameterTable::PhotonColorEntry::json() const { @@ -444,8 +515,8 @@ phosg::JSON ItemParameterTable::WeaponEffect::json() const { ItemParameterTable::WeaponRange ItemParameterTable::WeaponRange::from_json(const phosg::JSON& json) { ItemParameterTable::WeaponRange ret; - ret.unknown_a1 = json.get_int("UnknownA1"); - ret.unknown_a2 = json.get_int("UnknownA2"); + ret.unknown_a1 = json.get_float("UnknownA1"); + ret.unknown_a2 = json.get_float("UnknownA2"); ret.unknown_a3 = json.get_int("UnknownA3"); ret.unknown_a4 = json.get_int("UnknownA4"); ret.unknown_a5 = json.get_int("UnknownA5"); @@ -512,11 +583,18 @@ phosg::JSON ItemParameterTable::json() const { for (size_t data1_1 = 0; data1_1 < this->num_weapon_classes(); data1_1++) { size_t class_size = this->num_weapons_in_class(data1_1); uint8_t weapon_kind = this->get_weapon_kind(data1_1); - float sale_divisor = this->get_sale_divisor(0, data1_1); + std::optional sale_divisor; + if (data1_1 < this->num_weapon_sale_divisors()) { + sale_divisor = this->get_sale_divisor(0, data1_1); + } for (size_t data1_2 = 0; data1_2 < class_size; data1_2++) { auto weapon_dict = this->get_weapon(data1_1, data1_2).json(); weapon_dict.emplace("WeaponKind", weapon_kind); - weapon_dict.emplace("SaleDivisor", sale_divisor); + if (sale_divisor.has_value()) { + weapon_dict.emplace("SaleDivisor", *sale_divisor); + } else { + weapon_dict.emplace("SaleDivisor", phosg::JSON(nullptr)); + } items_json.emplace(std::format("00{:02X}{:02X}", data1_1, data1_2), std::move(weapon_dict)); } } @@ -618,15 +696,13 @@ phosg::JSON ItemParameterTable::json() const { } auto combination_table_json = phosg::JSON::list(); - for (const auto& [used_item, combos] : this->all_item_combinations()) { - for (const auto& combo : combos) { - combination_table_json.emplace_back(combo.json()); - } + for (size_t z = 0; z < this->num_item_combinations(); z++) { + combination_table_json.emplace_back(this->get_item_combination(z).json()); } auto sound_remaps_json = phosg::JSON::list(); - for (const auto& [_, remaps] : get_all_sound_remaps()) { - sound_remaps_json.emplace_back(remaps.json()); + for (const auto& remap : get_all_sound_remaps()) { + sound_remaps_json.emplace_back(remap.json()); } auto tech_boosts_json = phosg::JSON::list(); @@ -637,9 +713,11 @@ phosg::JSON ItemParameterTable::json() const { auto unwrap_tables_json = phosg::JSON::list(); for (size_t event = 0; event < this->num_events(); event++) { auto [items, count] = this->get_event_items(event); + auto this_unwrap_table_json = phosg::JSON::list(); for (size_t z = 0; z < count; z++) { - unwrap_tables_json.emplace_back(items[z].json()); + this_unwrap_table_json.emplace_back(items[z].json()); } + unwrap_tables_json.emplace_back(std::move(this_unwrap_table_json)); } auto unsealable_items_json = phosg::JSON::list(); @@ -693,14 +771,14 @@ public: explicit JSONItemParameterTable(const phosg::JSON& json) { for (const auto& [key, item_json] : json.get_dict("Items")) { auto item_code = phosg::parse_data_string(key); - if (item_code.size() != 3) { + if (item_code.size() < 2 || item_code.size() > 3) { throw std::runtime_error("invalid item code in Items dict"); } uint8_t data1_0 = item_code[0]; uint8_t data1_1 = item_code[1]; - uint8_t data1_2 = item_code[2]; + uint8_t data1_2 = (data1_0 != 2) ? item_code.at(2) : 0; switch (data1_0) { - case 0: + case 0: { if (this->weapons.size() <= data1_1) { this->weapons.resize(data1_1 + 1); } @@ -712,11 +790,15 @@ public: this->weapon_kinds.resize(data1_1 + 1, 0); } this->weapon_kinds[data1_1] = item_json->get_int("WeaponKind"); - if (this->weapon_sale_divisors.size() <= data1_1) { - this->weapon_sale_divisors.resize(data1_1 + 1, 0); + auto sale_divisor_json = item_json->at("SaleDivisor"); + if (!sale_divisor_json.is_null()) { + if (this->weapon_sale_divisors.size() <= data1_1) { + this->weapon_sale_divisors.resize(data1_1 + 1, 0); + } + this->weapon_sale_divisors[data1_1] = sale_divisor_json.as_float(); } - this->weapon_sale_divisors[data1_1] = item_json->get_int("WeaponKind"); break; + } case 1: switch (item_code[1]) { case 1: @@ -770,10 +852,10 @@ public: this->weapon_ranges.emplace_back(WeaponRange::from_json(*weapon_range_json)); } - this->armor_sale_divisor = json.get_int("ArmorSaleDivisor"); - this->shield_sale_divisor = json.get_int("ShieldSaleDivisor"); - this->unit_sale_divisor = json.get_int("UnitSaleDivisor"); - this->mag_sale_divisor = json.get_int("MagSaleDivisor"); + this->armor_sale_divisor = json.get_float("ArmorSaleDivisor"); + this->shield_sale_divisor = json.get_float("ShieldSaleDivisor"); + this->unit_sale_divisor = json.get_float("UnitSaleDivisor"); + this->mag_sale_divisor = json.get_float("MagSaleDivisor"); const auto& mag_feed_results_json = json.get_list("MagFeedResults"); for (size_t table_index = 0; table_index < 8; table_index++) { @@ -828,13 +910,11 @@ public: } for (const auto& combo_json : json.get_list("ItemCombinations")) { - auto combo = ItemCombination::from_json(*combo_json); - this->item_combinations[item_code_to_u32(combo.used_item)].emplace_back(std::move(combo)); + this->item_combinations.emplace_back(ItemCombination::from_json(*combo_json)); } for (const auto& remaps_json : json.get_list("SoundRemaps")) { - auto remaps = SoundRemaps::from_json(*remaps_json); - this->sound_remaps.emplace(remaps.sound_id, std::move(remaps)); + this->sound_remaps.emplace_back(SoundRemaps::from_json(*remaps_json)); } for (const auto& it : json.get_list("TechBoosts")) { @@ -873,13 +953,13 @@ public: if (data1_1 < 1 || data1_1 > 2) { throw std::logic_error("invalid armor/shield class"); } - return (data1_1 > 1) ? this->armors.size() : this->shields.size(); + return (data1_1 > 1) ? this->shields.size() : this->armors.size(); } virtual const ArmorOrShield& get_armor_or_shield(uint8_t data1_1, uint8_t data1_2) const { if (data1_1 < 1 || data1_1 > 2) { throw std::logic_error("invalid armor/shield class"); } - return (data1_1 > 1) ? this->armors.at(data1_2) : this->shields.at(data1_2); + return (data1_1 > 1) ? this->shields.at(data1_2) : this->armors.at(data1_2); } virtual size_t num_units() const { @@ -909,6 +989,9 @@ public: return this->mags.at(data1_1); } + virtual size_t num_weapon_kinds() const { + return this->weapon_kinds.size(); + } virtual uint8_t get_weapon_kind(uint8_t data1_1) const { return this->weapon_kinds.at(data1_1); } @@ -927,6 +1010,10 @@ public: return this->weapon_ranges.at(index); } + virtual size_t num_weapon_sale_divisors() const { + return this->weapon_sale_divisors.size(); + } + virtual float get_sale_divisor(uint8_t data1_0, uint8_t data1_1) const { switch (data1_0) { case 0: @@ -1020,11 +1107,15 @@ public: return this->max_tech_levels.at(tech_num).at(char_class); } - virtual const std::map>& all_item_combinations() const { - return this->item_combinations; + virtual size_t num_item_combinations() const { + return this->item_combinations.size(); } - virtual const std::unordered_map& get_all_sound_remaps() const { + virtual const ItemCombination& get_item_combination(size_t index) const { + return this->item_combinations.at(index); + } + + virtual const std::vector& get_all_sound_remaps() const { return this->sound_remaps; } @@ -1083,8 +1174,8 @@ protected: std::vector stat_boosts; std::vector shield_effects; MaxTechniqueLevels max_tech_levels; - std::map> item_combinations; - std::unordered_map sound_remaps; + std::vector item_combinations; + std::vector sound_remaps; std::vector tech_boosts; std::vector> unwrap_table; std::unordered_set unsealable_items; @@ -1098,6 +1189,8 @@ template struct ItemBaseV2T { /* 00 */ U32T id = 0xFFFFFFFF; /* 04 */ + ItemBaseV2T() = default; + ItemBaseV2T(const ItemParameterTable::ItemBase& b) : id(b.id) {} void parse_into(ItemParameterTable::ItemBase& ret) const { ret.id = this->id; } @@ -1108,6 +1201,8 @@ struct ItemBaseV3T : ItemBaseV2T { /* 04 */ U16T type = 0; /* 06 */ U16T skin = 0; /* 08 */ + ItemBaseV3T() = default; + ItemBaseV3T(const ItemParameterTable::ItemBase& b) : ItemBaseV2T(b), type(b.type), skin(b.skin) {} void parse_into(ItemParameterTable::ItemBase& ret) const { this->ItemBaseV2T::parse_into(ret); ret.type = this->type; @@ -1118,6 +1213,8 @@ struct ItemBaseV3T : ItemBaseV2T { struct ItemBaseV4 : ItemBaseV3T { /* 08 */ le_uint32_t team_points = 0; /* 0C */ + ItemBaseV4() = default; + ItemBaseV4(const ItemParameterTable::ItemBase& b) : ItemBaseV3T(b), team_points(b.team_points) {} void parse_into(ItemParameterTable::ItemBase& ret) const { this->ItemBaseV3T::parse_into(ret); ret.team_points = this->team_points; @@ -1137,6 +1234,19 @@ struct WeaponDCProtos { /* 12 */ uint8_t special = 0; /* 13 */ uint8_t ata = 0; /* 14 */ + WeaponDCProtos() = default; + WeaponDCProtos(const ItemParameterTable::Weapon& w) + : base(w), + class_flags(w.class_flags), + atp_min(w.atp_min), + atp_max(w.atp_max), + atp_required(w.atp_required), + mst_required(w.mst_required), + ata_required(w.ata_required), + max_grind(w.max_grind), + photon(w.photon), + special(w.special), + ata(w.ata) {} operator ItemParameterTable::Weapon() const { ItemParameterTable::Weapon ret; this->base.parse_into(ret); @@ -1158,9 +1268,13 @@ struct WeaponV1V2 : WeaponDCProtos { /* 14 */ uint8_t stat_boost_entry_index = 0; // TODO: This could be larger (16 or 32 bits) /* 15 */ parray unknown_a9; /* 18 */ + WeaponV1V2() = default; + WeaponV1V2(const ItemParameterTable::Weapon& w) + : WeaponDCProtos(w), stat_boost_entry_index(w.stat_boost_entry_index), unknown_a9(w.v2_unknown_a9) {} operator ItemParameterTable::Weapon() const { ItemParameterTable::Weapon ret = this->WeaponDCProtos::operator ItemParameterTable::Weapon(); ret.stat_boost_entry_index = this->stat_boost_entry_index; + ret.v2_unknown_a9 = this->unknown_a9; return ret; } } __packed_ws__(WeaponV1V2, 0x18); @@ -1188,6 +1302,28 @@ struct WeaponGCNTET { /* 20 */ int8_t color = 0; /* 21 */ parray unknown_a1 = 0; /* 24 */ + WeaponGCNTET() = default; + WeaponGCNTET(const ItemParameterTable::Weapon& w) + : base(w), + class_flags(w.class_flags), + atp_min(w.atp_min), + atp_max(w.atp_max), + atp_required(w.atp_required), + mst_required(w.mst_required), + ata_required(w.ata_required), + mst(w.mst), + max_grind(w.max_grind), + photon(w.photon), + special(w.special), + ata(w.ata), + stat_boost_entry_index(w.stat_boost_entry_index), + projectile(w.projectile), + trail1_x(w.trail1_x), + trail1_y(w.trail1_y), + trail2_x(w.trail2_x), + trail2_y(w.trail2_y), + color(w.color), + unknown_a1(w.unknown_a1) {} operator ItemParameterTable::Weapon() const { ItemParameterTable::Weapon ret; this->base.parse_into(ret); @@ -1222,6 +1358,13 @@ struct WeaponV3T : WeaponGCNTET { /* 26 */ uint8_t tech_boost_entry_index = 0; /* 27 */ uint8_t behavior_flags = 0; /* 28 */ + WeaponV3T() = default; + WeaponV3T(const ItemParameterTable::Weapon& w) + : WeaponGCNTET(w), + unknown_a4(w.unknown_a4), + unknown_a5(w.unknown_a5), + tech_boost_entry_index(w.tech_boost_entry_index), + behavior_flags(w.behavior_flags) {} operator ItemParameterTable::Weapon() const { ItemParameterTable::Weapon ret = this->WeaponGCNTET::operator ItemParameterTable::Weapon(); ret.unknown_a4 = this->unknown_a4; @@ -1260,6 +1403,32 @@ struct WeaponV4 { /* 2A */ uint8_t tech_boost_entry_index = 0; /* 2B */ uint8_t behavior_flags = 0; /* 2C */ + WeaponV4() = default; + WeaponV4(const ItemParameterTable::Weapon& w) + : base(w), + class_flags(w.class_flags), + atp_min(w.atp_min), + atp_max(w.atp_max), + atp_required(w.atp_required), + mst_required(w.mst_required), + ata_required(w.ata_required), + mst(w.mst), + max_grind(w.max_grind), + photon(w.photon), + special(w.special), + ata(w.ata), + stat_boost_entry_index(w.stat_boost_entry_index), + projectile(w.projectile), + trail1_x(w.trail1_x), + trail1_y(w.trail1_y), + trail2_x(w.trail2_x), + trail2_y(w.trail2_y), + color(w.color), + unknown_a1(w.unknown_a1), + unknown_a4(w.unknown_a4), + unknown_a5(w.unknown_a5), + tech_boost_entry_index(w.tech_boost_entry_index), + behavior_flags(w.behavior_flags) {} operator ItemParameterTable::Weapon() const { ItemParameterTable::Weapon ret; this->base.parse_into(ret); @@ -1308,6 +1477,22 @@ struct ArmorOrShieldT { /* 12 */ uint8_t dfp_range = 0; /* 13 */ uint8_t evp_range = 0; /* 14 */ + ArmorOrShieldT() = default; + ArmorOrShieldT(const ItemParameterTable::ArmorOrShield& as) + : base(as), + dfp(as.dfp), + evp(as.evp), + block_particle(as.block_particle), + block_effect(as.block_effect), + class_flags(as.class_flags), + required_level(as.required_level), + efr(as.efr), + eth(as.eth), + eic(as.eic), + edk(as.edk), + elt(as.elt), + dfp_range(as.dfp_range), + evp_range(as.evp_range) {} operator ItemParameterTable::ArmorOrShield() const { ItemParameterTable::ArmorOrShield ret; this->base.parse_into(ret); @@ -1341,6 +1526,13 @@ struct ArmorOrShieldFinalT : ArmorOrShieldT { /* 16 */ uint8_t flags_type = 0; /* 17 */ uint8_t unknown_a4 = 0; /* 18 */ + ArmorOrShieldFinalT() = default; + ArmorOrShieldFinalT(const ItemParameterTable::ArmorOrShield& as) + : ArmorOrShieldT(as), + stat_boost_entry_index(as.stat_boost_entry_index), + tech_boost_entry_index(as.tech_boost_entry_index), + flags_type(as.flags_type), + unknown_a4(as.unknown_a4) {} operator ItemParameterTable::ArmorOrShield() const { ItemParameterTable::ArmorOrShield ret = this->ArmorOrShieldT::operator ItemParameterTable::ArmorOrShield(); ret.stat_boost_entry_index = this->stat_boost_entry_index; @@ -1367,6 +1559,8 @@ struct UnitT { /* 04 */ U16T stat = 0; /* 06 */ U16T stat_amount = 0; /* 08 */ + UnitT() = default; + UnitT(const ItemParameterTable::Unit& u) : base(u), stat(u.stat), stat_amount(u.stat_amount) {} operator ItemParameterTable::Unit() const { ItemParameterTable::Unit ret; this->base.parse_into(ret); @@ -1385,8 +1579,10 @@ using UnitDCProtos = UnitT, false>; template struct UnitFinalT : UnitT { /* 08 */ S16T modifier_amount = 0; - /* 0A */ parray unused; + /* 0A */ parray unused = 0; /* 0C */ + UnitFinalT() = default; + UnitFinalT(const ItemParameterTable::Unit& u) : UnitT(u), modifier_amount(u.modifier_amount) {} operator ItemParameterTable::Unit() const { ItemParameterTable::Unit ret = this->UnitT::operator ItemParameterTable::Unit(); ret.modifier_amount = this->modifier_amount; @@ -1419,6 +1615,20 @@ struct MagT { /* 0E */ uint8_t on_death_flag = 0; /* 0F */ uint8_t on_boss_flag = 0; /* 10 */ + MagT() = default; + MagT(const ItemParameterTable::Mag& m) + : base(m), + feed_table(m.feed_table), + photon_blast(m.photon_blast), + activation(m.activation), + on_pb_full(m.on_pb_full), + on_low_hp(m.on_low_hp), + on_death(m.on_death), + on_boss(m.on_boss), + on_pb_full_flag(m.on_pb_full_flag), + on_low_hp_flag(m.on_low_hp_flag), + on_death_flag(m.on_death_flag), + on_boss_flag(m.on_boss_flag) {} operator ItemParameterTable::Mag() const { ItemParameterTable::Mag ret; this->base.parse_into(ret); @@ -1446,7 +1656,9 @@ using MagV1 = MagT, false>; template struct MagV2V3V4T : MagT { U16T class_flags = 0x00FF; - parray unused; + parray unused = 0; + MagV2V3V4T() = default; + MagV2V3V4T(const ItemParameterTable::Mag& m) : MagT(m), class_flags(m.class_flags) {} operator ItemParameterTable::Mag() const { ItemParameterTable::Mag ret = this->MagT::operator ItemParameterTable::Mag(); ret.class_flags = this->class_flags; @@ -1472,6 +1684,9 @@ struct ToolT { /* 08 */ S32T cost = 0; /* 0C */ U32T item_flags = 0; /* 10 */ + ToolT() = default; + ToolT(const ItemParameterTable::Tool& t) + : base(t), amount(t.amount), tech(t.tech), cost(t.cost), item_flags(t.item_flags) {} operator ItemParameterTable::Tool() const { ItemParameterTable::Tool ret; this->base.parse_into(ret); @@ -1501,6 +1716,8 @@ template struct SpecialT { U16T type = 0xFFFF; U16T amount = 0; + SpecialT() = default; + SpecialT(const ItemParameterTable::Special& t) : type(t.type), amount(t.amount) {} operator ItemParameterTable::Special() const { return {this->type, this->amount}; } @@ -1508,15 +1725,20 @@ struct SpecialT { template struct StatBoostT { - parray stats = 0; - parray, 2> amounts = 0; + uint8_t stat1 = 0; + uint8_t stat2 = 0; + U16T amount1 = 0; + U16T amount2 = 0; + StatBoostT() = default; + StatBoostT(const ItemParameterTable::StatBoost& sb) + : stat1(sb.stat1), stat2(sb.stat2), amount1(sb.amount1), amount2(sb.amount2) {} operator ItemParameterTable::StatBoost() const { - return {this->stats[0], this->amounts[0], this->stats[1], this->amounts[1]}; + return {this->stat1, this->amount1, this->stat2, this->amount2}; } } __packed_ws_be__(StatBoostT, 6); template -struct TechBoostEntryT { +struct TechBoostT { uint8_t tech_num1 = 0; uint8_t flags1 = 0; parray unused1; @@ -1529,6 +1751,17 @@ struct TechBoostEntryT { uint8_t flags3 = 0; parray unused3; F32T amount3 = 0.0f; + TechBoostT() = default; + TechBoostT(const ItemParameterTable::TechBoost& tb) + : tech_num1(tb.tech_num1), + flags1(tb.flags1), + amount1(tb.amount1), + tech_num2(tb.tech_num2), + flags2(tb.flags2), + amount2(tb.amount2), + tech_num3(tb.tech_num3), + flags3(tb.flags3), + amount3(tb.amount3) {} operator ItemParameterTable::TechBoost() const { return { this->tech_num1, @@ -1542,12 +1775,15 @@ struct TechBoostEntryT { this->amount3, }; } -} __packed_ws_be__(TechBoostEntryT, 0x18); +} __packed_ws_be__(TechBoostT, 0x18); struct NonWeaponSaleDivisorsDCProtos { uint8_t armor_divisor = 0; uint8_t shield_divisor = 0; uint8_t unit_divisor = 0; + NonWeaponSaleDivisorsDCProtos() = default; + NonWeaponSaleDivisorsDCProtos(const ItemParameterTable::NonWeaponSaleDivisors& sd) + : armor_divisor(sd.armor_divisor), shield_divisor(sd.shield_divisor), unit_divisor(sd.unit_divisor) {} operator ItemParameterTable::NonWeaponSaleDivisors() const { return { static_cast(this->armor_divisor), @@ -1563,6 +1799,12 @@ struct NonWeaponSaleDivisorsT { F32T shield_divisor = 0.0f; F32T unit_divisor = 0.0f; F32T mag_divisor = 0.0f; + NonWeaponSaleDivisorsT() = default; + NonWeaponSaleDivisorsT(const ItemParameterTable::NonWeaponSaleDivisors& sd) + : armor_divisor(sd.armor_divisor), + shield_divisor(sd.shield_divisor), + unit_divisor(sd.unit_divisor), + mag_divisor(sd.mag_divisor) {} operator ItemParameterTable::NonWeaponSaleDivisors() const { return {this->armor_divisor, this->shield_divisor, this->unit_divisor, this->mag_divisor}; } @@ -1572,6 +1814,8 @@ template struct ShieldEffectT { U32T sound_id; U32T unknown_a1; + ShieldEffectT() = default; + ShieldEffectT(const ItemParameterTable::ShieldEffect& se) : sound_id(se.sound_id), unknown_a1(se.unknown_a1) {} operator ItemParameterTable::ShieldEffect() const { return {this->sound_id, this->unknown_a1}; } @@ -1583,6 +1827,18 @@ struct PhotonColorEntryT { /* 04 */ parray, 4> unknown_a2; /* 14 */ parray, 4> unknown_a3; /* 24 */ + PhotonColorEntryT() = default; + PhotonColorEntryT(const ItemParameterTable::PhotonColorEntry pc) { + this->unknown_a1 = pc.unknown_a1; + this->unknown_a2[0] = pc.unknown_a2.x; + this->unknown_a2[1] = pc.unknown_a2.y; + this->unknown_a2[2] = pc.unknown_a2.z; + this->unknown_a2[3] = pc.unknown_a2.t; + this->unknown_a3[0] = pc.unknown_a3.x; + this->unknown_a3[1] = pc.unknown_a3.y; + this->unknown_a3[2] = pc.unknown_a3.z; + this->unknown_a3[3] = pc.unknown_a3.t; + } operator ItemParameterTable::PhotonColorEntry() const { ItemParameterTable::PhotonColorEntry ret; ret.unknown_a1 = this->unknown_a1; @@ -1602,6 +1858,8 @@ template struct UnknownA1T { U16T unknown_a1; U16T unknown_a2; + UnknownA1T() = default; + UnknownA1T(const ItemParameterTable::UnknownA1 a1) : unknown_a1(a1.unknown_a1), unknown_a2(a1.unknown_a2) {} operator ItemParameterTable::UnknownA1() const { return {this->unknown_a1, this->unknown_a2}; } @@ -1614,6 +1872,13 @@ struct WeaponRangeT { U32T unknown_a3; U32T unknown_a4; U32T unknown_a5; + WeaponRangeT() = default; + WeaponRangeT(const ItemParameterTable::WeaponRange& wr) + : unknown_a1(wr.unknown_a1), + unknown_a2(wr.unknown_a2), + unknown_a3(wr.unknown_a3), + unknown_a4(wr.unknown_a4), + unknown_a5(wr.unknown_a5) {} operator ItemParameterTable::WeaponRange() const { return {this->unknown_a1, this->unknown_a2, this->unknown_a3, this->unknown_a4, this->unknown_a5}; } @@ -1626,6 +1891,13 @@ struct WeaponEffectT { U32T sound_id2; U32T eff_value2; parray unknown_a5; + WeaponEffectT() = default; + WeaponEffectT(const ItemParameterTable::WeaponEffect& we) + : sound_id1(we.sound_id1), + eff_value1(we.eff_value1), + sound_id2(we.sound_id2), + eff_value2(we.eff_value2), + unknown_a5(we.unknown_a5) {} operator ItemParameterTable::WeaponEffect() const { return {this->sound_id1, this->eff_value1, this->sound_id2, this->eff_value2, this->unknown_a5}; } @@ -1638,42 +1910,9 @@ struct SoundRemapTableOffsetsT { U32T remaps_for_char_class_table; } __packed_ws_be__(SoundRemapTableOffsetsT, 0x0C); -/* The fields in the root structures are as follows. See the specializations of BinaryItemParameterTableT for the - * values of the hardcoded constants in each version (NumWeaponClasses, etc.). - * DCTE / 112K / V1 / V2 / GCTE / GCV3 / XBV3 / V4 - * 0013 / 0013 / 0013 / 0013 / ---- / ---- / ---- / ----- entry_count // Count of pointers in root struct; unused - * 2E1C / 2EB8 / 32E8 / 5AFC / 6F0C / F078 / F084 / 14884 weapon_table // -> {count, offset -> WeaponV*[count]}[NumWeaponClasses] - * 2D94 / 2E28 / 3258 / 5A5C / 6E4C / EF90 / EF9C / 1478C armor_table // -> {count, offset -> ArmorOrShieldV*[count]}][2] - * 2DA4 / 2E38 / 3268 / 5A6C / 6E5C / EFA0 / EFAC / 1479C unit_table // -> {count, offset -> UnitV*[count]} (last if out of range) - * 2DB4 / 2E48 / 3278 / 5A7C / 6E6C / EFB0 / EFBC / 147AC tool_table // -> {count, offset -> ToolV*[count]}[NumToolClasses] (last if out of range) - * 2DAC / 2E40 / 3270 / 5A74 / 6E64 / EFA8 / EFB4 / 147A4 mag_table // -> {count, offset -> MagV*[count]} - * 1F98 / 202C / 23C8 / 3DF8 / 47BC / B88C / B8A0 / 0F4B8 weapon_kind_table // -> uint8_t[NumWeaponClasses] - * 1994 / 1A28 / 1DB0 / 2E4C / 37A4 / A7FC / A7FC / 0DE7C photon_color_table // -> PhotonColorEntry[NumPhotonColors] - * 1C64 / 1CF8 / 2080 / 32CC / 3A74 / AACC / AACC / 0E194 weapon_range_table // -> WeaponRange[...] (indexed by data1_1, but also by RangedSpecial::weapon_range_index + a version-dependent constant, and also by the result of a vfunc call on some TItemWeapons) - * 1FBF / 2053 / 23F0 / 3E84 / 484C / B938 / B94C / 0F5A8 weapon_sale_divisor_table // -> uint8_t[NumWeaponClasses] on DC protos; float[NumWeaponClasses] on all other versions - * 1FE6 / 207A / 248C / 40A8 / 4A80 / BBCC / BBE0 / 0F83C non_weapon_sale_divisor_table // -> NonWeaponSaleDivisors - * 2F54 / 2FF0 / 3420 / 5F4C / 7384 / F608 / F614 / 1502C mag_feed_table // -> MagFeedResultsTable - * 22A9 / 233D / 275C / 4378 / 4D50 / BE9C / BEB0 / 0FB0C star_value_table // -> uint8_t[...] (indexed by .id from weapon, armor, etc.) - * 23EE / 2484 / 28A2 / ---- / ---- / ---- / ---- / ----- unknown_a1 // TODO - * 275E / 27F4 / 2C12 / 4540 / 4F72 / C100 / C114 / 0FE3C special_table // -> Special[NumSpecials] - * 2804 / 2898 / 2CB8 / 45E4 / 5018 / C1A4 / C1B8 / 0FEE0 weapon_effect_table // -> WeaponEffect[...] - * 1908 / 199C / ---- / ---- / ---- / ---- / ---- / ----- weapon_stat_boost_index_table // -> uint8_t[max(weapon.id : weapon_table) - (ItemStarsFirstID - 1)] - * 0668 / 0668 / ---- / ---- / ---- / ---- / ---- / ----- armor_stat_boost_index_table // -> uint8_t[armor_table[0].count] - * 030C / 030C / ---- / ---- / ---- / ---- / ---- / ----- shield_stat_boost_index_table // -> uint8_t[armor_table[1].count] - * 2CE4 / 2D78 / 3198 / 58DC / 68B8 / DE50 / DE64 / 1275C stat_boost_table // -> StatBoost[...] - * ---- / ---- / ---- / 5704 / 61B8 / D6E4 / D6F8 / 11C80 shield_effect_table // -> ShieldEffect[...] (indexed by data1[2]) - * ---- / ---- / ---- / ---- / 69D8 / DF88 / DF9C / 12894 max_tech_level_table // -> MaxTechniqueLevels - * ---- / ---- / ---- / ---- / 737C / F5D0 / F5DC / 14FF4 combination_table // -> {count, offset -> ItemCombination[count]} - * ---- / ---- / ---- / ---- / 68B0 / DE48 / DE5C / 12754 sound_remap_table // -> {count, offset -> {sound_id, by_rt_index_offset -> uint32_t[SoundRemapRTTableSize], by_char_class_offset -> uint32_t[12]}} - * ---- / ---- / ---- / ---- / 6B1C / EB8C / EBA0 / 14278 tech_boost_table // -> TechBoostEntry[...][3] - * ---- / ---- / ---- / ---- / ---- / F5F0 / F5FC / 15014 unwrap_table // -> {count, offset -> {count, offset -> EventItem[count]}[count] - * ---- / ---- / ---- / ---- / ---- / F5F8 / F604 / 1501C unsealable_table // -> {count, offset -> UnsealableItem[count]} - * ---- / ---- / ---- / ---- / ---- / F600 / F60C / 15024 ranged_special_table // -> {count, offset -> RangedSpecial[count]} - */ - struct RootDCProtos { /* ## / DCTE / 112K */ - /* 00 / 0013 / 0013 */ le_uint32_t entry_count; + /* 00 / 0013 / 0013 */ le_uint32_t entry_count = 0x13; /* 04 / 2E1C / 2EB8 */ le_uint32_t weapon_table; /* 08 / 2D94 / 2E28 */ le_uint32_t armor_table; /* 0C / 2DA4 / 2E38 */ le_uint32_t unit_table; @@ -1697,98 +1936,154 @@ struct RootDCProtos { struct RootV1 { /* ## / DCV1 */ - /* 00 / 0013 */ le_uint32_t entry_count; - /* 04 / 32E8 */ le_uint32_t weapon_table; - /* 08 / 3258 */ le_uint32_t armor_table; - /* 0C / 3268 */ le_uint32_t unit_table; - /* 10 / 3278 */ le_uint32_t tool_table; - /* 14 / 3270 */ le_uint32_t mag_table; - /* 18 / 23C8 */ le_uint32_t weapon_kind_table; - /* 1C / 1DB0 */ le_uint32_t photon_color_table; - /* 20 / 2080 */ le_uint32_t weapon_range_table; - /* 24 / 23F0 */ le_uint32_t weapon_sale_divisor_table; - /* 28 / 248C */ le_uint32_t non_weapon_sale_divisor_table; - /* 2C / 3420 */ le_uint32_t mag_feed_table; - /* 30 / 275C */ le_uint32_t star_value_table; - /* 34 / 28A2 */ le_uint32_t unknown_a1; - /* 38 / 2C12 */ le_uint32_t special_table; - /* 3C / 2CB8 */ le_uint32_t weapon_effect_table; - /* 40 / 3198 */ le_uint32_t stat_boost_table; + /* 00 / 0013 */ le_uint32_t entry_count = 0x13; + /* 04 / 32E8 */ le_uint32_t weapon_table = 0xFFFFFFFF; + /* 08 / 3258 */ le_uint32_t armor_table = 0xFFFFFFFF; + /* 0C / 3268 */ le_uint32_t unit_table = 0xFFFFFFFF; + /* 10 / 3278 */ le_uint32_t tool_table = 0xFFFFFFFF; + /* 14 / 3270 */ le_uint32_t mag_table = 0xFFFFFFFF; + /* 18 / 23C8 */ le_uint32_t weapon_kind_table = 0xFFFFFFFF; + /* 1C / 1DB0 */ le_uint32_t photon_color_table = 0xFFFFFFFF; + /* 20 / 2080 */ le_uint32_t weapon_range_table = 0xFFFFFFFF; + /* 24 / 23F0 */ le_uint32_t weapon_sale_divisor_table = 0xFFFFFFFF; + /* 28 / 248C */ le_uint32_t non_weapon_sale_divisor_table = 0xFFFFFFFF; + /* 2C / 3420 */ le_uint32_t mag_feed_table = 0xFFFFFFFF; + /* 30 / 275C */ le_uint32_t star_value_table = 0xFFFFFFFF; + /* 34 / 28A2 */ le_uint32_t unknown_a1 = 0xFFFFFFFF; + /* 38 / 2C12 */ le_uint32_t special_table = 0xFFFFFFFF; + /* 3C / 2CB8 */ le_uint32_t weapon_effect_table = 0xFFFFFFFF; + /* 40 / 3198 */ le_uint32_t stat_boost_table = 0xFFFFFFFF; } __packed_ws__(RootV1, 0x44); struct RootV2 { /* ## / DCV2 */ - /* 00 / 0013 */ le_uint32_t entry_count; - /* 04 / 5AFC */ le_uint32_t weapon_table; - /* 08 / 5A5C */ le_uint32_t armor_table; - /* 0C / 5A6C */ le_uint32_t unit_table; - /* 10 / 5A7C */ le_uint32_t tool_table; - /* 14 / 5A74 */ le_uint32_t mag_table; - /* 18 / 3DF8 */ le_uint32_t weapon_kind_table; - /* 1C / 2E4C */ le_uint32_t photon_color_table; - /* 20 / 32CC */ le_uint32_t weapon_range_table; - /* 24 / 3E84 */ le_uint32_t weapon_sale_divisor_table; - /* 28 / 40A8 */ le_uint32_t non_weapon_sale_divisor_table; - /* 2C / 5F4C */ le_uint32_t mag_feed_table; - /* 30 / 4378 */ le_uint32_t star_value_table; - /* 34 / 4540 */ le_uint32_t special_table; - /* 38 / 45E4 */ le_uint32_t weapon_effect_table; - /* 3C / 58DC */ le_uint32_t stat_boost_table; - /* 40 / 5704 */ le_uint32_t shield_effect_table; + /* 00 / 0013 */ le_uint32_t entry_count = 0x13; + /* 04 / 5AFC */ le_uint32_t weapon_table = 0xFFFFFFFF; + /* 08 / 5A5C */ le_uint32_t armor_table = 0xFFFFFFFF; + /* 0C / 5A6C */ le_uint32_t unit_table = 0xFFFFFFFF; + /* 10 / 5A7C */ le_uint32_t tool_table = 0xFFFFFFFF; + /* 14 / 5A74 */ le_uint32_t mag_table = 0xFFFFFFFF; + /* 18 / 3DF8 */ le_uint32_t weapon_kind_table = 0xFFFFFFFF; + /* 1C / 2E4C */ le_uint32_t photon_color_table = 0xFFFFFFFF; + /* 20 / 32CC */ le_uint32_t weapon_range_table = 0xFFFFFFFF; + /* 24 / 3E84 */ le_uint32_t weapon_sale_divisor_table = 0xFFFFFFFF; + /* 28 / 40A8 */ le_uint32_t non_weapon_sale_divisor_table = 0xFFFFFFFF; + /* 2C / 5F4C */ le_uint32_t mag_feed_table = 0xFFFFFFFF; + /* 30 / 4378 */ le_uint32_t star_value_table = 0xFFFFFFFF; + /* 34 / 4540 */ le_uint32_t special_table = 0xFFFFFFFF; + /* 38 / 45E4 */ le_uint32_t weapon_effect_table = 0xFFFFFFFF; + /* 3C / 58DC */ le_uint32_t stat_boost_table = 0xFFFFFFFF; + /* 40 / 5704 */ le_uint32_t shield_effect_table = 0xFFFFFFFF; } __packed_ws__(RootV2, 0x44); struct RootGCNTE { /* ## / GCTE */ - /* 00 / 6F0C */ be_uint32_t weapon_table; - /* 04 / 6E4C */ be_uint32_t armor_table; - /* 08 / 6E5C */ be_uint32_t unit_table; - /* 0C / 6E6C */ be_uint32_t tool_table; - /* 10 / 6E64 */ be_uint32_t mag_table; - /* 14 / 47BC */ be_uint32_t weapon_kind_table; - /* 18 / 37A4 */ be_uint32_t photon_color_table; - /* 1C / 3A74 */ be_uint32_t weapon_range_table; - /* 20 / 484C */ be_uint32_t weapon_sale_divisor_table; - /* 24 / 4A80 */ be_uint32_t non_weapon_sale_divisor_table; - /* 28 / 7384 */ be_uint32_t mag_feed_table; - /* 2C / 4D50 */ be_uint32_t star_value_table; - /* 30 / 4F72 */ be_uint32_t special_table; - /* 34 / 5018 */ be_uint32_t weapon_effect_table; - /* 38 / 68B8 */ be_uint32_t stat_boost_table; - /* 3C / 61B8 */ be_uint32_t shield_effect_table; - /* 40 / 69D8 */ be_uint32_t max_tech_level_table; - /* 44 / 737C */ be_uint32_t combination_table; - /* 48 / 68B0 */ be_uint32_t sound_remap_table; - /* 4C / 6B1C */ be_uint32_t tech_boost_table; + /* 00 / 6F0C */ be_uint32_t weapon_table = 0xFFFFFFFF; + /* 04 / 6E4C */ be_uint32_t armor_table = 0xFFFFFFFF; + /* 08 / 6E5C */ be_uint32_t unit_table = 0xFFFFFFFF; + /* 0C / 6E6C */ be_uint32_t tool_table = 0xFFFFFFFF; + /* 10 / 6E64 */ be_uint32_t mag_table = 0xFFFFFFFF; + /* 14 / 47BC */ be_uint32_t weapon_kind_table = 0xFFFFFFFF; + /* 18 / 37A4 */ be_uint32_t photon_color_table = 0xFFFFFFFF; + /* 1C / 3A74 */ be_uint32_t weapon_range_table = 0xFFFFFFFF; + /* 20 / 484C */ be_uint32_t weapon_sale_divisor_table = 0xFFFFFFFF; + /* 24 / 4A80 */ be_uint32_t non_weapon_sale_divisor_table = 0xFFFFFFFF; + /* 28 / 7384 */ be_uint32_t mag_feed_table = 0xFFFFFFFF; + /* 2C / 4D50 */ be_uint32_t star_value_table = 0xFFFFFFFF; + /* 30 / 4F72 */ be_uint32_t special_table = 0xFFFFFFFF; + /* 34 / 5018 */ be_uint32_t weapon_effect_table = 0xFFFFFFFF; + /* 38 / 68B8 */ be_uint32_t stat_boost_table = 0xFFFFFFFF; + /* 3C / 61B8 */ be_uint32_t shield_effect_table = 0xFFFFFFFF; + /* 40 / 69D8 */ be_uint32_t max_tech_level_table = 0xFFFFFFFF; + /* 44 / 737C */ be_uint32_t combination_table = 0xFFFFFFFF; + /* 48 / 68B0 */ be_uint32_t sound_remap_table = 0xFFFFFFFF; + /* 4C / 6B1C */ be_uint32_t tech_boost_table = 0xFFFFFFFF; } __packed_ws__(RootGCNTE, 0x50); template struct RootV3V4T { /* ## / GCV3 / XBV3 / BBV4 */ - /* 00 / F078 / F084 / 14884 */ U32T weapon_table; - /* 04 / EF90 / EF9C / 1478C */ U32T armor_table; - /* 08 / EFA0 / EFAC / 1479C */ U32T unit_table; - /* 0C / EFB0 / EFBC / 147AC */ U32T tool_table; - /* 10 / EFA8 / EFB4 / 147A4 */ U32T mag_table; - /* 14 / B88C / B8A0 / 0F4B8 */ U32T weapon_kind_table; - /* 18 / A7FC / A7FC / 0DE7C */ U32T photon_color_table; - /* 1C / AACC / AACC / 0E194 */ U32T weapon_range_table; - /* 20 / B938 / B94C / 0F5A8 */ U32T weapon_sale_divisor_table; - /* 24 / BBCC / BBE0 / 0F83C */ U32T non_weapon_sale_divisor_table; - /* 28 / F608 / F614 / 1502C */ U32T mag_feed_table; - /* 2C / BE9C / BEB0 / 0FB0C */ U32T star_value_table; - /* 30 / C100 / C114 / 0FE3C */ U32T special_table; - /* 34 / C1A4 / C1B8 / 0FEE0 */ U32T weapon_effect_table; - /* 38 / DE50 / DE64 / 1275C */ U32T stat_boost_table; - /* 3C / D6E4 / D6F8 / 11C80 */ U32T shield_effect_table; - /* 40 / DF88 / DF9C / 12894 */ U32T max_tech_level_table; - /* 44 / F5D0 / F5DC / 14FF4 */ U32T combination_table; - /* 48 / DE48 / DE5C / 12754 */ U32T sound_remap_table; - /* 4C / EB8C / EBA0 / 14278 */ U32T tech_boost_table; - /* 50 / F5F0 / F5FC / 15014 */ U32T unwrap_table; - /* 54 / F5F8 / F604 / 1501C */ U32T unsealable_table; - /* 58 / F600 / F60C / 15024 */ U32T ranged_special_table; + /* 00 / F078 / F084 / 14884 */ U32T weapon_table = 0xFFFFFFFF; + /* 04 / EF90 / EF9C / 1478C */ U32T armor_table = 0xFFFFFFFF; + /* 08 / EFA0 / EFAC / 1479C */ U32T unit_table = 0xFFFFFFFF; + /* 0C / EFB0 / EFBC / 147AC */ U32T tool_table = 0xFFFFFFFF; + /* 10 / EFA8 / EFB4 / 147A4 */ U32T mag_table = 0xFFFFFFFF; + /* 14 / B88C / B8A0 / 0F4B8 */ U32T weapon_kind_table = 0xFFFFFFFF; + /* 18 / A7FC / A7FC / 0DE7C */ U32T photon_color_table = 0xFFFFFFFF; + /* 1C / AACC / AACC / 0E194 */ U32T weapon_range_table = 0xFFFFFFFF; + /* 20 / B938 / B94C / 0F5A8 */ U32T weapon_sale_divisor_table = 0xFFFFFFFF; + /* 24 / BBCC / BBE0 / 0F83C */ U32T non_weapon_sale_divisor_table = 0xFFFFFFFF; + /* 28 / F608 / F614 / 1502C */ U32T mag_feed_table = 0xFFFFFFFF; + /* 2C / BE9C / BEB0 / 0FB0C */ U32T star_value_table = 0xFFFFFFFF; + /* 30 / C100 / C114 / 0FE3C */ U32T special_table = 0xFFFFFFFF; + /* 34 / C1A4 / C1B8 / 0FEE0 */ U32T weapon_effect_table = 0xFFFFFFFF; + /* 38 / DE50 / DE64 / 1275C */ U32T stat_boost_table = 0xFFFFFFFF; + /* 3C / D6E4 / D6F8 / 11C80 */ U32T shield_effect_table = 0xFFFFFFFF; + /* 40 / DF88 / DF9C / 12894 */ U32T max_tech_level_table = 0xFFFFFFFF; + /* 44 / F5D0 / F5DC / 14FF4 */ U32T combination_table = 0xFFFFFFFF; + /* 48 / DE48 / DE5C / 12754 */ U32T sound_remap_table = 0xFFFFFFFF; + /* 4C / EB8C / EBA0 / 14278 */ U32T tech_boost_table = 0xFFFFFFFF; + /* 50 / F5F0 / F5FC / 15014 */ U32T unwrap_table = 0xFFFFFFFF; + /* 54 / F5F8 / F604 / 1501C */ U32T unsealable_table = 0xFFFFFFFF; + /* 58 / F600 / F60C / 15024 */ U32T ranged_special_table = 0xFFFFFFFF; } __packed_ws_be__(RootV3V4T, 0x5C); +// All versions after v1 have a header before the actual data, which appears to be entirely unused by the game. +// TODO: Figure out what these bytes mean. +// V2: 29274435 3A44807F +// GC_NTE: FFFFFFFF 00000001 00010000 40400000 40C00000 FFFF0008 29274467 6C76807F 090C0D0F F0000000 00000003 00C80078 C8000000 00FA00C0 0000010C 00D20000 +// GC_V3: FFFFFFFF 00000001 00010000 40400000 40C00000 FFFF0008 29274467 6C768040 3F090C0D 0FF00000 00000003 00C80078 C8000000 010A00C7 0000011F 00DC0000 +// XB_V3: FFFFFFFF 01000000 00000100 00004040 0000C040 FFFF0800 29274467 6C768040 3F090C0D 0FF00000 03000000 C8007800 C8000000 0A01C700 00001F01 DC000000 +// BB_V4: FFFFFFFF 01000000 00000100 00004040 0000C040 FFFF0800 29274467 6C768040 3F090C0D 0FF00000 03000000 C8007800 C8000000 62010F01 00007A01 27010000 + +struct EmptyHeader {}; + +struct HeaderV2 { + le_uint32_t unknown_a1 = 0x35442729; + le_uint32_t unknown_a2 = 0x7F80443A; +} __packed_ws__(HeaderV2, 0x08); + +struct HeaderGCNTE { + /* 00 */ be_uint32_t unknown_a1 = 0xFFFFFFFF; + /* 04 */ be_uint32_t unknown_a2 = 0x00000001; + /* 08 */ be_uint32_t unknown_a3 = 0x00010000; + /* 0C */ be_float unknown_a4 = 3.0; + /* 10 */ be_float unknown_a5 = 6.0; + /* 14 */ be_uint16_t unknown_a6 = 0xFFFF; + /* 16 */ be_uint16_t unknown_a7 = 0x0008; + /* 18 */ parray unknown_a8 = {0x29, 0x27, 0x44, 0x67, 0x6C, 0x76, 0x80, 0x7F, 0x09, 0x0C, 0x0D, 0x0F, 0xF0, 0x00, 0x00, 0x00}; + /* 28 */ be_uint32_t unknown_a9 = 0x00000003; + /* 2C */ be_uint16_t unknown_a10 = 0x00C8; + /* 2E */ be_uint16_t unknown_a11 = 0x0078; + /* 30 */ parray unknown_a12 = {0xC8, 0x00, 0x00, 0x00}; + /* 34 */ parray unknown_a13 = {0x00FA, 0x00C0, 0x0000, 0x010C, 0x00D2, 0x0000}; +} __packed_ws__(HeaderGCNTE, 0x40); + +template +struct HeaderV3V4Base { + /* 00 */ U32T unknown_a1 = 0xFFFFFFFF; + /* 04 */ U32T unknown_a2 = 0x00000001; + /* 08 */ U32T unknown_a3 = 0x00010000; + /* 0C */ F32T unknown_a4 = 3.0; + /* 10 */ F32T unknown_a5 = 6.0; + /* 14 */ U16T unknown_a6 = 0xFFFF; + /* 16 */ U16T unknown_a7 = 0x0008; + /* 18 */ parray unknown_a8 = {0x29, 0x27, 0x44, 0x67, 0x6C, 0x76, 0x80, 0x40, 0x3F, 0x09, 0x0C, 0x0D, 0x0F, 0xF0, 0x00, 0x00}; + /* 28 */ U32T unknown_a9 = 0x00000003; + /* 2C */ U16T unknown_a10 = 0x00C8; + /* 2E */ U16T unknown_a11 = 0x0078; + /* 30 */ parray unknown_a12 = {0xC8, 0x00, 0x00, 0x00}; +} __packed_ws_be__(HeaderV3V4Base, 0x34); + +template +struct HeaderV3 : HeaderV3V4Base { + /* 34 */ parray, 6> unknown_a13 = {0x010A, 0x00C7, 0x0000, 0x011F, 0x00DC, 0x0000}; +} __packed_ws_be__(HeaderV3, 0x40); + +struct HeaderV4 : HeaderV3V4Base { + /* 34 */ parray unknown_a13 = {0x0162, 0x010F, 0x0000, 0x017A, 0x0127, 0x0000}; +} __packed_ws_be__(HeaderV3, 0x40); + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Reader implementation @@ -2006,6 +2301,28 @@ bool ItemParameterTable::is_unsealable_item(const ItemData& item) const { return this->is_unsealable_item(item.data1[0], item.data1[1], item.data1[2]); } +const std::map>& ItemParameterTable::item_combinations_index() const { + if (!this->item_combination_index.has_value()) { + auto& ret = this->item_combination_index.emplace(); + for (size_t z = 0; z < this->num_item_combinations(); z++) { + const auto& combo = this->get_item_combination(z); + ret[item_code_to_u32(combo.used_item)].emplace_back(combo); + } + } + return *this->item_combination_index; +} + +const std::vector& ItemParameterTable::all_combinations_for_used_item( + const ItemData& used_item) const { + try { + return this->item_combinations_index().at(item_code_to_u32( + used_item.data1[0], used_item.data1[1], used_item.data1[2])); + } catch (const out_of_range&) { + static const vector ret; + return ret; + } +} + const ItemParameterTable::ItemCombination& ItemParameterTable::get_item_combination( const ItemData& used_item, const ItemData& equipped_item) const { for (const auto& def : this->all_combinations_for_used_item(used_item)) { @@ -2018,17 +2335,6 @@ const ItemParameterTable::ItemCombination& ItemParameterTable::get_item_combinat throw out_of_range("no item combination applies"); } -const std::vector& ItemParameterTable::all_combinations_for_used_item( - const ItemData& used_item) const { - try { - return this->all_item_combinations().at(item_code_to_u32( - used_item.data1[0], used_item.data1[1], used_item.data1[2])); - } catch (const out_of_range&) { - static const vector ret; - return ret; - } -} - size_t ItemParameterTable::price_for_item(const ItemData& item) const { switch (item.data1[0]) { case 0: { @@ -2106,20 +2412,18 @@ size_t ItemParameterTable::price_for_item(const ItemData& item) const { } template < + typename HeaderT, typename RootT, typename WeaponT, - size_t NumWeaponClasses, typename ArmorOrShieldT, typename UnitT, typename ToolT, - size_t NumToolClasses, typename MagT, + bool HasImplicitPlaceholders, size_t ItemStarsFirstID, - size_t ItemStarsLastID, size_t SpecialStarsBeginIndex, - size_t NumSpecials, - size_t NumPhotonColors, size_t SoundRemapRTTableSize, + bool HasServerHeader, bool BE> class BinaryItemParameterTableT : public ItemParameterTable { public: @@ -2137,7 +2441,7 @@ public: template const T& indirect_lookup_2d(size_t base_offset, size_t co_index, size_t item_index) const { const auto& co = this->r.pget>(base_offset + sizeof(ArrayRefT) * co_index); - if (item_index >= co.count) { + if (item_index >= (co.count + HasImplicitPlaceholders)) { throw out_of_range("2-D array index out of range"); } return this->r.pget(co.offset + sizeof(T) * item_index); @@ -2161,18 +2465,18 @@ public: } virtual size_t num_weapon_classes() const { - return NumWeaponClasses; + return this->get_data_array_count>(this->root->weapon_table); } virtual size_t num_weapons_in_class(uint8_t data1_1) const { - if (data1_1 >= NumWeaponClasses) { + if (data1_1 >= this->num_weapon_classes()) { throw out_of_range("weapon ID out of range"); } return this->indirect_lookup_2d_count(this->root->weapon_table, data1_1); } virtual const Weapon& get_weapon(uint8_t data1_1, uint8_t data1_2) const { - if (data1_1 >= NumWeaponClasses) { + if (data1_1 >= this->num_weapon_classes()) { throw out_of_range("weapon ID out of range"); } uint16_t key = (data1_1 << 8) | data1_2; @@ -2188,7 +2492,7 @@ public: if ((data1_1 < 1) || (data1_1 > 2)) { throw out_of_range("armor/shield class ID out of range"); } - return this->indirect_lookup_2d_count(this->root->armor_table, data1_1 - 1); + return this->indirect_lookup_2d_count(this->root->armor_table, data1_1 - 1) + HasImplicitPlaceholders; } virtual const ArmorOrShield& get_armor_or_shield(uint8_t data1_1, uint8_t data1_2) const { @@ -2200,7 +2504,7 @@ public: } virtual size_t num_units() const { - return this->indirect_lookup_2d_count(this->root->unit_table, 0); + return this->indirect_lookup_2d_count(this->root->unit_table, 0) + HasImplicitPlaceholders; } virtual const Unit& get_unit(uint8_t data1_2) const { @@ -2208,18 +2512,18 @@ public: } virtual size_t num_tool_classes() const { - return NumToolClasses; + return this->get_data_array_count>(this->root->tool_table); } virtual size_t num_tools_in_class(uint8_t data1_1) const { - if (data1_1 >= NumToolClasses) { + if (data1_1 >= this->num_tool_classes()) { throw out_of_range("tool class ID out of range"); } return this->indirect_lookup_2d_count(this->root->tool_table, data1_1); } virtual const Tool& get_tool(uint8_t data1_1, uint8_t data1_2) const { - if (data1_1 >= NumToolClasses) { + if (data1_1 >= this->num_tool_classes()) { throw out_of_range("tool class ID out of range"); } uint16_t key = (data1_1 << 8) | data1_2; @@ -2232,8 +2536,9 @@ public: } virtual std::pair find_tool_by_id(uint32_t id) const { - const auto* cos = &this->r.pget>(this->root->tool_table, NumToolClasses * sizeof(ArrayRefT)); - for (size_t z = 0; z < NumToolClasses; z++) { + const auto* cos = &this->r.pget>( + this->root->tool_table, this->num_tool_classes() * sizeof(ArrayRefT)); + for (size_t z = 0; z < this->num_tool_classes(); z++) { const auto& co = cos[z]; const auto* defs = &this->r.pget(co.offset, sizeof(ToolT) * co.count); for (size_t y = 0; y < co.count; y++) { @@ -2246,25 +2551,26 @@ public: } virtual size_t num_mags() const { - return this->indirect_lookup_2d_count(this->root->mag_table, 0); + return this->indirect_lookup_2d_count(this->root->mag_table, 0) + HasImplicitPlaceholders; } virtual const Mag& get_mag(uint8_t data1_1) const { return this->add_to_vector_cache_2d_indirect(this->mags, this->root->mag_table, 0, data1_1); } + virtual size_t num_weapon_kinds() const { + return this->get_data_array_count(this->root->weapon_kind_table); + } + virtual uint8_t get_weapon_kind(uint8_t data1_1) const { - return (data1_1 < NumWeaponClasses) ? this->r.pget_u8(this->root->weapon_kind_table + data1_1) : 0x00; + return (data1_1 < this->num_weapon_kinds()) ? this->r.pget_u8(this->root->weapon_kind_table + data1_1) : 0x00; } virtual size_t num_photon_colors() const { - return NumPhotonColors; + return this->get_data_array_count>(this->root->photon_color_table); } virtual const PhotonColorEntry& get_photon_color(size_t index) const { - if (index >= NumPhotonColors) { - throw std::out_of_range("invalid photon color index"); - } return this->add_to_vector_cache>(this->photon_colors, this->root->photon_color_table, index); } @@ -2276,9 +2582,17 @@ public: return this->add_to_vector_cache>(this->weapon_ranges, this->root->weapon_range_table, index); } + virtual size_t num_weapon_sale_divisors() const { + if constexpr (requires { this->root->weapon_integral_sale_divisor_table; }) { + return this->get_data_array_count(this->root->weapon_integral_sale_divisor_table); + } else { + return this->get_data_array_count>(this->root->weapon_sale_divisor_table); + } + } + virtual float get_sale_divisor(uint8_t data1_0, uint8_t data1_1) const { if (data1_0 == 0) { - if (data1_1 >= NumWeaponClasses) { + if (data1_1 >= this->num_weapon_sale_divisors()) { return 0.0f; } if constexpr (requires { this->root->weapon_sale_divisor_table; }) { @@ -2332,7 +2646,8 @@ public: } virtual std::pair get_star_value_index_range() const { - return std::make_pair(ItemStarsFirstID, ItemStarsLastID); + return std::make_pair( + ItemStarsFirstID, this->get_data_array_count(this->root->star_value_table) + ItemStarsFirstID); } virtual uint32_t get_special_stars_base_index() const { @@ -2340,8 +2655,9 @@ public: } virtual uint8_t get_item_stars(uint32_t id) const { - return ((id >= ItemStarsFirstID) && (id < ItemStarsLastID)) - ? this->r.pget_u8(this->root->star_value_table + id - ItemStarsFirstID) + auto range = this->get_star_value_index_range(); + return ((id >= range.first) && (id < range.second)) + ? this->r.pget_u8(this->root->star_value_table + id - range.first) : 0; } @@ -2358,12 +2674,12 @@ public: } virtual size_t num_specials() const { - return NumSpecials; + return this->get_data_array_count>(this->root->special_table); } virtual const Special& get_special(uint8_t special) const { special &= 0x3F; - if (special >= NumSpecials) { + if (special >= this->num_specials()) { throw out_of_range("invalid special index"); } while (this->specials.size() <= special) { @@ -2471,31 +2787,34 @@ public: } } - virtual const std::map>& all_item_combinations() const { + virtual size_t num_item_combinations() const { if constexpr (requires { this->root->combination_table; }) { - if (!this->item_combination_index.has_value()) { - auto& ret = this->item_combination_index.emplace(); - const auto& co = this->r.pget>(this->root->combination_table); - const auto* defs = &this->r.pget(co.offset, co.count * sizeof(ItemCombination)); - for (size_t z = 0; z < co.count; z++) { - ret[item_code_to_u32(defs[z].used_item)].emplace_back(defs[z]); - } - } - return *this->item_combination_index; + return this->r.pget>(this->root->combination_table).count; } else { - static const std::map> empty_map{}; - return empty_map; + return 0; } } - virtual const std::unordered_map& get_all_sound_remaps() const { + virtual const ItemCombination& get_item_combination(size_t index) const { + if constexpr (requires { this->root->combination_table; }) { + const auto& co = this->r.pget>(this->root->combination_table); + if (index >= co.count) { + throw std::logic_error("Item combination index out of range"); + } + return this->r.pget(co.offset + index * sizeof(ItemCombination)); + } else { + throw std::logic_error("Item combinations not available"); + } + } + + virtual const std::vector& get_all_sound_remaps() const { if constexpr (requires { this->root->sound_remap_table; }) { if (!this->sound_remaps.has_value()) { auto& ret = this->sound_remaps.emplace(); const auto& co = this->r.pget>(this->root->sound_remap_table); const auto* entries = this->r.pget_array>(co.offset, co.count); for (size_t z = 0; z < co.count; z++) { - auto& remaps = ret.emplace(entries[z].sound_id, SoundRemaps{}).first->second; + auto& remaps = ret.emplace_back(); remaps.sound_id = entries[z].sound_id; auto sub_r = r.sub(entries[z].remaps_for_rt_index_table, SoundRemapRTTableSize * sizeof(U32T)); for (size_t z = 0; z < SoundRemapRTTableSize; z++) { @@ -2513,7 +2832,7 @@ public: virtual size_t num_tech_boosts() const { if constexpr (requires { this->root->tech_boost_table; }) { - return this->get_data_array_count>(this->root->tech_boost_table); + return this->get_data_array_count>(this->root->tech_boost_table); } else { return 0; } @@ -2521,7 +2840,7 @@ public: virtual const TechBoost& get_tech_boost(size_t index) const { if constexpr (requires { this->root->tech_boost_table; }) { - return this->add_to_vector_cache>(this->tech_boosts, this->root->tech_boost_table, index); + return this->add_to_vector_cache>(this->tech_boosts, this->root->tech_boost_table, index); } else { throw std::logic_error("tech boost table not available"); } @@ -2620,6 +2939,332 @@ public: return this->get_data_range_size(start_offset) / sizeof(T); } + static std::string serialize(const ItemParameterTable& pmt) { + set relocations; + RootT root; + phosg::StringWriter w; + + if constexpr (!std::is_same_v) { + w.put(HeaderT()); + } + + auto align = [&w](size_t alignment) -> void { + while (w.size() & (alignment - 1)) { + w.put_u8(0); + } + }; + auto write_ref = [&w, &relocations](const ArrayRefT& ref) -> void { + w.put>(ref); + relocations.emplace(w.size() - 4); + }; + + if constexpr (requires { root.entry_count; }) { + root.entry_count = 0x13; + } + + align(4); + ArrayRefT shields_ref{pmt.num_armors_or_shields_in_class(2) - HasImplicitPlaceholders, w.size()}; + for (size_t data1_2 = 0; data1_2 < (shields_ref.count + HasImplicitPlaceholders); data1_2++) { + w.put(pmt.get_armor_or_shield(2, data1_2)); + } + if constexpr (requires { root.shield_stat_boost_index_table; }) { + root.shield_stat_boost_index_table = w.size(); + w.write(pmt.get_shield_stat_boost_index_table()); + } + + align(4); + ArrayRefT armors_ref{pmt.num_armors_or_shields_in_class(1) - HasImplicitPlaceholders, w.size()}; + for (size_t data1_2 = 0; data1_2 < (armors_ref.count + HasImplicitPlaceholders); data1_2++) { + w.put(pmt.get_armor_or_shield(1, data1_2)); + } + if constexpr (requires { root.armor_stat_boost_index_table; }) { + root.armor_stat_boost_index_table = w.size(); + w.write(pmt.get_armor_stat_boost_index_table()); + } + + align(4); + ArrayRefT units_ref{pmt.num_units() - HasImplicitPlaceholders, w.size()}; + for (size_t data1_2 = 0; data1_2 < (units_ref.count + HasImplicitPlaceholders); data1_2++) { + w.put(pmt.get_unit(data1_2)); + } + + align(4); + ArrayRefT mags_ref{pmt.num_mags() - HasImplicitPlaceholders, w.size()}; + for (size_t data1_2 = 0; data1_2 < (mags_ref.count + HasImplicitPlaceholders); data1_2++) { + w.put(pmt.get_mag(data1_2)); + } + + align(4); + std::vector> tool_refs; + for (size_t data1_1 = 0; data1_1 < pmt.num_tool_classes(); data1_1++) { + auto& ref = tool_refs.emplace_back(ArrayRefT{pmt.num_tools_in_class(data1_1), w.size()}); + for (size_t data1_2 = 0; data1_2 < ref.count; data1_2++) { + w.put(pmt.get_tool(data1_1, data1_2)); + } + } + + align(4); + std::vector> weapon_refs; + for (size_t data1_1 = 0; data1_1 < pmt.num_weapon_classes(); data1_1++) { + auto& ref = weapon_refs.emplace_back(ArrayRefT{pmt.num_weapons_in_class(data1_1), w.size()}); + for (size_t data1_2 = 0; data1_2 < ref.count; data1_2++) { + w.put(pmt.get_weapon(data1_1, data1_2)); + } + } + if constexpr (requires { root.weapon_stat_boost_index_table; }) { + root.weapon_stat_boost_index_table = w.size(); + w.write(pmt.get_weapon_stat_boost_index_table()); + } + + align(4); + root.photon_color_table = w.size(); + for (size_t z = 0; z < pmt.num_photon_colors(); z++) { + w.put>(pmt.get_photon_color(z)); + } + + align(4); + root.weapon_range_table = w.size(); + for (size_t z = 0; z < pmt.num_weapon_ranges(); z++) { + w.put>(pmt.get_weapon_range(z)); + } + + root.weapon_kind_table = w.size(); + for (size_t z = 0; z < pmt.num_weapon_classes(); z++) { + w.put_u8(pmt.get_weapon_kind(z)); + } + + if constexpr (requires { root.weapon_integral_sale_divisor_table; }) { + root.weapon_integral_sale_divisor_table = w.size(); + for (size_t z = 0; z < pmt.num_weapon_classes(); z++) { + w.put_u8(pmt.get_sale_divisor(0, z)); + } + } else { + align(4); + root.weapon_sale_divisor_table = w.size(); + for (size_t z = 0; z < pmt.num_weapon_sale_divisors(); z++) { + w.put>(pmt.get_sale_divisor(0, z)); + } + } + + if constexpr (requires { root.non_weapon_integral_sale_divisor_table; }) { + root.non_weapon_integral_sale_divisor_table = w.size(); + NonWeaponSaleDivisorsDCProtos sds; + sds.armor_divisor = pmt.get_sale_divisor(1, 1); + sds.shield_divisor = pmt.get_sale_divisor(1, 2); + sds.unit_divisor = pmt.get_sale_divisor(1, 3); + w.put(sds); + } else { + align(4); + root.non_weapon_sale_divisor_table = w.size(); + NonWeaponSaleDivisorsT sds; + sds.armor_divisor = pmt.get_sale_divisor(1, 1); + sds.shield_divisor = pmt.get_sale_divisor(1, 2); + sds.unit_divisor = pmt.get_sale_divisor(1, 3); + sds.mag_divisor = pmt.get_sale_divisor(2, 0); + w.put>(sds); + } + + MagFeedResultsListOffsetsT mag_feed_result_offsets; + for (size_t table_index = 0; table_index < 8; table_index++) { + mag_feed_result_offsets[table_index] = w.size(); + for (size_t item_id = 0; item_id < 11; item_id++) { + w.put(pmt.get_mag_feed_result(table_index, item_id)); + } + } + + root.star_value_table = w.size(); + w.write(pmt.get_star_value_table()); + + if constexpr (requires { root.unknown_a1; }) { + align(2); + root.unknown_a1 = w.size(); + w.write(pmt.get_unknown_a1()); + } + + align(2); + root.special_table = w.size(); + for (size_t z = 0; z < pmt.num_specials(); z++) { + w.put>(pmt.get_special(z)); + } + + align(4); + root.weapon_effect_table = w.size(); + for (size_t z = 0; z < pmt.num_weapon_effects(); z++) { + w.put>(pmt.get_weapon_effect(z)); + } + + align(4); + if constexpr (requires { root.shield_effect_table; }) { + root.shield_effect_table = w.size(); + for (size_t z = 0; z < pmt.num_shield_effects(); z++) { + w.put>(pmt.get_shield_effect(z)); + } + } + + align(4); + if constexpr (requires { root.sound_remap_table; }) { + std::vector> remap_refs; + const auto& remaps = pmt.get_all_sound_remaps(); + for (const auto& remap : remaps) { + auto& remap_ref = remap_refs.emplace_back(); + remap_ref.sound_id = remap.sound_id; + remap_ref.remaps_for_rt_index_table = w.size(); + for (uint32_t remap_sound_id : remap.by_rt_index) { + w.put>(remap_sound_id); + } + remap_ref.remaps_for_char_class_table = w.size(); + for (uint32_t remap_sound_id : remap.by_char_class) { + w.put>(remap_sound_id); + } + } + ArrayRefT remap_vec{remaps.size(), w.size()}; + for (const auto& remap_ref : remap_refs) { + w.put>(remap_ref); + relocations.emplace(w.size() - 8); + relocations.emplace(w.size() - 4); + } + root.sound_remap_table = w.size(); + write_ref(remap_vec); + } + + align(4); + root.stat_boost_table = w.size(); + for (size_t z = 0; z < pmt.num_stat_boosts(); z++) { + w.put>(pmt.get_stat_boost(z)); + } + + if constexpr (requires { root.max_tech_level_table; }) { + root.max_tech_level_table = w.size(); + MaxTechniqueLevels max_tech_levels; + for (size_t tech_num = 0; tech_num < 0x13; tech_num++) { + for (size_t char_class = 0; char_class < 0x0C; char_class++) { + max_tech_levels[tech_num][char_class] = pmt.get_max_tech_level(char_class, tech_num); + } + } + w.put(max_tech_levels); + } + + ArrayRefT combination_table_ref; + if constexpr (requires { root.combination_table; }) { + combination_table_ref.offset = w.size(); + combination_table_ref.count = pmt.num_item_combinations(); + for (size_t z = 0; z < combination_table_ref.count; z++) { + w.put(pmt.get_item_combination(z)); + } + } + + if constexpr (requires { root.tech_boost_table; }) { + align(4); + root.tech_boost_table = w.size(); + for (size_t z = 0; z < pmt.num_tech_boosts(); z++) { + w.put>(pmt.get_tech_boost(z)); + } + } + + std::vector> unwrap_table_refs; + if constexpr (requires { root.unwrap_table; }) { + for (size_t event = 0; event < pmt.num_events(); event++) { + auto [event_items, num_items] = pmt.get_event_items(event); + unwrap_table_refs.emplace_back(ArrayRefT{num_items, w.size()}); + w.write(event_items, sizeof(EventItem) * num_items); + } + } + + ArrayRefT unsealable_table_ref; + if constexpr (requires { root.unsealable_table; }) { + const auto& items = pmt.all_unsealable_items(); + unsealable_table_ref.count = items.size(); + unsealable_table_ref.offset = w.size(); + for (const auto& item : items) { + UnsealableItem encoded; + u32_to_item_code(encoded.item, item); + w.put(encoded); + } + } + + ArrayRefT ranged_specials_ref; + if constexpr (requires { root.ranged_special_table; }) { + ranged_specials_ref.count = pmt.num_ranged_specials(); + ranged_specials_ref.offset = w.size(); + for (size_t z = 0; z < ranged_specials_ref.count; z++) { + w.put(pmt.get_ranged_special(z)); + } + } + + align(4); + root.armor_table = w.size(); + write_ref(armors_ref); + write_ref(shields_ref); + root.unit_table = w.size(); + write_ref(units_ref); + root.mag_table = w.size(); + write_ref(mags_ref); + root.tool_table = w.size(); + for (const auto& ref : tool_refs) { + write_ref(ref); + } + root.weapon_table = w.size(); + for (const auto& ref : weapon_refs) { + write_ref(ref); + } + if constexpr (requires { root.combination_table; }) { + root.combination_table = w.size(); + write_ref(combination_table_ref); + } + if constexpr (requires { root.unwrap_table; }) { + ArrayRefT event_ref{unwrap_table_refs.size(), w.size()}; + for (const auto& ref : unwrap_table_refs) { + write_ref(ref); + } + root.unwrap_table = w.size(); + write_ref(event_ref); + } + if constexpr (requires { root.unsealable_table; }) { + root.unsealable_table = w.size(); + write_ref(unsealable_table_ref); + } + if constexpr (requires { root.ranged_special_table; }) { + root.ranged_special_table = w.size(); + write_ref(ranged_specials_ref); + } + + root.mag_feed_table = w.size(); + w.put>(mag_feed_result_offsets); + for (size_t z = 1; z <= 8; z++) { + relocations.emplace(w.size() - (z * 4)); + } + + RELFileFooterT footer; + footer.root_offset = w.size(); + w.put(root); + constexpr size_t root_field_count = (sizeof(RootT) / 4) - ((requires { root.entry_count; }) ? 1 : 0); + for (size_t z = 1; z <= root_field_count; z++) { + relocations.emplace(w.size() - (z * 4)); + } + + align(0x20); + footer.relocations_offset = w.size(); + footer.num_relocations = relocations.size(); + footer.unused1[0] = 1; + uint32_t last_offset = 0; + for (uint32_t reloc_offset : relocations) { + if (reloc_offset & 3) { + throw logic_error("Relocation is not 4-byte aligned"); + } + size_t reloc_value = (reloc_offset - last_offset) >> 2; + if (reloc_value > 0xFFFF) { + throw runtime_error("Relocation offset is too far away from previous"); + } + w.put>(reloc_value); + last_offset = reloc_offset; + } + + align(0x20); + w.put>(footer); + + return std::move(w.str()); + } + protected: std::shared_ptr data; phosg::StringReader r; @@ -2640,7 +3285,7 @@ protected: mutable std::vector weapon_ranges; mutable std::vector weapon_effects; mutable std::vector shield_effects; - mutable std::optional> sound_remaps; + mutable std::optional> sound_remaps; mutable std::vector tech_boosts; // Key is used_item. We can't index on (used_item, equipped_item) because equipped_item may contain wildcards, and @@ -2651,132 +3296,116 @@ protected: }; using ItemParameterTableDCNTE = BinaryItemParameterTableT< + EmptyHeader, // typename HeaderT RootDCProtos, // typename RootT WeaponDCProtos, // typename WeaponT - 0x27, // size_t NumWeaponClasses ArmorOrShieldDCProtos, // typename ArmorOrShieldT UnitDCProtos, // typename UnitT ToolV1V2, // typename ToolT - 0x0D, // size_t NumToolClasses MagV1, // typename MagT + false, // bool HasImplicitPlaceholders 0x22, // size_t ItemStarsFirstID - 0x168, // size_t ItemStarsLastID 0xAA, // size_t SpecialStarsBeginIndex - 0x28, // size_t NumSpecials - 0x14, // size_t NumPhotonColors 0x00, // size_t SoundRemapRTTableSize + false, // bool HasServerHeader false>; // bool BE using ItemParameterTableDC112000 = BinaryItemParameterTableT< + EmptyHeader, // typename HeaderT RootDCProtos, // typename RootT WeaponDCProtos, // typename WeaponT - 0x27, // size_t NumWeaponClasses ArmorOrShieldDCProtos, // typename ArmorOrShieldT UnitDCProtos, // typename UnitT ToolV1V2, // typename ToolT - 0x0E, // size_t NumToolClasses MagV1, // typename MagT + false, // bool HasImplicitPlaceholders 0x26, // size_t ItemStarsFirstID - 0x16C, // size_t ItemStarsLastID 0xAE, // size_t SpecialStarsBeginIndex - 0x28, // size_t NumSpecials - 0x14, // size_t NumPhotonColors 0x00, // size_t SoundRemapRTTableSize + false, // bool HasServerHeader false>; // bool BE using ItemParameterTableV1 = BinaryItemParameterTableT< + EmptyHeader, // typename HeaderT RootV1, // typename RootT WeaponV1V2, // typename WeaponT - 0x27, // size_t NumWeaponClasses ArmorOrShieldV1V2, // typename ArmorOrShieldT UnitV1V2, // typename UnitT ToolV1V2, // typename ToolT - 0x0E, // size_t NumToolClasses MagV1, // typename MagT + false, // bool HasImplicitPlaceholders 0x26, // size_t ItemStarsFirstID - 0x16C, // size_t ItemStarsLastID 0xAE, // size_t SpecialStarsBeginIndex - 0x29, // size_t NumSpecials - 0x14, // size_t NumPhotonColors 0x00, // size_t SoundRemapRTTableSize + false, // bool HasServerHeader false>; // bool BE using ItemParameterTableV2 = BinaryItemParameterTableT< + HeaderV2, // typename HeaderT RootV2, // typename RootT WeaponV1V2, // typename WeaponT - 0x89, // size_t NumWeaponClasses ArmorOrShieldV1V2, // typename ArmorOrShieldT UnitV1V2, // typename UnitT ToolV1V2, // typename ToolT - 0x10, // size_t NumToolClasses MagV2, // typename MagT + true, // bool HasImplicitPlaceholders 0x4E, // size_t ItemStarsFirstID - 0x215, // size_t ItemStarsLastID 0x138, // size_t SpecialStarsBeginIndex - 0x29, // size_t NumSpecials - 0x20, // size_t NumPhotonColors 0x00, // size_t SoundRemapRTTableSize + false, // bool HasServerHeader false>; // bool BE using ItemParameterTableGCNTE = BinaryItemParameterTableT< + HeaderGCNTE, // typename HeaderT RootGCNTE, // typename RootT WeaponGCNTE, // typename WeaponT - 0x8D, // size_t NumWeaponClasses ArmorOrShieldGC, // typename ArmorOrShieldT UnitGC, // typename UnitT ToolGC, // typename ToolT - 0x13, // size_t NumToolClasses MagGC, // typename MagT + false, // bool HasImplicitPlaceholders 0x76, // size_t ItemStarsFirstID - 0x298, // size_t ItemStarsLastID 0x1A3, // size_t SpecialStarsBeginIndex - 0x29, // size_t NumSpecials - 0x20, // size_t NumPhotonColors 0x4F, // size_t SoundRemapRTTableSize + false, // bool HasServerHeader true>; // bool BE using ItemParameterTableGC = BinaryItemParameterTableT< + HeaderV3, // typename HeaderT RootV3V4T, // typename RootT WeaponGC, // typename WeaponT - 0xAA, // size_t NumWeaponClasses ArmorOrShieldGC, // typename ArmorOrShieldT UnitGC, // typename UnitT ToolGC, // typename ToolT - 0x18, // size_t NumToolClasses MagGC, // typename MagT + false, // bool HasImplicitPlaceholders 0x94, // size_t ItemStarsFirstID - 0x2F7, // size_t ItemStarsLastID 0x1CB, // size_t SpecialStarsBeginIndex - 0x29, // size_t NumSpecials - 0x20, // size_t NumPhotonColors 0x58, // size_t SoundRemapRTTableSize + false, // bool HasServerHeader true>; // bool BE using ItemParameterTableXB = BinaryItemParameterTableT< + HeaderV3, // typename HeaderT RootV3V4T, // typename RootT WeaponXB, // typename WeaponT - 0xAA, // size_t NumWeaponClasses ArmorOrShieldXB, // typename ArmorOrShieldT UnitXB, // typename UnitT ToolXB, // typename ToolT - 0x18, // size_t NumToolClasses MagXB, // typename MagT + false, // bool HasImplicitPlaceholders 0x94, // size_t ItemStarsFirstID - 0x2F7, // size_t ItemStarsLastID 0x1CB, // size_t SpecialStarsBeginIndex - 0x29, // size_t NumSpecials - 0x20, // size_t NumPhotonColors 0x58, // size_t SoundRemapRTTableSize + false, // bool HasServerHeader false>; // bool BE using ItemParameterTableV4 = BinaryItemParameterTableT< + HeaderV4, // typename HeaderT RootV3V4T, // typename RootT WeaponV4, // typename WeaponT - 0xED, // size_t NumWeaponClasses ArmorOrShieldV4, // typename ArmorOrShieldT UnitV4, // typename UnitT ToolV4, // typename ToolT - 0x1B, // size_t NumToolClasses MagV4, // typename MagT + false, // bool HasImplicitPlaceholders 0xB1, // size_t ItemStarsFirstID - 0x437, // size_t ItemStarsLastID 0x256, // size_t SpecialStarsBeginIndex - 0x29, // size_t NumSpecials - 0x20, // size_t NumPhotonColors 0x6A, // size_t SoundRemapRTTableSize + true, // bool HasServerHeader false>; // bool BE std::shared_ptr ItemParameterTable::from_binary( @@ -2810,3 +3439,30 @@ std::shared_ptr ItemParameterTable::from_binary( std::shared_ptr ItemParameterTable::from_json(const phosg::JSON& json) { return std::make_shared(json); } + +std::string ItemParameterTable::serialize_binary(Version version) const { + switch (version) { + case Version::DC_NTE: + return ItemParameterTableDCNTE::serialize(*this); + case Version::DC_11_2000: + return ItemParameterTableDC112000::serialize(*this); + case Version::DC_V1: + return ItemParameterTableV1::serialize(*this); + case Version::DC_V2: + case Version::PC_NTE: + case Version::PC_V2: + return ItemParameterTableV2::serialize(*this); + case Version::GC_NTE: + return ItemParameterTableGCNTE::serialize(*this); + case Version::GC_V3: + case Version::GC_EP3: + case Version::GC_EP3_NTE: + return ItemParameterTableGC::serialize(*this); + case Version::XB_V3: + return ItemParameterTableXB::serialize(*this); + case Version::BB_V4: + return ItemParameterTableV4::serialize(*this); + default: + throw std::logic_error("Cannot create item parameter table for this version"); + } +} diff --git a/src/ItemParameterTable.hh b/src/ItemParameterTable.hh index 47d3e2f0..854b83f5 100644 --- a/src/ItemParameterTable.hh +++ b/src/ItemParameterTable.hh @@ -68,6 +68,7 @@ public: uint8_t special = 0; uint8_t ata = 0; uint8_t stat_boost_entry_index = 0; + parray v2_unknown_a9; uint8_t projectile = 0; int8_t trail1_x = 0; int8_t trail1_y = 0; @@ -361,7 +362,7 @@ public: static std::shared_ptr from_json(const phosg::JSON& json); phosg::JSON json() const; - // std::string serialize_binary() const; // TODO + std::string serialize_binary(Version version) const; std::set compute_all_valid_primary_identifiers() const; @@ -389,6 +390,7 @@ public: virtual const Mag& get_mag(uint8_t data1_1) const = 0; // weapon_kind_table accessors (data1_1 in [0, num_weapon_classes()]) + virtual size_t num_weapon_kinds() const = 0; virtual uint8_t get_weapon_kind(uint8_t data1_1) const = 0; // photon_color_table accessors @@ -401,6 +403,7 @@ public: // weapon_sale_divisor_table and non_weapon_sale_divisor_table accessors (data1_0 in [0, 1, 2]; data1_1 in [0, // num_weapon_classes()] for weapons or ignored otherwise) + virtual size_t num_weapon_sale_divisors() const = 0; virtual float get_sale_divisor(uint8_t data1_0, uint8_t data1_1) const = 0; // mag_feed_table accessors (table_index in [0, 7], item_index in [0, 10]) @@ -451,12 +454,14 @@ public: virtual uint8_t get_max_tech_level(uint8_t char_class, uint8_t tech_num) const = 0; // combination_table accessors - virtual const std::map>& all_item_combinations() const = 0; + virtual size_t num_item_combinations() const = 0; + virtual const ItemCombination& get_item_combination(size_t index) const = 0; + const std::map>& item_combinations_index() const; const std::vector& all_combinations_for_used_item(const ItemData& used_item) const; const ItemCombination& get_item_combination(const ItemData& used_item, const ItemData& equipped_item) const; // sound_remap_table accessors - virtual const std::unordered_map& get_all_sound_remaps() const = 0; + virtual const std::vector& get_all_sound_remaps() const = 0; // tech_boost_table accessors virtual size_t num_tech_boosts() const = 0; @@ -487,4 +492,6 @@ public: protected: ItemParameterTable() = default; + + mutable std::optional>> item_combination_index; }; diff --git a/src/ItemTranslationTable.cc b/src/ItemTranslationTable.cc index 384db832..54aaaeae 100644 --- a/src/ItemTranslationTable.cc +++ b/src/ItemTranslationTable.cc @@ -46,18 +46,18 @@ ItemTranslationTable::ItemTranslationTable( uint32_t e_id = this->entries[z].id_for_version[v_s]; if (is_canonical(e_id)) { if (!entry_index.count(e_id)) { - throw logic_error(std::format("(row {} version {}) canonical ID {:X} is missing from the index", z, phosg::name_for_enum(v), e_id)); + throw logic_error(std::format("(row {} version {}) canonical ID {:08X} is missing from the index", z, phosg::name_for_enum(v), e_id)); } try { item_parameter_table->definition_for_primary_identifier(e_id); } catch (const out_of_range&) { - throw runtime_error(std::format("(row {} version {}) ID {:X} not defined in item parameter table", z, phosg::name_for_enum(v), e_id)); + throw runtime_error(std::format("(row {} version {}) ID {:08X} not defined in item parameter table", z, phosg::name_for_enum(v), e_id)); } if (!remaining_identifiers.erase(e_id)) { - throw runtime_error(std::format("(row {} version {}) ID {:X} not in item parameter table's primary identifier list", z, phosg::name_for_enum(v), e_id)); + throw runtime_error(std::format("(row {} version {}) ID {:08X} not in item parameter table's primary identifier list", z, phosg::name_for_enum(v), e_id)); } } else if (!entry_index.count(make_canonical(e_id))) { - throw runtime_error(std::format("(row {} version {}) ID {:X} refers to nonexistent canonical ID", z, phosg::name_for_enum(v), e_id)); + throw runtime_error(std::format("(row {} version {}) ID {:08X} refers to nonexistent canonical ID", z, phosg::name_for_enum(v), e_id)); } } diff --git a/src/Main.cc b/src/Main.cc index 644c4fd8..d07ec2f7 100644 --- a/src/Main.cc +++ b/src/Main.cc @@ -2387,10 +2387,20 @@ Action a_compare_common_item_set( cs1->print_diff(stdout, *cs2); }); -Action a_convert_item_parameter_table( - "decode-item-parameter-table", nullptr, +Action a_decode_item_parameter_table( + "decode-item-parameter-table", "\ + decode-item-parameter-table [INPUT-FILENAME [OUTPUT-FILENAME]] [OPTIONS...]\n\ + Converts an ItemPMT file into a JSON item parameter table. A version\n\ + option is required. Use --hex to make item codes in the output readable;\n\ + however, this option also uses nonstandard JSON syntax - newserv can parse\n\ + it, but many other JSON parsers can\'t. Expects compressed input (a .prs\n\ + file) by default; use --decompressed if the input is not compressed.\n", +[](phosg::Arguments& args) { - auto data = std::make_shared(read_input_data(args)); + auto input_data = read_input_data(args); + if (!args.get("decompressed")) { + input_data = prs_decompress(input_data); + } + auto data = std::make_shared(std::move(input_data)); auto pmt = ItemParameterTable::from_binary(data, get_cli_version(args, Version::BB_V4)); auto json = pmt->json(); uint32_t serialize_options = phosg::JSON::SerializeOption::FORMAT | phosg::JSON::SerializeOption::SORT_DICT_KEYS; @@ -2401,6 +2411,23 @@ Action a_convert_item_parameter_table( write_output_data(args, json_data.data(), json_data.size(), nullptr); }); +Action a_encode_item_parameter_table( + "encode-item-parameter-table", "\ + encode-item-parameter-table [INPUT-FILENAME [OUTPUT-FILENAME]] [OPTIONS...]\n\ + Converts a JSON item parameter table into an ItemPMT file compatible with\n\ + the game client. A version option is required. By default the output will\n\ + be compressed, as the client expects; use --decompressed to get\n\ + uncompressed output.\n", + +[](phosg::Arguments& args) { + auto json = phosg::JSON::parse(read_input_data(args)); + auto pmt = ItemParameterTable::from_json(json); + string data = pmt->serialize_binary(get_cli_version(args, Version::BB_V4)); + if (!args.get("decompressed")) { + data = prs_compress_optimal(data); + } + write_output_data(args, data.data(), data.size(), nullptr); + }); + Action a_describe_item( "describe-item", "\ describe-item DATA-OR-DESCRIPTION\n\ diff --git a/src/SendCommands.cc b/src/SendCommands.cc index c850c239..5708ef40 100644 --- a/src/SendCommands.cc +++ b/src/SendCommands.cc @@ -690,42 +690,16 @@ void send_guild_card_chunk_bb(shared_ptr c, size_t chunk_index) { send_command(c, 0x02DC, 0x00000000, &cmd, sizeof(cmd) - sizeof(cmd.data) + data_size); } -static const vector stream_file_entries = { - "ItemMagEdit.prs", - "ItemPMT.prs", - "BattleParamEntry.dat", - "BattleParamEntry_on.dat", - "BattleParamEntry_lab.dat", - "BattleParamEntry_lab_on.dat", - "BattleParamEntry_ep4.dat", - "BattleParamEntry_ep4_on.dat", - "PlyLevelTbl.prs", -}; - void send_stream_file_index_bb(shared_ptr c) { auto s = c->require_server_state(); vector entries; - size_t offset = 0; - for (const string& filename : stream_file_entries) { - string key = "system/blueburst/" + filename; - auto cache_res = s->bb_stream_files_cache->get_or_load(key); + for (const auto& sf_entry : s->bb_stream_file->entries) { auto& e = entries.emplace_back(); - e.size = cache_res.file->data->size(); - // Computing the checksum can be slow, so we cache it along with the file data. If the cache result was just - // populated, then it may be different, so we always recompute the checksum in that case. - if (cache_res.generate_called) { - e.checksum = crc32(cache_res.file->data->data(), e.size); - s->bb_stream_files_cache->replace_obj(key + ".crc32", e.checksum); - } else { - auto compute_checksum = [&](const string&) -> uint32_t { - return crc32(cache_res.file->data->data(), e.size); - }; - e.checksum = s->bb_stream_files_cache->get_obj(key + ".crc32", compute_checksum).obj; - } - e.offset = offset; - e.filename.encode(filename); - offset += e.size; + e.size = sf_entry.size; + e.checksum = sf_entry.checksum; + e.offset = sf_entry.offset; + e.filename.encode(sf_entry.filename); } send_command_vt(c, 0x01EB, entries.size(), entries); } @@ -733,30 +707,14 @@ void send_stream_file_index_bb(shared_ptr c) { void send_stream_file_chunk_bb(shared_ptr c, uint32_t chunk_index) { auto s = c->require_server_state(); - auto cache_result = s->bb_stream_files_cache->get( - "", [&](const string&) -> string { - size_t bytes = 0; - for (const auto& name : stream_file_entries) { - bytes += s->bb_stream_files_cache->get_or_load("system/blueburst/" + name).file->data->size(); - } - - string ret; - ret.reserve(bytes); - for (const auto& name : stream_file_entries) { - ret += *s->bb_stream_files_cache->get_or_load("system/blueburst/" + name).file->data; - } - return ret; - }); - const auto& contents = cache_result.file->data; - S_StreamFileChunk_BB_02EB chunk_cmd; chunk_cmd.chunk_index = chunk_index; size_t offset = sizeof(chunk_cmd.data) * chunk_index; - if (offset > contents->size()) { + if (offset > s->bb_stream_file->data.size()) { throw runtime_error("client requested chunk beyond end of stream file"); } - size_t bytes = min(contents->size() - offset, sizeof(chunk_cmd.data)); - chunk_cmd.data.assign_range(reinterpret_cast(contents->data() + offset), bytes, 0); + size_t bytes = min(s->bb_stream_file->data.size() - offset, sizeof(chunk_cmd.data)); + chunk_cmd.data.assign_range(reinterpret_cast(s->bb_stream_file->data.data() + offset), bytes, 0); size_t cmd_size = offsetof(S_StreamFileChunk_BB_02EB, data) + bytes; cmd_size = (cmd_size + 3) & ~3; diff --git a/src/ServerState.cc b/src/ServerState.cc index 2740808a..4409fc5a 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -79,7 +79,6 @@ ServerState::ServerState(const string& config_filename, bool is_replay) config_filename(config_filename), is_replay(is_replay), thread_pool(make_unique()), - bb_stream_files_cache(new FileContentsCache(3600000000ULL)), bb_system_cache(new FileContentsCache(3600000000ULL)), gba_files_cache(new FileContentsCache(3600000000ULL)) {} @@ -1831,8 +1830,6 @@ vector> ServerState::supermaps_for_variations( } void ServerState::clear_file_caches() { - config_log.info_f("Clearing BB stream file cache"); - this->bb_stream_files_cache.reset(new FileContentsCache(3600000000ULL)); config_log.info_f("Clearing BB system cache"); this->bb_system_cache.reset(new FileContentsCache(3600000000ULL)); config_log.info_f("Clearing GBA file cache"); @@ -2148,10 +2145,9 @@ void ServerState::load_item_definitions() { config_log.info_f("Loading item definition tables"); for (size_t v_s = NUM_PATCH_VERSIONS; v_s < NUM_VERSIONS; v_s++) { Version v = static_cast(v_s); - string path = std::format("system/item-tables/ItemPMT-{}.prs", file_path_token_for_version(v)); + string path = std::format("system/item-tables/item-parameter-table-{}.json", file_path_token_for_version(v)); config_log.debug_f("Loading item definition table {}", path); - auto data = make_shared(prs_decompress(phosg::load_file(path))); - new_item_parameter_tables[v_s] = ItemParameterTable::from_binary(data, v); + new_item_parameter_tables[v_s] = ItemParameterTable::from_json(phosg::JSON::parse(phosg::load_file(path))); } auto json = phosg::JSON::parse(phosg::load_file("system/item-tables/translation-table.json")); @@ -2227,6 +2223,39 @@ void ServerState::load_dol_files() { this->dol_file_index = make_shared("system/dol"); } +void ServerState::generate_bb_stream_file() { + config_log.info_f("Generating BB stream file"); + auto sf = std::make_shared(); + + auto add_file = [&](const std::string& filename, std::string&& file_data = "") -> void { + if (file_data.empty()) { + file_data = phosg::load_file("system/blueburst/" + filename); + } + auto& e = sf->entries.emplace_back(); + e.size = file_data.size(); + e.checksum = phosg::crc32(file_data.data(), file_data.size()); + e.offset = sf->data.size(); + e.filename = filename; + sf->data += file_data; + config_log.debug_f( + "[BBStreamFile] Added file {} at offset {:08X} ({:08X} bytes) with checksum {:08X}; total size is now {:08X}", + filename, e.offset, e.size, e.checksum, sf->data.size()); + }; + + add_file("BattleParamEntry.dat"); + add_file("BattleParamEntry_on.dat"); + add_file("BattleParamEntry_lab.dat"); + add_file("BattleParamEntry_lab_on.dat"); + add_file("BattleParamEntry_ep4.dat"); + add_file("BattleParamEntry_ep4_on.dat"); + add_file("PlyLevelTbl.prs"); + add_file("ItemMagEdit.prs"); + auto pmt = this->item_parameter_table(Version::BB_V4); + add_file("ItemPMT.prs", prs_compress_optimal(pmt->serialize_binary(Version::BB_V4))); + + this->bb_stream_file = sf; +} + void ServerState::create_default_lobbies() { if (this->default_lobbies_created) { return; @@ -2306,6 +2335,7 @@ void ServerState::load_all(bool enable_thread_pool) { this->load_config_late(); this->load_teams(); this->load_quest_index(); + this->generate_bb_stream_file(); } void ServerState::disconnect_all_banned_clients() { diff --git a/src/ServerState.hh b/src/ServerState.hh index 41365247..5ec33031 100644 --- a/src/ServerState.hh +++ b/src/ServerState.hh @@ -65,6 +65,17 @@ struct CheatFlags { explicit CheatFlags(const phosg::JSON& json); }; +struct BBStreamFile { + struct Entry { + uint32_t offset; + uint32_t size; + uint32_t checksum; // crc32 + std::string filename; + }; + std::vector entries; + std::string data; +}; + struct ServerState : public std::enable_shared_from_this { enum class RunShellBehavior { DEFAULT = 0, @@ -180,7 +191,7 @@ struct ServerState : public std::enable_shared_from_this { std::unordered_map> supermap_for_source_hash_sum; std::unordered_map> supermap_for_free_play_key; std::shared_ptr room_layout_index; - std::shared_ptr bb_stream_files_cache; + std::shared_ptr bb_stream_file; std::shared_ptr bb_system_cache; std::shared_ptr gba_files_cache; std::shared_ptr dol_file_index; @@ -442,6 +453,7 @@ struct ServerState : public std::enable_shared_from_this { void load_quest_index(bool raise_on_any_failure = false); void compile_functions(bool raise_on_any_failure = false); void load_dol_files(); + void generate_bb_stream_file(); void load_all(bool enable_thread_pool); diff --git a/src/ShellCommands.cc b/src/ShellCommands.cc index d0aa8780..eb2e886a 100644 --- a/src/ShellCommands.cc +++ b/src/ShellCommands.cc @@ -211,14 +211,17 @@ ShellCommand c_reload( args.s->load_set_data_tables(); } else if (type == "battle-params") { args.s->load_battle_params(); + args.s->generate_bb_stream_file(); } else if (type == "level-tables") { args.s->load_level_tables(); + args.s->generate_bb_stream_file(); } else if (type == "text-index") { args.s->load_text_index(); } else if (type == "word-select") { args.s->load_word_select_table(); } else if (type == "item-definitions") { args.s->load_item_definitions(); + args.s->generate_bb_stream_file(); } else if (type == "item-name-index") { args.s->load_item_name_indexes(); } else if (type == "drop-tables") { diff --git a/system/blueburst/ItemPMT.prs b/system/blueburst/ItemPMT.prs deleted file mode 120000 index 93acdd34..00000000 --- a/system/blueburst/ItemPMT.prs +++ /dev/null @@ -1 +0,0 @@ -../item-tables/ItemPMT-bb-v4.prs \ No newline at end of file diff --git a/system/item-tables/ItemPMT-bb-v4.prs b/system/item-tables/ItemPMT-bb-v4.prs deleted file mode 100644 index 46a923849437118417dc67b6f01539a3768ac70c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21068 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 LlD5g$G@AbbO?86n diff --git a/system/item-tables/ItemPMT-dc-11-2000.prs b/system/item-tables/ItemPMT-dc-11-2000.prs deleted file mode 100644 index d6e163f0ded00d4e19e3947854fc215ad69974b6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4833 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 M+V^b?$uaEz0k$e;kpKVy diff --git a/system/item-tables/ItemPMT-dc-v1.prs b/system/item-tables/ItemPMT-dc-v1.prs deleted file mode 100644 index 369d1580163cccd0cf18b0f4dd0bb98975f47a50..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5755 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 diff --git a/system/item-tables/ItemPMT-dc-v2.prs b/system/item-tables/ItemPMT-dc-v2.prs deleted file mode 120000 index 1e1d0196..00000000 --- a/system/item-tables/ItemPMT-dc-v2.prs +++ /dev/null @@ -1 +0,0 @@ -ItemPMT-pc-v2.prs \ No newline at end of file diff --git a/system/item-tables/ItemPMT-gc-ep3-nte.prs b/system/item-tables/ItemPMT-gc-ep3-nte.prs deleted file mode 120000 index de681f45..00000000 --- a/system/item-tables/ItemPMT-gc-ep3-nte.prs +++ /dev/null @@ -1 +0,0 @@ -ItemPMT-gc-v3.prs \ No newline at end of file diff --git a/system/item-tables/ItemPMT-gc-ep3.prs b/system/item-tables/ItemPMT-gc-ep3.prs deleted file mode 120000 index de681f45..00000000 --- a/system/item-tables/ItemPMT-gc-ep3.prs +++ /dev/null @@ -1 +0,0 @@ -ItemPMT-gc-v3.prs \ No newline at end of file diff --git a/system/item-tables/ItemPMT-gc-nte.prs b/system/item-tables/ItemPMT-gc-nte.prs deleted file mode 100644 index 3435fb34c5b31024707c08436e9fd0f3a61052eb..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5674 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 diff --git a/system/item-tables/ItemPMT-gc-v3.prs b/system/item-tables/ItemPMT-gc-v3.prs deleted file mode 100644 index 315360b76f36923d0e1bce157666bba598e57e47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 15673 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
    gJ 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 Qx_4*IF$K$rkV5GH0jsF(cK`qY diff --git a/system/item-tables/ItemPMT-pc-nte.prs b/system/item-tables/ItemPMT-pc-nte.prs deleted file mode 120000 index 1e1d0196..00000000 --- a/system/item-tables/ItemPMT-pc-nte.prs +++ /dev/null @@ -1 +0,0 @@ -ItemPMT-pc-v2.prs \ No newline at end of file diff --git a/system/item-tables/ItemPMT-pc-v2.prs b/system/item-tables/ItemPMT-pc-v2.prs deleted file mode 100644 index 9de810974decba46dd14a432ea3a576de0387799..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8454 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 QUMBonM8-FF$`Sg10Jq;+E&u=k diff --git a/system/item-tables/translation-table.json b/system/item-tables/translation-table.json index 68516999..70a342f1 100644 --- a/system/item-tables/translation-table.json +++ b/system/item-tables/translation-table.json @@ -1,19 +1,15 @@ [ - // This table maps in-game primary identifiers across client versions. The - // high bit of the entries in this table specifies the entry type; if this - // bit is set, the entry is not "canonical"; that is, it's a one-way mapping - // and the client does not actually have that item defined. Each primary - // identifier must have at most one "canonical" listing for each version - // (but may have none). To convert an item from client A to client B: - // 1. Scan the column for A's version in the table to find the cell that - // contains the primary identifier sent by A. (We optimize this with an - // index.) + // This table maps in-game primary identifiers across client versions. The high bit of the entries in this table + // specifies the entry type; if this bit is set, the entry is not "canonical"; that is, it's a one-way mapping and + // the client does not actually have that item defined. Each primary identifier must have at most one "canonical" + // listing for each version (but may have none). To convert an item from client A to client B: + // 1. Scan the column for A's version in the table to find the cell that contains the primary identifier sent by A. + // (We optimize this with an index.) // 2. Move left or right to the column for B's version. - // 3. Take the value from that cell, clear the high bit if needed, and use - // that as the primary identifier to show to B. + // 3. Take the value from that cell, clear the high bit if needed, and use that as the primary identifier for B. // This logic is implemented in ItemTranslationTable.cc. - // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME + // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME [0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, "UNUSED"], [0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, 0x00010000, "Saber"], [0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, 0x00010100, "Brand"], @@ -134,7 +130,6 @@ [0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x800F0000, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, 0x000F0100, "ANGRY FIST"], [0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x800F0000, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, 0x000F0200, "GOD HAND"], [0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x800F0000, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, 0x000F0300, "SONIC KNUCKLE"], - [0x000F0400, 0x000F0400, 0x000F0400, 0x000F0400, 0x000F0400, 0x000F0400, 0x80020500, 0x80100000, 0x80100000, 0x80100000, 0x80100000, 0x80100000, "OROTIAGITO (v0-v2)"], [0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0000, 0x800F0300, 0x800F0300, 0x800F0300, 0x800F0300, 0x000F0400, "LOGiN"], [0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, 0x00100000, "OROTIAGITO"], [0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x80100000, 0x00100100, 0x00100100, 0x00100100, 0x00100100, 0x00100100, "AGITO (1975)"], @@ -439,7 +434,9 @@ [0x80080500, 0x80080500, 0x80080500, 0x80770000, 0x80770000, 0x80770000, 0x80080500, 0x80770000, 0x80770000, 0x80770000, 0x80770000, 0x00EA0000, "TypeME/MECHGUN"], [0x80090500, 0x80090500, 0x80090500, 0x80780000, 0x80780000, 0x80780000, 0x80090500, 0x80780000, 0x80780000, 0x80780000, 0x80780000, 0x00EB0000, "TypeSH/SHOT"], [0x800C0400, 0x800C0400, 0x800C0400, 0x807B0000, 0x807B0000, 0x807B0000, 0x800C0400, 0x807B0000, 0x807B0000, 0x807B0000, 0x807B0000, 0x00EC0000, "TypeWA/WAND"], + [0x80010000, 0x80010000, 0x80010000, 0x00890000, 0x00890000, 0x00890000, 0x008D0000, 0x00AA0000, 0x00AA0000, 0x00AA0000, 0x00AA0000, 0x00ED0000, "???? (WEAPON)"], + // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME [0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, 0x01010000, "Frame"], [0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, 0x01010100, "Armor"], [0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, 0x01010200, "Psy Armor"], @@ -528,8 +525,9 @@ [0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x81010C00, 0x81013400, 0x81013400, 0x81013400, 0x81013400, 0x01015500, "UNION FIELD"], [0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x81010C00, 0x81013400, 0x81013400, 0x81013400, 0x81013400, 0x01015600, "SAMURAI ARMOR"], [0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x81010C00, 0x81013400, 0x81013400, 0x81013400, 0x81013400, 0x01015700, "STEALTH SUIT"], - [0x81012800, 0x81012800, 0x81012800, 0x81013400, 0x81013400, 0x81013400, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01015800, "???? (ARMOR)"], + [0x81012800, 0x81012800, 0x81012800, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01013500, 0x01015800, "???? (ARMOR)"], + // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME [0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, 0x01020000, "Barrier"], [0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, 0x01020100, "Shield"], [0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, 0x01020200, "Core Shield"], @@ -695,8 +693,9 @@ [0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x81028400, 0x81028400, 0x81028400, 0x81028400, 0x0102A200, "GENPEI (unused)"], [0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x81028400, 0x81028400, 0x81028400, 0x81028400, 0x0102A300, "GENPEI (unused)"], [0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x81028400, 0x81028400, 0x81028400, 0x81028400, 0x0102A400, "GENPEI (unused)"], - [0x81022600, 0x81022600, 0x81022600, 0x81023500, 0x81023500, 0x81023500, 0x81020C00, 0x01028500, 0x01028500, 0x01028500, 0x01028500, 0x0102A500, "???? (SHIELD)"], + [0x81022600, 0x81022600, 0x81022600, 0x01023A00, 0x01023A00, 0x01023A00, 0x81020C00, 0x01028500, 0x01028500, 0x01028500, 0x01028500, 0x0102A500, "???? (SHIELD)"], + // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME [0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, 0x01030000, "Knight/Power"], [0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, 0x01030100, "General/Power"], [0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, 0x01030200, "Ogre/Power"], @@ -799,8 +798,9 @@ [0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x81033400, 0x81033500, 0x81033500, 0x81033500, 0x81033500, 0x01036100, "HP/Resurrection"], [0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x81033700, 0x81033800, 0x81033800, 0x81033800, 0x81033800, 0x01036200, "TP/Resurrection"], [0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033A00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x01036300, "PB/Increase"], - [0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x81033B00, 0x01034700, 0x01034800, 0x01034800, 0x01034800, 0x01034800, 0x01036400, "???? (UNIT)"], + [0x81033B00, 0x81033B00, 0x81033B00, 0x01034400, 0x01034400, 0x01034400, 0x01034700, 0x01034800, 0x01034800, 0x01034800, 0x01034800, 0x01036400, "???? (UNIT)"], + // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME [0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, 0x02000000, "Mag"], [0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, 0x02010000, "Varuna"], [0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, 0x02020000, "Mitra"], @@ -841,10 +841,10 @@ [0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, 0x02250000, "Naraka"], [0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, 0x02260000, "Madhu"], [0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, 0x02270000, "Churel"], - [0x82000000, 0x82000000, 0x82000000, 0x02280000, 0x02280000, 0x02280000, 0x82000000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, "ROBOCHAO"], - [0x82000000, 0x82000000, 0x82000000, 0x02290000, 0x02290000, 0x02290000, 0x82000000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, "OPA-OPA"], - [0x82000000, 0x82000000, 0x82000000, 0x022A0000, 0x022A0000, 0x022A0000, 0x82000000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, "PIAN"], - [0x82000000, 0x82000000, 0x82000000, 0x022B0000, 0x022B0000, 0x022B0000, 0x82000000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, "CHAO"], + [0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x82000000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, 0x02280000, "ROBOCHAO"], + [0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x82000000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, 0x02290000, "OPA-OPA"], + [0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x82000000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, 0x022A0000, "PIAN"], + [0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x82000000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, 0x022B0000, "CHAO"], [0x82000000, 0x82000000, 0x82000000, 0x022C0000, 0x022C0000, 0x022C0000, 0x82000000, 0x022C0000, 0x022C0000, 0x022C0000, 0x022C0000, 0x022C0000, "CHU CHU"], [0x82000000, 0x82000000, 0x82000000, 0x022D0000, 0x022D0000, 0x022D0000, 0x82000000, 0x022D0000, 0x022D0000, 0x022D0000, 0x022D0000, 0x022D0000, "KAPU KAPU"], [0x82000000, 0x82000000, 0x82000000, 0x022E0000, 0x022E0000, 0x022E0000, 0x82000000, 0x022E0000, 0x022E0000, 0x022E0000, 0x022E0000, 0x022E0000, "ANGEL'S WING"], @@ -883,8 +883,9 @@ [0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x024F0000, "Cell of MAG 0505 (mag)"], [0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x02500000, "Cell of MAG 0506 (mag)"], [0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x02510000, "Cell of MAG 0507 (mag)"], - [0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x82000000, 0x02280000, 0x02420000, 0x02420000, 0x02420000, 0x02420000, 0x02520000, "???? (MAG)"], + [0x82000000, 0x82000000, 0x82000000, 0x02390000, 0x02390000, 0x02390000, 0x02280000, 0x02420000, 0x02420000, 0x02420000, 0x02420000, 0x02520000, "???? (MAG)"], + // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME [0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, 0x03000000, "Monomate"], [0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, 0x03000100, "Dimate"], [0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, 0x03000200, "Trimate"], @@ -1027,7 +1028,7 @@ [0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x03100200, 0x03100200, 0x03100200, 0x03100200, 0x03100200, "Photon Crystal"], [0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x83100000, 0x83100000, 0x83100000, 0x83100000, 0x03100300, "Secret Ticket"], [0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x83100000, 0x83100000, 0x83100000, 0x83100000, 0x03100400, "Photon Ticket"], - [0x830C0100, 0x830D0500, 0x830D0500, 0x030E0700, 0x030E0700, 0x030E0700, 0x830E0000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, "Weapons Bronze Badge"], + [0x830C0100, 0x830D0500, 0x830D0500, 0x030E0700, 0x030E0700, 0x030E0700, 0x03120000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, 0x03120000, "Weapons Bronze Badge"], [0x830C0100, 0x830D0500, 0x830D0500, 0x030E0800, 0x030E0800, 0x030E0800, 0x830E0000, 0x03120100, 0x03120100, 0x03120100, 0x03120100, 0x03120100, "Weapons Silver Badge"], [0x830C0100, 0x830D0500, 0x830D0500, 0x030E0900, 0x030E0900, 0x030E0900, 0x830E0000, 0x03120200, 0x03120200, 0x03120200, 0x03120200, 0x03120200, "Weapons Gold Badge"], [0x830C0100, 0x830D0500, 0x830D0500, 0x030E0A00, 0x030E0A00, 0x030E0A00, 0x830E0000, 0x03120300, 0x03120300, 0x03120300, 0x03120300, 0x03120300, "Weapons Crystal Badge"], @@ -1090,5 +1091,6 @@ [0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x03190100, "Team Points 1000"], [0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x03190200, "Team Points 5000"], [0x830C0100, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x830E0000, 0x830D0500, 0x830D0500, 0x830D0500, 0x830D0500, 0x03190300, "Team Points 10000"], - [0x830C0100, 0x830D0500, 0x830D0500, 0x030F0000, 0x030F0000, 0x030F0000, 0x03120000, 0x83170400, 0x83170400, 0x83170400, 0x83170400, 0x031A0000, "???? (TOOL)"], + [0x830C0100, 0x830D0500, 0x830D0500, 0x030F0000, 0x030F0000, 0x030F0000, 0x03130000, 0x03180000, 0x03180000, 0x03180000, 0x03180000, 0x031A0000, "???? (TOOL)"], + // DC_NTE-- 11/2000--- DC_V1----- DC_V2----- PC_NTE---- PC_V2----- GC_NTE---- GC_V3----- GC_EP3_NTE GC_EP3---- XB_V3----- BB_V4----- NAME ] diff --git a/tests/item-parameter-table.test.sh b/tests/item-parameter-table.test.sh new file mode 100755 index 00000000..ba111081 --- /dev/null +++ b/tests/item-parameter-table.test.sh @@ -0,0 +1,73 @@ +#!/bin/sh + +set -e + +EXECUTABLE="$1" +if [ -z "$EXECUTABLE" ]; then + EXECUTABLE="./newserv" +fi + +DIR=tests/item-parameter-tables + +echo "... DC NTE" +$EXECUTABLE decode-item-parameter-table --dc-nte $DIR/dc-nte.expected.bin --decompressed $DIR/dc-nte.json --hex +$EXECUTABLE encode-item-parameter-table --dc-nte $DIR/dc-nte.json $DIR/dc-nte.encoded.bin --decompressed +bindiff $DIR/dc-nte.expected.bin $DIR/dc-nte.encoded.bin + +echo "... DC 11/2000" +$EXECUTABLE decode-item-parameter-table --dc-11-2000 $DIR/dc-11-2000.expected.bin --decompressed $DIR/dc-11-2000.json --hex +$EXECUTABLE encode-item-parameter-table --dc-11-2000 $DIR/dc-11-2000.json $DIR/dc-11-2000.encoded.bin --decompressed +bindiff $DIR/dc-11-2000.expected.bin $DIR/dc-11-2000.encoded.bin + +echo "... DC V1" +$EXECUTABLE decode-item-parameter-table --dc-v1 $DIR/dc-v1.expected.bin --decompressed $DIR/dc-v1.json --hex +$EXECUTABLE encode-item-parameter-table --dc-v1 $DIR/dc-v1.json $DIR/dc-v1.encoded.bin --decompressed +bindiff $DIR/dc-v1.expected.bin $DIR/dc-v1.encoded.bin + +echo "... DC V2" +$EXECUTABLE decode-item-parameter-table --dc-v2 $DIR/dc-v2.expected.bin --decompressed $DIR/dc-v2.json --hex +$EXECUTABLE encode-item-parameter-table --dc-v2 $DIR/dc-v2.json $DIR/dc-v2.encoded.bin --decompressed +bindiff $DIR/dc-v2.expected.bin $DIR/dc-v2.encoded.bin + +echo "... PC NTE" +$EXECUTABLE decode-item-parameter-table --pc-nte $DIR/pc-nte.expected.bin --decompressed $DIR/pc-nte.json --hex +$EXECUTABLE encode-item-parameter-table --pc-nte $DIR/pc-nte.json $DIR/pc-nte.encoded.bin --decompressed +bindiff $DIR/pc-nte.expected.bin $DIR/pc-nte.encoded.bin + +echo "... PC V2" +$EXECUTABLE decode-item-parameter-table --pc-v2 $DIR/pc-v2.expected.bin --decompressed $DIR/pc-v2.json --hex +$EXECUTABLE encode-item-parameter-table --pc-v2 $DIR/pc-v2.json $DIR/pc-v2.encoded.bin --decompressed +bindiff $DIR/pc-v2.expected.bin $DIR/pc-v2.encoded.bin + +echo "... GC NTE" +$EXECUTABLE decode-item-parameter-table --gc-nte $DIR/gc-nte.expected.bin --decompressed $DIR/gc-nte.json --hex +$EXECUTABLE encode-item-parameter-table --gc-nte $DIR/gc-nte.json $DIR/gc-nte.encoded.bin --decompressed +bindiff $DIR/gc-nte.expected.bin $DIR/gc-nte.encoded.bin + +echo "... GC V3" +$EXECUTABLE decode-item-parameter-table --gc-v3 $DIR/gc-v3.expected.bin --decompressed $DIR/gc-v3.json --hex +$EXECUTABLE encode-item-parameter-table --gc-v3 $DIR/gc-v3.json $DIR/gc-v3.encoded.bin --decompressed +bindiff $DIR/gc-v3.expected.bin $DIR/gc-v3.encoded.bin + +echo "... GC Ep3 NTE" +$EXECUTABLE decode-item-parameter-table --gc-ep3-nte $DIR/gc-ep3-nte.expected.bin --decompressed $DIR/gc-ep3-nte.json --hex +$EXECUTABLE encode-item-parameter-table --gc-ep3-nte $DIR/gc-ep3-nte.json $DIR/gc-ep3-nte.encoded.bin --decompressed +bindiff $DIR/gc-ep3-nte.expected.bin $DIR/gc-ep3-nte.encoded.bin + +echo "... GC Ep3" +$EXECUTABLE decode-item-parameter-table --gc-ep3 $DIR/gc-ep3.expected.bin --decompressed $DIR/gc-ep3.json --hex +$EXECUTABLE encode-item-parameter-table --gc-ep3 $DIR/gc-ep3.json $DIR/gc-ep3.encoded.bin --decompressed +bindiff $DIR/gc-ep3.expected.bin $DIR/gc-ep3.encoded.bin + +echo "... XB" +$EXECUTABLE decode-item-parameter-table --xb-v3 $DIR/xb-v3.expected.bin --decompressed $DIR/xb-v3.json --hex +$EXECUTABLE encode-item-parameter-table --xb-v3 $DIR/xb-v3.json $DIR/xb-v3.encoded.bin --decompressed +bindiff $DIR/xb-v3.expected.bin $DIR/xb-v3.encoded.bin + +echo "... BB" +$EXECUTABLE decode-item-parameter-table --bb-v4 $DIR/bb-v4.expected.bin --decompressed $DIR/bb-v4.json --hex +$EXECUTABLE encode-item-parameter-table --bb-v4 $DIR/bb-v4.json $DIR/bb-v4.encoded.bin --decompressed +bindiff $DIR/bb-v4.expected.bin $DIR/bb-v4.encoded.bin + +echo "... clean up" +rm -f tests/item-parameter-tables/*.encoded.bin tests/item-parameter-tables/*.json diff --git a/tests/item-parameter-tables/bb-v4.expected.bin b/tests/item-parameter-tables/bb-v4.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..69805772a2a5a938458f3078f23b7638c3b812fd GIT binary patch literal 86880 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 PJOI_x*3gBKy88bBjh>VW literal 0 HcmV?d00001 diff --git a/tests/item-parameter-tables/dc-11-2000.expected.bin b/tests/item-parameter-tables/dc-11-2000.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..5086a40477d7a0c4b327107c6d20ec35d1de0f63 GIT binary patch literal 12608 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 EznIi34gdfE literal 0 HcmV?d00001 diff --git a/tests/item-parameter-tables/dc-nte.expected.bin b/tests/item-parameter-tables/dc-nte.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..90445709e0445c18562f5b896ed2a2dcb76f993f GIT binary patch literal 12480 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 Hjn}^eRibIm literal 0 HcmV?d00001 diff --git a/tests/item-parameter-tables/dc-v2.expected.bin b/tests/item-parameter-tables/dc-v2.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..5da466656878d450e27bcf24bcde533a6044b371 GIT binary patch literal 24928 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 literal 0 HcmV?d00001 diff --git a/tests/item-parameter-tables/gc-ep3-nte.expected.bin b/tests/item-parameter-tables/gc-ep3-nte.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..e86ff836618288f65beb7a26016ccd915c2eef80 GIT binary patch literal 63680 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�)px-L< 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 eO#yrix89Gv_S&B3c|@deQBM!OaYAc$PrM9Vkf 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�)px-L< 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 E10~0~LI3~& literal 0 HcmV?d00001 diff --git a/tests/item-parameter-tables/gc-v3.expected.bin b/tests/item-parameter-tables/gc-v3.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..e86ff836618288f65beb7a26016ccd915c2eef80 GIT binary patch literal 63680 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�)px-L< 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 literal 0 HcmV?d00001 diff --git a/tests/item-parameter-tables/pc-v2.expected.bin b/tests/item-parameter-tables/pc-v2.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..5da466656878d450e27bcf24bcde533a6044b371 GIT binary patch literal 24928 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 literal 0 HcmV?d00001 diff --git a/tests/item-parameter-tables/xb-v3.expected.bin b/tests/item-parameter-tables/xb-v3.expected.bin new file mode 100644 index 0000000000000000000000000000000000000000..10e04962a6765fa3c0bf45858546cebc601343ed GIT binary patch literal 63680 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