fix unit table in v2/v3 ItemCreator
This commit is contained in:
+37
-13
@@ -16,6 +16,7 @@ ItemCreator::ItemCreator(
|
||||
shared_ptr<const WeaponRandomSet> weapon_random_set,
|
||||
shared_ptr<const TekkerAdjustmentSet> tekker_adjustment_set,
|
||||
shared_ptr<const ItemParameterTable> item_parameter_table,
|
||||
GameVersion version,
|
||||
Episode episode,
|
||||
GameMode mode,
|
||||
uint8_t difficulty,
|
||||
@@ -23,6 +24,7 @@ ItemCreator::ItemCreator(
|
||||
uint32_t random_seed,
|
||||
shared_ptr<const BattleRules> restrictions)
|
||||
: log("[ItemCreator] "),
|
||||
version(version),
|
||||
episode(episode),
|
||||
mode(mode),
|
||||
difficulty(difficulty),
|
||||
@@ -35,7 +37,9 @@ ItemCreator::ItemCreator(
|
||||
item_parameter_table(item_parameter_table),
|
||||
pt(common_item_set->get_table(this->episode, this->mode, this->difficulty, this->section_id)),
|
||||
restrictions(restrictions),
|
||||
random_crypt(random_seed) {}
|
||||
random_crypt(random_seed) {
|
||||
this->generate_unit_weights_tables();
|
||||
}
|
||||
|
||||
bool ItemCreator::are_rare_drops_allowed() const {
|
||||
// Note: The client has an additional check here, which appears to be a subtle
|
||||
@@ -420,7 +424,7 @@ void ItemCreator::set_tool_item_amount_to_1(ItemData& item) const {
|
||||
}
|
||||
|
||||
void ItemCreator::clear_tool_item_if_invalid(ItemData& item) {
|
||||
if ((item.data1[1] == 2) &&
|
||||
if ((item.data1[1] == 0x02) &&
|
||||
((item.data1[2] > 0x1D) || (item.data1[4] > 0x12))) {
|
||||
item.clear();
|
||||
}
|
||||
@@ -591,7 +595,7 @@ void ItemCreator::generate_common_tool_variances(uint32_t area_norm, ItemData& i
|
||||
item.clear();
|
||||
|
||||
uint8_t tool_class = this->get_rand_from_weighted_tables_2d_vertical(this->pt->tool_class_prob_table(), area_norm);
|
||||
if (tool_class == 0x1A) {
|
||||
if (this->is_v3() && (tool_class == 0x1A)) {
|
||||
tool_class = 0x73;
|
||||
}
|
||||
|
||||
@@ -699,7 +703,7 @@ uint8_t ItemCreator::choose_weapon_special(uint8_t det) {
|
||||
static const uint8_t maxes[4] = {8, 10, 11, 11};
|
||||
uint8_t det2 = this->rand_int(maxes[det]);
|
||||
size_t index = 0;
|
||||
for (size_t z = 1; z < 0x29; z++) {
|
||||
for (size_t z = 1; z < this->item_parameter_table->num_specials; z++) {
|
||||
if (det + 1 == this->item_parameter_table->get_special_stars(z)) {
|
||||
if (index == det2) {
|
||||
return z;
|
||||
@@ -716,18 +720,38 @@ void ItemCreator::generate_unit_weights_tables() {
|
||||
// Note: This part of the function was originally in a different function,
|
||||
// since it had another callsite. Unlike the original code, we generate these
|
||||
// tables only once at construction time, so we've inlined the function here.
|
||||
|
||||
size_t star_base_index;
|
||||
switch (this->version) {
|
||||
case GameVersion::DC:
|
||||
case GameVersion::PC:
|
||||
star_base_index = 0x1D1;
|
||||
this->unit_weights_table1.resize(0x84);
|
||||
break;
|
||||
case GameVersion::GC:
|
||||
case GameVersion::XB:
|
||||
star_base_index = 0x2AF;
|
||||
this->unit_weights_table1.resize(0x88);
|
||||
break;
|
||||
case GameVersion::BB:
|
||||
star_base_index = 0x37D;
|
||||
this->unit_weights_table1.resize(0x88);
|
||||
break;
|
||||
default:
|
||||
throw logic_error("invalid game version");
|
||||
}
|
||||
|
||||
size_t z;
|
||||
for (z = 0; z < 0x10; z++) {
|
||||
uint8_t v = this->item_parameter_table->get_item_stars(z + 0x37D);
|
||||
this->unit_weights_table1[(z * 5) + 0] = v - 1;
|
||||
this->unit_weights_table1[(z * 5) + 1] = v - 1;
|
||||
this->unit_weights_table1[(z * 5) + 2] = v;
|
||||
this->unit_weights_table1[(z * 5) + 3] = v + 1;
|
||||
this->unit_weights_table1[(z * 5) + 4] = v + 1;
|
||||
uint8_t v = this->item_parameter_table->get_item_stars(z + star_base_index);
|
||||
this->unit_weights_table1.at((z * 5) + 0) = v - 1;
|
||||
this->unit_weights_table1.at((z * 5) + 1) = v - 1;
|
||||
this->unit_weights_table1.at((z * 5) + 2) = v;
|
||||
this->unit_weights_table1.at((z * 5) + 3) = v + 1;
|
||||
this->unit_weights_table1.at((z * 5) + 4) = v + 1;
|
||||
}
|
||||
for (; z < 0x48; z++) {
|
||||
this->unit_weights_table1[z + 0x50] =
|
||||
this->item_parameter_table->get_item_stars(z + 0x37D);
|
||||
for (; z < (this->unit_weights_table1.size() - 0x40); z++) {
|
||||
this->unit_weights_table1.at(z + 0x40) = this->item_parameter_table->get_item_stars(z + star_base_index);
|
||||
}
|
||||
// Note: Inlining ends here
|
||||
|
||||
|
||||
+7
-1
@@ -19,6 +19,7 @@ public:
|
||||
std::shared_ptr<const WeaponRandomSet> weapon_random_set,
|
||||
std::shared_ptr<const TekkerAdjustmentSet> tekker_adjustment_set,
|
||||
std::shared_ptr<const ItemParameterTable> item_parameter_table,
|
||||
GameVersion version,
|
||||
Episode episode,
|
||||
GameMode mode,
|
||||
uint8_t difficulty,
|
||||
@@ -45,6 +46,7 @@ public:
|
||||
|
||||
private:
|
||||
PrefixedLogger log;
|
||||
GameVersion version;
|
||||
Episode episode;
|
||||
GameMode mode;
|
||||
uint8_t difficulty;
|
||||
@@ -58,13 +60,17 @@ private:
|
||||
std::shared_ptr<const CommonItemSet::Table> pt;
|
||||
std::shared_ptr<const BattleRules> restrictions;
|
||||
|
||||
parray<uint8_t, 0x88> unit_weights_table1;
|
||||
std::vector<uint8_t> unit_weights_table1;
|
||||
parray<int8_t, 0x0D> unit_weights_table2;
|
||||
|
||||
// Note: The original implementation uses 17 different random states for some
|
||||
// reason. We forego that and use only one for simplicity.
|
||||
PSOV2Encryption random_crypt;
|
||||
|
||||
inline bool is_v3() const {
|
||||
return (this->version != GameVersion::DC) && (this->version != GameVersion::PC);
|
||||
}
|
||||
|
||||
bool are_rare_drops_allowed() const;
|
||||
uint8_t normalize_area_number(uint8_t area) const;
|
||||
|
||||
|
||||
@@ -334,6 +334,15 @@ public:
|
||||
|
||||
size_t price_for_item(const ItemData& item) const;
|
||||
|
||||
size_t num_weapon_classes;
|
||||
size_t num_tool_classes;
|
||||
size_t item_stars_first_id;
|
||||
size_t item_stars_last_id;
|
||||
size_t special_stars_begin_index;
|
||||
size_t num_specials;
|
||||
size_t first_rare_mag_index;
|
||||
size_t star_value_table_size;
|
||||
|
||||
private:
|
||||
struct TableOffsetsV2 {
|
||||
// TODO: Is weapon count 0x89 or 0x8A? It could be that the last entry in
|
||||
@@ -412,15 +421,6 @@ private:
|
||||
float get_sale_divisor_t(uint32_t weapon_table_offset, uint32_t non_weapon_table_offset, uint8_t data1_0, uint8_t data1_1) const;
|
||||
template <bool IsBigEndian>
|
||||
std::pair<const ItemParameterTable::EventItem*, size_t> get_event_items_t(uint32_t base_offset, uint8_t event_number) const;
|
||||
|
||||
size_t num_weapon_classes;
|
||||
size_t num_tool_classes;
|
||||
size_t item_stars_first_id;
|
||||
size_t item_stars_last_id;
|
||||
size_t special_stars_begin_index;
|
||||
size_t num_specials;
|
||||
size_t first_rare_mag_index;
|
||||
size_t star_value_table_size;
|
||||
};
|
||||
|
||||
class MagEvolutionTable {
|
||||
|
||||
@@ -67,6 +67,7 @@ void Lobby::create_item_creator() {
|
||||
s->weapon_random_sets.at(this->difficulty),
|
||||
s->tekker_adjustment_set,
|
||||
s->item_parameter_table_for_version(this->base_version),
|
||||
this->base_version,
|
||||
this->episode,
|
||||
(this->mode == GameMode::SOLO) ? GameMode::NORMAL : this->mode,
|
||||
this->difficulty,
|
||||
|
||||
Reference in New Issue
Block a user