fix spectator count when multiple spectator teams exist

This commit is contained in:
Martin Michelsen
2023-02-22 18:03:05 -08:00
parent c7009569b7
commit 8f0a33eb77
2 changed files with 37 additions and 12 deletions
+14 -8
View File
@@ -373,7 +373,7 @@ struct C_LegacyLogin_PC_V3_03 {
le_uint64_t unused = 0; // Same as unused field in 9D/9E
le_uint32_t sub_version = 0;
uint8_t is_extended = 0;
uint8_t language = 0; // Same as 9D/9E
uint8_t language = 0;
le_uint16_t unknown_a2 = 0;
// Note: These are suffixed with 2 since they come from the same source data
// as the corresponding fields in 9D/9E. (Even though serial_number and
@@ -420,7 +420,7 @@ struct C_LegacyLogin_PC_V3_04 {
le_uint64_t unused1 = 0; // Same as unused field in 9D/9E
le_uint32_t sub_version = 0;
uint8_t is_extended = 0;
uint8_t language = 0; // Same as 9D/9E
uint8_t language = 0;
le_uint16_t unknown_a2 = 0;
ptext<char, 0x10> serial_number;
ptext<char, 0x10> access_key;
@@ -5784,18 +5784,24 @@ struct G_TournamentMatchResult_GC_Ep3_6xB4x51 {
struct G_SetGameMetadata_GC_Ep3_6xB4x52 {
G_CardBattleCommandHeader header = {0xB4, sizeof(G_SetGameMetadata_GC_Ep3_6xB4x52) / 4, 0, 0x52, 0, 0, 0};
le_uint16_t unknown_a1 = 0; // Clamped to [0, 999] by the client
// If num_spectators is nonzero, an icon appears in the middle of the screen
// during battle when the details view is enabled (by pressing Z). However,
// the number of people visible in the icon doesn't match the actual number of
// spectators. Specifically:
// This field appears before the slash in the spectators' HUD. Presumably this
// is used to indecate how many spectators are in the current spectator team.
// In the primary game (watched lobby), this is presumably unused.
le_uint16_t local_spectators = 0; // Clamped to [0, 999] by the client
// This field appears after the slash in the spectators' HUD. This is used to
// indicate how many spectators there are in all spectator teams attached to
// the same battle.
// This field also controls the icon shown in the primary game. If this field
// is nonzero, an icon appears in the middle of the screen during battle when
// the details view is enabled (by pressing Z). However, the number of people
// visible in the icon doesn't match the value in this field. Specifically:
// 0 = no icon
// 1 = icon with a single spectator (green)
// 2-4 = icon with 3 spectators (blue)
// 5-10 = icon with 5 spectators (yellow)
// 11-29 = icon with 8 spectators (purple)
// 30+ = icon with 12 spectators (red)
le_uint16_t num_spectators = 0; // Clamped to [0, 999] by the client
le_uint16_t total_spectators = 0; // Clamped to [0, 999] by the client
le_uint16_t unused = 0;
le_uint16_t size = 0; // Number of used bytes in unknown_a2 (clamped to 0xFF)
parray<uint8_t, 0x100> unknown_a2;
+23 -4
View File
@@ -2304,15 +2304,34 @@ void send_ep3_update_spectator_count(shared_ptr<Lobby> l) {
G_SetGameMetadata_GC_Ep3_6xB4x52 cmd;
for (auto watcher_l : l->watcher_lobbies) {
for (auto c : watcher_l->clients) {
if (c) {
cmd.num_spectators++;
}
cmd.total_spectators += (c.get() != nullptr);
}
}
// TODO: Make s available here so we can apply masking if needed (perhaps by
// adding a weak_ptr in Lobby... it'd be dumb to require s to be passed in to
// this function just to check a behavior flag)
send_command_t(l, 0xC9, 0x00, cmd);
// Note: We can't use send_command_t(l, ...) here because that would send the
// same command to l and to all wather lobbies. The commands should have
// different values depending on who's in each watcher lobby, so we have to
// manually send to each client here.
for (auto c : l->clients) {
if (c) {
send_command_t(c, 0xC9, 0x00, cmd);
}
}
for (auto watcher_l : l->watcher_lobbies) {
cmd.local_spectators = 0;
for (auto c : watcher_l->clients) {
cmd.local_spectators += (c.get() != nullptr);
}
for (auto c : watcher_l->clients) {
if (c) {
send_command_t(c, 0xC9, 0x00, cmd);
}
}
}
}
void set_mask_for_ep3_game_command(void* vdata, size_t size, uint8_t mask_key) {