diff --git a/src/CommonItemSet.cc b/src/CommonItemSet.cc index 90fe8a29..ccdfff53 100644 --- a/src/CommonItemSet.cc +++ b/src/CommonItemSet.cc @@ -30,9 +30,9 @@ RELFileSet::RELFileSet(std::shared_ptr data) ArmorRandomSet::ArmorRandomSet(std::shared_ptr data) : RELFileSet(data) { // For some reason the footer tables are doubly indirect in this file - uint32_t specs_offset_offset = r.pget_u32b(data->size() - 0x10); - uint32_t specs_offset = r.pget_u32b(specs_offset_offset); - this->tables = &r.pget>(specs_offset); + uint32_t specs_offset_offset = this->r.pget_u32b(data->size() - 0x10); + uint32_t specs_offset = this->r.pget_u32b(specs_offset_offset); + this->tables = &this->r.pget>(specs_offset); } std::pair diff --git a/src/CommonItemSet.hh b/src/CommonItemSet.hh index dcb92bc2..3d95aeaa 100644 --- a/src/CommonItemSet.hh +++ b/src/CommonItemSet.hh @@ -3,9 +3,53 @@ #include #include "GSLArchive.hh" +#include "PSOEncryption.hh" #include "StaticGameData.hh" #include "Text.hh" +// Note: There are clearly better ways of doing this, but this implementation +// closely follows what the original code in the client does. +template +struct ProbabilityTable { + ItemT items[MaxCount]; + size_t count; + + ProbabilityTable() : count(0) {} + + void push(ItemT item) { + if (this->count == MaxCount) { + throw runtime_error("push to full probability table"); + } + this->items[this->count++] = item; + } + + ItemT pop() { + if (this->count == 0) { + throw runtime_error("pop from empty probability table"); + } + return this->items[--this->count]; + } + + void shuffle(PSOLFGEncryption& random_crypt) { + for (size_t z = 1; z < this->count; z++) { + size_t other_z = random_crypt.next() % (z + 1); + ItemT t = this->items[z]; + this->items[z] = this->items[other_z]; + this->items[other_z] = t; + } + } + + ItemT sample(PSOLFGEncryption& random_crypt) const { + if (this->count == 0) { + throw runtime_error("pop from empty probability table"); + } else if (this->count == 1) { + return this->items[0]; + } else { + return this->items[random_crypt.next() % this->count]; + } + } +}; + class CommonItemSet { public: template diff --git a/src/ItemCreator.cc b/src/ItemCreator.cc index 783d6535..c9e10f66 100644 --- a/src/ItemCreator.cc +++ b/src/ItemCreator.cc @@ -32,9 +32,7 @@ ItemCreator::ItemCreator( pt(&this->common_item_set->get_table( this->episode, this->mode, this->difficulty, this->section_id)), restrictions(restrictions), - random_crypt(random_seed) { - print_data(stderr, this->pt, sizeof(*this->pt)); -} + random_crypt(random_seed) {} bool ItemCreator::are_rare_drops_allowed() const { // Note: The client has an additional check here, which appears to be a subtle @@ -852,39 +850,6 @@ IntT ItemCreator::get_rand_from_weighted_tables_2d_vertical( offset, Y, X); } -// Note: There are clearly better ways of doing this, but this implementation -// closely follows what the original code in the client does. -template -struct ProbabilityTable { - ItemT items[MaxCount]; - size_t count; - - ProbabilityTable() : count(0) {} - - void push(ItemT item) { - if (this->count == MaxCount) { - throw runtime_error("push to full probability table"); - } - this->items[this->count++] = item; - } - - ItemT pop() { - if (this->count == 0) { - throw runtime_error("pop from empty probability table"); - } - return this->items[--this->count]; - } - - void shuffle(PSOLFGEncryption& random_crypt) { - for (size_t z = 1; z < this->count; z++) { - size_t other_z = random_crypt.next() % (z + 1); - ItemT t = this->items[z]; - this->items[z] = this->items[other_z]; - this->items[other_z] = t; - } - } -}; - vector ItemCreator::generate_armor_shop_contents(size_t player_level) { vector shop; this->generate_armor_shop_armors(shop, player_level); diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index a7bdafc1..9f5f2fc0 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -1646,7 +1646,7 @@ static void on_identify_item_bb(shared_ptr, size_t x = c->game_data.player()->inventory.find_item(cmd.item_id); if (c->game_data.player()->inventory.items[x].data.data1[0] != 0) { - return; // only weapons can be identified + return; // Only weapons can be identified } c->game_data.player()->disp.stats.meseta -= 100; diff --git a/src/ServerState.cc b/src/ServerState.cc index 70902ea5..0ed8ecbc 100644 --- a/src/ServerState.cc +++ b/src/ServerState.cc @@ -844,19 +844,22 @@ void ServerState::load_item_tables() { // Note: These files don't exist in BB, so we use the GC versions of them // instead. This doesn't include Episode 4 of course, so we use Episode 1 // parameters for Episode 4 implicitly. - config_log.info("Loading common item tables"); + config_log.info("Loading common item table"); shared_ptr pt_data(new string(load_file( "system/blueburst/ItemPT_GC.gsl"))); this->common_item_set.reset(new CommonItemSet(pt_data)); + config_log.info("Loading armor table"); shared_ptr armor_data(new string(load_file( "system/blueburst/ArmorRandom_GC.rel"))); this->armor_random_set.reset(new ArmorRandomSet(armor_data)); + config_log.info("Loading tool table"); shared_ptr tool_data(new string(load_file( "system/blueburst/ToolRandom_GC.rel"))); this->tool_random_set.reset(new ToolRandomSet(tool_data)); + config_log.info("Loading weapon tables"); const char* filenames[4] = { "system/blueburst/WeaponRandomNormal_GC.rel", "system/blueburst/WeaponRandomHard_GC.rel",