diff --git a/data/sound/combowhore.wav b/data/sound/combowhore.wav new file mode 100644 index 00000000..802efbe4 Binary files /dev/null and b/data/sound/combowhore.wav differ diff --git a/data/sound/dominating.wav b/data/sound/dominating.wav new file mode 100644 index 00000000..1c19acb7 Binary files /dev/null and b/data/sound/dominating.wav differ diff --git a/data/sound/doublekill.wav b/data/sound/doublekill.wav new file mode 100644 index 00000000..df6022ee Binary files /dev/null and b/data/sound/doublekill.wav differ diff --git a/data/sound/firstblood.wav b/data/sound/firstblood.wav new file mode 100644 index 00000000..3646b4a2 Binary files /dev/null and b/data/sound/firstblood.wav differ diff --git a/data/sound/godlike.wav b/data/sound/godlike.wav new file mode 100644 index 00000000..6c3dce8a Binary files /dev/null and b/data/sound/godlike.wav differ diff --git a/data/sound/hattrick.wav b/data/sound/hattrick.wav new file mode 100644 index 00000000..59071307 Binary files /dev/null and b/data/sound/hattrick.wav differ diff --git a/data/sound/headhunter.wav b/data/sound/headhunter.wav new file mode 100644 index 00000000..e7396023 Binary files /dev/null and b/data/sound/headhunter.wav differ diff --git a/data/sound/headshot.wav b/data/sound/headshot.wav new file mode 100644 index 00000000..6a768614 Binary files /dev/null and b/data/sound/headshot.wav differ diff --git a/data/sound/holyshit.wav b/data/sound/holyshit.wav new file mode 100644 index 00000000..4b2da972 Binary files /dev/null and b/data/sound/holyshit.wav differ diff --git a/data/sound/humiliation.wav b/data/sound/humiliation.wav new file mode 100644 index 00000000..170eabc2 Binary files /dev/null and b/data/sound/humiliation.wav differ diff --git a/data/sound/impressive.wav b/data/sound/impressive.wav new file mode 100644 index 00000000..09a48715 Binary files /dev/null and b/data/sound/impressive.wav differ diff --git a/data/sound/killingspree.wav b/data/sound/killingspree.wav new file mode 100644 index 00000000..e7cb3ba9 Binary files /dev/null and b/data/sound/killingspree.wav differ diff --git a/data/sound/ludicrouskill.wav b/data/sound/ludicrouskill.wav new file mode 100644 index 00000000..a6c0aca2 Binary files /dev/null and b/data/sound/ludicrouskill.wav differ diff --git a/data/sound/megakill.wav b/data/sound/megakill.wav new file mode 100644 index 00000000..022d135c Binary files /dev/null and b/data/sound/megakill.wav differ diff --git a/data/sound/monsterkill.wav b/data/sound/monsterkill.wav new file mode 100644 index 00000000..1dfb0698 Binary files /dev/null and b/data/sound/monsterkill.wav differ diff --git a/data/sound/multikill.wav b/data/sound/multikill.wav new file mode 100644 index 00000000..0a9f1f66 Binary files /dev/null and b/data/sound/multikill.wav differ diff --git a/data/sound/perfect.wav b/data/sound/perfect.wav new file mode 100644 index 00000000..a0a6c25c Binary files /dev/null and b/data/sound/perfect.wav differ diff --git a/data/sound/play.wav b/data/sound/play.wav new file mode 100644 index 00000000..f9300dbb Binary files /dev/null and b/data/sound/play.wav differ diff --git a/data/sound/prepare.wav b/data/sound/prepare.wav new file mode 100644 index 00000000..4ac754eb Binary files /dev/null and b/data/sound/prepare.wav differ diff --git a/data/sound/rampage.wav b/data/sound/rampage.wav new file mode 100644 index 00000000..97324ab1 Binary files /dev/null and b/data/sound/rampage.wav differ diff --git a/data/sound/teamkiller.wav b/data/sound/teamkiller.wav new file mode 100644 index 00000000..f9bbb140 Binary files /dev/null and b/data/sound/teamkiller.wav differ diff --git a/data/sound/triplekill.wav b/data/sound/triplekill.wav new file mode 100644 index 00000000..39485e73 Binary files /dev/null and b/data/sound/triplekill.wav differ diff --git a/data/sound/ultrakill.wav b/data/sound/ultrakill.wav new file mode 100644 index 00000000..448e67e9 Binary files /dev/null and b/data/sound/ultrakill.wav differ diff --git a/data/sound/unstoppable.wav b/data/sound/unstoppable.wav new file mode 100644 index 00000000..59e202f1 Binary files /dev/null and b/data/sound/unstoppable.wav differ diff --git a/data/sound/wickedsick.wav b/data/sound/wickedsick.wav new file mode 100644 index 00000000..937709df Binary files /dev/null and b/data/sound/wickedsick.wav differ diff --git a/include/hacks/Killstreak.hpp b/include/hacks/Killstreak.hpp new file mode 100644 index 00000000..e7fefa2e --- /dev/null +++ b/include/hacks/Killstreak.hpp @@ -0,0 +1,20 @@ +/* + * Killstreak.hpp + * + * Created on: Nov 13, 2017 + * Author: nullifiedcat + */ + +#pragma once + +#include "common.hpp" + +namespace hacks { namespace tf2 { namespace killstreak { + +int current_streak(); +void init(); +void shutdown(); +void fire_event(IGameEvent *event); +void apply_killstreaks(); + +}}} diff --git a/include/hacks/hacklist.hpp b/include/hacks/hacklist.hpp index 67fc306c..2c433a33 100644 --- a/include/hacks/hacklist.hpp +++ b/include/hacks/hacklist.hpp @@ -41,5 +41,6 @@ #include "Noisemaker.hpp" #include "FollowBot.hpp" #include "Announcer.hpp" +#include "Killstreak.hpp" #endif /* HACKS_HACKLIST_HPP_ */ diff --git a/include/netvars.hpp b/include/netvars.hpp index 25e3d1c8..e48ed412 100644 --- a/include/netvars.hpp +++ b/include/netvars.hpp @@ -139,6 +139,8 @@ public: offset_t m_angEyeAnglesLocal; offset_t m_nSequence; offset_t m_flSimulationTime; + offset_t m_nStreaks_Player; + offset_t m_nStreaks_Resource; }; extern NetVars netvar; diff --git a/include/offsets.hpp b/include/offsets.hpp index de927c2d..dc571f85 100644 --- a/include/offsets.hpp +++ b/include/offsets.hpp @@ -60,6 +60,8 @@ struct offsets { static constexpr uint32_t LevelShutdown() { return PlatformOffset(24, -1, -1); } static constexpr uint32_t BeginFrame() { return PlatformOffset(5, -1, -1); } static constexpr uint32_t FireGameEvent() { return PlatformOffset(2, -1, -1); } + static constexpr uint32_t FireEvent() { return PlatformOffset(8, 0, 0); } + static constexpr uint32_t FireEventClientSide() { return PlatformOffset(9, 0, 0); } static constexpr uint32_t lastoutgoingcommand() { return PlatformOffset(19228, -1, -1); } static constexpr uint32_t m_nOutSequenceNr() { return PlatformOffset(8, -1, -1); } diff --git a/src/drawing.cpp b/src/drawing.cpp index f162913a..d0508ab3 100644 --- a/src/drawing.cpp +++ b/src/drawing.cpp @@ -88,7 +88,7 @@ bool draw::EntityCenterToScreen(CachedEntity* entity, Vector& out) { Vector world, min, max; bool succ; - if (!entity) return false; + if (!entity || !RAW_ENT(entity)) return false; RAW_ENT(entity)->GetRenderBounds(min, max); world = RAW_ENT(entity)->GetAbsOrigin(); world.z += (min.z + max.z) / 2; diff --git a/src/entityhitboxcache.cpp b/src/entityhitboxcache.cpp index dc50c5b2..93bf8b0f 100644 --- a/src/entityhitboxcache.cpp +++ b/src/entityhitboxcache.cpp @@ -99,8 +99,9 @@ matrix3x4_t* EntityHitboxCache::GetBones() { bones_setup_time = CE_FLOAT(parent_ref, netvar.m_flSimulationTime); } if (!bones_setup) { - std::lock_guard lock(setupbones_mutex); - bones_setup = RAW_ENT(parent_ref)->SetupBones(bones, MAXSTUDIOBONES, 0x100, bones_setup_time); + //std::lock_guard lock(setupbones_mutex); + if (g_Settings.is_create_move) + bones_setup = RAW_ENT(parent_ref)->SetupBones(bones, MAXSTUDIOBONES, 0x100, bones_setup_time); } return bones; } diff --git a/src/hack.cpp b/src/hack.cpp index 47de0411..dfed6d9e 100644 --- a/src/hack.cpp +++ b/src/hack.cpp @@ -277,6 +277,7 @@ void hack::Initialize() { // FIXME [MP] hacks::shared::killsay::Init(); hacks::shared::announcer::init(); + hacks::tf2::killstreak::init(); logging::Info("Hooked!"); velocity::Init(); playerlist::Load(); diff --git a/src/hacks/Announcer.cpp b/src/hacks/Announcer.cpp index 25153f02..8b445d62 100644 --- a/src/hacks/Announcer.cpp +++ b/src/hacks/Announcer.cpp @@ -63,7 +63,12 @@ const announcer_entry_s *find_entry(const std::vector& vector void playsound(const std::string& sound) { - g_ISurface->PlaySound(std::string("announcer/" + sound).c_str()); + // yes + char command[128]; + snprintf(command, 128, "aplay %s/sound/%s &", DATA_PATH, sound.c_str()); + logging::Info("system(%s)", command); + system(command); + // g_ISurface->PlaySound(std::string("announcer/" + sound).c_str()); } void reset() @@ -136,11 +141,25 @@ void on_kill(IGameEvent *event) } } +void on_spawn(IGameEvent *event) +{ + int userid = g_IEngine->GetPlayerForUserID(event->GetInt("userid")); + + if (userid == g_IEngine->GetLocalPlayer()) + { + reset(); + } +} + class AnnouncerEventListener : public IGameEventListener2 { virtual void FireGameEvent(IGameEvent *event) { - if (enabled) + if (!enabled) + return; + if (0 == strcmp(event->GetName(), "player_death")) on_kill(event); + else if (0 == strcmp(event->GetName(), "player_spawn")) + on_spawn(event); } }; @@ -153,6 +172,7 @@ AnnouncerEventListener& listener() void init() { g_IEventManager2->AddListener(&listener(), "player_death", false); + g_IEventManager2->AddListener(&listener(), "player_spawn", false); } void shutdown() diff --git a/src/hacks/Killstreak.cpp b/src/hacks/Killstreak.cpp new file mode 100644 index 00000000..a037240d --- /dev/null +++ b/src/hacks/Killstreak.cpp @@ -0,0 +1,132 @@ +/* + * Killstreak.cpp + * + * Created on: Nov 13, 2017 + * Author: nullifiedcat + */ + +#include "common.hpp" +#include "hooks.hpp" + +namespace hacks { namespace tf2 { namespace killstreak { + +CatVar enabled(CV_SWITCH, "killstreak", "0", "Enable killstreaks on all weapons"); + +int killstreak { 0 }; + +void reset() +{ + killstreak = 0; +} + +int current_streak() +{ + return killstreak; +} + +void apply_killstreaks() +{ + if (!enabled) + return; + + IClientEntity *ent = g_IEntityList->GetClientEntity(g_IEngine->GetLocalPlayer()); + + IClientEntity *resource = g_IEntityList->GetClientEntity(g_pPlayerResource->entity); + if (!ent || ent->GetClientClass()->m_ClassID != RCC_PLAYERRESOURCE) return; + + if (!(ent && resource)) + { + logging::Info("1"); + } + + int *streaks_resource = (int*)((unsigned)resource + netvar.m_nStreaks_Resource + 4 * g_IEngine->GetLocalPlayer()); + if (*streaks_resource != current_streak()) + { + logging::Info("Adjusting %d -> %d", *streaks_resource, current_streak()); + *streaks_resource = current_streak(); + } + int *streaks_player = (int *)ent + netvar.m_nStreaks_Player; + //logging::Info("P0: %d", streaks_player[0]); + streaks_player[0] = current_streak(); + streaks_player[1] = current_streak(); + streaks_player[2] = current_streak(); + streaks_player[3] = current_streak(); +} + +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; + + killstreak++; + +// if (event->GetInt("kill_streak_total") == 0) + { + logging::Info("Manipulating KS %d", killstreak); + event->SetInt("kill_streak_total", current_streak()); + event->SetInt("kill_streak_wep", current_streak()); + } + apply_killstreaks(); +} + +void on_spawn(IGameEvent *event) +{ + int userid = g_IEngine->GetPlayerForUserID(event->GetInt("userid")); + + if (userid == g_IEngine->GetLocalPlayer()) + { + reset(); + } + apply_killstreaks(); +} + +void fire_event(IGameEvent *event) +{ + if (enabled) + { + if (0 == strcmp(event->GetName(), "player_death")) + on_kill(event); + else if (0 == strcmp(event->GetName(), "player_spawn")) + on_spawn(event); + + } +} + +hooks::VMTHook hook; + +typedef bool(*FireEvent_t)(IGameEventManager2 *, IGameEvent *, bool); +bool FireEvent_hook(IGameEventManager2 *manager, IGameEvent *event, bool bDontBroadcast) +{ + static FireEvent_t original = hook.GetMethod(offsets::FireEvent()); + fire_event(event); + return original(manager, event, bDontBroadcast); +} + +typedef bool(*FireEventClientSide_t)(IGameEventManager2 *, IGameEvent *); +bool FireEventClientSide(IGameEventManager2 *manager, IGameEvent *event) +{ + static FireEventClientSide_t original = hook.GetMethod(offsets::FireEventClientSide()); + fire_event(event); + return original(manager, event); +} + +void init() +{ + hook.Set(g_IEventManager2, 0); + // hook.HookMethod(FireEvent_hook, offsets::FireEvent()); + hook.HookMethod(FireEventClientSide, offsets::FireEventClientSide()); + hook.Apply(); +} + +}}} diff --git a/src/hacks/SkinChanger.cpp b/src/hacks/SkinChanger.cpp index c6a5e5d7..b5b3f54c 100644 --- a/src/hacks/SkinChanger.cpp +++ b/src/hacks/SkinChanger.cpp @@ -13,8 +13,8 @@ namespace hacks { namespace tf2 { namespace skinchanger { // Because fuck you, that's why. -const char* sig_GetAttributeDefinition = "55 89 E5 57 56 53 83 EC 6C C7 45 9C 00 00 00 00 8B 75 08 C7 45 A4 00 00 00 00 8B 45 0C C6 45 A8 00 C6 45 A9 00 C6 45 AA 00 8B BE B0 01 00 00 C6 45 AB 00 C6 45 B4 00 C7 45 B8 00 00 00 00 C7 45 BC 02 00 00 00 83 FF FF C7 45 C0 00 00 00 00 C7 45 C4 00 00 00 00 C7 45 C8 00 00 00 00 C7 45 CC 00 00 00 00 C7 45 D0 00 00 00 00 C6 45 D4 00 C6 45 D5 00 C7 45 D8 FF FF FF FF C7 45 DC 00 00 00 00 89 45 98 0F 84 86 01 00 00 8B 86 A4 01 00 00 EB 21"; -const char* sig_SetRuntimeAttributeValue = "55 89 E5 57 56 53 83 EC 3C 8B 5D 08 8B 4B 10 85 C9 7E 33 8B 75 0C 8B 43 04 0F B7 7E 04 66 3B 78 04 0F 84 CA 00 00 00 83 C0 10 31 D2 EB 11 66 90 89 C6 83 C0 10 66 39 78 F4 0F 84 B9 00 00 00"; +const char* sig_GetAttributeDefinition = "55 89 E5 57 56 53 83 EC 6C C7 45 9C 00 00 00 00 8B 75 08 C7 45 A4 00 00 00 00 8B 45 0C C6 45 A8 00 C6 45 A9 00 C6"; +const char* sig_SetRuntimeAttributeValue = "55 89 E5 57 56 53 83 EC 3C 8B 5D 08 8B 4B 10 85 C9 7E 33"; const char* sig_GetItemSchema = "55 89 E5 57 56 53 83 EC 1C 8B 1D ? ? ? ? 85 DB 89 D8 74 0B 83 C4 1C 5B 5E 5F 5D C3"; ItemSystem_t ItemSystem { nullptr }; diff --git a/src/helpers.cpp b/src/helpers.cpp index 4291ca96..871e5f72 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -332,6 +332,8 @@ bool IsEntityVisible(CachedEntity* entity, int hb) { } +CatVar tcm(CV_SWITCH, "debug_tcm", "1", "TCM"); + std::mutex trace_lock; bool IsEntityVectorVisible(CachedEntity* entity, Vector endpos) { trace_t trace_object; @@ -346,7 +348,8 @@ bool IsEntityVectorVisible(CachedEntity* entity, Vector endpos) { { PROF_SECTION(IEVV_TraceRay); std::lock_guard lock(trace_lock); - g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default, &trace_object); + if (!tcm || g_Settings.is_create_move) + g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default, &trace_object); } return (trace_object.fraction >= 0.99f || (((IClientEntity*)trace_object.m_pEnt)) == RAW_ENT(entity)); } diff --git a/src/hooks/others.cpp b/src/hooks/others.cpp index 4a5d575d..cd5e260f 100644 --- a/src/hooks/others.cpp +++ b/src/hooks/others.cpp @@ -435,6 +435,7 @@ void FireGameEvent_hook(void* _this, IGameEvent* event) { return; } } +// hacks::tf2::killstreak::fire_event(event); } original(_this, event); } @@ -445,6 +446,7 @@ void FrameStageNotify_hook(void* _this, int stage) { static IClientEntity *ent; PROF_SECTION(FrameStageNotify_TOTAL); + hacks::tf2::killstreak::apply_killstreaks(); static const FrameStageNotify_t original = (FrameStageNotify_t)hooks::client.GetMethod(offsets::FrameStageNotify()); SEGV_BEGIN; diff --git a/src/netvars.cpp b/src/netvars.cpp index 2e6df567..8fa67a4b 100644 --- a/src/netvars.cpp +++ b/src/netvars.cpp @@ -76,6 +76,8 @@ void NetVars::Init() { this->iWeaponState = gNetvars.get_offset("DT_WeaponMinigun", "m_iWeaponState"); this->flChargeLevel = gNetvars.get_offset("DT_WeaponMedigun", "NonLocalTFWeaponMedigunData", "m_flChargeLevel"); this->bChargeRelease = gNetvars.get_offset("DT_WeaponMedigun", "m_bChargeRelease"); + this->m_nStreaks_Player = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_nStreaks"); + this->m_nStreaks_Resource = gNetvars.get_offset("DT_TFPlayerResource", "m_iStreaks"); } IF_GAME (IsTF2C()) { this->iCritMult = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_iCritMult");