1. /* Guild Housing
  2.    Created by   ?
  3.    Edited by QQrofl/Tommy
  4.    Will Scarlet - Suggested for it to be updated
  5. */
  6.  
  7. #include "ScriptPCH.h"
  8.  
  9. #define MSG_GOSSIP_TELE          "Teleport to our GuildHouse"
  10. #define MSG_GOSSIP_BUY           "Buy GuildHouse (1000 gold)"
  11. #define MSG_GOSSIP_SELL          "Sell GuildHouse (500 gold)"
  12. #define MSG_GOSSIP_NEXTPAGE      "Next Page -->"
  13. #define MSG_INCOMBAT             "You are in combat!"
  14. #define MSG_NOGUILDHOUSE         "Your guild dont have any GuildHouse!"
  15. #define MSG_NOFREEGH             "Unfortunately, all GuildHouses are in use."
  16. #define MSG_ALREADYHAVEGH        "Sorry, but you already have GuildHouse (%s)."
  17. #define MSG_NOTENOUGHMONEY       "Not enough money. You must have %u gold to buy a GuildHouses."
  18. #define MSG_GHOCCUPIED           "Unfortunately, this GuildHouses already in use."
  19. #define MSG_CONGRATULATIONS      "Congratulations! You bought this Guild House!"
  20. #define MSG_SOLD                 "You sold your GuildHouse. Here is %u in gold."
  21. #define MSG_NOTINGUILD           "You are not in a guild. Join or create one."
  22.  
  23. #define CODE_SELL                "SELL"
  24. #define MSG_CODEBOX_SELL         "Enter \"" CODE_SELL "\" If you really want to sell your GuildHouse."
  25.  
  26. enum Vars
  27. {
  28.     /* Offset */
  29.     OFFSET_GH_ID_TO_ACTION = 1500,
  30.     OFFSET_SHOWBUY_FROM = 10000,
  31.     /* Actions */
  32.     ACTION_TELE = 1001,
  33.     ACTION_SHOW_BUYLIST = 1002,  //deprecated. Use (OFFSET_SHOWBUY_FROM + 0) instead
  34.     ACTION_SELL_GUILDHOUSE = 1003,
  35.     /* Costs */
  36.     COST_GH_BUY = 10000000, //1000 g.
  37.     COST_GH_SELL = 5000000   //500 g.
  38. };
  39.  
  40. #define GOSSIP_COUNT_MAX         10
  41.  
  42. bool isPlayerGuildLeader(Player *player)
  43. {
  44.     return (player->GetRank() == 0) && (player->GetGuildId() != 0);
  45. }
  46.  
  47. bool getGuildHouseCoords(uint32 guildId, float &x, float &y, float &z, uint32 &map)
  48. {
  49.     if (guildId == 0) //if player has no guild
  50.         return false;
  51.  
  52.     QueryResult result;
  53.     result = WorldDatabase.PQuery("SELECT `x`, `y`, `z`, `map` FROM `guildhouses` WHERE `guildId` = %u", guildId);
  54.     if(result)
  55.     {
  56.         Field *fields = result->Fetch();
  57.         x = fields[0].GetFloat();
  58.         y = fields[1].GetFloat();
  59.         z = fields[2].GetFloat();
  60.         map = fields[3].GetUInt32();
  61.         return true;
  62.     }
  63.     return false;
  64. }
  65.  
  66. void teleportPlayerToGuildHouse(Player *player, Creature *_creature)
  67. {
  68.     if (player->GetGuildId() == 0)
  69.     {
  70.         //if player has no guild
  71.         _creature->MonsterWhisper(MSG_NOTINGUILD, player->GetGUID());
  72.         return;
  73.     }
  74.  
  75.     if (!player->getAttackers().empty())
  76.     {
  77.         //if player in combat
  78.         _creature->MonsterSay(MSG_INCOMBAT, LANG_UNIVERSAL, player->GetGUID());
  79.         return;
  80.     }
  81.  
  82.     float x, y, z;
  83.     uint32 map;
  84.  
  85.     if (getGuildHouseCoords(player->GetGuildId(), x, y, z, map))
  86.     {
  87.         //teleport player to the specified location
  88.         player->TeleportTo(map, x, y, z, 0.0f);
  89.     }
  90.     else
  91.         _creature->MonsterWhisper(MSG_NOGUILDHOUSE, player->GetGUID());
  92. }
  93.  
  94. bool showBuyList(Player *player, Creature *_creature, uint32 showFromId = 0)
  95. {
  96.     QueryResult result;
  97.     result = WorldDatabase.PQuery("SELECT `id`, `comment` FROM `guildhouses` WHERE `guildId` = 0 AND `id` > %u ORDER BY `id` ASC LIMIT %u",
  98.         showFromId, GOSSIP_COUNT_MAX);
  99.  
  100.     if (result)
  101.     {
  102.         uint32 guildhouseId = 0;
  103.         std::string comment = "";
  104.         do
  105.         {
  106.  
  107.             Field *fields = result->Fetch();
  108.  
  109.             guildhouseId = fields[0].GetInt32();
  110.             comment = fields[1].GetString();
  111.            
  112.             //send comment as a gossip item
  113.             //transmit guildhouseId in Action variable
  114.             player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TABARD, comment, GOSSIP_SENDER_MAIN,
  115.                 guildhouseId + OFFSET_GH_ID_TO_ACTION);
  116.  
  117.         } while (result->NextRow());
  118.  
  119.         if (result->GetRowCount() == GOSSIP_COUNT_MAX)
  120.         {
  121.             //assume that we have additional page
  122.             //add link to next GOSSIP_COUNT_MAX items
  123.             player->ADD_GOSSIP_ITEM(GOSSIP_ICON_DOT, MSG_GOSSIP_NEXTPAGE, GOSSIP_SENDER_MAIN,
  124.                 guildhouseId + OFFSET_SHOWBUY_FROM);
  125.         }
  126.  
  127.  
  128.         player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, _creature->GetGUID());
  129.  
  130.         return true;
  131.     }
  132.     else
  133.     {
  134.         if (showFromId = 0)
  135.         {
  136.             //all guildhouses are occupied
  137.             _creature->MonsterWhisper(MSG_NOFREEGH, player->GetGUID());
  138.             player->CLOSE_GOSSIP_MENU();
  139.         } else
  140.         {
  141.             //this condition occurs when COUNT(guildhouses) % GOSSIP_COUNT_MAX == 0
  142.             //just show GHs from beginning
  143.             showBuyList(player, _creature, 0);
  144.         }
  145.     }
  146.     return false;
  147. }
  148.  
  149. bool isPlayerHasGuildhouse(Player *player, Creature *_creature, bool whisper = false)
  150. {
  151.     QueryResult result;
  152.  
  153.     result = WorldDatabase.PQuery("SELECT `comment` FROM `guildhouses` WHERE `guildId` = %u",
  154.         player->GetGuildId());
  155.  
  156.     if (result)
  157.     {
  158.         if (whisper)
  159.         {
  160.             //whisper to player "already have etc..."
  161.             Field *fields = result->Fetch();
  162.             char msg[100];
  163.             sprintf(msg, MSG_ALREADYHAVEGH, fields[0].GetString());
  164.             _creature->MonsterWhisper(msg, player->GetGUID());
  165.         }
  166.         return true;
  167.     }
  168.     return false;
  169.  
  170. }
  171.  
  172. void buyGuildhouse(Player *player, Creature *_creature, uint32 guildhouseId)
  173. {
  174.     if (player->GetMoney() < COST_GH_BUY)
  175.     {
  176.         //show how much money player need to buy GH (in gold)
  177.         char msg[100];
  178.         sprintf(msg, MSG_NOTENOUGHMONEY, COST_GH_BUY / 10000);
  179.         _creature->MonsterWhisper(msg, player->GetGUID());
  180.         return;
  181.     }
  182.  
  183.     if (isPlayerHasGuildhouse(player, _creature, true))//player already have GH
  184.         return;
  185.  
  186.     QueryResult result;
  187.  
  188.     //check if somebody already occupied this GH
  189.     result = WorldDatabase.PQuery("SELECT `id` FROM `guildhouses` WHERE `id` = %u AND `guildId` <> 0",
  190.         guildhouseId);
  191.  
  192.     if (result)
  193.     {
  194.         _creature->MonsterWhisper(MSG_GHOCCUPIED, player->GetGUID());
  195.         return;
  196.     }
  197.     //update DB
  198.     result = WorldDatabase.PQuery("UPDATE `guildhouses` SET `guildId` = %u WHERE `id` = %u",
  199.         player->GetGuildId(), guildhouseId);
  200.  
  201.     if (result)
  202.     {
  203.         player->ModifyMoney(-COST_GH_BUY);
  204.         _creature->MonsterSay(MSG_CONGRATULATIONS, LANG_UNIVERSAL, player->GetGUID());
  205.     }
  206. }
  207.  
  208. void sellGuildhouse(Player *player, Creature *_creature)
  209. {
  210.     if (isPlayerHasGuildhouse(player, _creature))
  211.     {
  212.         QueryResult result;
  213.  
  214.         result = WorldDatabase.PQuery("UPDATE `guildhouses` SET `guildId` = 0 WHERE `guildId` = %u",
  215.         player->GetGuildId());
  216.        
  217.         if (result)
  218.  
  219.         player->ModifyMoney(COST_GH_SELL);
  220.  
  221.         //display message e.g. "here your money etc."
  222.         char msg[100];
  223.         sprintf(msg, MSG_SOLD, COST_GH_SELL / 10000);
  224.         _creature->MonsterWhisper(msg, player->GetGUID());
  225.     }
  226. }
  227.  
  228. class npc_guildmaster : public CreatureScript
  229. {
  230.    public:
  231.        npc_guildmaster() : CreatureScript("npc_guildmaster") { }
  232.  
  233.         bool OnGossipHello(Player *player, Creature *_creature)
  234.         {
  235.             player->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, MSG_GOSSIP_TELE,
  236.                 GOSSIP_SENDER_MAIN, ACTION_TELE);
  237.  
  238.             if (isPlayerGuildLeader(player)) //show additional menu for guild leader
  239.             {
  240.                 player->ADD_GOSSIP_ITEM(GOSSIP_ICON_MONEY_BAG, MSG_GOSSIP_BUY,
  241.                     GOSSIP_SENDER_MAIN, ACTION_SHOW_BUYLIST);
  242.                 if (isPlayerHasGuildhouse(player, _creature))//and additional for guildhouse owner
  243.                     player->PlayerTalkClass->GetGossipMenu().AddMenuItem(-1, GOSSIP_ICON_MONEY_BAG, MSG_GOSSIP_SELL, GOSSIP_SENDER_MAIN, ACTION_SELL_GUILDHOUSE, MSG_CODEBOX_SELL, 0, true);
  244.             }
  245.             player->SEND_GOSSIP_MENU(DEFAULT_GOSSIP_MESSAGE, _creature->GetGUID());
  246.             return true;
  247.         }
  248.  
  249.  
  250.         bool OnGossipSelect(Player *player, Creature *_creature, uint32 sender, uint32 action )
  251.         {
  252.             if (sender != GOSSIP_SENDER_MAIN)
  253.                 return false;
  254.  
  255.             switch (action)
  256.             {
  257.                 case ACTION_TELE://teleport player to GH   
  258.                     player->CLOSE_GOSSIP_MENU();
  259.                     teleportPlayerToGuildHouse(player, _creature);
  260.                     break;
  261.                 case ACTION_SHOW_BUYLIST://show list of GHs which currently not occupied
  262.                     showBuyList(player, _creature);
  263.                     break;
  264.                 default:
  265.                     if (action > OFFSET_SHOWBUY_FROM)
  266.                     {
  267.                         showBuyList(player, _creature, action - OFFSET_SHOWBUY_FROM);
  268.                     }
  269.                     else if (action > OFFSET_GH_ID_TO_ACTION)
  270.                     {
  271.                         //player clicked on buy list
  272.                         player->CLOSE_GOSSIP_MENU();
  273.                         //get guildhouseId from action
  274.                         //guildhouseId = action - OFFSET_GH_ID_TO_ACTION
  275.                         buyGuildhouse(player, _creature, action - OFFSET_GH_ID_TO_ACTION);
  276.                     }break;
  277.             }
  278.             return true;
  279.         }
  280.  
  281.         bool OnGossipSelectCode( Player *player, Creature *_creature, uint32 sender, uint32 action, const char* sCode )
  282.         {
  283.             if(sender == GOSSIP_SENDER_MAIN)
  284.             {
  285.                 if(action == ACTION_SELL_GUILDHOUSE)
  286.                 {
  287.                     int i = -1;
  288.                     try
  289.                     {
  290.                         //compare code
  291.                         if (strlen(sCode) + 1 == sizeof CODE_SELL)
  292.                             i = strcmp(CODE_SELL, sCode);
  293.  
  294.                     }
  295.                     catch(char *str)
  296.                     {
  297.                         sLog->outError(str);
  298.                     }
  299.  
  300.                     if (i == 0)//right code
  301.                         sellGuildhouse(player, _creature);
  302.                     player->CLOSE_GOSSIP_MENU();
  303.                     return true;
  304.                 }
  305.             }
  306.             return false;
  307.         }
  308. };
  309.  
  310.  
  311. void AddSC_guildmaster()
  312. {
  313.     new npc_guildmaster;
  314. }