diff --git a/.gitignore b/.gitignore index c6e1299..ade4c67 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,8 @@ local.properties .loadpath .project .cproject + +# +# Config file +# +conf/mod_guild_house_v2.conf diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..848d188 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,76 @@ +sudo: required +dist: bionic # (18.04) + +language: cpp + +cache: ccache + +addons: + apt: + update: true + +services: + - mysql + +git: + depth: 10 + +stages: + - prepare_cache + - run + +jobs: + include: + - stage: prepare_cache + env: TRAVIS_BUILD_ID="1" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh OFF + script: + - source ./apps/ci/ci-compile.sh + + - stage: run + env: TRAVIS_BUILD_ID="1" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh ON + - source ./apps/ci/ci-import-db.sh + script: + - source ./apps/ci/ci-compile.sh + - source ./apps/ci/ci-worldserver-dry-run.sh + + - stage: prepare_cache + env: TRAVIS_BUILD_ID="2" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh OFF + script: + - source ./apps/ci/ci-compile.sh + + - stage: run + env: TRAVIS_BUILD_ID="2" + before_install: + - cd .. + - git clone --depth=1 --branch=master https://github.com/azerothcore/azerothcore-wotlk.git azerothcore-wotlk + - mv "$TRAVIS_BUILD_DIR" azerothcore-wotlk/modules + - cd azerothcore-wotlk + - source ./apps/ci/ci-before_install.sh + install: + - source ./apps/ci/ci-install.sh ON + script: + - source ./apps/ci/ci-compile.sh diff --git a/README.md b/README.md index e297534..d3e0010 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,48 @@ - +# ![logo](https://raw.githubusercontent.com/azerothcore/azerothcore.github.io/master/images/logo-github.png) AzerothCore +- Latest build status with azerothcore: [![Build Status](https://travis-ci.org/azerothcore/mod-guildhouse.svg?branch=master)](https://travis-ci.org/azerothcore/mod-guildhouse) # Guild House Module ## Description -This is a phased guild house system for Azerothcore, it allows players to from the same guild to visit their guild house to explore, train ect -All guilds will get their own phasing system which then the guild master will have to purchase NPC's creatures and other stuff to complete the creation. +This is a phased guild house system for AzerothCore, it allows players from the same guild to visit their guild house. +All guilds will get their own phasing system and then the guild master can purchase NPC creatures and other stuff to complete the Guild House. + +### Purchasables +* Class Trainers (all available in Wrath) +* Primary Profession Trainers (all available in Wrath) +* Secondary Profession Trainers (all available in Wrath) +* Vendors: Reagents Vendor, Food & Water, Trade Goods, and Repairs/Ammo Vendor +* Portals to Neutral, Horde and Alliance cities +* Spirit Healer +* Guild Bank and Personal Bank access +* Auctioneer +* Stable Master ## How to use ingame -Once a player has brought a guild house from the NPC they can either teleport to the guildhouse by via the NPC or do .guildhouse tele -Once the player is in the location of the guild house the guild master has a command .guildhouse spawnnpc this will allow the guild master -to start placing objects / npc within the guild house. +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` +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 -My new module requires: - - AzerothCore v1.0.1+ ## Installation ``` -1) Simply place the module under the `modules` directory of your AzerothCore source. -2) Import the SQL manually to the right Database (auth, world or characters) +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) Apply the guildhouse.patch to your source 4) Re-run cmake and launch a clean build of AzerothCore. ``` -## Patch Information -The patch basicly turns the selected area from a bitmask to a uint, this fixes the issues with the phasing +## Patch Information (guildhouse.patch) + +The patch basically turns the selected area from a bitmask to a uint, this fixes the issues with the phasing on GM Island ONLY Before Patch : Guild 1 Can see phase 1 @@ -46,7 +58,8 @@ If you need to change the module configuration, go to your server configuration ## Credits -* [Me](https://github.com/talamortis) (author of the module) +* [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) -AzerothCore: [repository](https://github.com/azerothcore) - [website](http://azerothcore.org/) - [discord chat community](https://discord.gg/PaqQRkd) +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_guild_house_v2.conf.dist index 4044c32..189376c 100644 --- a/conf/mod_guild_house_v2.conf.dist +++ b/conf/mod_guild_house_v2.conf.dist @@ -63,9 +63,29 @@ GuildHouseObject = 500000 # GuildHousePortal = 1000000 -# GuildHouseProff +# GuildHouseProf # # Cost of profession vendors within the guild. # default = 500000 (50g) # -GuildHouseProff = 500000 +GuildHouseProf = 500000 + +# GuildHouseSpirit +# +# Cost of Spirit Healer at the guildhouse graveyard . +# default = 100000 (10g) +# +GuildHouseSpirit = 100000 + +# GuildHouseBuyRank +# +# Minimum GuildRank able to make purchases in guild house +# default = 0 (Guild Master) +# GR_GUILDMASTER = 0 +# GR_OFFICER = 1 +# GR_VETERAN = 2 +# GR_MEMBER = 3 +# GR_INITIATE = 4 +# +GuildHouseBuyRank = 0 + diff --git a/guildhouse.patch b/guildhouse.patch index 73ed2f8..b3a0613 100644 --- a/guildhouse.patch +++ b/guildhouse.patch @@ -1,17 +1,17 @@ -diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h -index 0d779cd7..4d0d0594 100644 ---- a/src/server/game/Entities/Object/Object.h -+++ b/src/server/game/Entities/Object/Object.h -@@ -796,7 +796,11 @@ class WorldObject : public Object, public WorldLocation - virtual void SetPhaseMask(uint32 newPhaseMask, bool update); - uint32 GetPhaseMask() const { return m_phaseMask; } - bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); } -- bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); } -+ bool InSamePhase(uint32 phasemask) const { -+ if (GetZoneId() == 876) -+ return GetPhaseMask() == phasemask; -+ return (GetPhaseMask() & phasemask) != 0; -+ } - - virtual uint32 GetZoneId(bool forceRecalc = false) const; - virtual uint32 GetAreaId(bool forceRecalc = false) const; +diff --git a/src/server/game/Entities/Object/Object.h b/src/server/game/Entities/Object/Object.h +index 0d779cd7..4d0d0594 100644 +--- a/src/server/game/Entities/Object/Object.h ++++ b/src/server/game/Entities/Object/Object.h +@@ -796,7 +796,11 @@ class WorldObject : public Object, public WorldLocation + virtual void SetPhaseMask(uint32 newPhaseMask, bool update); + uint32 GetPhaseMask() const { return m_phaseMask; } + bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); } +- bool InSamePhase(uint32 phasemask) const { return (GetPhaseMask() & phasemask); } ++ bool InSamePhase(uint32 phasemask) const { ++ if (GetZoneId() == 876) ++ return GetPhaseMask() == phasemask; ++ return (GetPhaseMask() & phasemask) != 0; ++ } + + virtual uint32 GetZoneId(bool forceRecalc = false) const; + virtual uint32 GetAreaId(bool forceRecalc = false) const; diff --git a/sql/world/Creatures.sql b/sql/world/Creatures.sql index a71ddc0..ddba569 100644 --- a/sql/world/Creatures.sql +++ b/sql/world/Creatures.sql @@ -1,5 +1,6 @@ -REPLACE INTO `creature_template` VALUES (70101, 0, 0, 0, 0, 0, 25901, 0, 0, 0, 'Talamortis', 'Guild House Seller', '', 0, 35, 35, 0, 12, 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, 'GuildHouseSeller', 12340), +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, '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, 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, '', 12340), -(70102, 0, 0, 0, 0, 0, 25901, 0, 0, 0, 'Speedfang', 'Guild House Assistant', '', 0, 35, 35, 0, 12, 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, 'GuildHouseSpawner', 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, '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, '', 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, '', 12340); diff --git a/sql/world/Vendor_items.sql b/sql/world/Vendor_items.sql new file mode 100644 index 0000000..8075abd --- /dev/null +++ b/sql/world/Vendor_items.sql @@ -0,0 +1,2 @@ +REPLACE INTO `npc_vendor` VALUES(70103, 0, 1179, 0, 0, 0, 12340),(70103, 0, 414, 0, 0, 0, 12340),(70103, 0, 1205, 0, 0, 0, 12340),(70103, 0, 422, 0, 0, 0, 12340),(70103, 0, 1708, 0, 0, 0, 12340),(70103, 0, 1707, 0, 0, 0, 12340),(70103, 0, 1645, 0, 0, 0, 12340),(70103, 0, 1707, 0, 0, 0, 12340),(70103, 0, 8766, 0, 0, 0, 12340),(70103, 0, 8953, 0, 0, 0, 12340),(70103, 0, 18300, 0, 0, 0, 12340),(70103, 0, 29393, 0, 0, 0, 12340),(70103, 0, 27860, 0, 0, 0, 12340),(70103, 0, 38428, 0, 0, 0, 12340),(70103, 0, 44941, 0, 0, 0, 12340),(70103, 0, 42430, 0, 0, 0, 12340),(70103, 0, 33445, 0, 0, 0, 12340),(70103, 0, 42431, 0, 0, 0, 12340), +(70104, 0, 2515, 0, 0, 0, 12340),(70104, 0, 2519, 0, 0, 0, 12340),(70104, 0, 3030, 0, 0, 0, 12340),(70104, 0, 11285, 0, 0, 0, 12340),(70104, 0, 11284, 0, 0, 0, 12340),(70104, 0, 28053, 0, 0, 0, 12340),(70104, 0, 28060, 0, 0, 0, 12340),(70104, 0, 28056, 0, 0, 0, 12340),(70104, 0, 28061, 0, 0, 0, 12340),(70104, 0, 41586, 0, 0, 0, 12340),(70104, 0, 41584, 0, 0, 0, 12340) diff --git a/sql/world/guild_house_spawns.sql b/sql/world/guild_house_spawns.sql index aa7fafd..cdb6100 100644 --- a/sql/world/guild_house_spawns.sql +++ b/sql/world/guild_house_spawns.sql @@ -44,7 +44,7 @@ CREATE TABLE IF NOT EXISTS `guild_house_spawns` ( UNIQUE KEY `entry` (`entry`) ) ENGINE=InnoDB AUTO_INCREMENT=51 DEFAULT CHARSET=utf8; --- Dumping data for table acore_world.guild_house_spawns: ~29 rows (approximately) +-- 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'), @@ -86,12 +86,18 @@ REPLACE INTO `guild_house_spawns` (`id`, `entry`, `posX`, `posY`, `posZ`, `orien (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, 191164, 16206, 16216, 1.10669, 1.0453, 'Portal: Dalaran (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, 29715, 16223.7, 16293.3, 20.852, 4.57958, 'Food & Drink'), - (50, 191028, 16255.5, 16304.9, 20.9785, 2.97516, 'Barber Chair (Object)'); + (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 */; diff --git a/src/mod_guild_house_npc.cpp b/src/mod_guild_house_npc.cpp index 933091f..28df421 100644 --- a/src/mod_guild_house_npc.cpp +++ b/src/mod_guild_house_npc.cpp @@ -1,5 +1,7 @@ #include "ScriptMgr.h" #include "Player.h" +#include "Chat.h" +#include "ScriptedGossip.h" #include "Configuration/Config.h" #include "Creature.h" #include "Guild.h" @@ -9,8 +11,9 @@ #include "DataMap.h" #include "GameObject.h" #include "Transport.h" +#include "CreatureAI.h" -int cost, GuildHouseInnKeeper, GuildHouseBank, GuildHouseMailBox, GuildHouseAuctioneer, GuildHouseTrainer, GuildHouseVendor, GuildHouseObject, GuildHousePortal, GuildHouseProff; +int cost, GuildHouseInnKeeper, GuildHouseBank, GuildHouseMailBox, GuildHouseAuctioneer, GuildHouseTrainer, GuildHouseVendor, GuildHouseObject, GuildHousePortal, GuildHouseSpirit, GuildHouseProf, GuildHouseBuyRank; class GuildHouseSpawner : public CreatureScript { @@ -22,9 +25,11 @@ class GuildHouseSpawner : public CreatureScript { if (player->GetGuild()) { - if (player->GetGuild()->GetLeaderGUID() != 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 the guild leader, sorry i cant do business with you"); + ChatHandler(player->GetSession()).PSendSysMessage("You are not authorized to make guild house purchases."); return false; } } @@ -34,71 +39,81 @@ class GuildHouseSpawner : public CreatureScript { return false; } - player->PlayerTalkClass->ClearMenus(); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Spawn Innkeeper", GOSSIP_SENDER_MAIN, 18649, "Add a Innkeeper?", GuildHouseInnKeeper, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Spawn Mailbox", GOSSIP_SENDER_MAIN, 184137, "Spawn a mailbox?", GuildHouseMailBox, false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Spawn Class Trainer", GOSSIP_SENDER_MAIN, 2); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Spawn Vendor", GOSSIP_SENDER_MAIN, 3); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Spawn City Portals / Objects", GOSSIP_SENDER_MAIN, 4); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "Spawn Bank", GOSSIP_SENDER_MAIN, 30605, "Spawn banker?", GuildHouseBank, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "Spawn Auctioneer", GOSSIP_SENDER_MAIN, 6, "Spawn auctioneer", GuildHouseAuctioneer, false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, "Spawn Primary Profession Trainers", GOSSIP_SENDER_MAIN, 7); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TRAINER, "Spawn Secondry Profession Trainers", GOSSIP_SENDER_MAIN, 8); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); + 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 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_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_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 sender, uint32 action) + bool OnGossipSelect(Player *player, Creature * m_creature, uint32, uint32 action) { switch (action) { case 2: // spawn class trainer - player->PlayerTalkClass->ClearMenus(); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Death Knight", GOSSIP_SENDER_MAIN, 33251, "Spawn Death Knight Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Druid", GOSSIP_SENDER_MAIN, 26324, "Spawn Druid Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Hunter", GOSSIP_SENDER_MAIN, 26325, "Spawn Hunter Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Mage", GOSSIP_SENDER_MAIN, 26326, "Spawn Mage Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Paladin", GOSSIP_SENDER_MAIN, 26327, "Spawn Paladin Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Priest", GOSSIP_SENDER_MAIN, 26328, "Spawn Priest Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Rogue", GOSSIP_SENDER_MAIN, 26329, "Spawn Rogue Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Shaman", GOSSIP_SENDER_MAIN, 26330, "Spawn Shaman Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Warlock", GOSSIP_SENDER_MAIN, 26331, "Spawn Warlock Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Warrior", GOSSIP_SENDER_MAIN, 26332, "Spawn Warrior Trainer?", GuildHouseTrainer, false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); + ClearGossipMenuFor(player); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Death Knight", GOSSIP_SENDER_MAIN, 33251, "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); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Paladin", GOSSIP_SENDER_MAIN, 26327, "Spawn Paladin Trainer?", GuildHouseTrainer, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Priest", GOSSIP_SENDER_MAIN, 26328, "Spawn Priest Trainer?", GuildHouseTrainer, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Rogue", GOSSIP_SENDER_MAIN, 26329, "Spawn Rogue Trainer?", GuildHouseTrainer, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Shaman", GOSSIP_SENDER_MAIN, 26330, "Spawn Shaman Trainer?", GuildHouseTrainer, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Warlock", GOSSIP_SENDER_MAIN, 26331, "Spawn Warlock Trainer?", GuildHouseTrainer, false); + AddGossipItemFor(player, GOSSIP_ICON_TRAINER, "Warrior", GOSSIP_SENDER_MAIN, 26332, "Spawn Warrior Trainer?", GuildHouseTrainer, false); + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; case 3: // Vendors - player->PlayerTalkClass->ClearMenus(); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Trade Supplies", GOSSIP_SENDER_MAIN, 28692, "Spawn Trade Supplies?", GuildHouseVendor, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Tabard Vendor", GOSSIP_SENDER_MAIN, 28776, "Spawn Tabard Vendor?", GuildHouseVendor, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Food & Drink", GOSSIP_SENDER_MAIN, 29715, "Spawn Food & Drink?", GuildHouseVendor, false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); + 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, "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_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; case 4: //objects / portals - player->PlayerTalkClass->ClearMenus(); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Forge", GOSSIP_SENDER_MAIN, 1685, "Add a forge?", GuildHouseObject, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TALK, "Anvil", GOSSIP_SENDER_MAIN, 4087, "Add a Anvil?", GuildHouseObject, false); - if (player->GetTeamId() == TEAM_ALLIANCE) + 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); + + if (player->GetTeamId() == TEAM_ALLIANCE) // ALLIANCE players get these options { - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Stormwind", GOSSIP_SENDER_MAIN, 183325, "Add Stormwind Portal?", GuildHousePortal, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Ironforge", GOSSIP_SENDER_MAIN, 183322, "Add Ironforge Portal?", GuildHousePortal, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Darnassus", GOSSIP_SENDER_MAIN, 183317, "Add Darnassus Portal?", GuildHousePortal, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Exodar", GOSSIP_SENDER_MAIN, 183321, "Add Exodar Portal?", GuildHousePortal, false); + // 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); } - else + else // HORDE players get these options: { - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Orgrimmar", GOSSIP_SENDER_MAIN, 183323, "Add Orgrimmar Portal?", GuildHousePortal, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Undercity", GOSSIP_SENDER_MAIN, 183327, "Add Undercity Portal?", GuildHousePortal, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Thunderbluff", GOSSIP_SENDER_MAIN, 183326, "Add Thunderbuff Portal?", GuildHousePortal, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Silvermoon", GOSSIP_SENDER_MAIN, 183324, "Add Silvermoon Portal?", GuildHousePortal, false); + // 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); } - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TAXI, "Portal: Dalaran", GOSSIP_SENDER_MAIN, 191164, "Add Dalaran Portal?", GuildHousePortal, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "Guild Vault", GOSSIP_SENDER_MAIN, 187293, "Add Guild Vault?", GuildHouseObject, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_INTERACT_1, "Barber Chair", GOSSIP_SENDER_MAIN, 191028, "Add a Barber Chair?", GuildHouseObject, false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); + // 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); + + AddGossipItemFor(player, GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; case 6: // Auctioneer { @@ -107,29 +122,29 @@ class GuildHouseSpawner : public CreatureScript { SpawnNPC(auctioneer, player); break; } - case 7: // spawn proffession trainers - player->PlayerTalkClass->ClearMenus(); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Alchemy Trainer", GOSSIP_SENDER_MAIN, 33608, "Spawn Alchemy Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Blacksmithing Trainer", GOSSIP_SENDER_MAIN, 33609, "Spawn Blacksmithing Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Enchanting Trainer", GOSSIP_SENDER_MAIN, 33610, "Spawn Enchanting Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Engineering Trainer", GOSSIP_SENDER_MAIN, 33611, "Spawn Engineering Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Tailoring Trainer", GOSSIP_SENDER_MAIN, 33613, "Spawn Tailoring Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Leatherworking Trainer", GOSSIP_SENDER_MAIN, 33612, "Spawn Leatherworking Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Jewlelcrafing Trainer", GOSSIP_SENDER_MAIN, 33614, "Spawn Jewelcrafting Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Inscription Trainer", GOSSIP_SENDER_MAIN, 33615, "Spawn Inscription Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Skinning Trainer", GOSSIP_SENDER_MAIN, 33618, "Spawn Skinning Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Mining Trainer", GOSSIP_SENDER_MAIN, 33617, "Spawn Mining Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TRAINER, "Herbalism Trainer", GOSSIP_SENDER_MAIN, 33616, "Spawn Herbalism Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); + 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_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; - case 8: // secondry proff trainers - player->PlayerTalkClass->ClearMenus(); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "First Aid Trainer", GOSSIP_SENDER_MAIN, 33621, "Spawn Fist Aid Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "Fishing Trainer", GOSSIP_SENDER_MAIN, 33623, "Spawn Fishing Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "Cooking Trainer", GOSSIP_SENDER_MAIN, 33619, "Spawn Cooking Trainer?", GuildHouseProff, false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); + case 8: // secondry prof 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_CHAT, "Go Back!", GOSSIP_SENDER_MAIN, 9); + SendGossipMenuFor(player, DEFAULT_GOSSIP_MESSAGE, m_creature->GetGUID()); break; case 9: // go back! OnGossipHello(player, m_creature); @@ -171,13 +186,16 @@ class GuildHouseSpawner : public CreatureScript { case 33619: // Cooking case 33623: // Fishing case 33621: // First Aid - cost = GuildHouseProff; + cost = GuildHouseProf; SpawnNPC(action, player); break; case 28692: // Trade supplies case 28776: // Tabard Vendor - case 29715: // Food & Drink - cost = GuildHouseProff; + case 70103: // Food & Drink + case 29636: // Reagent Vendor + case 70104: // Ammo & Repair Vendor + case 28690: // Stable Master + cost = GuildHouseVendor; SpawnNPC(action, player); break; // @@ -187,6 +205,10 @@ class GuildHouseSpawner : public CreatureScript { cost = GuildHouseMailBox; SpawnObject(action, player); break; + case 6491: // spirit healer + cost = GuildHouseSpirit; + SpawnNPC(action, player); + break; case 1685: // forge case 4087: // Anvil case 187293: // Guild Vault @@ -194,15 +216,15 @@ class GuildHouseSpawner : public CreatureScript { cost = GuildHouseObject; SpawnObject(action, player); break; - case 183325: // Stormwind Portal - case 183323: // Orgrimmar Portal 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 191164: // Dalaran Portal + case 191013: // Shattrath Portal:Alliance + case 191014: // Shattrath Portal:Horde + case 195682: // Dalaran Portal cost = GuildHousePortal; SpawnObject(action, player); break; @@ -210,12 +232,16 @@ class GuildHouseSpawner : public CreatureScript { return true; } + uint32 GetGuildPhase(Player* player) { + return player->GetGuildId() + 10; + } + void SpawnNPC(uint32 entry, Player* player) { if (player->FindNearestCreature(entry, VISIBILITY_RANGE, true)) { ChatHandler(player->GetSession()).PSendSysMessage("You already have this creature!"); - player->CLOSE_GOSSIP_MENU(); + CloseGossipMenuFor(player); return; } @@ -241,12 +267,12 @@ class GuildHouseSpawner : public CreatureScript { Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), player->GetMap(), player->GetPhaseMask(), entry, 0, posX,posY, posZ, ori)) + if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), player->GetMap(), GetGuildPhase(player), entry, 0, posX,posY, posZ, ori)) { delete creature; return; } - creature->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), player->GetPhaseMask()); + creature->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), GetGuildPhase(player)); uint32 db_guid = creature->GetDBTableGUIDLow(); creature->CleanupsBeforeDelete(); @@ -260,7 +286,7 @@ class GuildHouseSpawner : public CreatureScript { sObjectMgr->AddCreatureToGrid(db_guid, sObjectMgr->GetCreatureData(db_guid)); player->ModifyMoney(-cost); - player->CLOSE_GOSSIP_MENU(); + CloseGossipMenuFor(player); } void SpawnObject(uint32 entry, Player* player) @@ -288,7 +314,7 @@ class GuildHouseSpawner : public CreatureScript { if (player->FindNearestGameObject(entry, VISIBLE_RANGE)) { ChatHandler(player->GetSession()).PSendSysMessage("You already have this object!"); - player->CLOSE_GOSSIP_MENU(); + CloseGossipMenuFor(player); return; } @@ -307,14 +333,14 @@ class GuildHouseSpawner : public CreatureScript { GameObject* object = sObjectMgr->IsGameObjectStaticTransport(objectInfo->entry) ? new StaticTransport() : new GameObject(); uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT); - if (!object->Create(guidLow, objectInfo->entry, player->GetMap(), player->GetPhaseMask(), posX, posY, posZ, ori, G3D::Quat(), 0, GO_STATE_READY)) + if (!object->Create(guidLow, objectInfo->entry, player->GetMap(), GetGuildPhase(player), posX, posY, posZ, ori, G3D::Quat(), 0, GO_STATE_READY)) { delete object; return; } // fill the gameobject data and save to the db - object->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), player->GetPhaseMask()); + object->SaveToDB(player->GetMapId(), (1 << player->GetMap()->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; @@ -330,8 +356,8 @@ class GuildHouseSpawner : public CreatureScript { // TODO: is it really necessary to add both the real and DB table guid here ? sObjectMgr->AddGameobjectToGrid(guidLow, sObjectMgr->GetGOData(guidLow)); player->ModifyMoney(-cost); - player->CLOSE_GOSSIP_MENU(); - } + CloseGossipMenuFor(player); + } }; class GuildHouseNPCConf : public WorldScript @@ -339,7 +365,7 @@ class GuildHouseNPCConf : public WorldScript public: GuildHouseNPCConf() : WorldScript("GuildHouseNPCConf") {} - void OnBeforeConfigLoad(bool reload) override + void OnBeforeConfigLoad(bool /*reload*/) override { GuildHouseInnKeeper = sConfigMgr->GetIntDefault("GuildHouseInnKeeper", 1000000); GuildHouseBank = sConfigMgr->GetIntDefault("GuildHouseBank", 1000000); @@ -349,7 +375,9 @@ class GuildHouseNPCConf : public WorldScript GuildHouseVendor = sConfigMgr->GetIntDefault("GuildHouseVendor", 500000); GuildHouseObject = sConfigMgr->GetIntDefault("GuildHouseObject", 500000); GuildHousePortal = sConfigMgr->GetIntDefault("GuildHousePortal", 500000); - GuildHouseProff = sConfigMgr->GetIntDefault("GuildHouseProff", 500000); + GuildHouseProf = sConfigMgr->GetIntDefault("GuildHouseProf", 500000); + GuildHouseSpirit = sConfigMgr->GetIntDefault("GuildHouseSpirit", 100000); + GuildHouseBuyRank = sConfigMgr->GetIntDefault("GuildHouseBuyRank", 0); } }; diff --git a/src/mod_guild_house_v2.cpp b/src/mod_guild_house_v2.cpp index db3be4f..8339764 100644 --- a/src/mod_guild_house_v2.cpp +++ b/src/mod_guild_house_v2.cpp @@ -3,12 +3,16 @@ #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 { @@ -21,27 +25,90 @@ class GuildData : public DataMap::Base float posZ; }; -class GuildHelper : public GuildScript{ +class GuildHelper : public GuildScript { public: - GuildHelper() : GuildScript("GuildHelper") { } + GuildHelper() : GuildScript("GuildHelper") {} - void OnCreate(Guild* guild, Player* leader, const std::string& name) + void OnCreate(Guild*, Player* leader, const std::string&) { ChatHandler(leader->GetSession()).PSendSysMessage("You now own a guild. You can purchase a guild house!"); } - void OnGuildDisband(Guild* guild) + uint32 GetGuildPhase(Guild* guild) { + return guild->GetId() + 10; + } + + void OnDisband(Guild* guild) { - if (guild->GetId() != 1) - { - WorldDatabase.PQuery("DELETE FROM `creature` WHERE map = 1 AND phaseMask = %u", guild->GetId()); - WorldDatabase.PQuery("DELETE FROM `gameobject WHERE map = 1 and phaseMask = %u", guild->GetId()); + + 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()); } - CharacterDatabase.PQuery("DELETE FROM `guild_house` WHERE guild = %u", guild->GetId()); + // 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 { @@ -53,24 +120,38 @@ class GuildHouseSeller : public CreatureScript { { if (!player->GetGuild()) { - ChatHandler(player->GetSession()).PSendSysMessage("You are not in a guild"); + 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 leader of the guild can buy / sell guild house - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TABARD, "Buy Guild House!", GOSSIP_SENDER_MAIN, 2); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_TABARD, "Sell Guild House!", GOSSIP_SENDER_MAIN, 3, "Are you sure you want to sell your Guild house?", NULL, false); + // 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); + } } - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TABARD, "Teleport to Guild House", GOSSIP_SENDER_MAIN, 1); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Close", GOSSIP_SENDER_MAIN, 5); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); + 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 sender, uint32 action) + bool OnGossipSelect(Player *player, Creature * m_creature, uint32, uint32 action) { uint32 map; float posX; @@ -86,47 +167,250 @@ class GuildHouseSeller : public CreatureScript { posZ = 13.257628f; break; case 5: // close - player->CLOSE_GOSSIP_MENU(); + CloseGossipMenuFor(player); + break; + case 4: // --- MORE TO COME --- + BuyGuildHouse(player->GetGuild(), player, m_creature); break; case 3: // Sell back guild house { - QueryResult result = CharacterDatabase.PQuery("SELECT id, `guild` FROM `guild_house` WHERE guild = %u", player->GetGuildId()); - - if (!result) + QueryResult has_gh = CharacterDatabase.PQuery("SELECT id, `guild` FROM `guild_house` WHERE guild = %u", player->GetGuildId()); + if (!has_gh) { - ChatHandler(player->GetSession()).PSendSysMessage("You do not have a active Guild house!"); + ChatHandler(player->GetSession()).PSendSysMessage("Your guild does not own a Guild House!"); + CloseGossipMenuFor(player); return false; } - CharacterDatabase.PQuery("DELETE FROM `guild_house` WHERE guild = %u", player->GetGuildId()); - - if (player->GetGuildId() != 1) + // Calculate total gold returned: 1) cost of guildhouse and cost of each purchase made. + if (RemoveGuildHouse(player)) { - WorldDatabase.PQuery("DELETE FROM `creature` WHERE `map` = 1 AND phaseMask = %u", player->GetGuildId()); - WorldDatabase.PQuery("DELETE FROM `gameobject` WHERE `map` = 1 and phaseMask = %u", player->GetGuildId()); - } - - ChatHandler(player->GetSession()).PSendSysMessage("You have successfully sold your guild house"); - player->ModifyMoney(+(sConfigMgr->GetIntDefault("CostGuildHouse", 10000000) / 2)); - + 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); + 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(), player->GetGuildId(), map, posX, posY, posZ); + 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 have now got a guild house", LANG_UNIVERSAL); + 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) @@ -135,26 +419,38 @@ class GuildHouseSeller : public CreatureScript { if (result) { - ChatHandler(player->GetSession()).PSendSysMessage("You cant buy any more guilds houses!"); - player->CLOSE_GOSSIP_MENU(); + ChatHandler(player->GetSession()).PSendSysMessage("Your guild already has a Guild House."); + CloseGossipMenuFor(player); return false; } - player->PlayerTalkClass->ClearMenus(); - player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_MONEY_BAG, "GM Island", GOSSIP_SENDER_MAIN, 100, "Buy GM island Guildhouse?", sConfigMgr->GetIntDefault("CostGuildHouse", 10000000), false); - player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, " ----- More to Come ----", GOSSIP_SENDER_MAIN, 4); - player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, creature->GetGUID()); + 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) + void TeleportGuildHouse(Guild* guild, Player* player, Creature* creature) { GuildData* guildData = player->CustomData.GetDefault("phase"); - QueryResult result = CharacterDatabase.PQuery("SELECT `id`, `guild`, `phase`, `map`,`positionX`, `positionY`, `positionZ` FROM guild_house WHERE `guild` = %u", guild->GetId()); + 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; } @@ -162,19 +458,18 @@ class GuildHouseSeller : public CreatureScript { do { Field* fields = result->Fetch(); - uint32 id = fields[0].GetUInt32(); - uint32 guild = fields[1].GetUInt32(); - 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(); + 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()); player->SetPhaseMask(guildData->phase, true); } while (result->NextRow()); } + }; class GuildHouseV2PlayerScript : public PlayerScript @@ -187,9 +482,9 @@ class GuildHouseV2PlayerScript : public PlayerScript CheckPlayer(player); } - void OnUpdateZone(Player* player, uint32 newZone, uint32 newArea) + void OnUpdateZone(Player* player, uint32 newZone, uint32 /*newArea*/) { - if (newZone = 876) + if (newZone == 876) CheckPlayer(player); else player->SetPhaseMask(GetNormalPhase(player), true); @@ -198,16 +493,13 @@ class GuildHouseV2PlayerScript : public PlayerScript uint32 GetNormalPhase(Player* player) const { if (player->IsGameMaster()) - return uint32(PHASEMASK_ANYWHERE); + return PHASEMASK_ANYWHERE; - uint32 phase = PHASEMASK_NORMAL; - Player::AuraEffectList const& phases = player->GetAuraEffectsByType(SPELL_AURA_PHASE); - if (!phases.empty()) - phase = phases.front()->GetMiscValue(); - if (uint32 n_phase = phase & ~PHASEMASK_NORMAL) - return n_phase; - - return PHASEMASK_NORMAL; + uint32 phase = player->GetPhaseByAuras(); + if (!phase) + return PHASEMASK_NORMAL; + else + return phase; } void CheckPlayer(Player* player) @@ -215,29 +507,30 @@ class GuildHouseV2PlayerScript : public PlayerScript 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) - return; - - do { - - Field* fields = result->Fetch(); - uint32 id = fields[0].GetUInt32(); - uint32 guild = fields[1].GetUInt32(); - 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(); - - } while (result->NextRow()); + 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"); + ChatHandler(player->GetSession()).PSendSysMessage("Your Guild does not own a guild house."); teleport(player); return; } @@ -279,18 +572,31 @@ class GuildHouseCommand : public CommandScript 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->GetAreaId() != 876) + if (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->GetGuild()->GetLeaderGUID() != player->GetGUID()) + 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)) + 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; @@ -299,12 +605,14 @@ class GuildHouseCommand : public CommandScript Creature* creature = new Creature(); - if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), player->GetMap(), player->GetPhaseMask(), 70102, 0, posX, posY, posZ, ori)) + 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()), player->GetPhaseMask()); + creature->SaveToDB(player->GetMapId(), (1 << player->GetMap()->GetSpawnMode()), GetGuildPhase(player)); uint32 db_guid = creature->GetDBTableGUIDLow(); creature->CleanupsBeforeDelete(); @@ -312,6 +620,8 @@ class GuildHouseCommand : public CommandScript 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; } @@ -324,23 +634,30 @@ class GuildHouseCommand : public CommandScript { Player* player = handler->GetSession()->GetPlayer(); - if (!player || player->IsInCombat()) + 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) { - ChatHandler(player->GetSession()).PSendSysMessage("Your Guild does not own a guild house"); + 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(); - uint32 guild = fields[1].GetUInt32(); + //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();