From 641fbfc841db797f4f22a743c093b782ced1f129 Mon Sep 17 00:00:00 2001 From: Shauren Date: Sun, 19 Apr 2026 11:53:30 +0200 Subject: [PATCH] Core/PacketIO: Add missing SMSG_DISPLAY_PLAYER_CHOICE bit --- .../{2026_04_19_01_world.sql‎‎ => 2026_04_19_01_world.sql} | 0 .../{2026_04_19_02_world.sql‎ => 2026_04_19_02_world.sql} | 0 sql/updates/world/master/2026_04_19_03_world.sql | 1 + src/server/game/Entities/Player/Player.cpp | 1 + src/server/game/Globals/ObjectMgr.cpp | 5 +++-- src/server/game/Globals/PlayerChoice.h | 1 + src/server/game/Handlers/TraitHandler.cpp | 2 +- src/server/game/Server/Packets/PacketUtilities.h | 7 +++---- src/server/game/Server/Packets/QuestPackets.cpp | 1 + src/server/game/Server/Packets/QuestPackets.h | 1 + 10 files changed, 12 insertions(+), 7 deletions(-) rename sql/updates/world/master/{2026_04_19_01_world.sql‎‎ => 2026_04_19_01_world.sql} (100%) rename sql/updates/world/master/{2026_04_19_02_world.sql‎ => 2026_04_19_02_world.sql} (100%) create mode 100644 sql/updates/world/master/2026_04_19_03_world.sql diff --git a/sql/updates/world/master/2026_04_19_01_world.sql‎‎ b/sql/updates/world/master/2026_04_19_01_world.sql similarity index 100% rename from sql/updates/world/master/2026_04_19_01_world.sql‎‎ rename to sql/updates/world/master/2026_04_19_01_world.sql diff --git a/sql/updates/world/master/2026_04_19_02_world.sql‎ b/sql/updates/world/master/2026_04_19_02_world.sql similarity index 100% rename from sql/updates/world/master/2026_04_19_02_world.sql‎ rename to sql/updates/world/master/2026_04_19_02_world.sql diff --git a/sql/updates/world/master/2026_04_19_03_world.sql b/sql/updates/world/master/2026_04_19_03_world.sql new file mode 100644 index 0000000000..45fd6ec0db --- /dev/null +++ b/sql/updates/world/master/2026_04_19_03_world.sql @@ -0,0 +1 @@ +ALTER TABLE `playerchoice` ADD `RequiresSelection` tinyint(1) NOT NULL DEFAULT 0 AFTER `ForceDontShowChoicesAsList`; diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index e837c7e71e..6700d3ea56 100644 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -30179,6 +30179,7 @@ void Player::SendPlayerChoice(ObjectGuid sender, int32 choiceId) displayPlayerChoice.KeepOpenAfterChoice = playerChoice->KeepOpenAfterChoice; displayPlayerChoice.ShowChoicesAsList = playerChoice->ShowChoicesAsList; displayPlayerChoice.ForceDontShowChoicesAsList = playerChoice->ForceDontShowChoicesAsList; + displayPlayerChoice.RequiresSelection = playerChoice->RequiresSelection; for (std::size_t i = 0; i < playerChoice->Responses.size() && (!playerChoice->MaxResponses || displayPlayerChoice.Responses.size() < *playerChoice->MaxResponses); ++i) { diff --git a/src/server/game/Globals/ObjectMgr.cpp b/src/server/game/Globals/ObjectMgr.cpp index 38059da292..df747a0ed6 100644 --- a/src/server/game/Globals/ObjectMgr.cpp +++ b/src/server/game/Globals/ObjectMgr.cpp @@ -11045,7 +11045,7 @@ void ObjectMgr::LoadPlayerChoices() _playerChoices.clear(); QueryResult choices = WorldDatabase.Query("SELECT ChoiceId, UiTextureKitId, SoundKitId, CloseSoundKitId, Duration, Question, PendingChoiceText, " - "InfiniteRange, HideWarboardHeader, KeepOpenAfterChoice, ShowChoicesAsList, ForceDontShowChoicesAsList, MaxResponses, ScriptName FROM playerchoice"); + "InfiniteRange, HideWarboardHeader, KeepOpenAfterChoice, ShowChoicesAsList, ForceDontShowChoicesAsList, RequiresSelection, MaxResponses, ScriptName FROM playerchoice"); if (!choices) { TC_LOG_INFO("server.loading", ">> Loaded 0 player choices. DB table `playerchoice` is empty."); @@ -11064,7 +11064,7 @@ void ObjectMgr::LoadPlayerChoices() do { DEFINE_FIELD_ACCESSOR_CACHE_ANONYMOUS(ResultSet, (ChoiceId)(UiTextureKitId)(SoundKitId)(CloseSoundKitId)(Duration)(Question)(PendingChoiceText) - (InfiniteRange)(HideWarboardHeader)(KeepOpenAfterChoice)(ShowChoicesAsList)(ForceDontShowChoicesAsList)(MaxResponses)(ScriptName)) fields { *choices }; + (InfiniteRange)(HideWarboardHeader)(KeepOpenAfterChoice)(ShowChoicesAsList)(ForceDontShowChoicesAsList)(RequiresSelection)(MaxResponses)(ScriptName)) fields { *choices }; int32 choiceId = fields.ChoiceId().GetInt32(); @@ -11082,6 +11082,7 @@ void ObjectMgr::LoadPlayerChoices() choice.KeepOpenAfterChoice = fields.KeepOpenAfterChoice().GetBool(); choice.ShowChoicesAsList = fields.ShowChoicesAsList().GetBool(); choice.ForceDontShowChoicesAsList = fields.ForceDontShowChoicesAsList().GetBool(); + choice.RequiresSelection = fields.RequiresSelection().GetBool(); choice.MaxResponses = fields.MaxResponses().GetUInt32OrNull(); choice.ScriptId = GetScriptId(fields.ScriptName().GetStringView()); diff --git a/src/server/game/Globals/PlayerChoice.h b/src/server/game/Globals/PlayerChoice.h index 17504586b3..942c32b59c 100644 --- a/src/server/game/Globals/PlayerChoice.h +++ b/src/server/game/Globals/PlayerChoice.h @@ -119,6 +119,7 @@ struct PlayerChoice bool KeepOpenAfterChoice = false; bool ShowChoicesAsList = false; bool ForceDontShowChoicesAsList = false; + bool RequiresSelection = false; Optional MaxResponses; diff --git a/src/server/game/Handlers/TraitHandler.cpp b/src/server/game/Handlers/TraitHandler.cpp index f26d04c75b..68cae5ccd8 100644 --- a/src/server/game/Handlers/TraitHandler.cpp +++ b/src/server/game/Handlers/TraitHandler.cpp @@ -201,7 +201,7 @@ void WorldSession::HandleClassTalentsRequestNewConfig(WorldPackets::Traits::Clas void WorldSession::HandleClassTalentsRenameConfig(WorldPackets::Traits::ClassTalentsRenameConfig& classTalentsRenameConfig) { - _player->RenameTraitConfig(classTalentsRenameConfig.ConfigID, classTalentsRenameConfig.Name.Move()); + _player->RenameTraitConfig(classTalentsRenameConfig.ConfigID, std::move(classTalentsRenameConfig.Name)); } void WorldSession::HandleClassTalentsDeleteConfig(WorldPackets::Traits::ClassTalentsDeleteConfig const& classTalentsDeleteConfig) diff --git a/src/server/game/Server/Packets/PacketUtilities.h b/src/server/game/Server/Packets/PacketUtilities.h index 97e0870264..235adfb38e 100644 --- a/src/server/game/Server/Packets/PacketUtilities.h +++ b/src/server/game/Server/Packets/PacketUtilities.h @@ -84,10 +84,9 @@ namespace WorldPackets char const* c_str() const { return _storage.c_str(); } operator std::string_view() const { return _storage; } - operator std::string&() { return _storage; } - operator std::string const&() const { return _storage; } - - std::string&& Move() { return std::move(_storage); } + operator std::string&() & { return _storage; } + operator std::string const&() const & { return _storage; } + operator std::string&&() && { return std::move(_storage); } friend ByteBuffer& operator>>(ByteBuffer& data, String& value) { diff --git a/src/server/game/Server/Packets/QuestPackets.cpp b/src/server/game/Server/Packets/QuestPackets.cpp index ed9eb27807..8f1d5d5bb4 100644 --- a/src/server/game/Server/Packets/QuestPackets.cpp +++ b/src/server/game/Server/Packets/QuestPackets.cpp @@ -852,6 +852,7 @@ WorldPacket const* DisplayPlayerChoice::Write() _worldPacket << Bits<1>(KeepOpenAfterChoice); _worldPacket << Bits<1>(ShowChoicesAsList); _worldPacket << Bits<1>(ForceDontShowChoicesAsList); + _worldPacket << Bits<1>(RequiresSelection); _worldPacket.FlushBits(); for (PlayerChoiceResponse const& response : Responses) diff --git a/src/server/game/Server/Packets/QuestPackets.h b/src/server/game/Server/Packets/QuestPackets.h index 08ec1c6af9..fe3d79ab8a 100644 --- a/src/server/game/Server/Packets/QuestPackets.h +++ b/src/server/game/Server/Packets/QuestPackets.h @@ -801,6 +801,7 @@ namespace WorldPackets bool KeepOpenAfterChoice = false; bool ShowChoicesAsList = false; bool ForceDontShowChoicesAsList = false; + bool RequiresSelection = false; }; class ChoiceResponse final : public ClientPacket