From 2e6aae7819be1b15c1e27d08b7651487b3c98d7d Mon Sep 17 00:00:00 2001 From: nullifiedcat Date: Mon, 13 Nov 2017 11:52:04 +0300 Subject: [PATCH] Announcer --- include/hacks/Announcer.hpp | 17 ++++ include/hacks/hacklist.hpp | 1 + src/drawex.cpp | 5 +- src/hack.cpp | 2 + src/hacks/Announcer.cpp | 165 ++++++++++++++++++++++++++++++++++++ 5 files changed, 189 insertions(+), 1 deletion(-) create mode 100644 include/hacks/Announcer.hpp create mode 100644 src/hacks/Announcer.cpp diff --git a/include/hacks/Announcer.hpp b/include/hacks/Announcer.hpp new file mode 100644 index 00000000..5c5172ee --- /dev/null +++ b/include/hacks/Announcer.hpp @@ -0,0 +1,17 @@ +/* + * Announcer.hpp + * + * Created on: Nov 13, 2017 + * Author: nullifiedcat + */ + +#pragma once + +#include "common.hpp" + +namespace hacks { namespace shared { namespace announcer { + +void init(); +void shutdown(); + +}}} diff --git a/include/hacks/hacklist.hpp b/include/hacks/hacklist.hpp index 42236d59..67fc306c 100644 --- a/include/hacks/hacklist.hpp +++ b/include/hacks/hacklist.hpp @@ -40,5 +40,6 @@ #include "Spam.hpp" #include "Noisemaker.hpp" #include "FollowBot.hpp" +#include "Announcer.hpp" #endif /* HACKS_HACKLIST_HPP_ */ diff --git a/src/drawex.cpp b/src/drawex.cpp index b79766fc..9c1f3a62 100644 --- a/src/drawex.cpp +++ b/src/drawex.cpp @@ -64,12 +64,15 @@ namespace api { bool ready_state = false; +bool init = false; void initialize() { - rendering_thread = std::thread(rendering_routine); + if (!init) + rendering_thread = std::thread(rendering_routine); ctx = cat_shm_connect("cathook-rendering"); ready_state = true; + init = true; } void draw_rect(float x, float y, float w, float h, const float* rgba) diff --git a/src/hack.cpp b/src/hack.cpp index 0e634e34..47de0411 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -276,6 +276,7 @@ void hack::Initialize() { // FIXME [MP] hacks::shared::killsay::Init(); + hacks::shared::announcer::init(); logging::Info("Hooked!"); velocity::Init(); playerlist::Load(); @@ -351,5 +352,6 @@ void hack::Shutdown() { ConVar_Unregister(); logging::Info("Shutting down killsay..."); hacks::shared::killsay::Shutdown(); + hacks::shared::announcer::shutdown(); logging::Info("Success.."); } diff --git a/src/hacks/Announcer.cpp b/src/hacks/Announcer.cpp new file mode 100644 index 00000000..25153f02 --- /dev/null +++ b/src/hacks/Announcer.cpp @@ -0,0 +1,165 @@ +/* + * Announcer.cpp + * + * Created on: Nov 13, 2017 + * Author: nullifiedcat + */ + +#include "common.hpp" + +namespace hacks { namespace shared { namespace announcer { + +CatVar enabled(CV_SWITCH, "announcer", "0", "Enable announcer"); + +struct announcer_entry_s +{ + int count; + const std::string sound; +}; + +std::vector announces_headshot_combo = { + { 1, "headshot.wav" }, + { 2, "headshot.wav" }, + { 4, "hattrick.wav" }, + { 6, "headhunter.wav" } +}; + +std::vector announces_kill = { + { 5, "dominating.wav" }, + { 7, "rampage.wav" }, + { 9, "killingspree.wav" }, + { 11, "monsterkill.wav" }, + { 15, "unstoppable.wav" }, + { 17, "ultrakill.wav" }, + { 19, "godlike.wav" }, + { 21, "wickedsick.wav" }, + { 23, "impressive.wav" }, + { 25, "ludicrouskill.wav" }, + { 27, "holyshit.wav" } +}; + +std::vector announces_kill_combo = { + { 2, "doublekill.wav" }, + { 3, "triplekill.wav" }, + { 4, "multikill.wav" }, + { 5, "combowhore.wav" } +}; + +unsigned killstreak { 0 }; +unsigned killcombo { 0 }; +unsigned headshotcombo { 0 }; +Timer last_kill {}; +Timer last_headshot {}; + +const announcer_entry_s *find_entry(const std::vector& vector, int count) +{ + for (auto it = vector.rbegin(); it != vector.rend(); ++it) + { + if ((*it).count <= count) + return &*it; + } + return nullptr; +} + +void playsound(const std::string& sound) +{ + g_ISurface->PlaySound(std::string("announcer/" + sound).c_str()); +} + +void reset() +{ + killstreak = 0; + killcombo = 0; + headshotcombo = 0; +} + +void check_combos() +{ + if (last_kill.check(5000)) + { + killcombo = 0; + } + if (last_headshot.check(5000)) + { + headshotcombo = 0; + } +} + +void on_kill(IGameEvent *event) +{ + int killer_id = g_IEngine->GetPlayerForUserID(event->GetInt("attacker")); + int victim_id = g_IEngine->GetPlayerForUserID(event->GetInt("userid")); + + if (victim_id == g_IEngine->GetLocalPlayer()) + { + reset(); + return; + } + + if (killer_id != g_IEngine->GetLocalPlayer()) + return; + if (killer_id == victim_id) + return; + + check_combos(); + last_kill.update(); + + killstreak++; + killcombo++; + + if (GetWeaponMode() == weaponmode::weapon_melee) + { + playsound("humiliation.wav"); + return; + } + if (event->GetInt("customkill") == 1) + { + headshotcombo++; + last_headshot.update(); + const auto sound = find_entry(announces_headshot_combo, headshotcombo); + if (sound) + { + playsound(sound->sound); + return; + } + } + auto entry = find_entry(announces_kill_combo, killcombo); + if (entry) + { + playsound(entry->sound); + return; + } + entry = find_entry(announces_kill, killstreak); + if (entry) + { + playsound(entry->sound); + } +} + +class AnnouncerEventListener : public IGameEventListener2 { + virtual void FireGameEvent(IGameEvent *event) + { + if (enabled) + on_kill(event); + } +}; + +AnnouncerEventListener& listener() +{ + static AnnouncerEventListener object {}; + return object; +} + +void init() +{ + g_IEventManager2->AddListener(&listener(), "player_death", false); +} + +void shutdown() +{ + g_IEventManager2->RemoveListener(&listener()); +} + +}}} + +