implement spectator count view in primary game
This commit is contained in:
+16
-6
@@ -5615,15 +5615,25 @@ struct G_TournamentMatchResult_GC_Ep3_6xB4x51 {
|
||||
ptext<char, 0x20> meseta_reward_text;
|
||||
} __packed__;
|
||||
|
||||
// 6xB4x52: Unknown
|
||||
// 6xB4x52: Set game metadata
|
||||
|
||||
struct G_Unknown_GC_Ep3_6xB4x52 {
|
||||
G_CardBattleCommandHeader header = {0xB4, sizeof(G_Unknown_GC_Ep3_6xB4x52) / 4, 0, 0x52, 0, 0, 0};
|
||||
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
|
||||
le_uint16_t unknown_a2 = 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:
|
||||
// 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 unused = 0;
|
||||
le_uint16_t size = 0; // Number of used bytes in data (clamped to 0xFF)
|
||||
parray<uint8_t, 0x100> data;
|
||||
le_uint16_t size = 0; // Number of used bytes in unknown_a2 (clamped to 0xFF)
|
||||
parray<uint8_t, 0x100> unknown_a2;
|
||||
} __packed__;
|
||||
|
||||
// 6xB4x53: Reject battle start request
|
||||
|
||||
+25
-1
@@ -132,6 +132,18 @@ void Lobby::add_client(shared_ptr<Client> c) {
|
||||
c->game_data.player()->inventory,
|
||||
c->game_data.player()->disp.to_dcpcv3());
|
||||
}
|
||||
|
||||
// Send spectator count notifications if needed
|
||||
if (this->is_game() && (this->flags & Lobby::Flag::EPISODE_3_ONLY)) {
|
||||
if (this->flags & Lobby::Flag::IS_SPECTATOR_TEAM) {
|
||||
auto watched_l = this->watched_lobby.lock();
|
||||
if (watched_l) {
|
||||
send_ep3_update_spectator_count(watched_l);
|
||||
}
|
||||
} else {
|
||||
send_ep3_update_spectator_count(this->shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Lobby::remove_client(shared_ptr<Client> c) {
|
||||
@@ -154,10 +166,22 @@ void Lobby::remove_client(shared_ptr<Client> c) {
|
||||
|
||||
this->reassign_leader_on_client_departure(c->lobby_client_id);
|
||||
|
||||
// If the lobby ios recording a battle record, add the player leave event
|
||||
// If the lobby is recording a battle record, add the player leave event
|
||||
if (this->battle_record) {
|
||||
this->battle_record->delete_player(c->lobby_client_id);
|
||||
}
|
||||
|
||||
// If the lobby is Episode 3, update the appropriate spectator counts
|
||||
if (this->is_game() && (this->flags & Lobby::Flag::EPISODE_3_ONLY)) {
|
||||
if (this->flags & Lobby::Flag::IS_SPECTATOR_TEAM) {
|
||||
auto watched_l = this->watched_lobby.lock();
|
||||
if (watched_l) {
|
||||
send_ep3_update_spectator_count(watched_l);
|
||||
}
|
||||
} else {
|
||||
send_ep3_update_spectator_count(this->shared_from_this());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Lobby::move_client_to_lobby(shared_ptr<Lobby> dest_lobby,
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
#include "Episode3/BattleRecord.hh"
|
||||
#include "Episode3/Server.hh"
|
||||
|
||||
struct Lobby {
|
||||
struct Lobby : public std::enable_shared_from_this<Lobby> {
|
||||
enum Flag {
|
||||
GAME = 0x00000001,
|
||||
EPISODE_3_ONLY = 0x00000002,
|
||||
|
||||
@@ -2284,6 +2284,25 @@ void send_ep3_tournament_match_result(
|
||||
// the player 1000000 and never charge for anything.
|
||||
cmd.meseta_amount = 100;
|
||||
cmd.meseta_reward_text = "You got %s meseta!";
|
||||
if (!(tourn->get_data_index()->behavior_flags & Episode3::BehaviorFlag::DISABLE_MASKING)) {
|
||||
uint8_t mask_key = (random_object<uint32_t>() % 0xFF) + 1;
|
||||
set_mask_for_ep3_game_command(&cmd, sizeof(cmd), mask_key);
|
||||
}
|
||||
send_command_t(l, 0xC9, 0x00, cmd);
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -339,6 +339,8 @@ void send_ep3_tournament_details(
|
||||
void send_ep3_game_details(
|
||||
std::shared_ptr<Client> c, std::shared_ptr<Lobby> l);
|
||||
|
||||
void send_ep3_update_spectator_count(std::shared_ptr<Lobby> l);
|
||||
|
||||
// Pass mask_key = 0 to unmask the command
|
||||
void set_mask_for_ep3_game_command(void* vdata, size_t size, uint8_t mask_key);
|
||||
|
||||
|
||||
@@ -2805,6 +2805,25 @@ I 13136 2022-11-27 21:06:44 - [Lobby/15] Created lobby
|
||||
[PlayerInventory] 3 (00010003): 030000 (Monomate x4)
|
||||
[PlayerInventory] 4 (00010004): 030100 (Monofluid x4)
|
||||
I 13136 2022-11-27 21:06:44 - [Commands] Sending to C-6 (Tali) (version=GC command=64 flag=01)
|
||||
0000 | C9 00 14 01 B4 44 00 00 52 00 00 00 00 00 00 00 | D R
|
||||
0010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0020 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0030 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0040 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0050 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0060 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0070 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0080 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0090 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
00A0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
00B0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
00C0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
00D0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
00E0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
00F0 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0100 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0110 | 00 00 00 00 |
|
||||
I 13136 2022-11-27 21:06:44 - [Commands] Sending to C-6 (Tali) (version=GC command=64 flag=01)
|
||||
0000 | 64 01 84 11 00 00 00 00 00 00 00 00 00 00 00 00 | d
|
||||
0010 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
0020 | 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |
|
||||
|
||||
Reference in New Issue
Block a user