Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. // written and created by tommy emudevs.com/forum.php  //
  2. struct KillStreak
  3. {
  4.     uint16 kills;
  5.     uint32 lastKilledGUID; // Prevents cheating
  6. };
  7.  
  8. std::unordered_map<uint32, KillStreak> KillStreakMap;
  9.  
  10. class killstreak_world_load : public WorldScript
  11. {
  12. public:
  13.     killstreak_world_load() : WorldScript("killstreak_world_load") { }
  14.  
  15.     void OnStartup()
  16.     {
  17.         QueryResult result = CharacterDatabase.Query("SELECT killerGUID, kills, lastKilledGUID FROM character_killstreak");
  18.         if (result)
  19.         {
  20.             do
  21.             {
  22.                 Field* fields = result->Fetch();
  23.  
  24.                 KillStreak killStreak;
  25.  
  26.                 killStreak.kills = fields[1].GetUInt16();
  27.                 killStreak.lastKilledGUID = fields[2].GetUInt32();
  28.  
  29.                 KillStreakMap[fields[0].GetUInt32()] = killStreak;
  30.  
  31.             } while (result->NextRow());
  32.         }
  33.     }
  34. };
  35.  
  36. class killstreak_player_system : public PlayerScript
  37. {
  38. public:
  39.     killstreak_player_system() : PlayerScript("killstreak_player_system") { }
  40.  
  41.     void OnSave(Player* player) // Save killstreak when player saves (it is best to do this for performance reasons.)
  42.     {
  43.         std::unordered_map<uint32, KillStreak>::iterator itr = KillStreakMap.find(player->GetGUIDLow());
  44.         if (itr != KillStreakMap.end())
  45.         {
  46.             QueryResult result = CharacterDatabase.PQuery("SELECT `kills`, `lastKilledGUID` FROM `character_killstreak` WHERE killerGUID=%u", player->GetGUIDLow());
  47.             if (!result) // Player isn't saved yet
  48.                 CharacterDatabase.PExecute("INSERT INTO `character_killstreak` VALUES(%u, %u, %u)", itr->first, itr->second.kills, itr->second.lastKilledGUID);
  49.             else
  50.             {
  51.                 Field* fields = result->Fetch();
  52.                 uint16 kills = fields[0].GetUInt16();
  53.                 uint32 lastKilledGUID = fields[1].GetUInt32();
  54.                 if (itr->second.kills < kills) // Did they lose their KS?
  55.                     CharacterDatabase.PExecute("DELETE FROM `character_killstreak` WHERE killerGUID=%u", itr->first);
  56.                 else // Else just continue updating
  57.                 {
  58.                     kills += itr->second.kills;
  59.                     if (lastKilledGUID == itr->second.lastKilledGUID)
  60.                         CharacterDatabase.PExecute("UPDATE `character_killstreak` SET kills=%u WHERE killerGUID=%u", kills, itr->first);
  61.                     else
  62.                         CharacterDatabase.PExecute("UPDATE `character_killstreak` SET kills=%u, lastKilledGUID=%u WHERE killerGUID=%u", kills, itr->second.lastKilledGUID, itr->first);
  63.                 }
  64.             }
  65.         }
  66.     }
  67.  
  68.     void OnPVPKill(Player* killer, Player* victim)
  69.     {
  70.         if (killer->GetGUIDLow() == victim->GetGUIDLow())
  71.             return;
  72.  
  73.         std::ostringstream ss;
  74.  
  75.         std::unordered_map<uint32, KillStreak>::iterator itr = KillStreakMap.find(victim->GetGUIDLow());
  76.         if (itr != KillStreakMap.end()) // KillStreak ends
  77.         {
  78.             ss << victim->GetName() << "'s "
  79.                 << "killstreak ended at "
  80.                 << itr->second.kills << " kills!";
  81.             sWorld->SendGlobalText(ss.str().c_str(), NULL);
  82.  
  83.             KillStreakMap.erase(victim->GetGUIDLow());
  84.         }
  85.  
  86.         std::unordered_map<uint32, KillStreak>::iterator itr2 = KillStreakMap.find(killer->GetGUIDLow());
  87.         if (itr2 != KillStreakMap.end()) // KillStreak exists
  88.         {
  89.             if (victim->GetGUIDLow() == itr2->second.lastKilledGUID)
  90.             {
  91.                 ChatHandler(killer->GetSession()).SendSysMessage("Kill someone else besides the same person!");
  92.                 return;
  93.             }
  94.  
  95.             switch (itr2->second.kills)
  96.             {
  97.                 case 5: // 5 kills
  98.                     break;
  99.                 case 10: // 10 kills
  100.                     break;
  101.                 case 20: // 20 kills
  102.                     ss.str("");
  103.                     if (RewardTitle(killer, 30)) // Change 30 to the appropriate itemId!
  104.                     {
  105.                         ss << killer->GetName()
  106.                             << " has earned a title for getting 20 kills on their killstreak!";
  107.                         sWorld->SendGlobalText(ss.str().c_str(), NULL);
  108.                     }
  109.                     break;
  110.                     // case X: etc...
  111.             }
  112.         }
  113.         else // Killstreak begins
  114.         {
  115.             KillStreak newKillStreak;
  116.             newKillStreak.kills = 1; // Kills starting
  117.             newKillStreak.lastKilledGUID = victim->GetGUIDLow(); // Last victim killed
  118.             KillStreakMap[killer->GetGUIDLow()] = newKillStreak;
  119.         }
  120.     }
  121.  
  122.     bool RewardTitle(Player* player, uint32 title)
  123.     {
  124.         CharTitlesEntry const* titleEntry = sCharTitlesStore.LookupEntry(title);
  125.         if (!titleEntry) // Invalid entry
  126.             return false;
  127.  
  128.         if (!player->HasTitle(titleEntry)) // Reward this Title
  129.             player->SetTitle(titleEntry);
  130.         else // Already has this title
  131.             return false;
  132.     }
  133. };
  134.  
  135. void SetupKillStreak()
  136. {
  137.     new killstreak_player_system;
  138.     new killstreak_world_load;
  139. }