From 48b936227aef680ba3378eadabb0904492ec5bca Mon Sep 17 00:00:00 2001 From: Greg Wilkinson Date: Mon, 4 Apr 2022 02:49:40 -0500 Subject: [PATCH] Fix build, sql and crashes - NPC's and GO's load on purchase (#30) * Add files via upload * Add files via upload * fix %u in queries * fix name * Add files via upload Update from local work * Delete loader.h * Update Creatures.sql Missed two NPC's Added Innkeeper and DK Trainer with edited columns to update old sql * Delete CMakeLists.txt * Cleanup Code and remove broken work * Update README.md * FInal Cleanup Updated sql queries to add NPC's and creatures. Reworked layout for current AC databases Fixed code to solve build errors fixed code to solve core crash on object spawn (StarterPortal etc) With core updates creatures now load scripts on manual summon - Thanks! Added new chat commands for teleport ".gh tele" and NPC Assistant ".gh butler" GameObjects now spawn on purchase - no core restart required Issues still remaining: NPC assistant is present at GH creation but is gone after core restart. Can be summoned with chat command and he stays in place after chat command summon. * Updated to use unique NPCs and to make the ammo & repairs vendor consistent. * Updated all of the Portal ids and moved code check in SpawnObject to make it consistent with SpawnNPC. * Refactored to use existing 'map' variable. * Updated to include new shortened command. * Updated to match the return type. * Fixed usage of 'map' variable. * Fixed various typos and updated to be more consistent in messaging. * Fixed commented out calls. * Updated to create all new Portal objects. * Updated command shortcut message. * Updated NPC ids to be consistent with the new Portal ids. * Updated to fix vendor positioning. * Fixed SQL to include new NPC ids. * Updated to use existing NPC for Food & Drink Vendor. * Updated to reflect moved custom NPC. * Adjusted vendor positioning. * Rearranged various vendors. * Adjusted Tabard Vendor position. * Updated tailoring trainer. * Updated herbalism trainer. * Updated blacksmithing and alchemy trainers. * Updated engineering trainer. * Updated first aid trainer. * Updated cooking trainer. * Updated fishing trainer. * Updated mining trainer. * Updated enchanting trainer and added support for both factions. * Updated jewelcrafting and inscription trainers and added support for both factions. * Updated leatherworking trainer. * Updated skinner trainer. * Updated alchemy trainer to a master trainer. * Hide the Ammo & Repair Vendor since it's broken anyway. * Hide Spirit Healer since that's broken anyway. * Update Creatures.sql Mistakenly removed column names * Added Neutral Auctioneer. * Revert "Hide Spirit Healer since that's broken anyway." This reverts commit dee436787cf39cad055bbda36b2a9e874295aca1. * Updated Innkeeper position. * Updated Banker position. * Replaced curly braces. * Updated menus. * Added Poisons Vendor. * Update Creatures.sql Old Column Names Snuck back in. Fixed * Fixed Ammo & Repair Vendor. * Updated to use existing Death Knight Trainer. * Fixed SQL error. * Updated method to be more descriptive. * Updated to allow anyone to purchase by default but only allow Guild Master to sell. * Fixed command typo in README.md. * Removed the V2 designation. * Updated filenames to be consistent. * Changed assistant to butler to match the new command. * Updated to fix compile error. * Updated again to fix compile error. * Renamed configuration file to match the rest of the module. * Updated so that the sell guild house menu is displayed if the permission requirement is met instead of requiring guild master. * Code cleanup and added test code. * Tweaked test code. * Tweaked test code. * Removed test code. * Fixed sell guild house permission check. * Updated to fix deprecation warnings. * Added required using. * Removed parameters that were not used anyway. * Updated to fix parameters. * Cleaned up SQL queries. * Updated to include orientation for the Guild House maps, this fixes teleporting there and facing weird directions. * Updated portal locations. * Fixed starter portal locations. * Fixed portal locations. * Updated files to match new command. * Delete Creatures.sql * Update README.md * chore: add npcflag 1 by default * Update mod_guildhouse_butler.cpp * add overrides to fix warnings Co-authored-by: Bogir[rus] Co-authored-by: SoulSeekkor Co-authored-by: Helias --- CMakeLists.txt | 7 - README.md | 15 +- ..._v2.conf.dist => mod_guildhouse.conf.dist} | 16 +- sql/characters/guild_house.sql | 30 - sql/characters/guildhouse.sql | 12 + sql/world/Creatures.sql | 11 - sql/world/creatures_objects.sql | 41 + sql/world/guild_house_spawns.sql | 106 --- sql/world/guildhouse_spawns.sql | 68 ++ src/loader.cpp | 7 + src/loader.h | 2 - src/mod_guild_house_v2.cpp | 695 ----------------- src/mod_guildhouse.cpp | 738 ++++++++++++++++++ ...ouse_npc.cpp => mod_guildhouse_butler.cpp} | 323 ++++---- 14 files changed, 1069 insertions(+), 1002 deletions(-) delete mode 100644 CMakeLists.txt rename conf/{mod_guild_house_v2.conf.dist => mod_guildhouse.conf.dist} (87%) delete mode 100644 sql/characters/guild_house.sql create mode 100644 sql/characters/guildhouse.sql delete mode 100644 sql/world/Creatures.sql create mode 100644 sql/world/creatures_objects.sql delete mode 100644 sql/world/guild_house_spawns.sql create mode 100644 sql/world/guildhouse_spawns.sql create mode 100755 src/loader.cpp delete mode 100644 src/loader.h delete mode 100644 src/mod_guild_house_v2.cpp create mode 100644 src/mod_guildhouse.cpp rename src/{mod_guild_house_npc.cpp => mod_guildhouse_butler.cpp} (56%) diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index a7c41f0..0000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -AC_ADD_SCRIPT("${CMAKE_CURRENT_LIST_DIR}/src/mod_guild_house_v2.cpp") -AC_ADD_SCRIPT("${CMAKE_CURRENT_LIST_DIR}/src/mod_guild_house_npc.cpp") - -AC_ADD_SCRIPT_LOADER("GuildHouseV2" "${CMAKE_CURRENT_LIST_DIR}/src/loader.h") -AC_ADD_SCRIPT_LOADER("GuildHouseV2NPC" "${CMAKE_CURRENT_LIST_DIR}/src/loader.h") - -AC_ADD_CONFIG_FILE("${CMAKE_CURRENT_LIST_DIR}/conf/mod_guild_house_v2.conf.dist") \ No newline at end of file diff --git a/README.md b/README.md index d8c2bcc..b69363d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## Important notes -You have to use at least AzerothCore commit [8f5c628](https://github.com/azerothcore/azerothcore-wotlk/commit/8f5c628836f7446d8d876bee7f5bdff5a35aaa2f). +You have to use at least AzerothCore commit [77f1363](https://github.com/azerothcore/azerothcore-wotlk/commit/77f13636b75f9b25fc1290e297cd002e7df3c89b). ## Description @@ -26,19 +26,16 @@ All guilds will get their own phasing system and then the guild master can purch ## How to use ingame -1) After installation, as GM you will need to: `.npc add 70101` -> somewhere public and accessible by other players. -2) Players can purchase a guild house from the added NPC, then either teleport to the guildhouse via the NPC or chat: `.guildhouse tele` +1) After installation, as GM you will need to: `.npc add 500030` -> somewhere public and accessible by other players. +2) Players can purchase a guild house from the added NPC, then either teleport to the guildhouse via the NPC or chat: `.guildhouse tele` or `.gh tele` 3) Each new Guild House starts with a portal to either Orgrimmar or Stormwind, based on Team (ALLIANCE / HORDE), and the Guild House Assistant. 4) Speak with the Guild House Assistant to begin purchasing additions to your Guild House! - -## Requirements - -- AzerothCore v1.0.1+ +5) Players in guild with proper rank will be able to spawn the Assistant with chat commands `.guildhouse butler` or `.gh butler` ## Installation ``` -1) Place the module under the `modules` directory of your AzerothCore source. +1) Place the module under the `modules` directory of your AzerothCore source. 2) Import the SQL files manually to the right Database (auth, world or characters) 3) Re-run cmake and launch a clean build of AzerothCore. ``` @@ -52,5 +49,7 @@ If you need to change the module configuration, go to your server configuration * [Talamortis](https://github.com/talamortis) (Original author of the module) * [Rochet2](https://github.com/Rochet2/): Thanks for the help with the phasing situation & General support * [rbedfordpro](https://github.com/rbedfordpro) & [WiZZy](https://github.com/wizzymore) +* [Nelnamara - Porkserver](https://github.com/Porkserver) & [SoulSeekkor](https://github.com/SoulSeekkor) 2022 rework, crash fixes and new additions +* [Bogir](https://github.com/Bogir) For being amazing and forever helpful AzerothCore: [repository](https://github.com/azerothcore) - [website](http://azerothcore.org/) - [discord chat community](https://discord.gg/64FH6Y8) diff --git a/conf/mod_guild_house_v2.conf.dist b/conf/mod_guildhouse.conf.dist similarity index 87% rename from conf/mod_guild_house_v2.conf.dist rename to conf/mod_guildhouse.conf.dist index 189376c..314eca0 100644 --- a/conf/mod_guild_house_v2.conf.dist +++ b/conf/mod_guildhouse.conf.dist @@ -80,6 +80,19 @@ GuildHouseSpirit = 100000 # GuildHouseBuyRank # # Minimum GuildRank able to make purchases in guild house +# default = 4 (Initiate) +# GR_GUILDMASTER = 0 +# GR_OFFICER = 1 +# GR_VETERAN = 2 +# GR_MEMBER = 3 +# GR_INITIATE = 4 +# +GuildHouseBuyRank = 4 + + +# GuildHouseSellRank +# +# Minimum GuildRank able to sell the guild house # default = 0 (Guild Master) # GR_GUILDMASTER = 0 # GR_OFFICER = 1 @@ -87,5 +100,4 @@ GuildHouseSpirit = 100000 # GR_MEMBER = 3 # GR_INITIATE = 4 # -GuildHouseBuyRank = 0 - +GuildHouseSellRank = 0 \ No newline at end of file diff --git a/sql/characters/guild_house.sql b/sql/characters/guild_house.sql deleted file mode 100644 index 28afc9a..0000000 --- a/sql/characters/guild_house.sql +++ /dev/null @@ -1,30 +0,0 @@ --- -------------------------------------------------------- --- Host: 127.0.0.1 --- Server version: 5.6.28 - MySQL Community Server (GPL) --- Server OS: Win64 --- HeidiSQL Version: 9.4.0.5125 --- -------------------------------------------------------- - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET NAMES utf8 */; -/*!50503 SET NAMES utf8mb4 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; - --- Dumping structure for table acore_char.guild_house -CREATE TABLE IF NOT EXISTS `guild_house` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `guild` int(11) NOT NULL DEFAULT '0', - `phase` int(11) NOT NULL, - `map` int(11) NOT NULL DEFAULT '0', - `positionX` float NOT NULL DEFAULT '0', - `positionY` float NOT NULL DEFAULT '0', - `positionZ` float NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `guild` (`guild`) -) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8; - --- Data exporting was unselected. -/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; -/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/characters/guildhouse.sql b/sql/characters/guildhouse.sql new file mode 100644 index 0000000..c0059f9 --- /dev/null +++ b/sql/characters/guildhouse.sql @@ -0,0 +1,12 @@ +CREATE TABLE IF NOT EXISTS `guild_house` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `guild` int(11) NOT NULL DEFAULT '0', + `phase` int(11) NOT NULL, + `map` int(11) NOT NULL DEFAULT '0', + `positionX` float NOT NULL DEFAULT '0', + `positionY` float NOT NULL DEFAULT '0', + `positionZ` float NOT NULL DEFAULT '0', + `orientation` float NOT NULL DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `guild` (`guild`) +) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/sql/world/Creatures.sql b/sql/world/Creatures.sql deleted file mode 100644 index 43314e0..0000000 --- a/sql/world/Creatures.sql +++ /dev/null @@ -1,11 +0,0 @@ -REPLACE INTO `creature_template` VALUES (70101, 0, 0, 0, 0, 0, 25901, 0, 0, 0, 'Talamortis', 'Guild House Seller', '', 0, 35, 35, 0, 35, 1, 1, 1.14286, 1, 0, 49, 64, 0, 118, 1, 2000, 2000, 1, 33536, 2048, 0, 0, 0, 0, 0, 0, 33, 49, 11, 7, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 'GuildHouseSeller', 12340), -(18649, 0, 0, 0, 0, 0, 18234, 0, 0, 0, 'Innkeeper Monica', NULL, NULL, 0, 1, 2, 0, 35, 65537, 0.8, 0.28571, 1, 0, 2, 2, 0, 26, 4.6, 2000, 1900, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 1, 1, 100, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 3, 1, 1, 1, 1, 0, 70, 1, 0, 0, 2, 'npc_innkeeper', 12340), -(33251, 0, 0, 0, 0, 0, 28516, 0, 0, 0, 'Death Knight Trainer', '', '', 9691, 80, 80, 2, 35, 51, 1, 1.14286, 1, 1, 422, 586, 0, 642, 7.5, 2000, 2000, 1, 32768, 2048, 0, 0, 0, 0, 6, 0, 345, 509, 103, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 10, 1, 1, 0, 0, 1, 8388624, 0, 0, '', 12340), -(70102, 0, 0, 0, 0, 0, 25901, 0, 0, 0, 'Xrispins', 'Guild House Assistant', '', 0, 35, 35, 0, 35, 1, 1, 1.14286, 1, 0, 49, 64, 0, 118, 1, 2000, 2000, 1, 33536, 2048, 0, 0, 0, 0, 0, 0, 33, 49, 11, 7, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 'GuildHouseSpawner', 12340), -(70103, 0, 0, 0, 0, 0, 27211, 0, 0, 0, 'Essenbaum', 'Food & Water Vendor', '', 0, 80, 80, 0, 2007, 640, 1, 1.4286, 1, 0, 49, 64, 0, 118, 1, 2000, 2000, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 33, 49, 11, 7, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340), -(70104, 0, 0, 0, 0, 0, 26307, 0, 0, 0, 'Archie', 'Ammo & Repairs', '', 0, 80, 80, 0, 2007, 4480, 1, 1.4286, 1, 0, 49, 64, 0, 118, 1, 2000, 2000, 1, 33536, 2048, 0, 0, 0, 0, 0, 0, 33, 49, 11, 7, 4096, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340); - --- To revert the original NPCs (who are unused anyway), run the query below: --- REPLACE INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `scale`, `rank`, `mindmg`, `maxdmg`, `dmgschool`, `attackpower`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `minrangedmg`, `maxrangedmg`, `rangedattackpower`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `resistance1`, `resistance2`, `resistance3`, `resistance4`, `resistance5`, `resistance6`, `spell1`, `spell2`, `spell3`, `spell4`, `spell5`, `spell6`, `spell7`, `spell8`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `InhabitType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `spell_school_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES --- (18649, 0, 0, 0, 0, 0, 18234, 0, 0, 0, 'Innkeeper Monica', NULL, NULL, 0, 1, 2, 0, 35, 0, 0.8, 0.28571, 1, 0, 2, 2, 0, 26, 4.6, 2000, 1900, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 1, 1, 100, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 3, 1, 1, 1, 1, 0, 70, 1, 0, 0, 2, 'npc_innkeeper', 12340), --- (33251, 0, 0, 0, 0, 0, 28516, 0, 0, 0, 'Death Knight Trainer and Runeforge', '', '', 0, 80, 80, 0, 35, 0, 1, 1.14286, 1, 0, 2, 2, 0, 24, 1, 2000, 2000, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 1, 1, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', 0, 3, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, '', 12340); diff --git a/sql/world/creatures_objects.sql b/sql/world/creatures_objects.sql new file mode 100644 index 0000000..0bcceb6 --- /dev/null +++ b/sql/world/creatures_objects.sql @@ -0,0 +1,41 @@ +-- !!! NOTE: set these before running the queries in order to avoid conflicts !!! +SET @C_TEMPLATE = 500030; + +DELETE FROM `creature_template` WHERE `entry` IN ( + @C_TEMPLATE + 0, + @C_TEMPLATE + 1, + @C_TEMPLATE + 2 +); + +INSERT INTO `creature_template` (`entry`, `difficulty_entry_1`, `difficulty_entry_2`, `difficulty_entry_3`, `KillCredit1`, `KillCredit2`, `modelid1`, `modelid2`, `modelid3`, `modelid4`, `name`, `subname`, `IconName`, `gossip_menu_id`, `minlevel`, `maxlevel`, `exp`, `faction`, `npcflag`, `speed_walk`, `speed_run`, `speed_swim`, `speed_flight`, `detection_range`, `scale`, `rank`, `dmgschool`, `DamageModifier`, `BaseAttackTime`, `RangeAttackTime`, `BaseVariance`, `RangeVariance`, `unit_class`, `unit_flags`, `unit_flags2`, `dynamicflags`, `family`, `trainer_type`, `trainer_spell`, `trainer_class`, `trainer_race`, `type`, `type_flags`, `lootid`, `pickpocketloot`, `skinloot`, `PetSpellDataId`, `VehicleId`, `mingold`, `maxgold`, `AIName`, `MovementType`, `HoverHeight`, `HealthModifier`, `ManaModifier`, `ArmorModifier`, `ExperienceModifier`, `RacialLeader`, `movementId`, `RegenHealth`, `mechanic_immune_mask`, `spell_school_immune_mask`, `flags_extra`, `ScriptName`, `VerifiedBuild`) VALUES + (@C_TEMPLATE + 0, 0, 0, 0, 0, 0, 25901, 0, 0, 0, 'Talamortis', 'Guild House Seller', '', 0, 35, 35, 0, 35, 0, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 2000, 2000, 1, 1, 1, 33536, 2048, 0, 0, 0, 0, 0, 0, 7, 4096, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 'GuildHouseSeller', 12340), + (@C_TEMPLATE + 1, 0, 0, 0, 0, 0, 25901, 0, 0, 0, 'Xrispins', 'Guild House Butler', '', 0, 35, 35, 0, 35, 0, 1, 1.14286, 1, 1, 20, 1, 0, 0, 1, 2000, 2000, 1, 1, 1, 33536, 2048, 0, 0, 0, 0, 0, 0, 7, 4096, 0, 0, 0, 0, 0, 0, 0, '', 0, 1, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 'GuildHouseSpawner', 12340), + (@C_TEMPLATE + 2, 0, 0, 0, 0, 0, 18234, 0, 0, 0, 'Innkeeper Monica', NULL, NULL, 0, 1, 2, 0, 35, 65536, 0.8, 0.28571, 1, 1, 20, 1, 0, 0, 4.6, 2000, 1900, 1, 1, 1, 0, 2048, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, '', 1, 1, 1, 1, 1, 1, 0, 70, 1, 0, 0, 2, 'npc_innkeeper', 12340); + +-- !!! NOTE: set these before running the queries in order to avoid conflicts !!! +SET @GO_TEMPLATE = 500000; + +DELETE FROM `gameobject_template` WHERE `entry` IN ( + @GO_TEMPLATE + 0, + @GO_TEMPLATE + 1, + @GO_TEMPLATE + 2, + @GO_TEMPLATE + 3, + @GO_TEMPLATE + 4, + @GO_TEMPLATE + 5, + @GO_TEMPLATE + 6, + @GO_TEMPLATE + 7, + @GO_TEMPLATE + 8, + @GO_TEMPLATE + 9 +); + +INSERT INTO `gameobject_template` (`entry`, `type`, `displayId`, `name`, `IconName`, `castBarCaption`, `unk1`, `size`, `Data0`, `Data1`, `Data2`, `Data3`, `Data4`, `Data5`, `Data6`, `Data7`, `Data8`, `Data9`, `Data10`, `Data11`, `Data12`, `Data13`, `Data14`, `Data15`, `Data16`, `Data17`, `Data18`, `Data19`, `Data20`, `Data21`, `Data22`, `Data23`, `AIName`, `ScriptName`, `VerifiedBuild`) VALUES + (@GO_TEMPLATE + 0, 22, 4396, 'Portal to Stormwind', '', '', '', 1, 17334, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 1, 22, 4393, 'Portal to Darnassus', '', '', '', 1, 17608, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 2, 22, 6955, 'Portal to Exodar', '', '', '', 1, 32268, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 3, 22, 4394, 'Portal to Ironforge', '', '', '', 1, 17607, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 4, 22, 4395, 'Portal to Orgrimmar', '', '', '', 1, 17609, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 5, 22, 6956, 'Portal to Silvermoon', '', '', '', 1, 32270, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 6, 22, 4397, 'Portal to Thunder Bluff', '', '', '', 1, 17610, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 7, 22, 4398, 'Portal to Undercity', '', '', '', 1, 17611, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 8, 22, 7146, 'Portal to Shattrath', '', '', '', 1, 35718, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0), + (@GO_TEMPLATE + 9, 22, 8111, 'Portal to Dalaran', '', '', '', 1, 53141, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '', '', 0); \ No newline at end of file diff --git a/sql/world/guild_house_spawns.sql b/sql/world/guild_house_spawns.sql deleted file mode 100644 index cdb6100..0000000 --- a/sql/world/guild_house_spawns.sql +++ /dev/null @@ -1,106 +0,0 @@ --- -------------------------------------------------------- --- Host: 127.0.0.1 --- Server version: 5.6.28 - MySQL Community Server (GPL) --- Server OS: Win64 --- HeidiSQL Version: 9.4.0.5125 --- -------------------------------------------------------- - -/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; -/*!40101 SET NAMES utf8 */; -/*!50503 SET NAMES utf8mb4 */; -/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; -/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; - --- Dumping structure for table acore_char.guild_house -CREATE TABLE IF NOT EXISTS `guild_house` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `guild` int(11) NOT NULL DEFAULT '0', - `phase` int(11) NOT NULL, - `map` int(11) NOT NULL DEFAULT '0', - `positionX` float NOT NULL DEFAULT '0', - `positionY` float NOT NULL DEFAULT '0', - `positionZ` float NOT NULL DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `guild` (`guild`) -) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8; - --- Dumping data for table acore_char.guild_house: ~2 rows (approximately) -/*!40000 ALTER TABLE `guild_house` DISABLE KEYS */; -REPLACE INTO `guild_house` (`id`, `guild`, `phase`, `map`, `positionX`, `positionY`, `positionZ`) VALUES - (19, 1, 1, 1, 16226.1, 16258, 13.2576), - (23, 2, 2, 1, 16226.1, 16258, 13.2576); -/*!40000 ALTER TABLE `guild_house` ENABLE KEYS */; - --- Dumping structure for table acore_world.guild_house_spawns -CREATE TABLE IF NOT EXISTS `guild_house_spawns` ( - `id` int(11) NOT NULL AUTO_INCREMENT, - `entry` int(11) NOT NULL DEFAULT '0', - `posX` float NOT NULL DEFAULT '0', - `posY` float NOT NULL DEFAULT '0', - `posZ` float NOT NULL DEFAULT '0', - `orientation` float NOT NULL DEFAULT '0', - `comment` varchar(500) DEFAULT '0', - PRIMARY KEY (`id`), - UNIQUE KEY `entry` (`entry`) -) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8; - --- Dumping data for table acore_world.guild_house_spawns: ~56 rows (approximately) -/*!40000 ALTER TABLE `guild_house_spawns` DISABLE KEYS */; -REPLACE INTO `guild_house_spawns` (`id`, `entry`, `posX`, `posY`, `posZ`, `orientation`, `comment`) VALUES - (1, 26327, 16216.5, 16279.4, 20.9306, 0.552869, 'Paladin Trainer'), - (2, 26324, 16221.3, 16275.7, 20.9285, 1.37363, 'Druid Trainer'), - (3, 26325, 16218.6, 16277, 20.9872, 0.967188, 'Hunter Trainer'), - (4, 26326, 16224.9, 16274.9, 20.9319, 1.58765, 'Mage Trainer'), - (5, 26328, 16227.9, 16275.9, 20.9254, 1.9941, 'Priest Trainer'), - (6, 26329, 16231.4, 16278.1, 20.9222, 2.20026, 'Rogue Trainer'), - (7, 26330, 16235.5, 16280.8, 20.9257, 2.18652, 'Shaman Trainer'), - (8, 26331, 16240.8, 16283.3, 20.9299, 1.86843, 'Warlock Trainer'), - (9, 26332, 16246.6, 16284.5, 20.9301, 1.68975, 'Warrior Trainer'), - (10, 18649, 16224.1, 16284.2, 13.1755, 4.65225, 'Inkeeper'), - (11, 30605, 16238.2, 16291.8, 22.9306, 1.55386, 'Banker'), - (12, 33251, 16252.3, 16284.9, 20.9324, 1.79537, 'Death Knight Trainer'), - (13, 33609, 16220.5, 16302.3, 13.176, 6.14647, 'Blacksmithing Trainer'), - (14, 33617, 16220.2, 16299.6, 13.178, 6.22894, 'Mining Trainer'), - (15, 33611, 16219.8, 16296.9, 13.1746, 6.24465, 'Engineering Trainer'), - (16, 33614, 16222.4, 16293, 13.1813, 1.51263, 'Jewelcrafting Trainer'), - (17, 33610, 16227.5, 16292.3, 13.1839, 1.49691, 'Enchanting Trainer'), - (18, 33615, 16231.6, 16301, 13.1757, 3.07372, 'Inscription Trainer'), - (19, 33612, 16231.2, 16295, 13.1761, 3.06574, 'Leatherworking Trainer'), - (20, 33618, 16228.9, 16304.7, 13.1819, 4.64831, 'Skinning Trainer'), - (21, 33608, 16218.1, 16281.8, 13.1756, 6.1975, 'Alchemy Trainer'), - (22, 33616, 16218.3, 16284.3, 13.1756, 6.1975, 'Herbalism Trainer'), - (23, 33613, 16220.4, 16278.7, 13.1756, 1.46157, 'Tailoring Trainer'), - (24, 33621, 16225, 16310.9, 29.262, 6.22119, 'First Aid Trainer'), - (25, 33623, 16225.3, 16313.9, 29.262, 6.28231, 'Fishing Trainer'), - (26, 33619, 16227, 16278, 13.1762, 1.4872, 'Cooking Trainer'), - (27, 8719, 16242, 16291.6, 22.9311, 1.52061, 'Alliance Auctioneer'), - (30, 9856, 16242, 16291.6, 22.9311, 1.52061, 'Horde Auctioneer'), - (31, 184137, 16220.3, 16272, 12.9736, 4.45592, 'Mailbox (Object)'), - (33, 1685, 16253.8, 16294.3, 13.1758, 6.11938, 'Forge (Object)'), - (34, 4087, 16254.4, 16298.7, 13.1758, 3.36027, 'Anvil (Object)'), - (36, 183325, 16214.8, 16218, 1.11903, 1.35357, 'Portal: Stormwind (Object)'), - (37, 183323, 16214.8, 16218, 1.11903, 1.35357, 'Portal: Orgrimmar (Object)'), - (38, 183322, 16222.8, 16216.9, 1.22016, 1.57937, 'Portal: Ironforge (Object)'), - (39, 183327, 16222.8, 16216.9, 1.22016, 1.57937, 'Portal: Undercity (Object)'), - (40, 183317, 16202.1, 16223.1, 1.03401, 0.829316, 'Portal: Darnassus (Object)'), - (41, 183326, 16202.1, 16223.1, 1.03401, 0.829316, 'Portal: Thunder Bluff (Object)'), - (42, 183324, 16196.8, 16227.5, 1.37206, 0.762557, 'Portal: Silvermoon (Object)'), - (43, 183321, 16196.8, 16227.5, 1.37206, 0.762557, 'Portal: Exodar (Object)'), - (44, 195682, 16207, 16216, 1.10669, 1.0453, 'Portal: Dalaran (Object)'), - (45, 187293, 16230.5, 16283.5, 13.9061, 3, 'Guild Vault (Object)'), - (46, 28692, 16230.2, 16316.4, 20.8455, 6.25643, 'Trade Supplies'), - (48, 28776, 16236.3, 16316.1, 20.8454, 3.06771, 'Tabard Vendor'), - (49, 70103, 16223.7, 16293.3, 20.852, 4.57958, 'Food & Drink'), - (50, 6491, 16319.937, 16242.404, 24.4747, 2.206830, 'Spirit Healer'), - (51, 191028, 16255.5, 16304.9, 20.9785, 2.97516, 'Barber Chair (Object)'), - (52, 191013, 16203, 16216, 1.10669, 1.0453, 'Portal: Shattrath (Object) - Alliance'), - (53, 29636, 16233.5, 16316.1, 20.8455, 3.07558, 'Reagent Vendor'), - (54, 191014, 16203, 16216, 1.10669, 1.0453, 'Portal: Shattrath (Object) - Horde'), - (55, 70104, 16242.8, 16302.1, 13.174, 4.6153, 'Ammo & Repair Vendor'), - (56, 28690, 16226.97, 16267.9, 13.15, 4.6533, 'Stable Master'); - -/*!40000 ALTER TABLE `guild_house_spawns` ENABLE KEYS */; - -/*!40101 SET SQL_MODE=IFNULL(@OLD_SQL_MODE, '') */; -/*!40014 SET FOREIGN_KEY_CHECKS=IF(@OLD_FOREIGN_KEY_CHECKS IS NULL, 1, @OLD_FOREIGN_KEY_CHECKS) */; -/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; diff --git a/sql/world/guildhouse_spawns.sql b/sql/world/guildhouse_spawns.sql new file mode 100644 index 0000000..10406cf --- /dev/null +++ b/sql/world/guildhouse_spawns.sql @@ -0,0 +1,68 @@ +CREATE TABLE IF NOT EXISTS `guild_house_spawns` ( + `id` int(11) NOT NULL AUTO_INCREMENT, + `entry` int(11) NOT NULL DEFAULT '0', + `posX` float NOT NULL DEFAULT '0', + `posY` float NOT NULL DEFAULT '0', + `posZ` float NOT NULL DEFAULT '0', + `orientation` float NOT NULL DEFAULT '0', + `comment` varchar(500) DEFAULT '0', + PRIMARY KEY (`id`), + UNIQUE KEY `entry` (`entry`) +) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8; + +REPLACE INTO `guild_house_spawns` (`id`, `entry`, `posX`, `posY`, `posZ`, `orientation`, `comment`) VALUES + (1, 26327, 16216.5, 16279.4, 20.9306, 0.552869, 'Paladin Trainer'), + (2, 26324, 16221.3, 16275.7, 20.9285, 1.37363, 'Druid Trainer'), + (3, 26325, 16218.6, 16277, 20.9872, 0.967188, 'Hunter Trainer'), + (4, 26326, 16224.9, 16274.9, 20.9319, 1.58765, 'Mage Trainer'), + (5, 26328, 16227.9, 16275.9, 20.9254, 1.9941, 'Priest Trainer'), + (6, 26329, 16231.4, 16278.1, 20.9222, 2.20026, 'Rogue Trainer'), + (7, 26330, 16235.5, 16280.8, 20.9257, 2.18652, 'Shaman Trainer'), + (8, 26331, 16240.8, 16283.3, 20.9299, 1.86843, 'Warlock Trainer'), + (9, 26332, 16246.6, 16284.5, 20.9301, 1.68975, 'Warrior Trainer'), + (10, 500032, 16218.9, 16284.5, 13.1761, 6.18533, 'Innkeeper'), + (11, 30605, 16228.0, 16280.5, 13.1761, 2.98877, 'Banker'), + (12, 29195, 16252.3, 16284.9, 20.9324, 1.79537, 'Death Knight Trainer'), + (13, 2836, 16220.5, 16302.3, 13.176, 6.14647, 'Blacksmithing Trainer'), + (14, 8128, 16220.2, 16299.6, 13.178, 6.22894, 'Mining Trainer'), + (15, 8736, 16219.8, 16296.9, 13.1746, 6.24465, 'Engineering Trainer'), + (16, 18774, 16222.4, 16293, 13.1813, 1.51263, 'Jewelcrafting Trainer (Alliance)'), + (17, 18751, 16222.4, 16293, 13.1813, 1.51263, 'Jewelcrafting Trainer (Horde)'), + (18, 18773, 16227.5, 16292.3, 13.1839, 1.49691, 'Enchanting Trainer (Alliance)'), + (19, 18753, 16227.5, 16292.3, 13.1839, 1.49691, 'Enchanting Trainer (Horde)'), + (20, 30721, 16231.6, 16301, 13.1757, 3.07372, 'Inscription Trainer (Alliance)'), + (21, 30722, 16231.6, 16301, 13.1757, 3.07372, 'Inscription Trainer (Horde)'), + (22, 19187, 16231.2, 16295, 13.1761, 3.06574, 'Leatherworking Trainer'), + (23, 19180, 16228.9, 16304.7, 13.1819, 4.64831, 'Skinning Trainer'), + (24, 19052, 16218.1, 16281.8, 13.1756, 6.1975, 'Alchemy Trainer'), + (25, 908, 16218.3, 16284.3, 13.1756, 6.1975, 'Herbalism Trainer'), + (26, 2627, 16220.4, 16278.7, 13.1756, 1.46157, 'Tailoring Trainer'), + (27, 19184, 16225, 16310.9, 29.262, 6.22119, 'First Aid Trainer'), + (28, 2834, 16225.3, 16313.9, 29.262, 6.28231, 'Fishing Trainer'), + (29, 19185, 16227, 16278, 13.1762, 1.4872, 'Cooking Trainer'), + (30, 8719, 16242, 16291.6, 22.9311, 1.52061, 'Alliance Auctioneer'), + (31, 9856, 16242, 16291.6, 22.9311, 1.52061, 'Horde Auctioneer'), + (32, 184137, 16220.3, 16272, 12.9736, 4.45592, 'Mailbox (Object)'), + (33, 1685, 16253.8, 16294.3, 13.1758, 6.11938, 'Forge (Object)'), + (34, 4087, 16254.4, 16298.7, 13.1758, 3.36027, 'Anvil (Object)'), + (35, 500000, 16232.9, 16264.1, 13.55570, 3.028813, 'Portal: Stormwind (Object)'), + (36, 500001, 16232.8, 16257.1, 13.93456, 3.028813, 'Portal: Darnassus (Object)'), + (37, 500002, 16231.3, 16254.2, 13.65647, 3.028813, 'Portal: Exodar (Object)'), + (38, 500003, 16233.4, 16260.6, 13.84770, 3.028813, 'Portal: Ironforge (Object)'), + (39, 500004, 16232.9, 16264.1, 13.55570, 3.028813, 'Portal: Orgrimmar (Object)'), + (40, 500005, 16231.3, 16254.2, 13.65647, 3.028813, 'Portal: Silvermoon (Object)'), + (41, 500006, 16233.4, 16260.6, 13.84770, 3.028813, 'Portal: Thunder Bluff (Object)'), + (42, 500007, 16232.8, 16257.1, 13.93456, 3.028813, 'Portal: Undercity (Object)'), + (43, 500008, 16211.1, 16266.9, 13.7458, 5.6724, 'Portal: Shattrath (Object)'), + (44, 500009, 16213.9, 16270.5, 13.1378, 5.4996, 'Portal: Dalaran (Object)'), + (45, 187293, 16230.5, 16283.5, 13.9061, 3, 'Guild Vault (Object)'), + (46, 28692, 16236.2, 16315.7, 20.8454, 4.64365, 'Trade Supplies'), + (47, 28776, 16223.7, 16297.9, 20.8454, 6.17044, 'Tabard Vendor'), + (48, 4255, 16230.2, 16316.1, 20.8455, 4.64365, 'Food & Drink Vendor'), + (49, 6491, 16319.937, 16242.404, 24.4747, 2.206830, 'Spirit Healer'), + (50, 191028, 16255.5, 16304.9, 20.9785, 2.97516, 'Barber Chair (Object)'), + (51, 29636, 16233.2, 16315.9, 20.8454, 4.64365, 'Reagent Vendor'), + (52, 29493, 16229.1, 16286.4, 13.176, 3.03831, 'Ammo & Repair Vendor'), + (53, 28690, 16226.97, 16267.9, 13.15, 4.6533, 'Stable Master'), + (54, 9858, 16238.2, 16291.8, 22.9306, 1.55386, 'Neutral Auctioneer'), + (55, 2622, 16242.8, 16302.1, 13.176, 4.55570, 'Poisons Vendor'); \ No newline at end of file diff --git a/src/loader.cpp b/src/loader.cpp new file mode 100755 index 0000000..335badd --- /dev/null +++ b/src/loader.cpp @@ -0,0 +1,7 @@ +void AddGuildHouseScripts(); +void AddGuildHouseButlerScripts(); + +void Addmod_guildhouseScripts() { + AddGuildHouseScripts(); + AddGuildHouseButlerScripts(); +} diff --git a/src/loader.h b/src/loader.h deleted file mode 100644 index 68e792c..0000000 --- a/src/loader.h +++ /dev/null @@ -1,2 +0,0 @@ -void AddGuildHouseV2Scripts(); -void AddGuildHouseV2NPCScripts(); diff --git a/src/mod_guild_house_v2.cpp b/src/mod_guild_house_v2.cpp deleted file mode 100644 index 2386091..0000000 --- a/src/mod_guild_house_v2.cpp +++ /dev/null @@ -1,695 +0,0 @@ -#include "ScriptMgr.h" -#include "Player.h" -#include "Configuration/Config.h" -#include "Creature.h" -#include "Guild.h" -#include "SpellAuraEffects.h" -#include "Chat.h" -#include "ScriptedGossip.h" -#include "GuildMgr.h" -#include "Define.h" -#include "GossipDef.h" -#include "DataMap.h" -#include "GameObject.h" -#include "Transport.h" -#include "Maps/MapManager.h" - -class GuildData : public DataMap::Base -{ -public: - GuildData() {} - GuildData(uint32 phase, float posX, float posY, float posZ) : phase(phase), posX(posX), posY(posY), posZ(posZ) {} - uint32 phase; - float posX; - float posY; - float posZ; -}; - -class GuildHelper : public GuildScript { - -public: - - GuildHelper() : GuildScript("GuildHelper") {} - - void OnCreate(Guild*, Player* leader, const std::string&) - { - ChatHandler(leader->GetSession()).PSendSysMessage("You now own a guild. You can purchase a guild house!"); - } - - uint32 GetGuildPhase(Guild* guild) { - return guild->GetId() + 10; - } - - void OnDisband(Guild* guild) - { - - if (RemoveGuildHouse(guild)) - { - sLog->outBasic("GUILDHOUSE: Deleting guild house data due to disbanding of guild..."); - } else { sLog->outBasic("GUILDHOUSE: Error deleting guild house data during disbanding of guild!!"); } - - } - - bool RemoveGuildHouse(Guild* guild) - { - - uint32 guildPhase = GetGuildPhase(guild); - QueryResult CreatureResult; - QueryResult GameobjResult; - - // Lets find all of the gameobjects to be removed - GameobjResult = WorldDatabase.PQuery("SELECT `guid` FROM `gameobject` WHERE `map` = 1 AND `phaseMask` = '%u'", guildPhase); - // Lets find all of the creatures to be removed - CreatureResult = WorldDatabase.PQuery("SELECT `guid` FROM `creature` WHERE `map` = 1 AND `phaseMask` = '%u'", guildPhase); - - - // remove creatures from the deleted guild house map - if (CreatureResult) { - do - { - Field* fields = CreatureResult->Fetch(); - uint32 lowguid = fields[0].GetInt32(); - if (CreatureData const* cr_data = sObjectMgr->GetCreatureData(lowguid)) { - if (Creature* creature = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT), (Creature*)NULL)) - { - creature->CombatStop(); - creature->DeleteFromDB(); - creature->AddObjectToRemoveList(); - } - } - } while (CreatureResult->NextRow()); - } - - - // remove gameobjects from the deleted guild house map - if (GameobjResult) { - do - { - Field* fields = GameobjResult->Fetch(); - uint32 lowguid = fields[0].GetInt32(); - if (GameObjectData const* go_data = sObjectMgr->GetGOData(lowguid)) { - //if (GameObject* gobject = ObjectAccessor::GetObjectInWorld(lowguid, (GameObject*)NULL)) - if (GameObject* gobject = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(lowguid, go_data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) - { - gobject->SetRespawnTime(0); - gobject->Delete(); - gobject->DeleteFromDB(); - gobject->CleanupsBeforeDelete(); - //delete gobject; - } - } - - } while (GameobjResult->NextRow()); - } - - // Delete actual guild_house data from characters database - CharacterDatabase.PQuery("DELETE FROM `guild_house` WHERE `guild` = '%u'", guild->GetId()); - - return true; - - } - -}; - -class GuildHouseSeller : public CreatureScript { - -public: - GuildHouseSeller() : CreatureScript("GuildHouseSeller") {} - - bool OnGossipHello(Player *player, Creature * creature) - { - if (!player->GetGuild()) - { - ChatHandler(player->GetSession()).PSendSysMessage("You are not a member of a guild."); - CloseGossipMenuFor(player); - return false; - } - - QueryResult has_gh = CharacterDatabase.PQuery("SELECT id, `guild` FROM `guild_house` WHERE guild = %u", player->GetGuildId()); - - // Only show Teleport option if guild owns a guildhouse - if (has_gh) - { - AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Teleport to Guild House", GOSSIP_SENDER_MAIN, 1); - } - - if (player->GetGuild()->GetLeaderGUID() == player->GetGUID()) - { - // Only show "Sell" option if they have a guild house & are guild leader - if (has_gh) - { - AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Sell Guild House!", GOSSIP_SENDER_MAIN, 3, "Are you sure you want to sell your Guild house?", 0, false); - } - else { - // Only leader of the guild can buy guild house & only if they don't already have a guild house - AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Buy Guild House!", GOSSIP_SENDER_MAIN, 2); - } - } - - AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Close", GOSSIP_SENDER_MAIN, 5); - SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); - return true; - } - - bool OnGossipSelect(Player *player, Creature * m_creature, uint32, uint32 action) - { - uint32 map; - float posX; - float posY; - float posZ; - - switch (action) - { - case 100: // gmsiland - map = 1; - posX = 16226.117f; - posY = 16258.046f; - posZ = 13.257628f; - break; - case 5: // close - CloseGossipMenuFor(player); - break; - case 4: // --- MORE TO COME --- - BuyGuildHouse(player->GetGuild(), player, m_creature); - break; - case 3: // Sell back guild house - { - QueryResult has_gh = CharacterDatabase.PQuery("SELECT id, `guild` FROM `guild_house` WHERE guild = %u", player->GetGuildId()); - if (!has_gh) - { - ChatHandler(player->GetSession()).PSendSysMessage("Your guild does not own a Guild House!"); - CloseGossipMenuFor(player); - return false; - } - - // Calculate total gold returned: 1) cost of guildhouse and cost of each purchase made. - if (RemoveGuildHouse(player)) - { - ChatHandler(player->GetSession()).PSendSysMessage("You have successfully sold your guild house."); - player->GetGuild()->BroadcastToGuild(player->GetSession(), false, "We just sold our guild house.", LANG_UNIVERSAL); - player->ModifyMoney(+(sConfigMgr->GetIntDefault("CostGuildHouse", 10000000) / 2)); - sLog->outBasic("GUILDHOUSE: Successfully returned money and sold guildhouse"); - CloseGossipMenuFor(player); - } else { - ChatHandler(player->GetSession()).PSendSysMessage("There was an error selling your guild house."); - CloseGossipMenuFor(player); - } - break; - } - case 2: // buy guild house - BuyGuildHouse(player->GetGuild(), player, m_creature); - break; - case 1: // teleport to guild house - TeleportGuildHouse(player->GetGuild(), player, m_creature); - break; - } - - if (action >= 100) - { - CharacterDatabase.PQuery("INSERT INTO `guild_house` (guild, phase, map, positionX, positionY, positionZ) VALUES (%u, %u, %u, %f, %f, %f)", - player->GetGuildId(), GetGuildPhase(player), map, posX, posY, posZ); - player->ModifyMoney(-(sConfigMgr->GetIntDefault("CostGuildHouse", 10000000))); - // Msg to purchaser and Msg Guild as purchaser - ChatHandler(player->GetSession()).PSendSysMessage("You have successfully purchased a guild house"); - player->GetGuild()->BroadcastToGuild(player->GetSession(), false, "We now have a Guild House!", LANG_UNIVERSAL); - player->GetGuild()->BroadcastToGuild(player->GetSession(), false, "In chat, type `.guildhouse teleport` to meet me there!", LANG_UNIVERSAL); - sLog->outBasic("GUILDHOUSE: GuildId: '%u' has purchased a guildhouse", player->GetGuildId()); - - // Spawn a portal and the guild assistant automatically as part of purchase. - SpawnStarterPortal(player); - SpawnAssistantNPC(player); - CloseGossipMenuFor(player); - } - - return true; - } - - uint32 GetGuildPhase(Player* player) { - return player->GetGuildId() + 10; - } - - - bool RemoveGuildHouse(Player* player) - { - - uint32 guildPhase = GetGuildPhase(player); - QueryResult CreatureResult; - QueryResult GameobjResult; - - // Lets find all of the gameobjects to be removed - GameobjResult = WorldDatabase.PQuery("SELECT `guid` FROM `gameobject` WHERE `map` = 1 AND `phaseMask` = '%u'", guildPhase); - // Lets find all of the creatures to be removed - CreatureResult = WorldDatabase.PQuery("SELECT `guid` FROM `creature` WHERE `map` = 1 AND `phaseMask` = '%u'", guildPhase); - - - // remove creatures from the deleted guild house map - if (CreatureResult) { - do - { - Field* fields = CreatureResult->Fetch(); - uint32 lowguid = fields[0].GetInt32(); - if (CreatureData const* cr_data = sObjectMgr->GetCreatureData(lowguid)) { - if (Creature* creature = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(lowguid, cr_data->id, HIGHGUID_UNIT), (Creature*)NULL)) - { - creature->CombatStop(); - creature->DeleteFromDB(); - creature->AddObjectToRemoveList(); - } - } - } while (CreatureResult->NextRow()); - } - - - // remove gameobjects from the deleted guild house map - if (GameobjResult) { - do - { - Field* fields = GameobjResult->Fetch(); - uint32 lowguid = fields[0].GetInt32(); - if (GameObjectData const* go_data = sObjectMgr->GetGOData(lowguid)) { - //if (GameObject* gobject = ObjectAccessor::GetObjectInWorld(lowguid, (GameObject*)NULL)) - if (GameObject* gobject = ObjectAccessor::GetObjectInWorld(MAKE_NEW_GUID(lowguid, go_data->id, HIGHGUID_GAMEOBJECT), (GameObject*)NULL)) - { - gobject->SetRespawnTime(0); - gobject->Delete(); - gobject->DeleteFromDB(); - gobject->CleanupsBeforeDelete(); - //delete gobject; - } - } - - } while (GameobjResult->NextRow()); - } - - // Delete actual guild_house data from characters database - CharacterDatabase.PQuery("DELETE FROM `guild_house` WHERE `guild` = '%u'", player->GetGuildId()); - - return true; - - } - - void SpawnStarterPortal(Player* player) - { - - uint32 entry = 0; - float posX; - float posY; - float posZ; - float ori; - - Map* map = sMapMgr->FindMap(1,0); - - if (player->GetTeamId() == TEAM_ALLIANCE) - { - // Portal to Stormwind - entry = 183325; - } else { - // Portal to Orgrimmar - entry = 183323; - } - - - if (entry == 0) { sLog->outBasic("Error with SpawnStarterPortal in GuildHouse Module!"); return; } - - QueryResult result = WorldDatabase.PQuery("SELECT `posX`, `posY`, `posZ`, `orientation` FROM `guild_house_spawns` WHERE `entry` = %u", entry); - - if (!result) - { - sLog->outBasic("GUILDHOUSE: Unable to find data on portal for entry: '%u'", entry); - return; - } - - do - { - Field* fields = result->Fetch(); - posX = fields[0].GetFloat(); - posY = fields[1].GetFloat(); - posZ = fields[2].GetFloat(); - ori = fields[3].GetFloat(); - - } while (result->NextRow()); - - - uint32 objectId = entry; - if (!objectId) - { - sLog->outBasic("GUILDHOUSE: objectId IS NULL, should be '%u'", entry); - return; - } - - const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId); - - if (!objectInfo) - { - sLog->outBasic("GUILDHOUSE: objectInfo is NULL!"); - return; - } - - if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) - { - sLog->outBasic("GUILDHOUSE: Unable to find displayId??"); - return; - } - - GameObject* object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); - uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); - - - if (!object->Create(guidLow, objectInfo->entry, map, GetGuildPhase(player), posX, posY, posZ, ori, G3D::Quat(), 0, GO_STATE_READY)) - { - delete object; - sLog->outBasic("GUILDHOUSE: Unable to create object!!"); - return; - } - - - // fill the gameobject data and save to the db - object->SaveToDB(sMapMgr->FindMap(1, 0)->GetId(), (1 << sMapMgr->FindMap(1, 0)->GetSpawnMode()), GetGuildPhase(player)); - // delete the old object and do a clean load from DB with a fresh new GameObject instance. - // this is required to avoid weird behavior and memory leaks - delete object; - - object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); - // this will generate a new guid if the object is in an instance - if (!object->LoadGameObjectFromDB(guidLow, sMapMgr->FindMap(1, 0))) - { - delete object; - return; - } - - // TODO: is it really necessary to add both the real and DB table guid here ? - sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow)); - CloseGossipMenuFor(player); - } - - void SpawnAssistantNPC(Player* player) - { - uint32 entry = 70102; - float posX = 16202.185547f; - float posY = 16255.916992f; - float posZ = 21.160221f; - float ori = 6.195375f; - - Creature* creature = new Creature(); - - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), sMapMgr->FindMap(1, 0), GetGuildPhase(player), entry, 0, posX, posY, posZ, ori)) - { - delete creature; - return; - } - creature->SaveToDB(sMapMgr->FindMap(1, 0)->GetId(), (1 << sMapMgr->FindMap(1, 0)->GetSpawnMode()), GetGuildPhase(player)); - uint32 db_guid = creature->GetDBTableGUIDLow(); - - creature->CleanupsBeforeDelete(); - delete creature; - creature = new Creature(); - if (!creature->LoadCreatureFromDB(db_guid, sMapMgr->FindMap(1, 0))) - { - delete creature; - return; - } - - sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid)); - return; - } - - bool BuyGuildHouse(Guild* guild, Player* player, Creature* creature) - { - QueryResult result = CharacterDatabase.PQuery("SELECT `id`, `guild` FROM guild_house WHERE `guild` = %u", guild->GetId()); - - if (result) - { - ChatHandler(player->GetSession()).PSendSysMessage("Your guild already has a Guild House."); - CloseGossipMenuFor(player); - return false; - } - - ClearGossipMenuFor(player); - AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "GM Island", GOSSIP_SENDER_MAIN, 100, "Buy Guild House on GM Island?", sConfigMgr->GetIntDefault("CostGuildHouse", 10000000), false); - // Removing this tease for now, as right now the phasing code is specific go GM Island, so its not a simple thing to add new areas yet. - //AddGossipItemFor(player, GOSSIP_ICON_CHAT, " ----- More to Come ----", GOSSIP_SENDER_MAIN, 4); - SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); - return true; - - } - - void TeleportGuildHouse(Guild* guild, Player* player, Creature* creature) - { - GuildData* guildData = player->CustomData.GetDefault("phase"); - QueryResult result = CharacterDatabase.PQuery("SELECT `phase`, `map`,`positionX`, `positionY`, `positionZ` FROM guild_house WHERE `guild` = %u", guild->GetId()); - - if (!result) - { - ClearGossipMenuFor(player); - if (player->GetGuild()->GetLeaderGUID() == player->GetGUID()) - { - // Only leader of the guild can buy / sell guild house - AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Buy Guild House!", GOSSIP_SENDER_MAIN, 2); - AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Sell Guild House!", GOSSIP_SENDER_MAIN, 3, "Are you sure you want to sell your Guild house?", 0, false); - } - - AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Teleport to Guild House", GOSSIP_SENDER_MAIN, 1); - AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Close", GOSSIP_SENDER_MAIN, 5); - SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); - ChatHandler(player->GetSession()).PSendSysMessage("Your Guild does not own a guild house"); - return; - } - - do { - - Field* fields = result->Fetch(); - guildData->phase = fields[0].GetUInt32(); - uint32 map = fields[1].GetUInt32(); - guildData->posX = fields[2].GetFloat(); - guildData->posY = fields[3].GetFloat(); - guildData->posZ = fields[4].GetFloat(); - - player->TeleportTo(map, guildData->posX, guildData->posY, guildData->posZ, player->GetOrientation()); - - } while (result->NextRow()); - } - -}; - -class GuildHouseV2PlayerScript : public PlayerScript -{ -public: - GuildHouseV2PlayerScript() : PlayerScript("GuildHouseV2PlayerScript") { } - - void OnLogin(Player* player) - { - CheckPlayer(player); - } - - void OnUpdateZone(Player* player, uint32 newZone, uint32 /*newArea*/) - { - if (newZone == 876) - CheckPlayer(player); - else - player->SetPhaseMask(GetNormalPhase(player), true); - } - - uint32 GetNormalPhase(Player* player) const - { - if (player->IsGameMaster()) - return PHASEMASK_ANYWHERE; - - uint32 phase = player->GetPhaseByAuras(); - if (!phase) - return PHASEMASK_NORMAL; - else - return phase; - } - - void CheckPlayer(Player* player) - { - GuildData* guildData = player->CustomData.GetDefault("phase"); - QueryResult result = CharacterDatabase.PQuery("SELECT `id`, `guild`, `phase`, `map`,`positionX`, `positionY`, `positionZ` FROM guild_house WHERE `guild` = %u", player->GetGuildId()); - - if (result) - { - do { - // commented out due to travis, but keeping for future expansion into other areas - Field* fields = result->Fetch(); - //uint32 id = fields[0].GetUInt32(); // fix for travis - //uint32 guild = fields[1].GetUInt32(); // fix for travis - guildData->phase = fields[2].GetUInt32(); - //uint32 map = fields[3].GetUInt32(); // fix for travis - //guildData->posX = fields[4].GetFloat(); // fix for travis - //guildData->posY = fields[5].GetFloat(); // fix for travis - //guildData->posZ = fields[6].GetFloat(); // fix for travis - - } while (result->NextRow()); - } - - if (player->GetZoneId() == 876 && player->GetAreaId() == 876) // GM Island - { - // If player is not in a guild he doesnt have a guild house teleport away - // TODO: What if they are in a guild, but somehow are in the wrong phaseMask and seeing someone else's area? - - if (!result || !player->GetGuild()) - { - ChatHandler(player->GetSession()).PSendSysMessage("Your Guild does not own a guild house."); - teleport(player); - return; - } - player->SetPhaseMask(guildData->phase, true); - } - else - player->SetPhaseMask(GetNormalPhase(player), true); - } - - void teleport(Player* player) - { - if (player->GetTeamId() == TEAM_ALLIANCE) - player->TeleportTo(0, -8833.379883f, 628.627991f, 94.006599f, 1.0f); - else - player->TeleportTo(1, 1486.048340f, -4415.140625f, 24.187496f, 0.13f); - } -}; - -class GuildHouseCommand : public CommandScript -{ -public: - GuildHouseCommand() : CommandScript("GuildHouseCommand") { } - - std::vector GetCommands() const override - { - static std::vector GuildHouseCommandTable = - { - // View Command - { "Teleport", SEC_PLAYER, false, &HandleGuildHouseTeleCommand, "" }, - // Set Command - { "SpawnNpc", SEC_PLAYER, false, &HandleSpawnNPCCommand, "" }, - }; - - static std::vector GuildHouseCommandBaseTable = - { - { "Guildhouse", SEC_PLAYER, false, nullptr, "", GuildHouseCommandTable } - }; - - return GuildHouseCommandBaseTable; - } - - static uint32 GetGuildPhase(Player* player) { - return player->GetGuildId() + 10; - } - - static bool HandleSpawnNPCCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - if (!player->GetGuild() || (player->GetGuild()->GetLeaderGUID() != player->GetGUID())) { - handler->SendSysMessage("You must be the Guild Master of a guild to use this command!"); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->GetAreaId() != 876) { - handler->SendSysMessage("You must be in your Guild House to use this command!"); - handler->SetSentErrorMessage(true); - return false; - } - - if (player->FindNearestCreature(70102, VISIBLE_RANGE, true)) { - handler->SendSysMessage("You already have the Guild House Assistant!"); - handler->SetSentErrorMessage(true); - return false; - } - - float posX = 16202.185547f; - float posY = 16255.916992f; - float posZ = 21.160221f; - float ori = 6.195375f; - - Creature* creature = new Creature(); - - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), player->GetMap(), GetGuildPhase(player), 70102, 0, posX, posY, posZ, ori)) - { - handler->SendSysMessage("You already have the Guild House Assistant!"); - handler->SetSentErrorMessage(true); - delete creature; - return false; - } - creature->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), GetGuildPhase(player)); - uint32 db_guid = creature->GetDBTableGUIDLow(); - - creature->CleanupsBeforeDelete(); - delete creature; - creature = new Creature(); - if (!creature->LoadCreatureFromDB(db_guid, player->GetMap())) - { - handler->SendSysMessage("Something went wrong when adding the NPC."); - handler->SetSentErrorMessage(true); - delete creature; - return false; - } - - sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid)); - return true; - } - - static bool HandleGuildHouseTeleCommand(ChatHandler* handler, char const* /*args*/) - { - Player* player = handler->GetSession()->GetPlayer(); - - if (!player) - return false; - - if (player->IsInCombat()) { - handler->SendSysMessage("You can't use this command while in combat!"); - handler->SetSentErrorMessage(true); - return false; - } - - GuildData* guildData = player->CustomData.GetDefault("phase"); - QueryResult result = CharacterDatabase.PQuery("SELECT `id`, `guild`, `phase`, `map`,`positionX`, `positionY`, `positionZ` FROM guild_house WHERE `guild` = %u", player->GetGuildId()); - - if (!result) - { - handler->SendSysMessage("Your Guild does not own a guild house!"); - handler->SetSentErrorMessage(true); - return false; - } - - do { - - Field* fields = result->Fetch(); - //uint32 id = fields[0].GetUInt32(); // fix for travis - //uint32 guild = fields[1].GetUInt32(); // fix for travis - guildData->phase = fields[2].GetUInt32(); - uint32 map = fields[3].GetUInt32(); - guildData->posX = fields[4].GetFloat(); - guildData->posY = fields[5].GetFloat(); - guildData->posZ = fields[6].GetFloat(); - - player->TeleportTo(map, guildData->posX, guildData->posY, guildData->posZ, player->GetOrientation()); - - } while (result->NextRow()); - - return true; - } -}; - -class GuildHouseGlobal : public GlobalScript -{ -public: - GuildHouseGlobal() : GlobalScript("GuildHouseGlobal") {} - - void OnBeforeWorldObjectSetPhaseMask(WorldObject const* worldObject, uint32& /*oldPhaseMask*/, uint32& /*newPhaseMask*/, bool& useCombinedPhases, bool& /*update*/) override - { - if (worldObject->GetZoneId() == 876) - useCombinedPhases = false; - else - useCombinedPhases = true; - } -}; - -void AddGuildHouseV2Scripts() { - new GuildHelper(); - new GuildHouseSeller(); - new GuildHouseV2PlayerScript(); - new GuildHouseCommand(); - new GuildHouseGlobal(); -} - diff --git a/src/mod_guildhouse.cpp b/src/mod_guildhouse.cpp new file mode 100644 index 0000000..5a3b22e --- /dev/null +++ b/src/mod_guildhouse.cpp @@ -0,0 +1,738 @@ +#include "ScriptMgr.h" +#include "Player.h" +#include "Configuration/Config.h" +#include "Creature.h" +#include "Guild.h" +#include "SpellAuraEffects.h" +#include "Chat.h" +#include "ScriptedCreature.h" +#include "ScriptedGossip.h" +#include "GuildMgr.h" +#include "Define.h" +#include "GossipDef.h" +#include "DataMap.h" +#include "GameObject.h" +#include "Transport.h" +#include "Maps/MapMgr.h" + +class GuildData : public DataMap::Base +{ +public: + GuildData() {} + GuildData(uint32 phase, float posX, float posY, float posZ, float ori) : phase(phase), posX(posX), posY(posY), posZ(posZ), ori(ori) {} + uint32 phase; + float posX; + float posY; + float posZ; + float ori; +}; + +class GuildHelper : public GuildScript +{ + +public: + GuildHelper() : GuildScript("GuildHelper") {} + + void OnCreate(Guild *, Player *leader, const std::string &) + { + ChatHandler(leader->GetSession()).PSendSysMessage("You now own a guild. You can purchase a Guild House!"); + } + + uint32 GetGuildPhase(Guild *guild) + { + return guild->GetId() + 10; + } + + void OnDisband(Guild *guild) + { + + if (RemoveGuildHouse(guild)) + { + LOG_INFO("modules", "GUILDHOUSE: Deleting Guild House data due to disbanding of guild..."); + } + else + { + LOG_INFO("modules", "GUILDHOUSE: Error deleting Guild House data during disbanding of guild!!"); + } + } + + bool RemoveGuildHouse(Guild *guild) + { + + uint32 guildPhase = GetGuildPhase(guild); + QueryResult CreatureResult; + QueryResult GameobjResult; + + // Lets find all of the gameobjects to be removed + GameobjResult = WorldDatabase.Query("SELECT `guid` FROM `gameobject` WHERE `map` = 1 AND `phaseMask` = '{}'", guildPhase); + // Lets find all of the creatures to be removed + CreatureResult = WorldDatabase.Query("SELECT `guid` FROM `creature` WHERE `map` = 1 AND `phaseMask` = '{}'", guildPhase); + + Map *map = sMapMgr->FindMap(1, 0); + // Remove creatures from the deleted guild house map + if (CreatureResult) + { + do + { + Field *fields = CreatureResult->Fetch(); + uint32 lowguid = fields[0].Get(); + if (CreatureData const *cr_data = sObjectMgr->GetCreatureData(lowguid)) + { + if (Creature *creature = map->GetCreature(ObjectGuid::Create(cr_data->id1, lowguid))) + { + creature->CombatStop(); + creature->DeleteFromDB(); + creature->AddObjectToRemoveList(); + } + } + } while (CreatureResult->NextRow()); + } + + // Remove gameobjects from the deleted guild house map + if (GameobjResult) + { + do + { + Field *fields = GameobjResult->Fetch(); + uint32 lowguid = fields[0].Get(); + if (GameObjectData const *go_data = sObjectMgr->GetGOData(lowguid)) + { + if (GameObject *gobject = map->GetGameObject(ObjectGuid::Create(go_data->id, lowguid))) + { + gobject->SetRespawnTime(0); + gobject->Delete(); + gobject->DeleteFromDB(); + gobject->CleanupsBeforeDelete(); + // delete gobject; + } + } + + } while (GameobjResult->NextRow()); + } + + // Delete actual guild_house data from characters database + CharacterDatabase.Query("DELETE FROM `guild_house` WHERE `guild` = '{}'", guild->GetId()); + + return true; + } +}; + +class GuildHouseSeller : public CreatureScript +{ + +public: + GuildHouseSeller() : CreatureScript("GuildHouseSeller") + { + } + + struct GuildHouseSellerAI : public ScriptedAI + { + GuildHouseSellerAI(Creature *creature) : ScriptedAI(creature) {} + + void UpdateAI(uint32 /* diff */) override + { + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + }; + + CreatureAI * + GetAI(Creature *creature) const override + { + return new GuildHouseSellerAI(creature); + } + + bool OnGossipHello(Player *player, Creature *creature) override + { + if (!player->GetGuild()) + { + ChatHandler(player->GetSession()).PSendSysMessage("You are not a member of a guild."); + CloseGossipMenuFor(player); + return false; + } + + QueryResult has_gh = CharacterDatabase.Query("SELECT id, `guild` FROM `guild_house` WHERE guild = {}", player->GetGuildId()); + + // Only show Teleport option if guild owns a guild house + if (has_gh) + { + AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Teleport to Guild House", GOSSIP_SENDER_MAIN, 1); + + // Only show "Sell" option if they have a guild house & have permission to sell it + Guild *guild = sGuildMgr->GetGuildById(player->GetGuildId()); + Guild::Member const *memberMe = guild->GetMember(player->GetGUID()); + if (memberMe->IsRankNotLower(sConfigMgr->GetOption("GuildHouseSellRank", 0))) + { + AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Sell Guild House!", GOSSIP_SENDER_MAIN, 3, "Are you sure you want to sell your Guild House?", 0, false); + } + } + else + { + // Only leader of the guild can buy guild house & only if they don't already have a guild house + if (player->GetGuild()->GetLeaderGUID() == player->GetGUID()) + { + AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Buy Guild House!", GOSSIP_SENDER_MAIN, 2); + } + } + + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Close", GOSSIP_SENDER_MAIN, 5); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); + return true; + } + + bool OnGossipSelect(Player *player, Creature *m_creature, uint32, uint32 action) override + { + uint32 map; + float posX; + float posY; + float posZ; + float ori; + + switch (action) + { + case 100: // GM Island + map = 1; + posX = 16222.972f; + posY = 16267.802f; + posZ = 13.136777f; + ori = 1.461173f; + break; + case 5: // close + CloseGossipMenuFor(player); + break; + case 4: // --- MORE TO COME --- + BuyGuildHouse(player->GetGuild(), player, m_creature); + break; + case 3: // sell back guild house + { + QueryResult has_gh = CharacterDatabase.Query("SELECT id, `guild` FROM `guild_house` WHERE guild = {}", player->GetGuildId()); + if (!has_gh) + { + ChatHandler(player->GetSession()).PSendSysMessage("Your guild does not own a Guild House!"); + CloseGossipMenuFor(player); + return false; + } + + // calculate total gold returned: 1) cost of guild house and cost of each purchase made + if (RemoveGuildHouse(player)) + { + ChatHandler(player->GetSession()).PSendSysMessage("You have successfully sold your Guild House."); + player->GetGuild()->BroadcastToGuild(player->GetSession(), false, "We just sold our Guild House.", LANG_UNIVERSAL); + player->ModifyMoney(+(sConfigMgr->GetOption("CostGuildHouse", 10000000) / 2)); + LOG_INFO("modules", "GUILDHOUSE: Successfully returned money and sold Guild House"); + CloseGossipMenuFor(player); + } + else + { + ChatHandler(player->GetSession()).PSendSysMessage("There was an error selling your Guild House."); + CloseGossipMenuFor(player); + } + break; + } + case 2: // buy guild house + BuyGuildHouse(player->GetGuild(), player, m_creature); + break; + case 1: // teleport to guild house + TeleportGuildHouse(player->GetGuild(), player, m_creature); + break; + } + + if (action >= 100) + { + CharacterDatabase.Query("INSERT INTO `guild_house` (guild, phase, map, positionX, positionY, positionZ, orientation) VALUES ({}, {}, {}, {}, {}, {}, {})", player->GetGuildId(), GetGuildPhase(player), map, posX, posY, posZ, ori); + player->ModifyMoney(-(sConfigMgr->GetOption("CostGuildHouse", 10000000))); + // Msg to purchaser and Msg Guild as purchaser + ChatHandler(player->GetSession()).PSendSysMessage("You have successfully purchased a Guild House"); + player->GetGuild()->BroadcastToGuild(player->GetSession(), false, "We now have a Guild House!", LANG_UNIVERSAL); + player->GetGuild()->BroadcastToGuild(player->GetSession(), false, "In chat, type `.guildhouse teleport` or `.gh tele` to meet me there!", LANG_UNIVERSAL); + LOG_INFO("modules", "GUILDHOUSE: GuildId: '{}' has purchased a guildhouse", player->GetGuildId()); + + // Spawn a portal and the guild house butler automatically as part of purchase. + SpawnStarterPortal(player); + SpawnButlerNPC(player); + CloseGossipMenuFor(player); + } + + return true; + } + + uint32 GetGuildPhase(Player *player) + { + return player->GetGuildId() + 10; + } + + bool RemoveGuildHouse(Player *player) + { + + uint32 guildPhase = GetGuildPhase(player); + QueryResult CreatureResult; + QueryResult GameobjResult; + Map *map = sMapMgr->FindMap(1, 0); + // Lets find all of the gameobjects to be removed + GameobjResult = WorldDatabase.Query("SELECT `guid` FROM `gameobject` WHERE `map` = 1 AND `phaseMask` = '{}'", guildPhase); + // Lets find all of the creatures to be removed + CreatureResult = WorldDatabase.Query("SELECT `guid` FROM `creature` WHERE `map` = 1 AND `phaseMask` = '{}'", guildPhase); + + // Remove creatures from the deleted guild house map + if (CreatureResult) + { + do + { + Field *fields = CreatureResult->Fetch(); + uint32 lowguid = fields[0].Get(); + if (CreatureData const *cr_data = sObjectMgr->GetCreatureData(lowguid)) + { + if (Creature *creature = map->GetCreature(ObjectGuid::Create(cr_data->id1, lowguid))) + { + creature->CombatStop(); + creature->DeleteFromDB(); + creature->AddObjectToRemoveList(); + } + } + } while (CreatureResult->NextRow()); + } + + // Remove gameobjects from the deleted guild house map + if (GameobjResult) + { + do + { + Field *fields = GameobjResult->Fetch(); + uint32 lowguid = fields[0].Get(); + if (GameObjectData const *go_data = sObjectMgr->GetGOData(lowguid)) + { + if (GameObject *gobject = map->GetGameObject(ObjectGuid::Create(go_data->id, lowguid))) + { + gobject->SetRespawnTime(0); + gobject->Delete(); + gobject->DeleteFromDB(); + gobject->CleanupsBeforeDelete(); + // delete gobject; + } + } + + } while (GameobjResult->NextRow()); + } + + // Delete actual guild_house data from characters database + CharacterDatabase.Query("DELETE FROM `guild_house` WHERE `guild` = '{}'", player->GetGuildId()); + + return true; + } + + void SpawnStarterPortal(Player *player) + { + + uint32 entry = 0; + float posX; + float posY; + float posZ; + float ori; + + Map *map = sMapMgr->FindMap(1, 0); + + if (player->GetTeamId() == TEAM_ALLIANCE) + { + // Portal to Stormwind + entry = 500000; + } + else + { + // Portal to Orgrimmar + entry = 500004; + } + + if (entry == 0) + { + LOG_INFO("modules", "Error with SpawnStarterPortal in GuildHouse Module!"); + return; + } + + QueryResult result = WorldDatabase.Query("SELECT `posX`, `posY`, `posZ`, `orientation` FROM `guild_house_spawns` WHERE `entry` = {}", entry); + + if (!result) + { + LOG_INFO("modules", "GUILDHOUSE: Unable to find data on portal for entry: {}", entry); + return; + } + + do + { + Field *fields = result->Fetch(); + posX = fields[0].Get(); + posY = fields[1].Get(); + posZ = fields[2].Get(); + ori = fields[3].Get(); + + } while (result->NextRow()); + + uint32 objectId = entry; + if (!objectId) + { + LOG_INFO("modules", "GUILDHOUSE: objectId IS NULL, should be '{}'", entry); + return; + } + + const GameObjectTemplate *objectInfo = sObjectMgr->GetGameObjectTemplate(objectId); + + if (!objectInfo) + { + LOG_INFO("modules", "GUILDHOUSE: objectInfo is NULL!"); + return; + } + + if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) + { + LOG_INFO("modules", "GUILDHOUSE: Unable to find displayId??"); + return; + } + + GameObject *object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); + ObjectGuid::LowType guidLow = player->GetMap()->GenerateLowGuid(); + + if (!object->Create(guidLow, objectInfo->entry, map, GetGuildPhase(player), posX, posY, posZ, ori, G3D::Quat(), 0, GO_STATE_READY)) + { + delete object; + LOG_INFO("modules", "GUILDHOUSE: Unable to create object!!"); + return; + } + + // fill the gameobject data and save to the db + object->SaveToDB(sMapMgr->FindMap(1, 0)->GetId(), (1 << sMapMgr->FindMap(1, 0)->GetSpawnMode()), GetGuildPhase(player)); + guidLow = object->GetSpawnId(); + // delete the old object and do a clean load from DB with a fresh new GameObject instance. + // this is required to avoid weird behavior and memory leaks + delete object; + + object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); + // this will generate a new guid if the object is in an instance + if (!object->LoadGameObjectFromDB(guidLow, sMapMgr->FindMap(1, 0), true)) + { + delete object; + return; + } + + // TODO: is it really necessary to add both the real and DB table guid here ? + sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow)); + CloseGossipMenuFor(player); + } + + void SpawnButlerNPC(Player *player) + { + uint32 entry = 500031; + float posX = 16202.185547f; + float posY = 16255.916992f; + float posZ = 21.160221f; + float ori = 6.195375f; + + Map *map = sMapMgr->FindMap(1, 0); + Creature *creature = new Creature(); + + if (!creature->Create(map->GenerateLowGuid(), map, player->GetPhaseMaskForSpawn(), entry, 0, posX, posY, posZ, ori)) + { + delete creature; + return; + } + creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), GetGuildPhase(player)); + uint32 lowguid = creature->GetSpawnId(); + + creature->CleanupsBeforeDelete(); + delete creature; + creature = new Creature(); + if (!creature->LoadCreatureFromDB(lowguid, map)) + { + delete creature; + return; + } + + sObjectMgr->AddCreatureToGrid(lowguid, sObjectMgr->GetCreatureData(lowguid)); + return; + } + + bool BuyGuildHouse(Guild *guild, Player *player, Creature *creature) + { + QueryResult result = CharacterDatabase.Query("SELECT `id`, `guild` FROM guild_house WHERE `guild` = {}", guild->GetId()); + + if (result) + { + ChatHandler(player->GetSession()).PSendSysMessage("Your guild already has a Guild House."); + CloseGossipMenuFor(player); + return false; + } + + ClearGossipMenuFor(player); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "GM Island", GOSSIP_SENDER_MAIN, 100, "Buy Guild House on GM Island?", sConfigMgr->GetOption("CostGuildHouse", 10000000), false); + // Removing this tease for now, as right now the phasing code is specific go GM Island, so it's not a simple thing to add new areas yet. + // AddGossipItemFor(player, GOSSIP_ICON_CHAT, " ----- More to Come ----", GOSSIP_SENDER_MAIN, 4); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); + return true; + } + + void TeleportGuildHouse(Guild *guild, Player *player, Creature *creature) + { + GuildData *guildData = player->CustomData.GetDefault("phase"); + QueryResult result = CharacterDatabase.Query("SELECT `phase`, `map`,`positionX`, `positionY`, `positionZ`, `orientation` FROM guild_house WHERE `guild` = {}", guild->GetId()); + + if (!result) + { + ClearGossipMenuFor(player); + if (player->GetGuild()->GetLeaderGUID() == player->GetGUID()) + { + // Only leader of the guild can buy / sell guild house + AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Buy Guild House!", GOSSIP_SENDER_MAIN, 2); + AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Sell Guild House!", GOSSIP_SENDER_MAIN, 3, "Are you sure you want to sell your Guild House?", 0, false); + } + + AddGossipItemFor(player, GOSSIP_ICON_TABARD, "Teleport to Guild House", GOSSIP_SENDER_MAIN, 1); + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Close", GOSSIP_SENDER_MAIN, 5); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); + ChatHandler(player->GetSession()).PSendSysMessage("Your Guild does not own a Guild House"); + return; + } + + do + { + + Field *fields = result->Fetch(); + guildData->phase = fields[0].Get(); + uint32 map = fields[1].Get(); + guildData->posX = fields[2].Get(); + guildData->posY = fields[3].Get(); + guildData->posZ = fields[4].Get(); + guildData->ori = fields[5].Get(); + + player->TeleportTo(map, guildData->posX, guildData->posY, guildData->posZ, guildData->ori); + + } while (result->NextRow()); + } +}; + +class GuildHousePlayerScript : public PlayerScript +{ +public: + GuildHousePlayerScript() : PlayerScript("GuildHousePlayerScript") {} + + void OnLogin(Player *player) + { + CheckPlayer(player); + } + + void OnUpdateZone(Player *player, uint32 newZone, uint32 /*newArea*/) + { + if (newZone == 876) + CheckPlayer(player); + else + player->SetPhaseMask(GetNormalPhase(player), true); + } + + uint32 GetNormalPhase(Player *player) const + { + if (player->IsGameMaster()) + return PHASEMASK_ANYWHERE; + + uint32 phase = player->GetPhaseByAuras(); + if (!phase) + return PHASEMASK_NORMAL; + else + return phase; + } + + void CheckPlayer(Player *player) + { + GuildData *guildData = player->CustomData.GetDefault("phase"); + QueryResult result = CharacterDatabase.Query("SELECT `id`, `guild`, `phase`, `map`,`positionX`, `positionY`, `positionZ`, `orientation` FROM guild_house WHERE `guild` = {}", player->GetGuildId()); + + if (result) + { + do + { + // commented out due to travis, but keeping for future expansion into other areas + Field *fields = result->Fetch(); + // uint32 id = fields[0].Get(); // fix for travis + // uint32 guild = fields[1].Get(); // fix for travis + guildData->phase = fields[2].Get(); + // uint32 map = fields[3].Get(); // fix for travis + // guildData->posX = fields[4].Get(); // fix for travis + // guildData->posY = fields[5].Get(); // fix for travis + // guildData->posZ = fields[6].Get(); // fix for travis + // guildData->ori = fields[7].Get(); // fix for travis + + } while (result->NextRow()); + } + + if (player->GetZoneId() == 876 && player->GetAreaId() == 876) // GM Island + { + // If player is not in a guild he doesnt have a guild house teleport away + // TODO: What if they are in a guild, but somehow are in the wrong phaseMask and seeing someone else's area? + + if (!result || !player->GetGuild()) + { + ChatHandler(player->GetSession()).PSendSysMessage("Your guild does not own a Guild House."); + teleportToDefault(player); + return; + } + player->SetPhaseMask(guildData->phase, true); + } + else + player->SetPhaseMask(GetNormalPhase(player), true); + } + + void teleportToDefault(Player *player) + { + if (player->GetTeamId() == TEAM_ALLIANCE) + player->TeleportTo(0, -8833.379883f, 628.627991f, 94.006599f, 1.0f); + else + player->TeleportTo(1, 1486.048340f, -4415.140625f, 24.187496f, 0.13f); + } +}; + +using namespace Acore::ChatCommands; + +class GuildHouseCommand : public CommandScript +{ +public: + GuildHouseCommand() : CommandScript("GuildHouseCommand") {} + + ChatCommandTable GetCommands() const override + { + static ChatCommandTable GuildHouseCommandTable = + { + {"teleport", HandleGuildHouseTeleCommand, SEC_PLAYER, Console::Yes}, + {"butler", HandleSpawnButlerCommand, SEC_PLAYER, Console::Yes}, + }; + + static ChatCommandTable GuildHouseCommandBaseTable = + { + {"guildhouse", GuildHouseCommandTable}, + {"gh", GuildHouseCommandTable}}; + + return GuildHouseCommandBaseTable; + } + + static uint32 GetGuildPhase(Player *player) + { + return player->GetGuildId() + 10; + } + + static bool HandleSpawnButlerCommand(ChatHandler *handler) + { + Player *player = handler->GetSession()->GetPlayer(); + Map *map = player->GetMap(); + if (!player->GetGuild() || (player->GetGuild()->GetLeaderGUID() != player->GetGUID())) + { + handler->SendSysMessage("You must be the Guild Master of a guild to use this command!"); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->GetAreaId() != 876) + { + handler->SendSysMessage("You must be in your Guild House to use this command!"); + handler->SetSentErrorMessage(true); + return false; + } + + if (player->FindNearestCreature(500031, VISIBLE_RANGE, true)) + { + handler->SendSysMessage("You already have the Guild House Butler!"); + handler->SetSentErrorMessage(true); + return false; + } + + float posX = 16202.185547f; + float posY = 16255.916992f; + float posZ = 21.160221f; + float ori = 6.195375f; + + Creature *creature = new Creature(); + if (!creature->Create(map->GenerateLowGuid(), map, GetGuildPhase(player), 500031, 0, posX, posY, posZ, ori)) + { + handler->SendSysMessage("You already have the Guild House Butler!"); + handler->SetSentErrorMessage(true); + delete creature; + return false; + } + creature->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), GetGuildPhase(player)); + uint32 lowguid = creature->GetSpawnId(); + + creature->CleanupsBeforeDelete(); + delete creature; + creature = new Creature(); + if (!creature->LoadCreatureFromDB(lowguid, player->GetMap())) + { + handler->SendSysMessage("Something went wrong when adding the Butler."); + handler->SetSentErrorMessage(true); + delete creature; + return false; + } + + sObjectMgr->AddCreatureToGrid(lowguid, sObjectMgr->GetCreatureData(lowguid)); + return true; + } + + static bool HandleGuildHouseTeleCommand(ChatHandler *handler) + { + Player *player = handler->GetSession()->GetPlayer(); + + if (!player) + return false; + + if (player->IsInCombat()) + { + handler->SendSysMessage("You can't use this command while in combat!"); + handler->SetSentErrorMessage(true); + return false; + } + + GuildData *guildData = player->CustomData.GetDefault("phase"); + QueryResult result = CharacterDatabase.Query("SELECT `id`, `guild`, `phase`, `map`,`positionX`, `positionY`, `positionZ`, `orientation` FROM guild_house WHERE `guild` = {}", player->GetGuildId()); + + if (!result) + { + handler->SendSysMessage("Your guild does not own a Guild House!"); + handler->SetSentErrorMessage(true); + return false; + } + + do + { + + Field *fields = result->Fetch(); + // uint32 id = fields[0].Get(); // fix for travis + // uint32 guild = fields[1].Get(); // fix for travis + guildData->phase = fields[2].Get(); + uint32 map = fields[3].Get(); + guildData->posX = fields[4].Get(); + guildData->posY = fields[5].Get(); + guildData->posZ = fields[6].Get(); + guildData->ori = fields[7].Get(); + + player->TeleportTo(map, guildData->posX, guildData->posY, guildData->posZ, guildData->ori); + + } while (result->NextRow()); + + return true; + } +}; + +class GuildHouseGlobal : public GlobalScript +{ +public: + GuildHouseGlobal() : GlobalScript("GuildHouseGlobal") {} + + void OnBeforeWorldObjectSetPhaseMask(WorldObject const *worldObject, uint32 & /*oldPhaseMask*/, uint32 & /*newPhaseMask*/, bool &useCombinedPhases, bool & /*update*/) override + { + if (worldObject->GetZoneId() == 876) + useCombinedPhases = false; + else + useCombinedPhases = true; + } +}; + +void AddGuildHouseScripts() +{ + new GuildHelper(); + new GuildHouseSeller(); + new GuildHousePlayerScript(); + new GuildHouseCommand(); + new GuildHouseGlobal(); +} diff --git a/src/mod_guild_house_npc.cpp b/src/mod_guildhouse_butler.cpp similarity index 56% rename from src/mod_guild_house_npc.cpp rename to src/mod_guildhouse_butler.cpp index 28df421..2b23018 100644 --- a/src/mod_guild_house_npc.cpp +++ b/src/mod_guildhouse_butler.cpp @@ -1,6 +1,7 @@ #include "ScriptMgr.h" #include "Player.h" #include "Chat.h" +#include "ScriptedCreature.h" #include "ScriptedGossip.h" #include "Configuration/Config.h" #include "Creature.h" @@ -15,21 +16,38 @@ int cost, GuildHouseInnKeeper, GuildHouseBank, GuildHouseMailBox, GuildHouseAuctioneer, GuildHouseTrainer, GuildHouseVendor, GuildHouseObject, GuildHousePortal, GuildHouseSpirit, GuildHouseProf, GuildHouseBuyRank; -class GuildHouseSpawner : public CreatureScript { +class GuildHouseSpawner : public CreatureScript +{ public: - GuildHouseSpawner() : CreatureScript("GuildHouseSpawner") { } + GuildHouseSpawner() : CreatureScript("GuildHouseSpawner") {} - bool OnGossipHello(Player *player, Creature * creature) + struct GuildHouseSpawnerAI : public ScriptedAI + { + GuildHouseSpawnerAI(Creature *creature) : ScriptedAI(creature) {} + + void UpdateAI(uint32 /* diff */) override + { + me->SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_GOSSIP); + } + }; + + CreatureAI * + GetAI(Creature *creature) const override + { + return new GuildHouseSpawnerAI(creature); + } + + bool OnGossipHello(Player *player, Creature *creature) override { if (player->GetGuild()) { - Guild* guild = sGuildMgr->GetGuildById(player->GetGuildId()); - Guild::Member const* memberMe = guild->GetMember(player->GetGUID()); + Guild *guild = sGuildMgr->GetGuildById(player->GetGuildId()); + Guild::Member const *memberMe = guild->GetMember(player->GetGUID()); if (!memberMe->IsRankNotLower(GuildHouseBuyRank)) { - ChatHandler(player->GetSession()).PSendSysMessage("You are not authorized to make guild house purchases."); + ChatHandler(player->GetSession()).PSendSysMessage("You are not authorized to make Guild House purchases."); return false; } } @@ -40,29 +58,30 @@ public: } ClearGossipMenuFor(player); - AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Innkeeper", GOSSIP_SENDER_MAIN, 18649, "Add an Innkeeper?", GuildHouseInnKeeper, false); - AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Mailbox", GOSSIP_SENDER_MAIN, 184137, "Spawn a mailbox?", GuildHouseMailBox, false); + AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Innkeeper", GOSSIP_SENDER_MAIN, 500032, "Add an Innkeeper?", GuildHouseInnKeeper, false); + AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Mailbox", GOSSIP_SENDER_MAIN, 184137, "Spawn a Mailbox?", GuildHouseMailBox, false); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Stable Master", GOSSIP_SENDER_MAIN, 28690, "Spawn a Stable Master?", GuildHouseVendor, false); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Class Trainer", GOSSIP_SENDER_MAIN, 2); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Vendor", GOSSIP_SENDER_MAIN, 3); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn City Portals / Objects", GOSSIP_SENDER_MAIN, 4); - AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Spawn Bank", GOSSIP_SENDER_MAIN, 30605, "Spawn a banker?", GuildHouseBank, false); - AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Spawn Auctioneer", GOSSIP_SENDER_MAIN, 6, "Spawn an auctioneer", GuildHouseAuctioneer, false); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Spawn Bank", GOSSIP_SENDER_MAIN, 30605, "Spawn a Banker?", GuildHouseBank, false); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Spawn Auctioneer", GOSSIP_SENDER_MAIN, 6, "Spawn an Auctioneer?", GuildHouseAuctioneer, false); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Spawn Neutral Auctioneer", GOSSIP_SENDER_MAIN, 9858, "Spawn a Neutral Auctioneer?", GuildHouseAuctioneer, false); AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Spawn Primary Profession Trainers", GOSSIP_SENDER_MAIN, 7); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Spawn Secondry Profession Trainers", GOSSIP_SENDER_MAIN, 8); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Spawn Secondary Profession Trainers", GOSSIP_SENDER_MAIN, 8); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Spawn Sprirt Healer", GOSSIP_SENDER_MAIN, 6491, "Spawn a Spirit Healer?", GuildHouseSpirit, false); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); return true; } - bool OnGossipSelect(Player *player, Creature * m_creature, uint32, uint32 action) + bool OnGossipSelect(Player *player, Creature *m_creature, uint32, uint32 action) override { switch (action) { - case 2: // spawn class trainer + case 2: // Spawn Class Trainer ClearGossipMenuFor(player); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Death Knight", GOSSIP_SENDER_MAIN, 33251, "Spawn Death Knight Trainer?", GuildHouseTrainer, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Death Knight", GOSSIP_SENDER_MAIN, 29195, "Spawn Death Knight Trainer?", GuildHouseTrainer, false); AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Druid", GOSSIP_SENDER_MAIN, 26324, "Spawn Druid Trainer?", GuildHouseTrainer, false); AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Hunter", GOSSIP_SENDER_MAIN, 26325, "Spawn Hunter Trainer?", GuildHouseTrainer, false); AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Mage", GOSSIP_SENDER_MAIN, 26326, "Spawn Mage Trainer?", GuildHouseTrainer, false); @@ -79,38 +98,38 @@ public: ClearGossipMenuFor(player); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Trade Supplies", GOSSIP_SENDER_MAIN, 28692, "Spawn Trade Supplies?", GuildHouseVendor, false); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Tabard Vendor", GOSSIP_SENDER_MAIN, 28776, "Spawn Tabard Vendor?", GuildHouseVendor, false); - AddGossipItemFor(player, GOSSIP_ICON_TALK, "Food & Drink", GOSSIP_SENDER_MAIN, 70103, "Spawn Food & Drink?", GuildHouseVendor, false); + AddGossipItemFor(player, GOSSIP_ICON_TALK, "Food & Drink Vendor", GOSSIP_SENDER_MAIN, 4255, "Spawn Food & Drink Vendor?", GuildHouseVendor, false); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Reagent Vendor", GOSSIP_SENDER_MAIN, 29636, "Spawn Reagent Vendor?", GuildHouseVendor, false); - AddGossipItemFor(player, GOSSIP_ICON_TALK, "Ammo & Repair Vendor", GOSSIP_SENDER_MAIN, 70104, "Spawn Ammo & Repair Vendor?", GuildHouseVendor, false); + AddGossipItemFor(player, GOSSIP_ICON_TALK, "Ammo & Repair Vendor", GOSSIP_SENDER_MAIN, 29493, "Spawn Ammo & Repair Vendor?", GuildHouseVendor, false); + AddGossipItemFor(player, GOSSIP_ICON_TALK, "Poisons Vendor", GOSSIP_SENDER_MAIN, 2622, "Spawn Poisons Vendor?", GuildHouseVendor, false); AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; - case 4: //objects / portals + case 4: // Objects & Portals ClearGossipMenuFor(player); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Forge", GOSSIP_SENDER_MAIN, 1685, "Add a forge?", GuildHouseObject, false); AddGossipItemFor(player, GOSSIP_ICON_TALK, "Anvil", GOSSIP_SENDER_MAIN, 4087, "Add an Anvil?", GuildHouseObject, false); - AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Guild Vault", GOSSIP_SENDER_MAIN, 187293, "Add Guild Vault?", GuildHouseObject, false); - AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "Barber Chair", GOSSIP_SENDER_MAIN, 191028, "Add a Barber Chair?", GuildHouseObject, false); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Guild Vault", GOSSIP_SENDER_MAIN, 187293, "Add Guild Vault?", GuildHouseObject, false); + AddGossipItemFor(player, GOSSIP_ICON_INTERACT_1, "Barber Chair", GOSSIP_SENDER_MAIN, 191028, "Add a Barber Chair?", GuildHouseObject, false); - if (player->GetTeamId() == TEAM_ALLIANCE) // ALLIANCE players get these options + if (player->GetTeamId() == TEAM_ALLIANCE) { - // Commenting out as we are auto-creating Stormwind portal upon guild purchase - //AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Stormwind", GOSSIP_SENDER_MAIN, 183325, "Add Stormwind Portal?", GuildHousePortal, false); - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Ironforge", GOSSIP_SENDER_MAIN, 183322, "Add Ironforge Portal?", GuildHousePortal, false); - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Darnassus", GOSSIP_SENDER_MAIN, 183317, "Add Darnassus Portal?", GuildHousePortal, false); - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Exodar", GOSSIP_SENDER_MAIN, 183321, "Add Exodar Portal?", GuildHousePortal, false); + // ALLIANCE players get these options + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Ironforge", GOSSIP_SENDER_MAIN, 500003, "Add Ironforge Portal?", GuildHousePortal, false); + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Darnassus", GOSSIP_SENDER_MAIN, 500001, "Add Darnassus Portal?", GuildHousePortal, false); + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Exodar", GOSSIP_SENDER_MAIN, 500002, "Add Exodar Portal?", GuildHousePortal, false); } - else // HORDE players get these options: + else { - // Commenting out as we are auto-creating Orgrimmar portal upon guild purchase - //AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Orgrimmar", GOSSIP_SENDER_MAIN, 183323, "Add Orgrimmar Portal?", GuildHousePortal, false); - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Undercity", GOSSIP_SENDER_MAIN, 183327, "Add Undercity Portal?", GuildHousePortal, false); - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Thunderbluff", GOSSIP_SENDER_MAIN, 183326, "Add Thunderbuff Portal?", GuildHousePortal, false); - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Silvermoon", GOSSIP_SENDER_MAIN, 183324, "Add Silvermoon Portal?", GuildHousePortal, false); + // HORDE players get these options + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Undercity", GOSSIP_SENDER_MAIN, 500007, "Add Undercity Portal?", GuildHousePortal, false); + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Thunderbluff", GOSSIP_SENDER_MAIN, 500006, "Add Thunderbuff Portal?", GuildHousePortal, false); + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Silvermoon", GOSSIP_SENDER_MAIN, 500005, "Add Silvermoon Portal?", GuildHousePortal, false); } - // These two portals work for either Team - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Shattrath", GOSSIP_SENDER_MAIN, 191013, "Add Shattrath Portal?", GuildHousePortal, false); - AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Dalaran", GOSSIP_SENDER_MAIN, 195682, "Add Dalaran Portal?", GuildHousePortal, false); + + // These two portals work for either Team + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Shattrath", GOSSIP_SENDER_MAIN, 500008, "Add Shattrath Portal?", GuildHousePortal, false); + AddGossipItemFor(player, GOSSIP_ICON_TAXI, "Portal: Dalaran", GOSSIP_SENDER_MAIN, 500009, "Add Dalaran Portal?", GuildHousePortal, false); AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); @@ -122,109 +141,129 @@ public: SpawnNPC(auctioneer, player); break; } - case 7: // spawn profession trainers + case 9858: // Neutral Auctioneer + cost = GuildHouseAuctioneer; + SpawnNPC(action, player); + break; + case 7: // Spawn Profession Trainers ClearGossipMenuFor(player); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Alchemy Trainer", GOSSIP_SENDER_MAIN, 33608, "Spawn Alchemy Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Blacksmithing Trainer", GOSSIP_SENDER_MAIN, 33609, "Spawn Blacksmithing Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Enchanting Trainer", GOSSIP_SENDER_MAIN, 33610, "Spawn Enchanting Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Engineering Trainer", GOSSIP_SENDER_MAIN, 33611, "Spawn Engineering Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Tailoring Trainer", GOSSIP_SENDER_MAIN, 33613, "Spawn Tailoring Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Leatherworking Trainer", GOSSIP_SENDER_MAIN, 33612, "Spawn Leatherworking Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Jewlelcrafing Trainer", GOSSIP_SENDER_MAIN, 33614, "Spawn Jewelcrafting Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Inscription Trainer", GOSSIP_SENDER_MAIN, 33615, "Spawn Inscription Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Skinning Trainer", GOSSIP_SENDER_MAIN, 33618, "Spawn Skinning Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Mining Trainer", GOSSIP_SENDER_MAIN, 33617, "Spawn Mining Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Herbalism Trainer", GOSSIP_SENDER_MAIN, 33616, "Spawn Herbalism Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Alchemy Trainer", GOSSIP_SENDER_MAIN, 19052, "Spawn Alchemy Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Blacksmithing Trainer", GOSSIP_SENDER_MAIN, 2836, "Spawn Blacksmithing Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Engineering Trainer", GOSSIP_SENDER_MAIN, 8736, "Spawn Engineering Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Tailoring Trainer", GOSSIP_SENDER_MAIN, 2627, "Spawn Tailoring Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Leatherworking Trainer", GOSSIP_SENDER_MAIN, 19187, "Spawn Leatherworking Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Skinning Trainer", GOSSIP_SENDER_MAIN, 19180, "Spawn Skinning Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Mining Trainer", GOSSIP_SENDER_MAIN, 8128, "Spawn Mining Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Herbalism Trainer", GOSSIP_SENDER_MAIN, 908, "Spawn Herbalism Trainer?", GuildHouseProf, false); + + if (player->GetTeamId() == TEAM_ALLIANCE) + { + // ALLIANCE players get these options + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Enchanting Trainer", GOSSIP_SENDER_MAIN, 18773, "Spawn Enchanting Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Jewelcrafing Trainer", GOSSIP_SENDER_MAIN, 18774, "Spawn Jewelcrafting Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Inscription Trainer", GOSSIP_SENDER_MAIN, 30721, "Spawn Inscription Trainer?", GuildHouseProf, false); + } + else + { + // HORDE players get these options + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Enchanting Trainer", GOSSIP_SENDER_MAIN, 18753, "Spawn Enchanting Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Jewelcrafing Trainer", GOSSIP_SENDER_MAIN, 18751, "Spawn Jewelcrafting Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Inscription Trainer", GOSSIP_SENDER_MAIN, 30722, "Spawn Inscription Trainer?", GuildHouseProf, false); + } + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; - case 8: // secondry prof trainers + case 8: // Secondary Profession Trainers ClearGossipMenuFor(player); - AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "First Aid Trainer", GOSSIP_SENDER_MAIN, 33621, "Spawn Fist Aid Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Fishing Trainer", GOSSIP_SENDER_MAIN, 33623, "Spawn Fishing Trainer?", GuildHouseProf, false); - AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Cooking Trainer", GOSSIP_SENDER_MAIN, 33619, "Spawn Cooking Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "First Aid Trainer", GOSSIP_SENDER_MAIN, 19184, "Spawn First Aid Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Fishing Trainer", GOSSIP_SENDER_MAIN, 2834, "Spawn Fishing Trainer?", GuildHouseProf, false); + AddGossipItemFor(player, GOSSIP_ICON_MONEY_BAG, "Cooking Trainer", GOSSIP_SENDER_MAIN, 19185, "Spawn Cooking Trainer?", GuildHouseProf, false); AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; - case 9: // go back! + case 9: // Go back! OnGossipHello(player, m_creature); break; - case 10: //PVP toggle + case 10: // PVP toggle break; case 30605: // Banker cost = GuildHouseBank; SpawnNPC(action, player); break; - case 18649: // Innkeeper + case 500032: // Innkeeper cost = GuildHouseInnKeeper; SpawnNPC(action, player); break; case 26327: // Paladin case 26324: // Druid case 26325: // Hunter - case 26326: // Mage - case 26328: // Priest. + case 26326: // Mage + case 26328: // Priest case 26329: // Rogue case 26330: // Shaman case 26331: // Warlock case 26332: // Warrior - case 33251: // Death Knight + case 29195: // Death Knight cost = GuildHouseTrainer; SpawnNPC(action, player); break; - case 33609: // Blacksmithing - case 33617: // Mining - case 33611: // Engineering - case 33614: // Jewelcrafting - case 33610: // Enchanting - case 33615: // Inscription - case 33612: // Leatherworking - case 33618: // Skinning - case 33608: // Alchemy - case 33616: // Herbalism - case 33613: // Tailoring - case 33619: // Cooking - case 33623: // Fishing - case 33621: // First Aid + case 2836: // Blacksmithing + case 8128: // Mining + case 8736: // Engineering + case 18774: // Jewelcrafting (Alliance) + case 18751: // Jewelcrafting (Horde) + case 18773: // Enchanting (Alliance) + case 18753: // Enchanting (Horde) + case 30721: // Inscription (Alliance) + case 30722: // Inscription (Horde) + case 19187: // Leatherworking + case 19180: // Skinning + case 19052: // Alchemy + case 908: // Herbalism + case 2627: // Tailoring + case 19185: // Cooking + case 2834: // Fishing + case 19184: // First Aid cost = GuildHouseProf; SpawnNPC(action, player); break; - case 28692: // Trade supplies + case 28692: // Trade Supplies case 28776: // Tabard Vendor - case 70103: // Food & Drink + case 4255: // Food & Drink Vendor case 29636: // Reagent Vendor - case 70104: // Ammo & Repair Vendor + case 29493: // Ammo & Repair Vendor case 28690: // Stable Master + case 2622: // Poisons Vendor cost = GuildHouseVendor; SpawnNPC(action, player); break; // // Objects // - case 184137: // mailbox + case 184137: // Mailbox cost = GuildHouseMailBox; SpawnObject(action, player); break; - case 6491: // spirit healer + case 6491: // Spirit Healer cost = GuildHouseSpirit; SpawnNPC(action, player); - break; - case 1685: // forge - case 4087: // Anvil + break; + case 1685: // Forge + case 4087: // Anvil case 187293: // Guild Vault case 191028: // Barber Chair cost = GuildHouseObject; SpawnObject(action, player); break; - case 183322: // Ironforge Portal - case 183327: // Undercity Portal - case 183317: // Darnassus Portal - case 183326: // Thunder bluff portal - case 183324: // Silvermoon Portal - case 183321: // Exodar Portal - case 191013: // Shattrath Portal:Alliance - case 191014: // Shattrath Portal:Horde - case 195682: // Dalaran Portal + case 500001: // Darnassus Portal + case 500002: // Exodar Portal + case 500003: // Ironforge Portal + case 500005: // Silvermoon Portal + case 500006: // Thunder Bluff Portal + case 500007: // Undercity Portal + case 500008: // Shattrath Portal + case 500009: // Dalaran Portal cost = GuildHousePortal; SpawnObject(action, player); break; @@ -232,11 +271,12 @@ public: return true; } - uint32 GetGuildPhase(Player* player) { - return player->GetGuildId() + 10; - } + uint32 GetGuildPhase(Player *player) + { + return player->GetGuildId() + 10; + } - void SpawnNPC(uint32 entry, Player* player) + void SpawnNPC(uint32 entry, Player *player) { if (player->FindNearestCreature(entry, VISIBILITY_RANGE, true)) { @@ -250,30 +290,30 @@ public: float posZ; float ori; - QueryResult result = WorldDatabase.PQuery("SELECT `posX`, `posY`, `posZ`, `orientation` FROM `guild_house_spawns` WHERE `entry` = %u", entry); + QueryResult result = WorldDatabase.Query("SELECT `posX`, `posY`, `posZ`, `orientation` FROM `guild_house_spawns` WHERE `entry` = {}", entry); if (!result) return; do { - Field* fields = result->Fetch(); - posX = fields[0].GetFloat(); - posY = fields[1].GetFloat(); - posZ = fields[2].GetFloat(); - ori = fields[3].GetFloat(); + Field *fields = result->Fetch(); + posX = fields[0].Get(); + posY = fields[1].Get(); + posZ = fields[2].Get(); + ori = fields[3].Get(); } while (result->NextRow()); - Creature* creature = new Creature(); + Creature *creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), player->GetMap(), GetGuildPhase(player), entry, 0, posX,posY, posZ, ori)) + if (!creature->Create(player->GetMap()->GenerateLowGuid(), player->GetMap(), GetGuildPhase(player), entry, 0, posX, posY, posZ, ori)) { delete creature; return; } creature->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), GetGuildPhase(player)); - uint32 db_guid = creature->GetDBTableGUIDLow(); + uint32 db_guid = creature->GetSpawnId(); creature->CleanupsBeforeDelete(); delete creature; @@ -289,28 +329,8 @@ public: CloseGossipMenuFor(player); } - void SpawnObject(uint32 entry, Player* player) + void SpawnObject(uint32 entry, Player *player) { - float posX; - float posY; - float posZ; - float ori; - - QueryResult result = WorldDatabase.PQuery("SELECT `posX`, `posY`, `posZ`, `orientation` FROM `guild_house_spawns` WHERE `entry` = %u", entry); - - if (!result) - return; - - do - { - Field* fields = result->Fetch(); - posX = fields[0].GetFloat(); - posY = fields[1].GetFloat(); - posZ = fields[2].GetFloat(); - ori = fields[3].GetFloat(); - - } while (result->NextRow()); - if (player->FindNearestGameObject(entry, VISIBLE_RANGE)) { ChatHandler(player->GetSession()).PSendSysMessage("You already have this object!"); @@ -318,20 +338,40 @@ public: return; } + float posX; + float posY; + float posZ; + float ori; + + QueryResult result = WorldDatabase.Query("SELECT `posX`, `posY`, `posZ`, `orientation` FROM `guild_house_spawns` WHERE `entry` = {}", entry); + + if (!result) + return; + + do + { + Field *fields = result->Fetch(); + posX = fields[0].Get(); + posY = fields[1].Get(); + posZ = fields[2].Get(); + ori = fields[3].Get(); + + } while (result->NextRow()); + uint32 objectId = entry; if (!objectId) return; - const GameObjectTemplate* objectInfo = sObjectMgr->GetGameObjectTemplate(objectId); + const GameObjectTemplate *objectInfo = sObjectMgr->GetGameObjectTemplate(objectId); if (!objectInfo) return; if (objectInfo->displayId && !sGameObjectDisplayInfoStore.LookupEntry(objectInfo->displayId)) - return ; + return; - GameObject* object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); - uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); + GameObject *object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); + ObjectGuid::LowType guidLow = player->GetMap()->GenerateLowGuid(); if (!object->Create(guidLow, objectInfo->entry, player->GetMap(), GetGuildPhase(player), posX, posY, posZ, ori, G3D::Quat(), 0, GO_STATE_READY)) { @@ -341,13 +381,14 @@ public: // fill the gameobject data and save to the db object->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), GetGuildPhase(player)); + guidLow = object->GetSpawnId(); // delete the old object and do a clean load from DB with a fresh new GameObject instance. // this is required to avoid weird behavior and memory leaks delete object; object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); // this will generate a new guid if the object is in an instance - if (!object->LoadGameObjectFromDB(guidLow, player->GetMap())) + if (!object->LoadGameObjectFromDB(guidLow, player->GetMap(), true)) { delete object; return; @@ -360,29 +401,29 @@ public: } }; -class GuildHouseNPCConf : public WorldScript +class GuildHouseButlerConf : public WorldScript { public: - GuildHouseNPCConf() : WorldScript("GuildHouseNPCConf") {} + GuildHouseButlerConf() : WorldScript("GuildHouseButlerConf") {} void OnBeforeConfigLoad(bool /*reload*/) override { - GuildHouseInnKeeper = sConfigMgr->GetIntDefault("GuildHouseInnKeeper", 1000000); - GuildHouseBank = sConfigMgr->GetIntDefault("GuildHouseBank", 1000000); - GuildHouseMailBox = sConfigMgr->GetIntDefault("GuildHouseMailbox", 500000); - GuildHouseAuctioneer = sConfigMgr->GetIntDefault("GuildHouseAuctioneer", 500000); - GuildHouseTrainer = sConfigMgr->GetIntDefault("GuildHouseTrainerCost", 1000000); - GuildHouseVendor = sConfigMgr->GetIntDefault("GuildHouseVendor", 500000); - GuildHouseObject = sConfigMgr->GetIntDefault("GuildHouseObject", 500000); - GuildHousePortal = sConfigMgr->GetIntDefault("GuildHousePortal", 500000); - GuildHouseProf = sConfigMgr->GetIntDefault("GuildHouseProf", 500000); - GuildHouseSpirit = sConfigMgr->GetIntDefault("GuildHouseSpirit", 100000); - GuildHouseBuyRank = sConfigMgr->GetIntDefault("GuildHouseBuyRank", 0); + GuildHouseInnKeeper = sConfigMgr->GetOption("GuildHouseInnKeeper", 1000000); + GuildHouseBank = sConfigMgr->GetOption("GuildHouseBank", 1000000); + GuildHouseMailBox = sConfigMgr->GetOption("GuildHouseMailbox", 500000); + GuildHouseAuctioneer = sConfigMgr->GetOption("GuildHouseAuctioneer", 500000); + GuildHouseTrainer = sConfigMgr->GetOption("GuildHouseTrainerCost", 1000000); + GuildHouseVendor = sConfigMgr->GetOption("GuildHouseVendor", 500000); + GuildHouseObject = sConfigMgr->GetOption("GuildHouseObject", 500000); + GuildHousePortal = sConfigMgr->GetOption("GuildHousePortal", 500000); + GuildHouseProf = sConfigMgr->GetOption("GuildHouseProf", 500000); + GuildHouseSpirit = sConfigMgr->GetOption("GuildHouseSpirit", 100000); + GuildHouseBuyRank = sConfigMgr->GetOption("GuildHouseBuyRank", 4); } }; -void AddGuildHouseV2NPCScripts() +void AddGuildHouseButlerScripts() { new GuildHouseSpawner(); - new GuildHouseNPCConf(); + new GuildHouseButlerConf(); }