From b56d077892f73d1ff4d1626a20e0717a541ca2a5 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Mon, 3 Jun 2024 21:50:12 -0500 Subject: [PATCH 1/6] feat: spectate command --- dGame/dGameMessages/GameMessages.cpp | 14 ++++++++++++++ dGame/dGameMessages/GameMessages.h | 6 ++++++ dGame/dUtilities/SlashCommandHandler.cpp | 9 +++++++++ .../SlashCommands/GMGreaterThanZeroCommands.cpp | 8 ++++++++ .../SlashCommands/GMGreaterThanZeroCommands.h | 1 + 5 files changed, 38 insertions(+) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index a97407d8..c6a4cf3d 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -6212,3 +6212,17 @@ void GameMessages::SendSlashCommandFeedbackText(Entity* entity, std::u16string t auto sysAddr = entity->GetSystemAddress(); SEND_PACKET; } + +void GameMessages::SendForceCameraTargetCycle(Entity* entity, bool bForceCycling, eCameraTargetCyclingMode cyclingMode, LWOOBJID optionalTargetID) { + CBITSTREAM; + CMSGHEADER; + + bitStream.Write(entity->GetObjectID()); + bitStream.Write(eGameMessageType::FORCE_CAMERA_TARGET_CYCLE); + bitStream.Write(bForceCycling); + bitStream.Write(cyclingMode); + bitStream.Write(optionalTargetID); + + auto sysAddr = entity->GetSystemAddress(); + SEND_PACKET; +} diff --git a/dGame/dGameMessages/GameMessages.h b/dGame/dGameMessages/GameMessages.h index b842710e..21bdfb41 100644 --- a/dGame/dGameMessages/GameMessages.h +++ b/dGame/dGameMessages/GameMessages.h @@ -40,6 +40,11 @@ enum class eQuickBuildState : uint32_t; enum class BehaviorSlot : int32_t; enum class eVendorTransactionResult : uint32_t; +enum class eCameraTargetCyclingMode : int32_t { + ALLOW_CYCLE_TEAMMATES, + DISALLOW_CYCLING +}; + namespace GameMessages { class PropertyDataMessage; void SendFireEventClientSide(const LWOOBJID& objectID, const SystemAddress& sysAddr, std::u16string args, const LWOOBJID& object, int64_t param1, int param2, const LWOOBJID& sender); @@ -666,6 +671,7 @@ namespace GameMessages { void HandleCancelDonationOnPlayer(RakNet::BitStream& inStream, Entity* entity); void SendSlashCommandFeedbackText(Entity* entity, std::u16string text); + void SendForceCameraTargetCycle(Entity* entity, bool bForceCycling, eCameraTargetCyclingMode cyclingMode, LWOOBJID optionalTargetID); }; #endif // GAMEMESSAGES_H diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 428ccbcb..20f2634a 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -929,6 +929,15 @@ void SlashCommandHandler::Startup() { }; RegisterCommand(FindPlayerCommand); + Command SpectateCommand{ + .help = "Spectate a player", + .info = "Specify a player name to spectate. They must be in the same world as you", + .aliases = { "spectate", "follow" }, + .handle = GMGreaterThanZeroCommands::Spectate, + .requiredLevel = eGameMasterLevel::JUNIOR_MODERATOR + }; + RegisterCommand(SpectateCommand); + // Register GM Zero Commands Command HelpCommand{ diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp index ea33aa03..e2802d62 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp @@ -322,4 +322,12 @@ namespace GMGreaterThanZeroCommands { request.Serialize(bitStream); Game::chatServer->Send(&bitStream, SYSTEM_PRIORITY, RELIABLE, 0, Game::chatSysAddr, false); } + + void Spectate(Entity* entity, const SystemAddress& sysAddr, const std::string args) { + if (args.length() <= 0) GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); + auto player = PlayerManager::GetPlayer(args); + if (!player) GameMessages::SendSlashCommandFeedbackText(entity, u"Player not found"); + GameMessages::SendSlashCommandFeedbackText(entity, u"Spectating Player"); + GameMessages::SendForceCameraTargetCycle(entity, false, eCameraTargetCyclingMode::DISALLOW_CYCLING, player->GetObjectID()); + } } diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.h b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.h index 7cb3d8d7..c278fc0a 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.h +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.h @@ -15,6 +15,7 @@ namespace GMGreaterThanZeroCommands { void Title(Entity* entity, const SystemAddress& sysAddr, const std::string args); void ShowAll(Entity* entity, const SystemAddress& sysAddr, const std::string args); void FindPlayer(Entity* entity, const SystemAddress& sysAddr, const std::string args); + void Spectate(Entity* entity, const SystemAddress& sysAddr, const std::string args); } #endif //!GMGREATERTHANZEROCOMMANDS_H From 2ef45bd7ee8bf466c52a90e286370f5221bc59e0 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Mon, 3 Jun 2024 22:28:37 -0500 Subject: [PATCH 2/6] use empty --- dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp index e2802d62..e71c0058 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp @@ -324,7 +324,7 @@ namespace GMGreaterThanZeroCommands { } void Spectate(Entity* entity, const SystemAddress& sysAddr, const std::string args) { - if (args.length() <= 0) GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); + if (args.empty()) GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); auto player = PlayerManager::GetPlayer(args); if (!player) GameMessages::SendSlashCommandFeedbackText(entity, u"Player not found"); GameMessages::SendSlashCommandFeedbackText(entity, u"Spectating Player"); From 1a14c29c39ff8e00f999cfe9ee5fd1ea73d4bcdf Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Mon, 3 Jun 2024 22:29:21 -0500 Subject: [PATCH 3/6] add returns, lol --- .../SlashCommands/GMGreaterThanZeroCommands.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp index e71c0058..c1cb6b4b 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp @@ -324,9 +324,16 @@ namespace GMGreaterThanZeroCommands { } void Spectate(Entity* entity, const SystemAddress& sysAddr, const std::string args) { - if (args.empty()) GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); + if (args.empty()) { + GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); + return; + } + auto player = PlayerManager::GetPlayer(args); - if (!player) GameMessages::SendSlashCommandFeedbackText(entity, u"Player not found"); + if (!player) { + GameMessages::SendSlashCommandFeedbackText(entity, u"Player not found"); + return; + } GameMessages::SendSlashCommandFeedbackText(entity, u"Spectating Player"); GameMessages::SendForceCameraTargetCycle(entity, false, eCameraTargetCyclingMode::DISALLOW_CYCLING, player->GetObjectID()); } From 9d5d2a68eedc9172455370a3af8367fd4b949691 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Mon, 3 Jun 2024 22:30:57 -0500 Subject: [PATCH 4/6] fix gm serialization --- dGame/dGameMessages/GameMessages.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dGame/dGameMessages/GameMessages.cpp b/dGame/dGameMessages/GameMessages.cpp index c6a4cf3d..a80bc1aa 100644 --- a/dGame/dGameMessages/GameMessages.cpp +++ b/dGame/dGameMessages/GameMessages.cpp @@ -6220,7 +6220,8 @@ void GameMessages::SendForceCameraTargetCycle(Entity* entity, bool bForceCycling bitStream.Write(entity->GetObjectID()); bitStream.Write(eGameMessageType::FORCE_CAMERA_TARGET_CYCLE); bitStream.Write(bForceCycling); - bitStream.Write(cyclingMode); + bitStream.Write(cyclingMode != eCameraTargetCyclingMode::ALLOW_CYCLE_TEAMMATES); + if (cyclingMode != eCameraTargetCyclingMode::ALLOW_CYCLE_TEAMMATES) bitStream.Write(cyclingMode); bitStream.Write(optionalTargetID); auto sysAddr = entity->GetSystemAddress(); From 3f22bf5cc04e914273481ea51a0f82a6d79d9aa1 Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Mon, 3 Jun 2024 22:44:54 -0500 Subject: [PATCH 5/6] Add an easy way to stop spectating --- dGame/dUtilities/SlashCommandHandler.cpp | 2 +- dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/dGame/dUtilities/SlashCommandHandler.cpp b/dGame/dUtilities/SlashCommandHandler.cpp index 20f2634a..477044b1 100644 --- a/dGame/dUtilities/SlashCommandHandler.cpp +++ b/dGame/dUtilities/SlashCommandHandler.cpp @@ -931,7 +931,7 @@ void SlashCommandHandler::Startup() { Command SpectateCommand{ .help = "Spectate a player", - .info = "Specify a player name to spectate. They must be in the same world as you", + .info = "Specify a player name to spectate. They must be in the same world as you. Leave blank to stop spectating", .aliases = { "spectate", "follow" }, .handle = GMGreaterThanZeroCommands::Spectate, .requiredLevel = eGameMasterLevel::JUNIOR_MODERATOR diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp index c1cb6b4b..19a40983 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp @@ -325,6 +325,7 @@ namespace GMGreaterThanZeroCommands { void Spectate(Entity* entity, const SystemAddress& sysAddr, const std::string args) { if (args.empty()) { + GameMessages::SendForceCameraTargetCycle(entity, false, eCameraTargetCyclingMode::DISALLOW_CYCLING, entity->GetObjectID()); GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); return; } From ff38503597cf2c50e75ae60cd4fa4a7f7787a88d Mon Sep 17 00:00:00 2001 From: Aaron Kimbre Date: Mon, 3 Jun 2024 22:51:46 -0500 Subject: [PATCH 6/6] no feedback if empty --- dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp index 19a40983..b9eaf7bf 100644 --- a/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp +++ b/dGame/dUtilities/SlashCommands/GMGreaterThanZeroCommands.cpp @@ -326,7 +326,6 @@ namespace GMGreaterThanZeroCommands { void Spectate(Entity* entity, const SystemAddress& sysAddr, const std::string args) { if (args.empty()) { GameMessages::SendForceCameraTargetCycle(entity, false, eCameraTargetCyclingMode::DISALLOW_CYCLING, entity->GetObjectID()); - GameMessages::SendSlashCommandFeedbackText(entity, u"No player Given"); return; }