load non-v4 level tables

This commit is contained in:
Martin Michelsen
2024-05-17 20:32:52 -07:00
parent f71980382a
commit d8230eb37a
11 changed files with 110 additions and 35 deletions
+3 -2
View File
@@ -1299,8 +1299,9 @@ static void server_command_edit(shared_ptr<Client> c, const std::string& args) {
p->disp.stats.experience = stoul(tokens.at(1)); p->disp.stats.experience = stoul(tokens.at(1));
} else if (tokens.at(0) == "level" && cheats_allowed) { } else if (tokens.at(0) == "level" && cheats_allowed) {
uint32_t level = stoul(tokens.at(1)) - 1; uint32_t level = stoul(tokens.at(1)) - 1;
s->level_table->reset_to_base(p->disp.stats, p->disp.visual.char_class); auto level_table = s->level_table(c->version());
s->level_table->advance_to_level(p->disp.stats, level, p->disp.visual.char_class); level_table->reset_to_base(p->disp.stats, p->disp.visual.char_class);
level_table->advance_to_level(p->disp.stats, level, p->disp.visual.char_class);
} else if (tokens.at(0) == "namecolor") { } else if (tokens.at(0) == "namecolor") {
uint32_t new_color; uint32_t new_color;
sscanf(tokens.at(1).c_str(), "%8X", &new_color); sscanf(tokens.at(1).c_str(), "%8X", &new_color);
+14 -6
View File
@@ -775,12 +775,8 @@ void Client::load_all_files() {
player_data_log.info("Loaded system data from %s", char_filename.c_str()); player_data_log.info("Loaded system data from %s", char_filename.c_str());
} }
uint8_t lang = this->language(); this->update_character_data_after_load(this->character_data);
player_data_log.info("Overriding language fields in save files with %02hhX (%c)", this->system_data->base.language = this->language();
lang, char_for_language_code(lang));
this->character_data->inventory.language = lang;
this->character_data->guild_card.language = lang;
this->system_data->base.language = lang;
} else { } else {
player_data_log.info("Character file is missing: %s", char_filename.c_str()); player_data_log.info("Character file is missing: %s", char_filename.c_str());
@@ -873,6 +869,7 @@ void Client::load_all_files() {
} else { } else {
player_data_log.info("Loaded legacy player data from %s", nsc_filename.c_str()); player_data_log.info("Loaded legacy player data from %s", nsc_filename.c_str());
} }
this->update_character_data_after_load(this->character_data);
} }
} }
@@ -892,6 +889,15 @@ void Client::load_all_files() {
} }
} }
void Client::update_character_data_after_load(shared_ptr<PSOBBCharacterFile> charfile) {
charfile->import_tethealla_material_usage(this->require_server_state()->level_table(this->version()));
uint8_t lang = this->language();
player_data_log.info("Overriding language fields in save files with %02hhX (%c)", lang, char_for_language_code(lang));
charfile->inventory.language = lang;
charfile->guild_card.language = lang;
}
void Client::save_all() { void Client::save_all() {
if (this->system_data) { if (this->system_data) {
this->save_system_file(); this->save_system_file();
@@ -991,6 +997,7 @@ void Client::load_backup_character(uint32_t account_id, size_t index) {
throw runtime_error("incorrect flag in character file header"); throw runtime_error("incorrect flag in character file header");
} }
this->character_data = make_shared<PSOBBCharacterFile>(freadx<PSOBBCharacterFile>(f.get())); this->character_data = make_shared<PSOBBCharacterFile>(freadx<PSOBBCharacterFile>(f.get()));
this->update_character_data_after_load(this->character_data);
this->v1_v2_last_reported_disp.reset(); this->v1_v2_last_reported_disp.reset();
} }
@@ -1075,6 +1082,7 @@ void Client::use_character_bank(int8_t index) {
throw runtime_error("incorrect flag in character file header"); throw runtime_error("incorrect flag in character file header");
} }
this->external_bank_character = make_shared<PSOBBCharacterFile>(freadx<PSOBBCharacterFile>(f.get())); this->external_bank_character = make_shared<PSOBBCharacterFile>(freadx<PSOBBCharacterFile>(f.get()));
this->update_character_data_after_load(this->external_bank_character);
this->external_bank_character_index = index; this->external_bank_character_index = index;
files_manager->set_character(filename, this->external_bank_character); files_manager->set_character(filename, this->external_bank_character);
player_data_log.info("Loaded character data from %s for external bank", filename.c_str()); player_data_log.info("Loaded character data from %s for external bank", filename.c_str());
+1
View File
@@ -406,4 +406,5 @@ private:
void save_and_clear_external_bank(); void save_and_clear_external_bank();
void load_all_files(); void load_all_files();
void update_character_data_after_load(std::shared_ptr<PSOBBCharacterFile> character_data);
}; };
+2 -4
View File
@@ -1567,10 +1567,8 @@ void ItemCreator::generate_weapon_shop_item_grind(ItemData& item, size_t player_
? this->weapon_random_set->get_favored_grind_range(table_index) ? this->weapon_random_set->get_favored_grind_range(table_index)
: this->weapon_random_set->get_standard_grind_range(table_index); : this->weapon_random_set->get_standard_grind_range(table_index);
const auto& weapon_def = this->item_parameter_table->get_weapon( const auto& weapon_def = this->item_parameter_table->get_weapon(item.data1[1], item.data1[2]);
item.data1[1], item.data1[2]); item.data1[3] = clamp<uint8_t>(this->rand_int(range->max + 1), range->min, weapon_def.max_grind);
item.data1[3] = clamp<uint8_t>(
this->rand_int(range->max + 1), range->min, weapon_def.max_grind);
} }
void ItemCreator::generate_weapon_shop_item_special(ItemData& item, size_t player_level) { void ItemCreator::generate_weapon_shop_item_special(ItemData& item, size_t player_level) {
+8 -6
View File
@@ -1989,11 +1989,11 @@ static void on_quest_loaded(shared_ptr<Lobby> l) {
lc->delete_overlay(); lc->delete_overlay();
if (l->quest->battle_rules) { if (l->quest->battle_rules) {
lc->use_default_bank(); lc->use_default_bank();
lc->create_battle_overlay(l->quest->battle_rules, s->level_table); lc->create_battle_overlay(l->quest->battle_rules, s->level_table(lc->version()));
lc->log.info("Created battle overlay"); lc->log.info("Created battle overlay");
} else if (l->quest->challenge_template_index >= 0) { } else if (l->quest->challenge_template_index >= 0) {
lc->use_default_bank(); lc->use_default_bank();
lc->create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table); lc->create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table(lc->version()));
lc->log.info("Created challenge overlay"); lc->log.info("Created challenge overlay");
l->assign_inventory_and_bank_item_ids(lc, true); l->assign_inventory_and_bank_item_ids(lc, true);
} }
@@ -3216,17 +3216,19 @@ static void on_61_98(shared_ptr<Client> c, uint16_t command, uint32_t flag, stri
c->language(), c->language(),
player->disp.visual, player->disp.visual,
player->disp.name.decode(c->language()), player->disp.name.decode(c->language()),
s->level_table); s->level_table(c->version()));
bb_player->disp.visual.version = 4; bb_player->disp.visual.version = 4;
bb_player->disp.visual.name_color_checksum = 0x00000000; bb_player->disp.visual.name_color_checksum = 0x00000000;
bb_player->inventory = player->inventory; bb_player->inventory = player->inventory;
// Before V3, player stats can't be correctly computed from other fields // Before V3, player stats can't be correctly computed from other fields
// because material usage isn't stored anywhere. For these versions, we // because material usage isn't stored anywhere. For these versions, we
// have to trust the stats field from the player's data. // have to trust the stats field from the player's data.
auto level_table = s->level_table(c->version());
if (is_v1_or_v2(c->version())) { if (is_v1_or_v2(c->version())) {
bb_player->disp.stats = player->disp.stats; bb_player->disp.stats = player->disp.stats;
bb_player->import_tethealla_material_usage(level_table);
} else { } else {
s->level_table->advance_to_level(bb_player->disp.stats, player->disp.stats.level, bb_player->disp.visual.char_class); level_table->advance_to_level(bb_player->disp.stats, player->disp.stats.level, bb_player->disp.visual.char_class);
bb_player->disp.stats.char_stats.atp += bb_player->get_material_usage(PSOBBCharacterFile::MaterialType::POWER) * 2; bb_player->disp.stats.char_stats.atp += bb_player->get_material_usage(PSOBBCharacterFile::MaterialType::POWER) * 2;
bb_player->disp.stats.char_stats.mst += bb_player->get_material_usage(PSOBBCharacterFile::MaterialType::MIND) * 2; bb_player->disp.stats.char_stats.mst += bb_player->get_material_usage(PSOBBCharacterFile::MaterialType::MIND) * 2;
bb_player->disp.stats.char_stats.evp += bb_player->get_material_usage(PSOBBCharacterFile::MaterialType::EVADE) * 2; bb_player->disp.stats.char_stats.evp += bb_player->get_material_usage(PSOBBCharacterFile::MaterialType::EVADE) * 2;
@@ -3641,7 +3643,7 @@ static void on_E5_BB(shared_ptr<Client> c, uint16_t, uint32_t, string& data) {
} else { } else {
try { try {
auto s = c->require_server_state(); auto s = c->require_server_state();
c->create_character_file(c->login->account->account_id, c->language(), cmd.preview, s->level_table); c->create_character_file(c->login->account->account_id, c->language(), cmd.preview, s->level_table(c->version()));
} catch (const exception& e) { } catch (const exception& e) {
send_message_box(c, string_printf("$C6New character could not be created:\n%s", e.what())); send_message_box(c, string_printf("$C6New character could not be created:\n%s", e.what()));
return; return;
@@ -3761,7 +3763,7 @@ static void on_DF_BB(shared_ptr<Client> c, uint16_t command, uint32_t, string& d
for (auto lc : l->clients) { for (auto lc : l->clients) {
if (lc) { if (lc) {
lc->use_default_bank(); lc->use_default_bank();
lc->create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table); lc->create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table(lc->version()));
lc->log.info("Created challenge overlay"); lc->log.info("Created challenge overlay");
l->assign_inventory_and_bank_item_ids(lc, true); l->assign_inventory_and_bank_item_ids(lc, true);
} }
+6 -6
View File
@@ -3232,7 +3232,8 @@ static void on_level_up(shared_ptr<Client> c, uint8_t command, uint8_t flag, voi
if (is_pre_v1(c->version())) { if (is_pre_v1(c->version())) {
check_size_t<G_LevelUp_DCNTE_6x30>(data, size); check_size_t<G_LevelUp_DCNTE_6x30>(data, size);
auto s = c->require_server_state(); auto s = c->require_server_state();
const auto& level_incrs = s->level_table->stats_delta_for_level(p->disp.visual.char_class, p->disp.stats.level + 1); auto level_table = s->level_table(c->version());
const auto& level_incrs = level_table->stats_delta_for_level(p->disp.visual.char_class, p->disp.stats.level + 1);
p->disp.stats.char_stats.atp += level_incrs.atp; p->disp.stats.char_stats.atp += level_incrs.atp;
p->disp.stats.char_stats.mst += level_incrs.mst; p->disp.stats.char_stats.mst += level_incrs.mst;
p->disp.stats.char_stats.evp += level_incrs.evp; p->disp.stats.char_stats.evp += level_incrs.evp;
@@ -3265,8 +3266,7 @@ static void add_player_exp(shared_ptr<Client> c, uint32_t exp) {
bool leveled_up = false; bool leveled_up = false;
do { do {
const auto& level = s->level_table->stats_delta_for_level( const auto& level = s->level_table(c->version())->stats_delta_for_level(p->disp.visual.char_class, p->disp.stats.level + 1);
p->disp.visual.char_class, p->disp.stats.level + 1);
if (p->disp.stats.experience >= level.experience) { if (p->disp.stats.experience >= level.experience) {
leveled_up = true; leveled_up = true;
level.apply(p->disp.stats.char_stats); level.apply(p->disp.stats.char_stats);
@@ -3775,7 +3775,7 @@ static void on_battle_restart_bb(shared_ptr<Client> c, uint8_t, uint8_t, void* d
if (lc) { if (lc) {
lc->delete_overlay(); lc->delete_overlay();
lc->use_default_bank(); lc->use_default_bank();
lc->create_battle_overlay(new_rules, s->level_table); lc->create_battle_overlay(new_rules, s->level_table(c->version()));
} }
} }
l->load_maps(); l->load_maps();
@@ -3795,7 +3795,7 @@ static void on_battle_level_up_bb(shared_ptr<Client> c, uint8_t, uint8_t, void*
auto lp = lc->character(); auto lp = lc->character();
uint32_t target_level = lp->disp.stats.level + cmd.num_levels; uint32_t target_level = lp->disp.stats.level + cmd.num_levels;
uint32_t before_exp = lp->disp.stats.experience; uint32_t before_exp = lp->disp.stats.experience;
s->level_table->advance_to_level(lp->disp.stats, target_level, lp->disp.visual.char_class); s->level_table(lc->version())->advance_to_level(lp->disp.stats, target_level, lp->disp.visual.char_class);
send_give_experience(lc, lp->disp.stats.experience - before_exp); send_give_experience(lc, lp->disp.stats.experience - before_exp);
send_level_up(lc); send_level_up(lc);
} }
@@ -3839,7 +3839,7 @@ static void on_challenge_mode_retry_or_quit(shared_ptr<Client> c, uint8_t comman
for (auto lc : l->clients) { for (auto lc : l->clients) {
if (lc) { if (lc) {
lc->use_default_bank(); lc->use_default_bank();
lc->create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table); lc->create_challenge_overlay(lc->version(), l->quest->challenge_template_index, s->level_table(c->version()));
lc->log.info("Created challenge overlay"); lc->log.info("Created challenge overlay");
l->assign_inventory_and_bank_item_ids(lc, true); l->assign_inventory_and_bank_item_ids(lc, true);
} }
+35
View File
@@ -4,6 +4,7 @@
#include <stdexcept> #include <stdexcept>
#include <string> #include <string>
#include "LevelTable.hh"
#include "PSOProtocol.hh" #include "PSOProtocol.hh"
using namespace std; using namespace std;
@@ -919,6 +920,40 @@ void PSOBBCharacterFile::clear_all_material_usage() {
} }
} }
void PSOBBCharacterFile::import_tethealla_material_usage(std::shared_ptr<const LevelTable> level_table) {
// Tethealla (Ephinea) doesn't store material counts anywhere in the file,
// so if the material counts in the inventory extension data are all zero,
// check the current stats against the expected stats for the character's
// current level and set the material counts if they make sense.
if (this->get_material_usage(PSOBBCharacterFile::MaterialType::POWER) |
this->get_material_usage(PSOBBCharacterFile::MaterialType::MIND) |
this->get_material_usage(PSOBBCharacterFile::MaterialType::EVADE) |
this->get_material_usage(PSOBBCharacterFile::MaterialType::DEF) |
this->get_material_usage(PSOBBCharacterFile::MaterialType::LUCK)) {
return;
}
PlayerStats level_base_stats = this->disp.stats;
level_table->reset_to_base(level_base_stats, this->disp.visual.char_class);
level_table->advance_to_level(level_base_stats, this->disp.stats.level, this->disp.visual.char_class);
uint64_t pow = (this->disp.stats.char_stats.atp - level_base_stats.char_stats.atp) / 2;
uint64_t mind = (this->disp.stats.char_stats.mst - level_base_stats.char_stats.mst) / 2;
uint64_t evade = (this->disp.stats.char_stats.evp - level_base_stats.char_stats.evp) / 2;
uint64_t def = (this->disp.stats.char_stats.dfp - level_base_stats.char_stats.dfp) / 2;
uint64_t luck = (this->disp.stats.char_stats.lck - level_base_stats.char_stats.lck) / 2;
// We intentionally do not check any limits here. This is because on pre-v3,
// there are no limits, and we don't want to reject legitimate characters
// that have used more than 250 materials.
this->set_material_usage(PSOBBCharacterFile::MaterialType::POWER, pow);
this->set_material_usage(PSOBBCharacterFile::MaterialType::MIND, mind);
this->set_material_usage(PSOBBCharacterFile::MaterialType::EVADE, evade);
this->set_material_usage(PSOBBCharacterFile::MaterialType::DEF, def);
this->set_material_usage(PSOBBCharacterFile::MaterialType::LUCK, luck);
}
static uint16_t crc16(const void* data, size_t size) { static uint16_t crc16(const void* data, size_t size) {
static const uint16_t table[0x100] = { static const uint16_t table[0x100] = {
// clang-format off // clang-format off
+1
View File
@@ -674,6 +674,7 @@ struct PSOBBCharacterFile {
uint8_t get_material_usage(MaterialType which) const; uint8_t get_material_usage(MaterialType which) const;
void set_material_usage(MaterialType which, uint8_t usage); void set_material_usage(MaterialType which, uint8_t usage);
void clear_all_material_usage(); void clear_all_material_usage();
void import_tethealla_material_usage(std::shared_ptr<const LevelTable> level_table);
} __packed_ws__(PSOBBCharacterFile, 0x2EA4); } __packed_ws__(PSOBBCharacterFile, 0x2EA4);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
+3 -3
View File
@@ -209,7 +209,7 @@ CommandDefinition c_reload(
functions - recompile all client-side patches and functions\n\ functions - recompile all client-side patches and functions\n\
item-definitions - reload item definitions files\n\ item-definitions - reload item definitions files\n\
item-name-index - regenerate item name list\n\ item-name-index - regenerate item name list\n\
level-table - reload the level-up tables\n\ level-tables - reload the player stats tables\n\
patch-files - reindex the PC and BB patch directories\n\ patch-files - reindex the PC and BB patch directories\n\
quests - reindex all quests (including Episode3 download quests)\n\ quests - reindex all quests (including Episode3 download quests)\n\
set-tables - reload set data tables\n\ set-tables - reload set data tables\n\
@@ -246,8 +246,8 @@ CommandDefinition c_reload(
args.s->load_set_data_tables(true); args.s->load_set_data_tables(true);
} else if (type == "battle-params") { } else if (type == "battle-params") {
args.s->load_battle_params(true); args.s->load_battle_params(true);
} else if (type == "level-table") { } else if (type == "level-tables") {
args.s->load_level_table(true); args.s->load_level_tables(true);
} else if (type == "text-index") { } else if (type == "text-index") {
args.s->load_text_index(true); args.s->load_text_index(true);
} else if (type == "word-select") { } else if (type == "word-select") {
+32 -6
View File
@@ -372,6 +372,28 @@ shared_ptr<const SetDataTableBase> ServerState::set_data_table(
return ret; return ret;
} }
shared_ptr<const LevelTable> ServerState::level_table(Version version) const {
switch (version) {
case Version::DC_NTE:
case Version::DC_V1_11_2000_PROTOTYPE:
case Version::DC_V1:
case Version::DC_V2:
case Version::PC_NTE:
case Version::PC_V2:
case Version::GC_NTE: // TODO: Does NTE use the v2 table, the v3 table, or neither?
return this->level_table_v1_v2;
case Version::GC_V3:
case Version::GC_EP3_NTE:
case Version::GC_EP3:
case Version::XB_V3:
return this->level_table_v3;
case Version::BB_V4:
return this->level_table_v4;
default:
throw logic_error("level table not available for version");
}
}
shared_ptr<const ItemParameterTable> ServerState::item_parameter_table(Version version) const { shared_ptr<const ItemParameterTable> ServerState::item_parameter_table(Version version) const {
auto ret = this->item_parameter_tables.at(static_cast<size_t>(version)); auto ret = this->item_parameter_tables.at(static_cast<size_t>(version));
if (ret == nullptr) { if (ret == nullptr) {
@@ -1407,12 +1429,16 @@ void ServerState::load_battle_params(bool from_non_event_thread) {
this->forward_or_call(from_non_event_thread, std::move(set)); this->forward_or_call(from_non_event_thread, std::move(set));
} }
void ServerState::load_level_table(bool from_non_event_thread) { void ServerState::load_level_tables(bool from_non_event_thread) {
config_log.info("Loading level table"); config_log.info("Loading level tables");
auto new_table = make_shared<LevelTableV4>(*this->load_bb_file("PlyLevelTbl.prs"), true); auto new_table_v1_v2 = make_shared<LevelTableV2>(load_file("system/level-tables/PlayerTable-pc-v2.prs"), true);
auto new_table_v3 = make_shared<LevelTableV3BE>(load_file("system/level-tables/PlyLevelTbl-gc-v3.cpt"), true);
auto new_table_v4 = make_shared<LevelTableV4>(*this->load_bb_file("PlyLevelTbl.prs"), true);
auto set = [s = this->shared_from_this(), new_table = std::move(new_table)]() { auto set = [s = this->shared_from_this(), new_table_v1_v2 = std::move(new_table_v1_v2), new_table_v3 = std::move(new_table_v3), new_table_v4 = std::move(new_table_v4)]() {
s->level_table = std::move(new_table); s->level_table_v1_v2 = std::move(new_table_v1_v2);
s->level_table_v3 = std::move(new_table_v3);
s->level_table_v4 = std::move(new_table_v4);
}; };
this->forward_or_call(from_non_event_thread, std::move(set)); this->forward_or_call(from_non_event_thread, std::move(set));
} }
@@ -1834,7 +1860,7 @@ void ServerState::load_all() {
this->create_default_lobbies(); this->create_default_lobbies();
this->load_set_data_tables(false); this->load_set_data_tables(false);
this->load_battle_params(false); this->load_battle_params(false);
this->load_level_table(false); this->load_level_tables(false);
this->load_text_index(false); this->load_text_index(false);
this->load_word_select_table(false); this->load_word_select_table(false);
this->load_item_definitions(false); this->load_item_definitions(false);
+5 -2
View File
@@ -155,7 +155,9 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
std::shared_ptr<const QuestCategoryIndex> quest_category_index; std::shared_ptr<const QuestCategoryIndex> quest_category_index;
std::shared_ptr<const QuestIndex> default_quest_index; std::shared_ptr<const QuestIndex> default_quest_index;
std::shared_ptr<const QuestIndex> ep3_download_quest_index; std::shared_ptr<const QuestIndex> ep3_download_quest_index;
std::shared_ptr<const LevelTable> level_table; std::shared_ptr<const LevelTable> level_table_v1_v2;
std::shared_ptr<const LevelTable> level_table_v3;
std::shared_ptr<const LevelTable> level_table_v4;
std::shared_ptr<const BattleParamsIndex> battle_params; std::shared_ptr<const BattleParamsIndex> battle_params;
std::shared_ptr<const GSLArchive> bb_data_gsl; std::shared_ptr<const GSLArchive> bb_data_gsl;
std::unordered_map<std::string, std::shared_ptr<const RareItemSet>> rare_item_sets; std::unordered_map<std::string, std::shared_ptr<const RareItemSet>> rare_item_sets;
@@ -302,6 +304,7 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
std::shared_ptr<const SetDataTableBase> set_data_table(Version version, Episode episode, GameMode mode, uint8_t difficulty) const; std::shared_ptr<const SetDataTableBase> set_data_table(Version version, Episode episode, GameMode mode, uint8_t difficulty) const;
std::shared_ptr<const LevelTable> level_table(Version version) const;
std::shared_ptr<const ItemParameterTable> item_parameter_table(Version version) const; std::shared_ptr<const ItemParameterTable> item_parameter_table(Version version) const;
std::shared_ptr<const ItemParameterTable> item_parameter_table_for_encode(Version version) const; std::shared_ptr<const ItemParameterTable> item_parameter_table_for_encode(Version version) const;
std::shared_ptr<const ItemData::StackLimits> item_stack_limits(Version version) const; std::shared_ptr<const ItemData::StackLimits> item_stack_limits(Version version) const;
@@ -364,7 +367,7 @@ struct ServerState : public std::enable_shared_from_this<ServerState> {
void load_patch_indexes(bool from_non_event_thread); void load_patch_indexes(bool from_non_event_thread);
void clear_map_file_caches(); void clear_map_file_caches();
void load_battle_params(bool from_non_event_thread); void load_battle_params(bool from_non_event_thread);
void load_level_table(bool from_non_event_thread); void load_level_tables(bool from_non_event_thread);
void load_text_index(bool from_non_event_thread); void load_text_index(bool from_non_event_thread);
std::shared_ptr<ItemNameIndex> create_item_name_index_for_version( std::shared_ptr<ItemNameIndex> create_item_name_index_for_version(
std::shared_ptr<const ItemParameterTable> pmt, std::shared_ptr<const ItemParameterTable> pmt,