1. /*
  2. Bounty Hunter by Sdyess
  3. Redone by Tommy because it was shit
  4. <http://emudevs.com>
  5. */
  6. enum BountyPrice
  7. {
  8. BOUNTY_PRICE_1 = 20,
  9. BOUNTY_PRICE_2 = 40,
  10. BOUNTY_PRICE_3 = 100,
  11. BOUNTY_PRICE_4 = 200,
  12. };
  13. void BountyAlert(const char* name, int msg)
  14. {
  15. std::string message;
  16. if(msg == 1)
  17. {
  18. message = "A bounty has been placed on ";
  19. message += name;
  20. message += ". Kill them immediately to collect the reward!";
  21. }
  22. else if(msg == 2)
  23. {
  24. message = "The bounty on ";
  25. message += name;
  26. message += " has been collected!";
  27. }
  28. sWorld->SendServerMessage(SERVER_MSG_STRING, message.c_str(), 0);
  29. }
  30. class BountyHunter : public CreatureScript
  31. {
  32. public:
  33. BountyHunter() : CreatureScript("BountyHunter"){}
  34. bool OnGossipHello(Player* player, Creature* creature)
  35. {
  36. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, "I would like to place a bounty!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
  37. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Show me the bounty list!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
  38. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Nevermind..", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+3);
  39. if (player->IsGameMaster())
  40. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_TALK, "Wipe Bounties", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+4);
  41. player->SEND_GOSSIP_MENU(1, creature->GetGUID());
  42. return true;
  43. }
  44. bool OnGossipSelect(Player* player, Creature* creature, uint32 /* sender */, uint32 actions)
  45. {
  46. player->PlayerTalkClass->ClearMenus();
  47. switch (actions)
  48. {
  49. case GOSSIP_ACTION_INFO_DEF+1:
  50. player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_BATTLE, "I would like to place a 20g bounty.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+5, "", 0, true);
  51. player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_BATTLE, "I would like to place a 40g bounty.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+6, "", 0, true);
  52. player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_BATTLE, "I would like to place a 100g bounty.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+7, "", 0, true);
  53. player->ADD_GOSSIP_ITEM_EXTENDED(GOSSIP_ICON_BATTLE, "I would like to place a 200g bounty.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+8, "", 0, true);
  54. player->SEND_GOSSIP_MENU(1, creature->GetGUID());
  55. break;
  56. case GOSSIP_ACTION_INFO_DEF+2:
  57. {
  58. QueryResult result = CharacterDatabase.Query("SELECT * FROM bounties");
  59. if (!result)
  60. {
  61. player->CLOSE_GOSSIP_MENU();
  62. return false;
  63. }
  64. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, "Bounties: ", GOSSIP_SENDER_MAIN, 1);
  65. do
  66. {
  67. Field* fields = result->Fetch();
  68. std::string option;
  69. QueryResult result2 = CharacterDatabase.PQuery("SELECT `name` FROM characters WHERE guid='%u' LIMIT 10", fields[0].GetUInt64());
  70. if (!result2)
  71. return false;
  72. Field* names = result2->Fetch();
  73. option = names[0].GetString();
  74. option += " ";
  75. option += fields[1].GetString();
  76. option += " gold";
  77. player->ADD_GOSSIP_ITEM(GOSSIP_ICON_BATTLE, option.c_str(), GOSSIP_SENDER_MAIN, 1);
  78. }while(result->NextRow());
  79. player->SEND_GOSSIP_MENU(1, creature->GetGUID());
  80. }break;
  81. case GOSSIP_ACTION_INFO_DEF+3:
  82. player->CLOSE_GOSSIP_MENU();
  83. break;
  84. case GOSSIP_ACTION_INFO_DEF+4:
  85. CharacterDatabase.Execute("TRUNCATE TABLE bounties");
  86. player->CLOSE_GOSSIP_MENU();
  87. break;
  88. }
  89. return true;
  90. }
  91. bool OnGossipSelectCode(Player* player, Creature* creature, uint32 /* sender */, uint32 actions, const char* code)
  92. {
  93. player->PlayerTalkClass->ClearMenus();
  94. if (islower(code[0]))
  95. toupper(code[0]);
  96. if (passChecks(player, code))
  97. {
  98. Player* hunted = sObjectAccessor->FindPlayerByName(code);
  99. switch (actions)
  100. {
  101. case GOSSIP_ACTION_INFO_DEF+5:
  102. {
  103. if (HasCurrency(player, BOUNTY_PRICE_1, 0))
  104. {
  105. CharacterDatabase.PExecute("INSERT INTO bounties VALUES('%u','20', '1')", hunted->GetGUID());
  106. BountyAlert(code, 1);
  107. FlagPlayer(code);
  108. player->CLOSE_GOSSIP_MENU();
  109. }
  110. }break;
  111. case GOSSIP_ACTION_INFO_DEF+6:
  112. {
  113. if (HasCurrency(player, BOUNTY_PRICE_2, 0))
  114. {
  115. CharacterDatabase.PExecute("INSERT INTO bounties VALUES('%u', '40', '2')", hunted->GetGUID());
  116. BountyAlert(code, 1);
  117. FlagPlayer(code);
  118. player->CLOSE_GOSSIP_MENU();
  119. }
  120. }break;
  121. case GOSSIP_ACTION_INFO_DEF+7:
  122. {
  123. if (HasCurrency(player, BOUNTY_PRICE_3, 0))
  124. {
  125. CharacterDatabase.PExecute("INSERT INTO bounties VALUES('%u', '100', '3')", hunted->GetGUID());
  126. BountyAlert(code, 1);
  127. FlagPlayer(code);
  128. player->CLOSE_GOSSIP_MENU();
  129. }
  130. }break;
  131. case GOSSIP_ACTION_INFO_DEF+8:
  132. {
  133. if (HasCurrency(player, BOUNTY_PRICE_4, 0))
  134. {
  135. CharacterDatabase.PExecute("INSERT INTO bounties VALUES('%u', '200', '4')", hunted->GetGUID());
  136. BountyAlert(code, 1);
  137. FlagPlayer(code);
  138. player->CLOSE_GOSSIP_MENU();
  139. }
  140. }break;
  141. }
  142. }
  143. else
  144. player->CLOSE_GOSSIP_MENU();
  145. return true;
  146. }
  147. bool HasCurrency(Player* player, uint32 required, int currency)
  148. {
  149. uint32 currentmoney = player->GetMoney();
  150. uint32 requiredmoney = (required * 10000);
  151. if(currentmoney < requiredmoney)
  152. {
  153. player->GetSession()->SendNotification("You don't have enough gold!");
  154. return false;
  155. }
  156. player->SetMoney(currentmoney - requiredmoney);
  157. return true;
  158. }
  159. bool passChecks(Player* player, const char* name)
  160. {
  161. Player* hunted = sObjectAccessor->FindPlayerByName(name);
  162. if(!hunted)
  163. {
  164. player->GetSession()->SendNotification("The player is offline or doesn't exist!");
  165. return false;
  166. }
  167. QueryResult result = CharacterDatabase.PQuery("SELECT * FROM bounties WHERE guid ='%u'", hunted->GetGUID());
  168. if(result)
  169. {
  170. player->GetSession()->SendNotification("This player already has a bounty on them!");
  171. return false;
  172. }
  173. if(player->GetGUID() == hunted->GetGUID())
  174. {
  175. player->GetSession()->SendNotification("You cannot set a bounty on yourself!");
  176. return false;
  177. }
  178. return true;
  179. }
  180. void FlagPlayer(const char* name)
  181. {
  182. Player* hunted = sObjectAccessor->FindPlayerByName(name);
  183. hunted->SetPvP(true);
  184. hunted->SetByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_FFA_PVP);
  185. }
  186. };
  187. class BountyKills : public PlayerScript
  188. {
  189. public:
  190. BountyKills() : PlayerScript("BountyKills"){}
  191. void OnPVPKill(Player* killer, Player* victim)
  192. {
  193. if(killer->GetGUID() == victim->GetGUID())
  194. return;
  195. QueryResult result = CharacterDatabase.PQuery("SELECT * FROM bounties WHERE guid='%u'", victim->GetGUID());
  196. if(!result)
  197. return;
  198. Field* fields = result->Fetch();
  199. switch(fields[2].GetUInt64())
  200. {
  201. case 1:
  202. killer->SetMoney(killer->GetMoney() + (BOUNTY_PRICE_1 * 10000));
  203. break;
  204. case 2:
  205. killer->SetMoney(killer->GetMoney() + (BOUNTY_PRICE_2 * 10000));
  206. break;
  207. case 3:
  208. killer->SetMoney(killer->GetMoney() + (BOUNTY_PRICE_3 * 10000));
  209. break;
  210. case 4:
  211. killer->SetMoney(killer->GetMoney() + (BOUNTY_PRICE_4 * 10000));
  212. break;
  213. }
  214. CharacterDatabase.PExecute("DELETE FROM bounties WHERE guid='%u'", victim->GetGUID());
  215. BountyAlert(victim->GetName().c_str(), 2);
  216. }
  217. };
  218. void AddSC_bounty()
  219. {
  220. new BountyHunter();
  221. new BountyKills();
  222. }