diff --git a/src/CommandFormats.hh b/src/CommandFormats.hh index d6c534bd..529cb8dd 100644 --- a/src/CommandFormats.hh +++ b/src/CommandFormats.hh @@ -4292,25 +4292,26 @@ struct G_CreateInventoryItem_PC_V3_BB_6x2B : G_CreateInventoryItem_DC_6x2B { parray unused2 = 0; } __packed_ws__(G_CreateInventoryItem_PC_V3_BB_6x2B, 0x1C); -// 6x2C: Talk to NPC (protected on V3/V4) -// This updates G_6x70_NPCTalkState in the TObjPlayer struct, but the format is -// not the same. The names here match the fields in G_6x70_NPCTalkState, hence -// the unusual numbering. +// 6x2C: Impose hold (protected on V3/V4) +// This updates PlayerHoldState in the TObjPlayer struct, but the format is not +// the same. The names here match the fields in PlayerHoldState. A player hold +// prevents the player from moving further than the trigger radius from the +// given x/z coordinates. -struct G_TalkToNPC_6x2C { +struct G_ImposeHold_6x2C { G_ClientIDHeader header; le_uint16_t unknown_a1 = 0; le_uint16_t unknown_a2 = 0; - le_float unknown_a5 = 0.0f; - le_float unknown_a6 = 0.0f; - le_float unknown_a4 = 0.0f; -} __packed_ws__(G_TalkToNPC_6x2C, 0x14); + le_float x = 0.0f; + le_float z = 0.0f; + le_float trigger_radius2 = 0.0f; // "2" here means "squared" +} __packed_ws__(G_ImposeHold_6x2C, 0x14); -// 6x2D: Done talking to NPC (protected on V3/V4) +// 6x2D: Release hold (protected on V3/V4) -struct G_EndTalkToNPC_6x2D { +struct G_ReleaseHold_6x2D { G_ClientIDHeader header; -} __packed_ws__(G_EndTalkToNPC_6x2D, 4); +} __packed_ws__(G_ReleaseHold_6x2D, 4); // 6x2E: Set and/or clear player flags (protected on V3/V4) @@ -4979,7 +4980,7 @@ struct G_SyncPlayerDispAndInventory_DCNTE_6x70 { /* 0034 */ le_uint32_t unknown_a6 = 0; /* 0038 */ G_6x70_Sub_Telepipe telepipe; /* 0054 */ le_uint32_t death_flags = 0; - /* 0058 */ NPCTalkState_DCProtos npc_talk_state; + /* 0058 */ PlayerHoldState_DCProtos hold_state; /* 0068 */ le_uint32_t area = 0; /* 006C */ le_uint32_t game_flags = 0; /* 0070 */ PlayerVisualConfig visual; @@ -4998,7 +4999,7 @@ struct G_SyncPlayerDispAndInventory_DC112000_6x70 { /* 0034 */ parray unknown_a5; /* 0044 */ G_6x70_Sub_Telepipe telepipe; /* 0060 */ le_uint32_t death_flags = 0; - /* 0064 */ NPCTalkState_DCProtos npc_talk_state; + /* 0064 */ PlayerHoldState_DCProtos hold_state; /* 0074 */ le_uint32_t area = 0; /* 0078 */ le_uint32_t game_flags = 0; /* 007C */ PlayerVisualConfig visual; @@ -5024,7 +5025,7 @@ struct G_6x70_Base_V1 { /* 0074 */ le_uint32_t battle_team_number = 0; /* 0078 */ G_6x70_Sub_Telepipe telepipe; /* 0094 */ le_uint32_t death_flags = 0; // Only a few bits are used. 4 = player is dead - /* 0098 */ NPCTalkState npc_talk_state; + /* 0098 */ PlayerHoldState hold_state; /* 00AC */ le_uint32_t area = 0; /* 00B0 */ le_uint32_t game_flags = 0; /* 00B4 */ parray technique_levels_v1 = 0xFF; // Last byte is uninitialized @@ -6174,7 +6175,9 @@ struct G_SetQuestCounter_BB_6xD2 { struct G_Unknown_BB_6xD4 { G_UnusedHeader header; le_uint16_t action = 0; // Must be in [0, 5] - uint8_t unknown_a1 = 0; // Must be in [0, 15] + // object_identifier must be in [0, 15]; it should match param4 of the + // relevant object. + uint8_t object_identifier = 0; uint8_t unused = 0; } __packed_ws__(G_Unknown_BB_6xD4, 8); diff --git a/src/Map.cc b/src/Map.cc index c77af7fd..cdcc16c2 100644 --- a/src/Map.cc +++ b/src/Map.cc @@ -1350,7 +1350,9 @@ const char* MapFile::name_for_object_type(uint16_t type) { {0x0084, "TLazerFenceSw"}, // Light rays. Params: - // param1-3 = scale (x, y, z) + // param1 = TODO + // param2 = vertical scale (y) + // param3 = horizontal scale (x, z) {0x0085, "TKomorebi"}, // Butterfly. Params: @@ -2421,13 +2423,45 @@ const char* MapFile::name_for_object_type(uint16_t type) { // Availability: Ep3 Morgue only {0x02E8, "__UNKNOWN_02E8__"}, - // TODO: Describe the rest of the object types. - {0x0300, "__EP4_LIGHT__"}, // Constructor in 59NL: 00661158 (v4 only) - {0x0301, "__WILDS_CRATER_CACTUS__"}, // Constructor in 59NL: 0067612C (v4 only) - {0x0302, "__WILDS_CRATER_BROWN_ROCK__"}, // Constructor in 59NL: 00675748 (v4 only) - {0x0303, "__WILDS_CRATER_BROWN_ROCK_DESTRUCTIBLE__"}, // Constructor in 59NL: 00675BF8 (v4 only) + // Episode 4 light source. + // TODO: Find and document this object's parameters. + // Availability: v4 only + {0x0300, "__EP4_LIGHT__"}, + + // Wilds/Crater cactus. Params: + // param1 = horizontal scale (x, z) + // param2 = vertical scale (y) + // param4 = model number (0-2, not bounds-checked) + // param5 = TODO + // Availability: v4 only + {0x0301, "__WILDS_CRATER_CACTUS__"}, + + // Wilds/Crater brown rock. Params: + // param1-3 = scale factors (x, y, z); z factor also scales hitbox size + // param4 = model number (0-2, not bounds-checked) + // Availability: v4 only + {0x0302, "__WILDS_CRATER_BROWN_ROCK__"}, + + // Wilds/Crater destructible brown rock. Params: + // param4 = switch flag number + // Availability: v4 only + {0x0303, "__WILDS_CRATER_BROWN_ROCK_DESTRUCTIBLE__"}, + + // TODO: Construct this object and see what it is. Params: + // param4 = object identifier (must be in range [0, 15]; used in 6xD4 + // command) + // Availability: v4 only {0x0340, "__UNKNOWN_0340__"}, // Constructor in 59NL: 00673FB8 (v4 only) + + // TODO: Construct this object and see what it is. It looks like some + // kind of child object of 0340. Params: + // param4 = object identifier (must be in range [0, 15]; used in 6xD4 + // command; looks like it should match an existing 0340's identifier) + // param5 = child index? (must be in range [0, 3]) + // Availability: v4 only {0x0341, "__UNKNOWN_0341__"}, // Constructor in 59NL: 00674118 (v4 only) + + // TODO: Describe the rest of the object types. {0x0380, "__POISON_PLANT__"}, // Constructor in 59NL: 0067927C (v4 only) {0x0381, "__UNKNOWN_0381__"}, // Constructor in 59NL: 00679678 (v4 only) {0x0382, "__UNKNOWN_0382__"}, // Constructor in 59NL: 0067A264 (v4 only) diff --git a/src/PlayerSubordinates.cc b/src/PlayerSubordinates.cc index 49790433..2a191b8c 100644 --- a/src/PlayerSubordinates.cc +++ b/src/PlayerSubordinates.cc @@ -743,20 +743,20 @@ const ChallengeTemplateDefinition& get_challenge_template_definition(Version ver } } -NPCTalkState::NPCTalkState(const NPCTalkState_DCProtos& proto) +PlayerHoldState::PlayerHoldState(const PlayerHoldState_DCProtos& proto) : unknown_a1(proto.unknown_a1), unknown_a2(proto.unknown_a2), unknown_a3(0), - unknown_a4(proto.unknown_a4), - unknown_a5(proto.unknown_a5), - unknown_a6(proto.unknown_a6) {} + trigger_radius2(proto.trigger_radius2), + x(proto.x), + z(proto.z) {} -NPCTalkState::operator NPCTalkState_DCProtos() const { - NPCTalkState_DCProtos ret; +PlayerHoldState::operator PlayerHoldState_DCProtos() const { + PlayerHoldState_DCProtos ret; ret.unknown_a1 = this->unknown_a1; ret.unknown_a2 = this->unknown_a2; - ret.unknown_a4 = this->unknown_a4; - ret.unknown_a5 = this->unknown_a5; - ret.unknown_a6 = this->unknown_a6; + ret.trigger_radius2 = this->trigger_radius2; + ret.x = this->x; + ret.z = this->z; return ret; } diff --git a/src/PlayerSubordinates.hh b/src/PlayerSubordinates.hh index a83596d9..65b44825 100644 --- a/src/PlayerSubordinates.hh +++ b/src/PlayerSubordinates.hh @@ -1007,31 +1007,31 @@ struct TelepipeState { /* 18 */ } __packed_ws__(TelepipeState, 0x18); -struct NPCTalkState_DCProtos { +struct PlayerHoldState_DCProtos { // This is used in all versions of this command except DCNTE and 11/2000. /* 00 */ le_uint16_t unknown_a1 = 0; /* 02 */ le_uint16_t unknown_a2 = 0; // unknown_a3 is missing in this format, unlike the v1+ format below - /* 04 */ le_float unknown_a4 = 0.0f; - /* 08 */ le_float unknown_a5 = 0.0f; - /* 0C */ le_float unknown_a6 = 0.0f; + /* 04 */ le_float trigger_radius2 = 0.0f; + /* 08 */ le_float x = 0.0f; + /* 0C */ le_float z = 0.0f; /* 10 */ -} __packed_ws__(NPCTalkState_DCProtos, 0x10); +} __packed_ws__(PlayerHoldState_DCProtos, 0x10); -struct NPCTalkState { +struct PlayerHoldState { // This is used in all versions of this command except DCNTE and 11/2000. /* 00 */ le_uint16_t unknown_a1 = 0; /* 02 */ le_uint16_t unknown_a2 = 0; /* 04 */ le_uint32_t unknown_a3 = 0; - /* 08 */ le_float unknown_a4 = 0.0f; - /* 0C */ le_float unknown_a5 = 0.0f; - /* 10 */ le_float unknown_a6 = 0.0f; + /* 08 */ le_float trigger_radius2 = 0.0f; + /* 0C */ le_float x = 0.0f; + /* 10 */ le_float z = 0.0f; /* 14 */ - NPCTalkState() = default; - NPCTalkState(const NPCTalkState_DCProtos& proto); - operator NPCTalkState_DCProtos() const; -} __packed_ws__(NPCTalkState, 0x14); + PlayerHoldState() = default; + PlayerHoldState(const PlayerHoldState_DCProtos& proto); + operator PlayerHoldState_DCProtos() const; +} __packed_ws__(PlayerHoldState, 0x14); struct StatusEffectState { /* 00 */ le_uint32_t effect_type = 0; diff --git a/src/ReceiveSubcommands.cc b/src/ReceiveSubcommands.cc index a43780bf..cd459c8c 100644 --- a/src/ReceiveSubcommands.cc +++ b/src/ReceiveSubcommands.cc @@ -789,7 +789,7 @@ Parsed6x70Data::Parsed6x70Data( battle_team_number(0), telepipe(cmd.telepipe), death_flags(cmd.death_flags), - npc_talk_state(cmd.npc_talk_state), + hold_state(cmd.hold_state), area(cmd.area), game_flags(cmd.game_flags), game_flags_is_v3(false), @@ -825,7 +825,7 @@ Parsed6x70Data::Parsed6x70Data( battle_team_number(0), telepipe(cmd.telepipe), death_flags(cmd.death_flags), - npc_talk_state(cmd.npc_talk_state), + hold_state(cmd.hold_state), area(cmd.area), game_flags(cmd.game_flags), game_flags_is_v3(false), @@ -910,7 +910,7 @@ G_SyncPlayerDispAndInventory_DCNTE_6x70 Parsed6x70Data::as_dc_nte(shared_ptrunknown_a6; ret.telepipe = this->telepipe; ret.death_flags = this->death_flags; - ret.npc_talk_state = this->npc_talk_state; + ret.hold_state = this->hold_state; ret.area = this->area; ret.game_flags = this->get_game_flags(false); ret.visual = this->visual; @@ -938,7 +938,7 @@ G_SyncPlayerDispAndInventory_DC112000_6x70 Parsed6x70Data::as_dc_112000(shared_p ret.unknown_a5 = this->unknown_a5_112000; ret.telepipe = this->telepipe; ret.death_flags = this->death_flags; - ret.npc_talk_state = this->npc_talk_state; + ret.hold_state = this->hold_state; ret.area = this->area; ret.game_flags = this->get_game_flags(false); ret.visual = this->visual; @@ -1100,7 +1100,7 @@ Parsed6x70Data::Parsed6x70Data( battle_team_number(base.battle_team_number), telepipe(base.telepipe), death_flags(base.death_flags), - npc_talk_state(base.npc_talk_state), + hold_state(base.hold_state), area(base.area), game_flags(base.game_flags), game_flags_is_v3(!is_v1_or_v2(from_version)), @@ -1124,7 +1124,7 @@ G_6x70_Base_V1 Parsed6x70Data::base_v1(bool is_v3) const { ret.battle_team_number = this->battle_team_number; ret.telepipe = this->telepipe; ret.death_flags = this->death_flags; - ret.npc_talk_state = this->npc_talk_state; + ret.hold_state = this->hold_state; ret.area = this->area; ret.game_flags = this->get_game_flags(is_v3); ret.technique_levels_v1 = this->technique_levels_v1; diff --git a/src/ReceiveSubcommands.hh b/src/ReceiveSubcommands.hh index d89649e8..6e4cea45 100644 --- a/src/ReceiveSubcommands.hh +++ b/src/ReceiveSubcommands.hh @@ -62,7 +62,7 @@ public: uint32_t battle_team_number = 0; G_6x70_Sub_Telepipe telepipe; uint32_t death_flags = 0; - NPCTalkState npc_talk_state; + PlayerHoldState hold_state; uint32_t area = 0; uint32_t game_flags = 0; bool game_flags_is_v3 = false;