refine Episode3::MapDefinition
This commit is contained in:
+66
-26
@@ -1584,6 +1584,19 @@ void StateFlags::clear_FF() {
|
||||
this->client_sc_card_types.clear(CardType::INVALID_FF);
|
||||
}
|
||||
|
||||
OverlayState::OverlayState() {
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void OverlayState::clear() {
|
||||
for (size_t y = 0; y < this->tiles.size(); y++) {
|
||||
this->tiles[y].clear(0);
|
||||
}
|
||||
this->unused1.clear(0);
|
||||
this->trap_tile_colors_nte.clear(0);
|
||||
this->trap_card_ids_nte.clear(0);
|
||||
}
|
||||
|
||||
void MapDefinition::assert_semantically_equivalent(const MapDefinition& other) const {
|
||||
if (this->map_number != other.map_number) {
|
||||
throw runtime_error("map number not equal");
|
||||
@@ -1603,12 +1616,9 @@ void MapDefinition::assert_semantically_equivalent(const MapDefinition& other) c
|
||||
if (this->start_tile_definitions != other.start_tile_definitions) {
|
||||
throw runtime_error("start tile definitions not equal");
|
||||
}
|
||||
if (this->modification_tiles != other.modification_tiles) {
|
||||
if (this->overlay_state.tiles != other.overlay_state.tiles) {
|
||||
throw runtime_error("modification tiles not equal");
|
||||
}
|
||||
if (this->unknown_a5 != other.unknown_a5) {
|
||||
throw runtime_error("unknown_a5 not equal");
|
||||
}
|
||||
if (this->default_rules != other.default_rules) {
|
||||
throw runtime_error("default rules not equal");
|
||||
}
|
||||
@@ -1814,19 +1824,52 @@ string MapDefinition::str(const CardIndex* card_index, uint8_t language) const {
|
||||
lines.emplace_back(phosg::string_printf(" overview_specs[%zu][team %zu]: %s", w, z, spec_str.c_str()));
|
||||
}
|
||||
}
|
||||
lines.emplace_back(" modification tiles:");
|
||||
add_map(this->modification_tiles);
|
||||
for (size_t z = 0; z < 0x70; z += 0x10) {
|
||||
lines.emplace_back(phosg::string_printf(
|
||||
" a5[0x%02zX:0x%02zX]: %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX %02hhX", z, z + 0x10,
|
||||
this->unknown_a5[z + 0x00], this->unknown_a5[z + 0x01], this->unknown_a5[z + 0x02], this->unknown_a5[z + 0x03],
|
||||
this->unknown_a5[z + 0x04], this->unknown_a5[z + 0x05], this->unknown_a5[z + 0x06], this->unknown_a5[z + 0x07],
|
||||
this->unknown_a5[z + 0x08], this->unknown_a5[z + 0x09], this->unknown_a5[z + 0x0A], this->unknown_a5[z + 0x0B],
|
||||
this->unknown_a5[z + 0x0C], this->unknown_a5[z + 0x0D], this->unknown_a5[z + 0x0E], this->unknown_a5[z + 0x0F]));
|
||||
}
|
||||
lines.emplace_back(" overlay tiles:");
|
||||
add_map(this->overlay_state.tiles);
|
||||
lines.emplace_back(phosg::string_printf(
|
||||
" a5[0x70:0x74]: %02hhX %02hhX %02hhX %02hhX",
|
||||
this->unknown_a5[0x70], this->unknown_a5[0x71], this->unknown_a5[0x72], this->unknown_a5[0x73]));
|
||||
" unused1: %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32,
|
||||
this->overlay_state.unused1[0].load(),
|
||||
this->overlay_state.unused1[1].load(),
|
||||
this->overlay_state.unused1[2].load(),
|
||||
this->overlay_state.unused1[3].load(),
|
||||
this->overlay_state.unused1[4].load()));
|
||||
lines.emplace_back(phosg::string_printf(
|
||||
" trap_tile_colors_nte: %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32 " %08" PRIX32,
|
||||
this->overlay_state.trap_tile_colors_nte[0].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[1].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[2].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[3].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[4].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[5].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[6].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[7].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[8].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[9].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[10].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[11].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[12].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[13].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[14].load(),
|
||||
this->overlay_state.trap_tile_colors_nte[15].load()));
|
||||
lines.emplace_back(phosg::string_printf(
|
||||
" trap_card_ids_nte: #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX #%04hX",
|
||||
this->overlay_state.trap_card_ids_nte[0].load(),
|
||||
this->overlay_state.trap_card_ids_nte[1].load(),
|
||||
this->overlay_state.trap_card_ids_nte[2].load(),
|
||||
this->overlay_state.trap_card_ids_nte[3].load(),
|
||||
this->overlay_state.trap_card_ids_nte[4].load(),
|
||||
this->overlay_state.trap_card_ids_nte[5].load(),
|
||||
this->overlay_state.trap_card_ids_nte[6].load(),
|
||||
this->overlay_state.trap_card_ids_nte[7].load(),
|
||||
this->overlay_state.trap_card_ids_nte[8].load(),
|
||||
this->overlay_state.trap_card_ids_nte[9].load(),
|
||||
this->overlay_state.trap_card_ids_nte[10].load(),
|
||||
this->overlay_state.trap_card_ids_nte[11].load(),
|
||||
this->overlay_state.trap_card_ids_nte[12].load(),
|
||||
this->overlay_state.trap_card_ids_nte[13].load(),
|
||||
this->overlay_state.trap_card_ids_nte[14].load(),
|
||||
this->overlay_state.trap_card_ids_nte[15].load()));
|
||||
|
||||
lines.emplace_back(" default_rules: " + this->default_rules.str());
|
||||
lines.emplace_back(" name: " + this->name.decode(language));
|
||||
lines.emplace_back(" location_name: " + this->location_name.decode(language));
|
||||
@@ -1868,9 +1911,9 @@ string MapDefinition::str(const CardIndex* card_index, uint8_t language) const {
|
||||
}
|
||||
if (entry) {
|
||||
string name = entry->def.en_name.decode(language);
|
||||
lines.emplace_back(phosg::string_printf(" cards[%02zu]: %04hX (%s)", w, card_id, name.c_str()));
|
||||
lines.emplace_back(phosg::string_printf(" cards[%02zu]: #%04hX (%s)", w, card_id, name.c_str()));
|
||||
} else {
|
||||
lines.emplace_back(phosg::string_printf(" cards[%02zu]: %04hX", w, card_id));
|
||||
lines.emplace_back(phosg::string_printf(" cards[%02zu]: #%04hX", w, card_id));
|
||||
}
|
||||
}
|
||||
for (size_t x = 0; x < 0x10; x++) {
|
||||
@@ -1911,9 +1954,9 @@ string MapDefinition::str(const CardIndex* card_index, uint8_t language) const {
|
||||
}
|
||||
if (entry) {
|
||||
string name = entry->def.en_name.decode(language);
|
||||
lines.emplace_back(phosg::string_printf(" reward_cards[%02zu]: %04hX (%s)", z, card_id, name.c_str()));
|
||||
lines.emplace_back(phosg::string_printf(" reward_cards[%02zu]: #%04hX (%s)", z, card_id, name.c_str()));
|
||||
} else {
|
||||
lines.emplace_back(phosg::string_printf(" reward_cards[%02zu]: %04hX", z, card_id));
|
||||
lines.emplace_back(phosg::string_printf(" reward_cards[%02zu]: #%04hX", z, card_id));
|
||||
}
|
||||
}
|
||||
lines.emplace_back(phosg::string_printf(" level_overrides: [win: %" PRId32 ", loss: %" PRId32 "]",
|
||||
@@ -2022,8 +2065,7 @@ MapDefinitionTrial::MapDefinitionTrial(const MapDefinition& map)
|
||||
camera_zone_maps(map.camera_zone_maps),
|
||||
camera_zone_specs(map.camera_zone_specs),
|
||||
overview_specs(map.overview_specs),
|
||||
modification_tiles(map.modification_tiles),
|
||||
unknown_a5(map.unknown_a5),
|
||||
overlay_state(map.overlay_state),
|
||||
default_rules(map.default_rules),
|
||||
name(map.name),
|
||||
location_name(map.location_name),
|
||||
@@ -2077,9 +2119,7 @@ MapDefinitionTrial::operator MapDefinition() const {
|
||||
ret.camera_zone_maps = this->camera_zone_maps;
|
||||
ret.camera_zone_specs = this->camera_zone_specs;
|
||||
ret.overview_specs = this->overview_specs;
|
||||
ret.modification_tiles = this->modification_tiles;
|
||||
ret.unknown_a5.clear(0xFF);
|
||||
ret.unknown_a5 = this->unknown_a5;
|
||||
ret.overlay_state = this->overlay_state;
|
||||
ret.default_rules = this->default_rules;
|
||||
ret.name = this->name;
|
||||
ret.location_name = this->location_name;
|
||||
@@ -2737,7 +2777,7 @@ const string& MapIndex::get_compressed_list(size_t num_players, uint8_t language
|
||||
e.width = vm->map->width;
|
||||
e.height = vm->map->height;
|
||||
e.map_tiles = vm->map->map_tiles;
|
||||
e.modification_tiles = vm->map->modification_tiles;
|
||||
e.modification_tiles = vm->map->overlay_state.tiles;
|
||||
|
||||
e.name_offset = strings_w.size();
|
||||
strings_w.write(vm->map->name.data, vm->map->name.used_chars_8());
|
||||
|
||||
+39
-20
@@ -1131,6 +1131,40 @@ struct CompressedMapHeader { // .mnm file format
|
||||
// Compressed data immediately follows (which decompresses to a MapDefinition)
|
||||
} __packed_ws__(CompressedMapHeader, 8);
|
||||
|
||||
struct OverlayState {
|
||||
// In the tiles array, the high 4 bits of each value are the tile type, and
|
||||
// the low 4 bits are the subtype. The types are:
|
||||
// 10: blocked by rock (as if the corresponding map_tiles value was 00)
|
||||
// 20: blocked by fence (as if the corresponding map_tiles value was 00)
|
||||
// 30-34: teleporters (2 of each value may be present)
|
||||
// 40-4F: traps on NTE
|
||||
// 40-44: traps on non-NTE (there may be up to 8 of each type, and one of
|
||||
// each is chosen to be a real trap at battle start); the trap types are:
|
||||
// 40: Dice Fever, Heavy Fog, Muscular, Immortality, Snail Pace
|
||||
// 41: Gold Rush, Charity, Requiem
|
||||
// 42: Powerless Rain, Trash 1, Empty Hand, Skip Draw
|
||||
// 43: Brave Wind, Homesick, Fly
|
||||
// 44: Dice+1, Battle Royale, Reverse Card, Giant Garden, Fix
|
||||
// 50: blocked by metal box (appears as an improperly-z-buffered teal cube in
|
||||
// preview; behaves like 10 and 20 in game)
|
||||
// Any other value here will behave like 00 (no special tile behavior).
|
||||
parray<parray<uint8_t, 0x10>, 0x10> tiles;
|
||||
|
||||
parray<le_uint32_t, 5> unused1;
|
||||
|
||||
// TODO: Figure out exactly where these colors are used
|
||||
parray<le_uint32_t, 0x10> trap_tile_colors_nte; // Unused on non-NTE
|
||||
|
||||
// This specifies the assist card IDs that each trap value (40-4F) will set
|
||||
// when triggered. This only has an effect on NTE; on non-NTE, this is unused
|
||||
// and a fixed set of assist cards is used instead. (On newserv, the set of
|
||||
// used assist cards can be overridden in the server configuration.)
|
||||
parray<le_uint16_t, 0x10> trap_card_ids_nte;
|
||||
|
||||
OverlayState();
|
||||
void clear();
|
||||
} __packed_ws__(OverlayState, 0x174);
|
||||
|
||||
struct MapDefinition { // .mnmd format; also the format of (decompressed) quests
|
||||
// If tag is not 0x00000100, the game considers the map to be corrupt in
|
||||
// offline mode and will delete it (if it's a download quest). The tag field
|
||||
@@ -1250,24 +1284,10 @@ struct MapDefinition { // .mnmd format; also the format of (decompressed) quests
|
||||
// (it is not yet known what the major index represents).
|
||||
/* 1AB8 */ parray<parray<CameraSpec, 2>, 3> overview_specs;
|
||||
|
||||
// In the modification_tiles array, the values are:
|
||||
// 10 = blocked by rock (as if the corresponding map_tiles value was 00)
|
||||
// 20 = blocked by fence (as if the corresponding map_tiles value was 00)
|
||||
// 30-34 = teleporters (2 of each value may be present)
|
||||
// 40-4F = traps on NTE
|
||||
// 40-44 = traps on non-NTE (one of each type is chosen at random to be a real
|
||||
// trap at battle start time)
|
||||
// 50 = blocked by metal box (appears as improperly-z-buffered teal cube in
|
||||
// preview; behaves like 10 and 20 in game)
|
||||
// The assist cards that each trap type can contain are:
|
||||
// 40: Dice Fever, Heavy Fog, Muscular, Immortality, Snail Pace
|
||||
// 41: Gold Rush, Charity, Requiem
|
||||
// 42: Powerless Rain, Trash 1, Empty Hand, Skip Draw
|
||||
// 43: Brave Wind, Homesick, Fly
|
||||
// 44: Dice+1, Battle Royale, Reverse Card, Giant Garden, Fix
|
||||
/* 1C68 */ parray<parray<uint8_t, 0x10>, 0x10> modification_tiles;
|
||||
// This specifies the locations of blocked tiles, teleporters, and traps. See
|
||||
// the comments in OverlayState for details.
|
||||
/* 1C68 */ OverlayState overlay_state;
|
||||
|
||||
/* 1D68 */ parray<uint8_t, 0x74> unknown_a5;
|
||||
/* 1DDC */ Rules default_rules;
|
||||
|
||||
/* 1DF0 */ pstring<TextEncoding::MARKED, 0x14> name;
|
||||
@@ -1470,9 +1490,8 @@ struct MapDefinitionTrial {
|
||||
/* 0118 */ parray<parray<parray<parray<uint8_t, 0x10>, 0x10>, 10>, 2> camera_zone_maps;
|
||||
/* 1518 */ parray<parray<MapDefinition::CameraSpec, 10>, 2> camera_zone_specs;
|
||||
/* 1AB8 */ parray<parray<MapDefinition::CameraSpec, 2>, 3> overview_specs;
|
||||
/* 1C68 */ parray<parray<uint8_t, 0x10>, 0x10> modification_tiles;
|
||||
/* 1D68 */ parray<uint8_t, 0x74> unknown_a5;
|
||||
/* 1DD4 */ RulesTrial default_rules;
|
||||
/* 1C68 */ OverlayState overlay_state;
|
||||
/* 1DDC */ RulesTrial default_rules;
|
||||
/* 1DE8 */ pstring<TextEncoding::MARKED, 0x14> name;
|
||||
/* 1DFC */ pstring<TextEncoding::MARKED, 0x14> location_name;
|
||||
/* 1E10 */ pstring<TextEncoding::MARKED, 0x3C> quest_name;
|
||||
|
||||
@@ -99,17 +99,4 @@ MapAndRulesStateTrial::operator MapAndRulesState() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
OverlayState::OverlayState() {
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void OverlayState::clear() {
|
||||
for (size_t y = 0; y < this->tiles.size(); y++) {
|
||||
this->tiles[y].clear(0);
|
||||
}
|
||||
this->unused1.clear(0);
|
||||
this->unused2.clear(0);
|
||||
this->trap_card_ids_nte.clear(0);
|
||||
}
|
||||
|
||||
} // namespace Episode3
|
||||
|
||||
@@ -67,14 +67,4 @@ struct MapAndRulesStateTrial {
|
||||
operator MapAndRulesState() const;
|
||||
} __packed_ws__(MapAndRulesStateTrial, 0x130);
|
||||
|
||||
struct OverlayState {
|
||||
parray<parray<uint8_t, 0x10>, 0x10> tiles;
|
||||
parray<le_uint32_t, 5> unused1;
|
||||
parray<le_uint32_t, 0x10> unused2;
|
||||
parray<le_uint16_t, 0x10> trap_card_ids_nte; // Unused on non-NTE
|
||||
|
||||
OverlayState();
|
||||
void clear();
|
||||
} __packed_ws__(OverlayState, 0x174);
|
||||
|
||||
} // namespace Episode3
|
||||
|
||||
Reference in New Issue
Block a user