diff --git a/src/Episode3.cc b/src/Episode3.cc index fee6e9e4..4dc25db4 100644 --- a/src/Episode3.cc +++ b/src/Episode3.cc @@ -429,7 +429,7 @@ string Ep3CardDefinition::Effect::str_for_arg(const std::string& arg) { } string Ep3CardDefinition::Effect::str() const { - string cmd_str = string_printf("%02hhX", this->command); + string cmd_str = string_printf("(%hhu) %02hhX", this->effect_num, this->command); try { const char* name = name_for_effect_command.at(this->command).name; if (name) { @@ -630,8 +630,8 @@ string Ep3CardDefinition::str() const { return string_printf( "[Card: %04" PRIX32 " name=%s type=%s-%02hhX rare=%s cost=%hhX+%hhX " "target=%s range=%s assist_turns=%s cannot_move=%s cannot_attack=%s " - "hidden=%s hp=%s ap=%s tp=%s mv=%s left=%s right=%s top=%s a2=%08" PRIX32 " " - "assist_effect=[%hu, %hu] a3=[%hu, %hu] has_effects=%s effects=[%s]]", + "hidden=%s hp=%s ap=%s tp=%s mv=%s left=%s right=%s top=%s a2=%04hX " + "a3=%04hX assist_effect=[%hu, %hu] drop_rates=[%hu, %hu] effects=[%s]]", this->card_id.load(), this->name.data(), type_str.c_str(), @@ -653,11 +653,11 @@ string Ep3CardDefinition::str() const { right_str.c_str(), top_str.c_str(), this->unknown_a2.load(), + this->unknown_a3.load(), this->assist_effect[0].load(), this->assist_effect[1].load(), - this->unknown_a3[0].load(), - this->unknown_a3[1].load(), - this->has_effects ? "true" : "false", + this->drop_rates[0].load(), + this->drop_rates[1].load(), effects_str.c_str()); } diff --git a/src/Episode3.hh b/src/Episode3.hh index 86f32997..344f15a7 100644 --- a/src/Episode3.hh +++ b/src/Episode3.hh @@ -65,13 +65,14 @@ struct Ep3CardDefinition { } __attribute__((packed)); struct Effect { + uint8_t effect_num; uint8_t command; // See name_for_effect_command in Episode3.cc for details ptext expr; // May be blank if the command doesn't use it uint8_t when; // See description_for_when in Episode3.cc for details ptext arg1; ptext arg2; ptext arg3; - parray unknown_a3; // Possibly completely unused + parray unknown_a3; bool is_empty() const; static std::string str_for_arg(const std::string& arg); @@ -112,7 +113,8 @@ struct Ep3CardDefinition { uint8_t hide_in_deck_edit; // 0 = player can use this card (appears in deck edit) uint8_t subtype; // e.g. gun, sword, etc. (used for checking if SCs can use it) uint8_t rarity; // Rarity enum - be_uint32_t unknown_a2; + be_uint16_t unknown_a2; + be_uint16_t unknown_a3; // These two fields seem to always contain the same value, and are always 0 // for non-assist cards and nonzero for assists. Each assist card has a unique // value here and no effects, which makes it look like this is how assist @@ -122,12 +124,29 @@ struct Ep3CardDefinition { // other fields are also involved in determining their effects (see e.g. Skip // Draw / Skip Move, Dice Fever / Dice Fever +, Reverse Card / Rich +). parray assist_effect; - parray unknown_a3; + // Drop rates are decimal-encoded with the following fields: + // - rate % 10 (that is, the lowest decimal place) specifies the required game + // mode. 0 means any mode, 1 means offline only, 2 means 1P free-battle, 3 + // means 2P+ free battle, 4 means story mode. + // - (rate / 10) % 100 (that is, the tens and hundreds decimal places) specify + // something else, but it's not clear what exactly. + // - rate / 1000 (the thousands decimal place) specifies the level class + // required to get this drop. + // - rate / 10000 (the ten-thousands decimal place) must be either 0, 1, or 2, + // but it's not clear yet what each value means. + // The drop rates are completely ignored if any of the following are true + // (which means the card can never be found in a normal post-battle draw): + // - type is SC_HUNTERS or SC_ARKZ + // - unknown_a3 is 0x23 or 0x24 + // - rarity is E, D1, D2, or INVIS + // - hide_in_deck_edit is 1 (specifically 1; other nonzero values here don't + // prevent the card from appearing in post-battle draws) + parray drop_rates; ptext name; ptext jp_short_name; - ptext short_name; - be_uint16_t has_effects; // 1 if any of the following structs are not blank + ptext short_name; Effect effects[3]; + uint8_t unused_a3; void decode_range(); std::string str() const;