From f8e65ac3cd0e524740db6a6287c9cf90da15bfe8 Mon Sep 17 00:00:00 2001 From: Skjalf <47818697+Nyeriah@users.noreply.github.com> Date: Tue, 11 Jan 2022 13:27:54 -0300 Subject: [PATCH] feat: Implement optional transmogs (#62) * feat: Implement optional transmogs * logic * Enable disabling transmog * Update transmog.conf.dist * Hide the npc if transmog is off --- conf/transmog.conf.dist | 7 +++ data/sql/db-world/trasm_world_texts.sql | 9 +++- src/Transmogrification.cpp | 7 +++ src/Transmogrification.h | 11 +++++ src/cs_transmog.cpp | 64 +++++++++++++++++++++++++ src/transmog_loader.cpp | 2 + src/transmog_scripts.cpp | 44 +++++++++++++++++ 7 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 src/cs_transmog.cpp diff --git a/conf/transmog.conf.dist b/conf/transmog.conf.dist index 5f3cfbc..08fbdaf 100644 --- a/conf/transmog.conf.dist +++ b/conf/transmog.conf.dist @@ -7,6 +7,11 @@ # # SETTINGS # +# Transmogrification.Enable +# Description: Enables/Disables transmog. +# Players won't be able to see any transmogrified item while disabled, however, database data remains intact. +# Default: 1 +# # Transmogrification.EnableTransmogInfo # Description: Enables / Disables the info button for transmogrification # Default: 1 @@ -25,6 +30,8 @@ # Example: "25 35674 5623" # Default: "" +Transmogrification.Enable = 1 + Transmogrification.EnableTransmogInfo = 1 Transmogrification.TransmogNpcText = 601083 diff --git a/data/sql/db-world/trasm_world_texts.sql b/data/sql/db-world/trasm_world_texts.sql index b32fd11..8de1f17 100644 --- a/data/sql/db-world/trasm_world_texts.sql +++ b/data/sql/db-world/trasm_world_texts.sql @@ -5,7 +5,7 @@ INSERT INTO `npc_text` (`ID`, `text0_0`) VALUES (@TEXT_ID+1, 'You can save your own transmogrification sets.\r\n\r\nTo save, first you must transmogrify your equipped items.\r\nThen when you go to the set management menu and go to save set menu,\r\nall items you have transmogrified are displayed so you see what you are saving.\r\nIf you think the set is fine, you can click to save the set and name it as you wish.\r\n\r\nTo use a set you can click the saved set in the set management menu and then select use set.\r\nIf the set has a transmogrification for an item that is already transmogrified, the old transmogrification is lost.\r\nNote that same transmogrification restrictions apply when trying to use a set as in normal transmogrification.\r\n\r\nTo delete a set you can go to the set\'s menu and select delete set.'); SET @STRING_ENTRY := 11100; -DELETE FROM `acore_string` WHERE `entry` IN (@STRING_ENTRY+0,@STRING_ENTRY+1,@STRING_ENTRY+2,@STRING_ENTRY+3,@STRING_ENTRY+4,@STRING_ENTRY+5,@STRING_ENTRY+6,@STRING_ENTRY+7,@STRING_ENTRY+8,@STRING_ENTRY+9,@STRING_ENTRY+10); +DELETE FROM `acore_string` WHERE `entry` IN (@STRING_ENTRY+0,@STRING_ENTRY+1,@STRING_ENTRY+2,@STRING_ENTRY+3,@STRING_ENTRY+4,@STRING_ENTRY+5,@STRING_ENTRY+6,@STRING_ENTRY+7,@STRING_ENTRY+8,@STRING_ENTRY+9,@STRING_ENTRY+10, @STRING_ENTRY+11, @STRING_ENTRY+12); INSERT INTO `acore_string` (`entry`, `content_default`) VALUES (@STRING_ENTRY+0, 'Item successfully transmogrified.'), (@STRING_ENTRY+1, 'Equipment slot is empty.'), @@ -17,5 +17,10 @@ INSERT INTO `acore_string` (`entry`, `content_default`) VALUES (@STRING_ENTRY+7, 'You don''t have enough tokens.'), (@STRING_ENTRY+8, 'All your transmogrifications were removed.'), (@STRING_ENTRY+9, 'No transmogrification found.'), -(@STRING_ENTRY+10, 'Invalid name inserted.'); +(@STRING_ENTRY+10, 'Invalid name inserted.'), +(@STRING_ENTRY+11, 'Showing transmogrifieded items, relog to update the current area.'), +(@STRING_ENTRY+12, 'Hiding transmogrifieded items, relog to update the current area.'); +DELETE FROM `command` WHERE `name` IN ('transmog'); +INSERT INTO `command` (`name`, `security`, `help`) VALUES +('transmog', 0, 'Syntax: .transmog \nAllows seeing transmogrified items and the transmogrifier NPC.'); diff --git a/src/Transmogrification.cpp b/src/Transmogrification.cpp index 8ee6c9b..dac9349 100644 --- a/src/Transmogrification.cpp +++ b/src/Transmogrification.cpp @@ -665,6 +665,8 @@ void Transmogrification::LoadConfig(bool reload) IgnoreReqEvent = sConfigMgr->GetOption("Transmogrification.IgnoreReqEvent", false); IgnoreReqStats = sConfigMgr->GetOption("Transmogrification.IgnoreReqStats", false); + IsTransmogEnabled = sConfigMgr->GetOption("Transmogrification.Enable", true); + if (!sObjectMgr->GetItemTemplate(TokenEntry)) { //sLog->outError(LOG_FILTER_SERVER_LOADING, "Transmogrification.TokenEntry (%u) does not exist. Using default.", TokenEntry); @@ -732,3 +734,8 @@ bool Transmogrification::GetAllowMixedWeaponTypes() const { return AllowMixedWeaponTypes; }; + +bool Transmogrification::IsEnabled() const +{ + return IsTransmogEnabled; +}; diff --git a/src/Transmogrification.h b/src/Transmogrification.h index df456c7..1af3866 100644 --- a/src/Transmogrification.h +++ b/src/Transmogrification.h @@ -17,6 +17,11 @@ class Player; class WorldSession; struct ItemTemplate; +enum TransmogSettings +{ + SETTING_HIDE_TRANSMOG = 0, +}; + enum TransmogAcoreStrings // Language.h might have same entries, appears when executing SQL, change if needed { LANG_ERR_TRANSMOG_OK = 11100, // change this @@ -34,6 +39,8 @@ enum TransmogAcoreStrings // Language.h might have same entries, appears when ex #ifdef PRESETS LANG_PRESET_ERR_INVALID_NAME, #endif + LANG_CMD_TRANSMOG_SHOW = 11111, + LANG_CMD_TRANSMOG_HIDE = 11112, }; class Transmogrification @@ -111,6 +118,8 @@ public: bool IgnoreReqEvent; bool IgnoreReqStats; + bool IsTransmogEnabled; + bool IsAllowed(uint32 entry) const; bool IsNotAllowed(uint32 entry) const; bool IsAllowedQuality(uint32 quality) const; @@ -151,6 +160,8 @@ public: uint32 GetTransmogNpcText() const; bool GetEnableSetInfo() const; uint32 GetSetNpcText() const; + + [[nodiscard]] bool IsEnabled() const; }; #define sTransmogrification Transmogrification::instance() diff --git a/src/cs_transmog.cpp b/src/cs_transmog.cpp new file mode 100644 index 0000000..3c5e3e1 --- /dev/null +++ b/src/cs_transmog.cpp @@ -0,0 +1,64 @@ +/* + * This file is part of the AzerothCore Project. See AUTHORS file for Copyright information + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Affero General Public License as published by the + * Free Software Foundation; either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +#include "Chat.h" +#include "ObjectMgr.h" +#include "Player.h" +#include "ScriptMgr.h" +#include "Transmogrification.h" + +using namespace Acore::ChatCommands; + +class transmog_commandscript : public CommandScript +{ +public: + transmog_commandscript() : CommandScript("transmog_commandscript") { } + + ChatCommandTable GetCommands() const override + { + static ChatCommandTable commandTable = + { + { "transmog", HandleDisableTransMogVisual, SEC_PLAYER, Console::No }, + }; + + return commandTable; + } + + static bool HandleDisableTransMogVisual(ChatHandler* handler, bool hide) + { + Player* player = handler->GetPlayer(); + + if (hide) + { + player->UpdatePlayerSetting("mod-transmog", SETTING_HIDE_TRANSMOG, 0); + handler->SendSysMessage(LANG_CMD_TRANSMOG_SHOW); + } + else + { + player->UpdatePlayerSetting("mod-transmog", SETTING_HIDE_TRANSMOG, 1); + handler->SendSysMessage(LANG_CMD_TRANSMOG_HIDE); + } + + player->UpdateObjectVisibility(); + return true; + } +}; + +void AddSC_transmog_commandscript() +{ + new transmog_commandscript(); +} diff --git a/src/transmog_loader.cpp b/src/transmog_loader.cpp index f7be53c..1ec1e5d 100644 --- a/src/transmog_loader.cpp +++ b/src/transmog_loader.cpp @@ -5,9 +5,11 @@ // From SC void AddSC_Transmog(); +void AddSC_transmog_commandscript(); // Add all void Addmod_transmogScripts() { AddSC_Transmog(); + AddSC_transmog_commandscript(); } diff --git a/src/transmog_scripts.cpp b/src/transmog_scripts.cpp index 39a52e1..3369838 100644 --- a/src/transmog_scripts.cpp +++ b/src/transmog_scripts.cpp @@ -21,6 +21,8 @@ Cant transmogrify rediculus items // Foereaper: would be fun to stab people with */ #include "Transmogrification.h" +#include "ScriptedCreature.h" + #define sT sTransmogrification #define GTS session->GetAcoreString // dropped translation support, no one using? @@ -29,6 +31,22 @@ class npc_transmogrifier : public CreatureScript public: npc_transmogrifier() : CreatureScript("npc_transmogrifier") { } + struct npc_transmogrifierAI : ScriptedAI + { + npc_transmogrifierAI(Creature* creature) : ScriptedAI(creature) { }; + + bool CanBeSeen(Player const* player) override + { + Player* target = ObjectAccessor::FindConnectedPlayer(player->GetGUID()); + return !sTransmogrification->IsEnabled() && !target->GetPlayerSetting("mod-transmog", SETTING_HIDE_TRANSMOG).value; + } + }; + + CreatureAI* GetAI(Creature* creature) const override + { + return new npc_transmogrifierAI(creature); + } + bool OnGossipHello(Player* player, Creature* creature) { WorldSession* session = player->GetSession(); @@ -373,7 +391,9 @@ public: return; if (uint32 entry = sT->GetFakeEntry(item->GetGUID())) + { player->SetUInt32Value(PLAYER_VISIBLE_ITEM_1_ENTRYID + (slot * 2), entry); + } } void OnAfterMoveItemFromInventory(Player* /*player*/, Item* it, uint8 /*bag*/, uint8 /*slot*/, bool /*update*/) @@ -472,9 +492,33 @@ public: } }; +class unit_transmog_script : public UnitScript +{ +public: + unit_transmog_script() : UnitScript("unit_transmog_script") { } + + bool OnBuildValuesUpdate(Unit const* unit, uint8 /*updateType*/, ByteBuffer& fieldBuffer, Player* target, uint16 index) override + { + if (unit->IsPlayer() && index >= PLAYER_VISIBLE_ITEM_1_ENTRYID && index <= PLAYER_VISIBLE_ITEM_19_ENTRYID && (index & 1)) + { + if (Item* item = unit->ToPlayer()->GetItemByPos(INVENTORY_SLOT_BAG_0, ((index - PLAYER_VISIBLE_ITEM_1_ENTRYID) / 2U))) + { + if (!sTransmogrification->IsEnabled() || target->GetPlayerSetting("mod-transmog", SETTING_HIDE_TRANSMOG).value) + { + fieldBuffer << item->GetEntry(); + return true; + } + } + } + + return false; + } +}; + void AddSC_Transmog() { new global_transmog_script(); + new unit_transmog_script(); new npc_transmogrifier(); new PS_Transmogrification(); new WS_Transmogrification();