explain a few of the unknown player_flags bits

This commit is contained in:
Martin Michelsen
2026-03-30 18:00:47 -07:00
parent b7819413b0
commit a05971017d
5 changed files with 51 additions and 50 deletions
+5 -6
View File
@@ -1136,9 +1136,8 @@ Action a_decrypt_dcv2_executable(
executable (DP_ADDRESS.JPN), INDEXES should be the path to the index fixup\n\
table (KATSUO.SEA), and VALUES should be the path to the value fixup table\n\
(IWASHI.SEA). The output is written to EXEC.dec.\n\
If --simple is given, uses the simpler encryption method used in some\n\
community modifications of the game (Enhancement Pack, for example). In\n\
this case, --seed is not required; if not given, finds the seed\n\
If --simple is given, uses the encryption method used in Ives\' Enhancement\n\
Pack. In this case, --seed is not required; if not given, finds the seed\n\
automatically, and prints it to stderr so you will be able to use it when\n\
re-encrypting.\n",
+[](phosg::Arguments& args) {
@@ -1166,8 +1165,8 @@ Action a_encrypt_dcv2_executable(
executable (DP_ADDRESS.JPN) and INDEXES should be the path to the index\n\
fixup table (KATSUO.SEA). The output is written to EXEC.enc and\n\
INDEXES.enc.\n\
If --simple is given, uses the simpler encryption method used in some\n\
community modifications of the game. In this case, --seed is required.\n",
If --simple is given, uses the simpler encryption method used in Ives\'\n\
Enhancement Pack. In this case, --seed is required.\n",
+[](phosg::Arguments& args) {
string executable_filename = args.get<string>("executable", true);
string executable_data = phosg::load_file(executable_filename);
@@ -1188,7 +1187,7 @@ Action a_encrypt_dcv2_executable(
Action a_decode_gci_snapshot(
"decode-gci-snapshot", "\
decode-gci-snapshot [INPUT-FILENAME [OUTPUT-FILENAME]]\n\
Decode a PSO GC snapshot file into a Windows BMP image.\n",
Decode a PSO GC snapshot file (in GCI format) into a Windows BMP image.\n",
+[](phosg::Arguments& args) {
auto data = read_input_data(args);
phosg::StringReader r(data);
+5 -4
View File
@@ -866,9 +866,10 @@ static const vector<DATEntityDefinition> dat_object_definitions({
// param5; if the dot product is positive, param2 is used)
// param3 = room ID to use if the dot product described above is zero or negative
// param5 = angle (see param2)
// param6 = if equal to 0x00010000, only the player's room_id field is set, and game flag 0x02000000 is set on
// the player; if not equal to 0x00010000, then both room_id and room_id2 are set and no game flag is set
// (TODO: What are the visible behavior differences due to this parameter?)
// param6 = on v2 and before, this is ignored; on v3 and later, if param6 is equal to 0x00010000, only the
// player's room_id field is set, and player flag 0x02000000 is set on the player; if not equal to 0x00010000,
// then both room_id and room_id_in_custom_area (if in a non-rearrangeable area, like Pioneer 2 or Forest) are
// set and no game flag is set (TODO: What are the visible behavior differences due to this parameter?)
{0x000E, F_V0_V4, 0x00005FFFFFF83FFE, "TObjRoomId"},
// Sensor of some kind (TODO). Params:
@@ -6607,7 +6608,7 @@ void MapState::import_enemy_states_from_sync(Version from_version, const SyncEne
// Only set the state if it's not an alias
if (ene_st->super_ene == ene) {
if (ene_st->game_flags != entry.flags) {
this->log.warning_f("({:04X} => E-{:03X}) Flags from client ({:08X}) do not match game flags from map ({:08X})",
this->log.warning_f("({:04X} => E-{:03X}) Game flags from client ({:08X}) do not match game flags from map ({:08X})",
enemy_index, ene_st->e_id, entry.flags, ene_st->game_flags);
ene_st->game_flags = entry.flags;
}
+2 -2
View File
@@ -721,7 +721,7 @@ const ChallengeTemplateDefinition& get_challenge_template_definition(Version ver
}
PlayerHoldState::PlayerHoldState(const PlayerHoldState_DCProtos& proto)
: unknown_a1(proto.unknown_a1),
: expiration_frames(proto.expiration_frames),
unknown_a2(proto.unknown_a2),
unknown_a3(0),
trigger_radius2(proto.trigger_radius2),
@@ -730,7 +730,7 @@ PlayerHoldState::PlayerHoldState(const PlayerHoldState_DCProtos& proto)
PlayerHoldState::operator PlayerHoldState_DCProtos() const {
PlayerHoldState_DCProtos ret;
ret.unknown_a1 = this->unknown_a1;
ret.expiration_frames = this->expiration_frames;
ret.unknown_a2 = this->unknown_a2;
ret.trigger_radius2 = this->trigger_radius2;
ret.x = this->x;
+2 -2
View File
@@ -1129,7 +1129,7 @@ struct TelepipeState {
struct PlayerHoldState_DCProtos {
// This is used in all versions of this command except DCNTE and 11/2000.
/* 00 */ le_uint16_t unknown_a1 = 0;
/* 00 */ le_uint16_t expiration_frames = 0;
/* 02 */ le_uint16_t unknown_a2 = 0;
// unknown_a3 is missing in this format, unlike the v1+ format below
/* 04 */ le_float trigger_radius2 = 0.0f;
@@ -1140,7 +1140,7 @@ struct PlayerHoldState_DCProtos {
struct PlayerHoldState {
// This is used in all versions of this command except DCNTE and 11/2000.
/* 00 */ le_uint16_t unknown_a1 = 0;
/* 00 */ le_uint16_t expiration_frames = 0;
/* 02 */ le_uint16_t unknown_a2 = 0;
/* 04 */ le_uint32_t unknown_a3 = 0;
/* 08 */ le_float trigger_radius2 = 0.0f;
+37 -36
View File
@@ -1148,42 +1148,43 @@ uint32_t Parsed6x70Data::convert_player_flags(uint32_t player_flags, bool to_v3)
// 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 = player hold is set for the purpose of dropping an item
// 00000004 00000004 = is on a different floor from the local player (or is loading into game)
// 00000008 00000008 ? = unknown (TODO: appears to be entirely unused, at least in v3)
// 00000010 00000010 = player has sent any update command (position, attack, etc.) this frame
// 00000020 00000020 ? = unknown (TODO: appears to be entirely unused, at least in v3)
// 00000040 00000040 ? = unknown (TODO: appears to be entirely unused, at least in v3)
// 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: appears to be entirely unused, at least in v3)
// 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 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 ? = if set, the player will freeze when attempting any lobby animation (TODO: what does this
// actually do? it doesn't appear to be set anywhere normally)
// -------- 40000000 ? = unknown (TODO: used in offline multi-player Challenge mode; see tree from 3OE1:801BE594)
// 00000001 00000001 = player hold is set (see notes on 6x2C and 6x2D in CommandFormats.hh)
// 00000002 00000002 = player hold is set for the purpose of dropping an item
// 00000004 00000004 = is on a different floor from the local player (or is loading into game)
// 00000008 00000008 = unknown (TODO: appears to be entirely unused, at least in v2 and later)
// 00000010 00000010 = player has sent any update command (position, attack, etc.) this frame
// 00000020 00000020 = unknown (TODO: appears to be entirely unused, at least in v2 and later)
// 00000040 00000040 = unknown (TODO: appears to be entirely unused, at least in v2 and later)
// 00000080 00000080 = is in windup animation for technique or PB
// 00000100 -------- = unknown (TODO: appears to be entirely unused, at least in v2)
// 00000200 00000100 = chat, pause, or quick menu is open (suppresses action palette)
// 00000400 00000200 = is in PB cutscene
// 00000800 -------- = player is standing in water (steps create splash particles)
// 00001000 -------- = player is standing in grass (steps create grass particles)
// 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: appears to be entirely unused, at least in v3)
// 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: appears to be entirely unused, at least in v2)
// 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 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 = player's room_id_in_custom_area does not match player's room_id (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 = appears to be unused (there is no codepath that sets this flag); if set, the player will
// freeze when attempting any lobby animation
// -------- 40000000 = unknown (TODO: used in offline multi-player Challenge mode; see tree from 3OE1:801BE594)
if (to_v3) {
return (player_flags & 0x000000FF) |