more details on player_flags

This commit is contained in:
Martin Michelsen
2026-03-19 23:01:30 -07:00
parent 55be92a56f
commit 83291d5501
6 changed files with 99 additions and 67 deletions
+11 -17
View File
@@ -3782,13 +3782,14 @@ struct G_UpdateObjectState_6x0B {
} __packed_ws__(G_UpdateObjectState_6x0B, 0x0C);
// 6x0C: Add status effect (poison/slow/etc.) (protected on V3/V4)
// 6x0D: Remove status effect (protected on V3/V4)
struct G_AddStatusEffect_6x0C {
struct G_AddOrRemoveStatusEffect_6x0C_6x0D {
G_ClientIDHeader header;
// Each status effect has an assigned slot; there are 5 slots and each slot may only hold one effect at a time. (The
// last slot, slot 4, is unused.) If a new status effect is added to a slot that already contains one, the existing
// status effect is replaced. Non-technique status effects have fixed or indefinite durations; technique-based
// effects have durations based on the technique's level.
// last slot, slot 4, may be used by certain boss effects; this is unconfirmed.) If a new status effect is added to a
// slot that already contains one, the existing status effect is replaced. Non-technique status effects have fixed or
// indefinite durations; technique-based effects have durations based on the technique's level.
// Values for effect_type:
// 02 = Freeze (slot 1; 5 seconds)
// 03 = Shock (slot 1; 10 seconds)
@@ -3803,16 +3804,8 @@ struct G_AddStatusEffect_6x0C {
// 12 = Confuse (slot 1; 10 seconds)
// Anything else = command is ignored
le_uint32_t effect_type = 0;
le_float amount = 0; // Only used for Shifta/Deband/Jellen/Zalure
} __packed_ws__(G_AddStatusEffect_6x0C, 0x0C);
// 6x0D: Clear status effect slot (protected on V3/V4)
struct G_RemoveStatusEffect_6x0D {
G_ClientIDHeader header;
le_uint32_t slot = 0; // See 6x0C description for slot values
le_uint32_t unused = 0;
} __packed_ws__(G_RemoveStatusEffect_6x0D, 0x0C);
le_float amount = 0; // Only used in 6x0C for Shifta/Deband/Jellen/Zalure; unused in 6x0D
} __packed_ws__(G_AddOrRemoveStatusEffect_6x0C_6x0D, 0x0C);
// 6x0E: Clear all negative status effects (protected on V3/V4)
// It seems that the client never sends this command.
@@ -5452,9 +5445,10 @@ struct G_SetAnimationState_6xAE {
G_ClientIDHeader header;
le_uint16_t animation_number = 0;
le_uint16_t unused = 0;
// This field contains the flags field on the sender's TObjPlayer object. If the bit 04000000 is set in this field,
// then (flags & 1C000000) is or'ed into the TObjPlayer's flags field. All other bits are ignored.
le_uint32_t flags = 0;
// This field contains the player_flags field on the sender's TObjPlayer object. If the bit 04000000 is set in this
// field, then (flags & 1C000000) is or'ed into the TObjPlayer's player_flags field on the receiver's end; all other
// bits are ignored. (For the meanings of these bits, see Parsed6x70Data::convert_player_flags.)
le_uint32_t player_flags = 0;
le_float animation_timer = 0;
} __packed_ws__(G_SetAnimationState_6xAE, 0x10);
+42 -3
View File
@@ -3446,9 +3446,48 @@ void MapFile::RandomState::generate_shuffled_location_table(
}
const array<uint32_t, 41> MapFile::RAND_ENEMY_BASE_TYPES = {
0x44, 0x43, 0x41, 0x42, 0x40, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0xA0, 0xA1,
0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
0xE0, 0xE0, 0xE1};
0x0044, /* TObjEneBeast */
0x0043, /* TObjEneBm5Wolf */
0x0041, /* TObjEneLappy */
0x0042, /* TObjEneBm3FlyNest */
0x0040, /* TObjEneMoja */
0x0060, /* TObjGrass */
0x0061, /* TObjEneRe2Flower */
0x0062, /* TObjEneNanoDrago */
0x0063, /* TObjEneShark */
0x0064, /* TObjEneSlime */
0x0065, /* TObjEnePanarms */
0x0080, /* TObjEneDubchik */
0x0081, /* TObjEneGyaranzo */
0x0082, /* TObjEneMe3ShinowaReal */
0x0083, /* TObjEneMe1Canadin */
0x0084, /* TObjEneMe1CanadinLeader */
0x0085, /* TOCtrlDubchik */
0x00A0, /* TObjEneSaver */
0x00A1, /* TObjEneRe4Sorcerer */
0x00A2, /* TObjEneDarkGunner */
0x00A3, /* TObjEneDarkGunCenter */
0x00A4, /* TObjEneDf2Bringer */
0x00A5, /* TObjEneRe7Berura */
0x00A6, /* TObjEneDimedian */
0x00A7, /* TObjEneBalClawBody */
0x00A8, /* TObjEneBalClawClaw */
0x00D4, /* TObjEneMe3StelthReal */
0x00D5, /* TObjEneMerillLia */
0x00D6, /* TObjEneBm9Mericarol */
0x00D7, /* TObjEneBm5GibonU */
0x00D8, /* TObjEneGibbles */
0x00D9, /* TObjEneMe1Gee */
0x00DA, /* TObjEneMe1GiGue */
0x00DB, /* TObjEneDelDepth */
0x00DC, /* TObjEneDellBiter */
0x00DD, /* TObjEneDolmOlm */
0x00DE, /* TObjEneMorfos */
0x00DF, /* TObjEneRecobox */
0x00E0, /* TObjEneMe3SinowZoaReal/TObjEneEpsilonBody (depending on area) */
0x00E0, /* TObjEneMe3SinowZoaReal/TObjEneEpsilonBody (depending on area) */
0x00E1, /* TObjEneIllGill */
};
MapFile::MapFile(std::shared_ptr<const std::string> data) {
for (uint8_t z = 0; z < this->sections_for_floor.size(); z++) {
+1 -1
View File
@@ -676,7 +676,7 @@ static const QuestScriptOpcodeDefinition opcode_defs[] = {
// Sets a player's starting position.
// valueA = client ID
// regsB[0-2] = position (x, y, z as integers)
// r egsB[3] = angle
// regsB[3] = angle
{0x76, "set_player_start_position", "p_setpos", {CLIENT_ID, {R_REG_SET_FIXED, 4}}, F_V0_V4 | F_ARGS},
// Returns players to the Hunter's Guild counter.
+36 -34
View File
@@ -1147,40 +1147,42 @@ uint32_t Parsed6x70Data::convert_player_flags(uint32_t player_flags, bool to_v3)
// effects like other characters not appearing when joining a game. Unfortunately, some bits were deleted on v3 and
// other bits were added, so it doesn't suffice to simply store the most complete format of this field - we have to
// be able to convert between the two. What's known about these bits (? indicates meaning/behavior is unverified):
// * V1/V2 * V3/V4
// ? 00000001 00000001 = player hold is set (see notes on 6x2C and 6x2D in CommandFormats.hh)
// ? 00000002 ? 00000002 = unknown (TODO)
// ? 00000004 ? 00000004 = loading? (allows 6x3E to update room ID and near-enemy flag; TODO: what does this do?)
// ? 00000008 ? 00000008 = unknown (TODO)
// ? 00000010 00000010 = should send position update? (6x3E, 6x40, or 6x42)
// ? 00000020 ? 00000020 = unknown (TODO)
// ? 00000040 ? 00000040 = unknown (TODO)
// ? 00000080 ? 00000080 = seems to affect some particle effects? (TODO)
// ? 00000100 -------- = unknown (TODO)
// ? 00000200 00000100 = chat or pause menu is open (suppresses action palette)
// ? 00000400 ? 00000200 = unknown (TODO)
// ? 00000800 -------- = unknown (TODO)
// ? 00001000 -------- = unknown (TODO)
// ? 00002000 00000400 = action palette is disabled by p_action_disable or one of the TObjQuestColA* objects
// ? 00004000 00000800 = is about to return to Pioneer 2 after a death (TODO: also set by p_return_guild)
// ? 00008000 00001000 = cannot use telepipe / Ryuker (e.g. boss warps set this flag when the player is nearby)
// ? 00010000 ? 00002000 = unknown (TODO)
// ? 00020000 00004000 = is teleporting as a result of 6x24 (set only briefly after appearing at destination)
// ? 00040000 ? 00008000 = is dead NPC? (set by e.g. npc_crptalk_id when regsA[4] == 1)
// ? 00080000 -------- = unknown (TODO)
// ? 00100000 00010000 = has permanent trap vision (e.g. is android)
// ? 00200000 ? 00020000 = related to items; seems always set for the local player in P2 but not other players?
// ? 00400000 ? 00040000 = warping? (TODO: set by 6x21 and 6x22)
// ? 00800000 ? 00080000 = unknown (TODO)
// ? 01000000 ? 00100000 = unknown (TODO)
// ? 02000000 00200000 = is visible (set shortly after warping into a floor; remains set until next warp)
// ? 04000000 ? 00400000 = position is valid (therefore player can be rendered)
// ? 08000000 00800000 = player is invisible, but items are visible (TODO: is this used for Stealth Suit on BB?)
// ? 10000000 01000000 = if set, player does not drop weapon on death
// -------- ? 02000000 = used by TObjRoomId when param6 == 0x00010000 (TODO: figure out what this does)
// -------- 04000000 = is sitting in lobby chair
// -------- ? 08000000 = related to lobby chairs (TODO: see handle_6xAE)
// -------- 10000000 = using alternate lobby chair pose (X+B instead of X+A on GC, for example)
// V1/V2 V3/V4
// 00000001 00000001 = player hold is set (see notes on 6x2C and 6x2D in CommandFormats.hh)
// 00000002 00000002 ? = unknown (TODO: related to player holds; client sends 6x2D when this is set)
// 00000004 00000004 = is on a different floor from the local player (or is loading into game)
// 00000008 00000008 ? = unknown (TODO)
// 00000010 00000010 = player has sent any update command (position, attack, etc.) this frame
// 00000020 00000020 ? = unknown (TODO)
// 00000040 00000040 ? = unknown (TODO)
// 00000080 00000080 = is in windup animation for technique or PB
// 00000100 -------- ? = unknown (TODO)
// 00000200 00000100 = chat, pause, or quick menu is open (suppresses action palette)
// 00000400 00000200 = is in PB cutscene
// 00000800 -------- ? = unknown (TODO)
// 00001000 -------- ? = unknown (TODO)
// 00002000 00000400 = action palette is disabled by p_action_disable or one of the TObjQuestColA* objects
// 00004000 00000800 = is about to return to Pioneer 2 after a death (TODO: also set by p_return_guild)
// 00008000 00001000 = cannot use telepipe / Ryuker (e.g. boss warps set this flag when the player is nearby)
// 00010000 00002000 ? = unknown (TODO)
// 00020000 00004000 = is teleporting as a result of 6x24 (set only briefly after appearing at destination)
// 00040000 00008000 = is dead NPC (set by e.g. npc_crptalk_id when regsA[4] == 1)
// 00080000 -------- ? = unknown (TODO)
// 00100000 00010000 = has permanent trap vision (e.g. is android)
// 00200000 00020000 = equipped items are invisible / intangible (e.g. in Pioneer 2)
// 00400000 00040000 = is loading / changing floors (set by 6x22 and at game join, cleared by 6x23)
// 00800000 00080000 = player data is in the process of being exported to save file format
// 01000000 00100000 = initial free-play cutscene with the Principal has started in offline free-play single-mode
// 02000000 00200000 = is visible (set shortly after warping into a floor; remains set until next warp)
// 04000000 00400000 = position is valid (therefore player can be rendered)
// 08000000 00800000 = player is invisible if not local, but items are still visible (TODO: what about on BB?)
// 10000000 01000000 = if set, player does not drop weapon on death
// -------- 02000000 ? = used by TObjRoomId when param6 == 0x00010000 (TODO: figure out what this does)
// -------- 04000000 = is sitting in lobby chair
// -------- 08000000 = using male animations / poses in lobby chair
// -------- 10000000 = using alternate lobby chair pose (X+B instead of X+A on GC, for example)
// -------- 20000000 ? = is doing lobby animation? (TODO: verify this)
// -------- 40000000 ? = unknown (TODO: used in offline multi-player Challenge mode; see tree from 3OE1:801BE594)
if (to_v3) {
return (player_flags & 0x000000FF) |
+4 -4
View File
@@ -2663,16 +2663,16 @@ asio::awaitable<void> send_change_player_hp(
}
asio::awaitable<void> send_remove_negative_conditions(shared_ptr<Client> c) {
G_AddStatusEffect_6x0C cmd;
cmd.header = {0x0C, sizeof(G_AddStatusEffect_6x0C) >> 2, c->lobby_client_id};
G_AddOrRemoveStatusEffect_6x0C_6x0D cmd;
cmd.header = {0x0C, sizeof(G_AddOrRemoveStatusEffect_6x0C_6x0D) >> 2, c->lobby_client_id};
cmd.effect_type = 7; // Healing ring
cmd.amount = 0;
co_await send_protected_command(c, &cmd, sizeof(cmd), true);
}
void send_remove_negative_conditions(std::shared_ptr<Channel> ch, uint16_t client_id) {
G_AddStatusEffect_6x0C cmd;
cmd.header = {0x0C, sizeof(G_AddStatusEffect_6x0C) >> 2, client_id};
G_AddOrRemoveStatusEffect_6x0C_6x0D cmd;
cmd.header = {0x0C, sizeof(G_AddOrRemoveStatusEffect_6x0C_6x0D) >> 2, client_id};
cmd.effect_type = 7; // Healing ring
cmd.amount = 0;
ch->send(0x60, 0x00, &cmd, sizeof(cmd));