diff --git a/include/entitycache.hpp b/include/entitycache.hpp index 28917113..2a5e5d06 100644 --- a/include/entitycache.hpp +++ b/include/entitycache.hpp @@ -110,6 +110,7 @@ public: { return RAW_ENT(this)->GetAbsOrigin(); }; + Vector m_vecDormantOrigin(); int m_iTeam() { return NET_INT(RAW_ENT(this), netvar.iTeamNum); diff --git a/include/soundcache.hpp b/include/soundcache.hpp index 6b606217..f01937b9 100644 --- a/include/soundcache.hpp +++ b/include/soundcache.hpp @@ -1,9 +1,10 @@ #pragma once -#include "common.hpp" +#include "timer.hpp" +#include "map" +#include "public/mathlib/vector.h" struct CSndInfo_t { Vector m_pOrigin; - int m_nSoundSource; }; struct SoundStruct diff --git a/src/entitycache.cpp b/src/entitycache.cpp index 5413ef1a..ca2965ba 100644 --- a/src/entitycache.cpp +++ b/src/entitycache.cpp @@ -9,6 +9,7 @@ #include #include +#include "soundcache.hpp" bool IsProjectileACrit(CachedEntity *ent) { @@ -127,6 +128,15 @@ bool CachedEntity::IsVisible() return false; } +Vector CachedEntity::m_vecDormantOrigin() +{ + if (!RAW_ENT(this)->IsDormant()) + return m_vecOrigin(); + else if (!sound_cache[m_IDX].last_update.check(10000) && !sound_cache[m_IDX].sound.m_pOrigin.IsZero()) + return sound_cache[m_IDX].sound.m_pOrigin; + return Vector(0.0f); +} + namespace entity_cache { diff --git a/src/hacks/DominateMark.cpp b/src/hacks/DominateMark.cpp index 1b81b037..e296f63c 100644 --- a/src/hacks/DominateMark.cpp +++ b/src/hacks/DominateMark.cpp @@ -5,6 +5,7 @@ * */ #include "common.hpp" +#include "soundcache.hpp" namespace hacks::tf2::dominatemark { @@ -24,7 +25,7 @@ static InitRoutine init([]() { for (int i = 0; i <= g_IEngine->GetMaxClients(); i++) { CachedEntity *ent = ENTITY(i); - if (CE_GOOD(ent) && ent->m_bAlivePlayer() && re::CTFPlayerShared::IsDominatingPlayer(shared_player, i)) + if (CE_VALID(ent) && ent->m_bAlivePlayer() && re::CTFPlayerShared::IsDominatingPlayer(shared_player, i)) { Vector draw_pos; float size; @@ -33,6 +34,13 @@ static InitRoutine init([]() { // Calculate draw pos auto c = ent->InternalEntity()->GetCollideable(); draw_pos = ent->m_vecOrigin(); + if (RAW_ENT(ent)->IsDormant()) + { + if (!sound_cache[ent->m_IDX].last_update.check(10000) && !sound_cache[ent->m_IDX].sound.m_pOrigin.IsZero()) + draw_pos = sound_cache[ent->m_IDX].sound.m_pOrigin; + else + continue; + } draw_pos.z += c->OBBMaxs().z; // Calculate draw size size = *max_size * 1.5f - ent->m_flDistance() / 20.0f; diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp index eec48ff2..4ad1e119 100644 --- a/src/hacks/ESP.cpp +++ b/src/hacks/ESP.cpp @@ -272,7 +272,14 @@ static void cm() { // Set entity color - SetEntityColor(ent, colors::EntityF(ent)); + rgba_t color = colors::EntityF(ent); + if (RAW_ENT(ent)->IsDormant()) + { + color.r *= 0.5f; + color.g *= 0.5f; + color.b *= 0.5f; + } + SetEntityColor(ent, color); // If snow distance, add string here if (show_distance) @@ -391,7 +398,16 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent) // TODO, check if we can move this after world to screen check rgba_t fg = ent_data.color; if (!fg || fg.a == 0.0f) - fg = ent_data.color = colors::EntityF(ent); + { + fg = colors::EntityF(ent); + if (RAW_ENT(ent)->IsDormant()) + { + fg.r *= 0.5f; + fg.g *= 0.5f; + fg.b *= 0.5f; + } + ent_data.color = fg; + } // Check if entity is on screen, then save screen position if true Vector position = ent->m_vecOrigin(); @@ -539,6 +555,12 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent) fg = colors::EntityF(ent); if (transparent) fg = colors::Transparent(fg); + if (RAW_ENT(ent)->IsDormant()) + { + fg.r *= 0.5f; + fg.g *= 0.5f; + fg.b *= 0.5f; + } if (!box_3d_player && box_esp) DrawBox(ent, fg); else if (box_3d_player) @@ -553,6 +575,12 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent) fg = colors::EntityF(ent); if (transparent) fg = colors::Transparent(fg); + if (RAW_ENT(ent)->IsDormant()) + { + fg.r *= 0.5f; + fg.g *= 0.5f; + fg.b *= 0.5f; + } if (!box_3d_building && box_esp) DrawBox(ent, fg); else if (box_3d_building) @@ -1151,7 +1179,13 @@ void _FASTCALL ProcessEntity(CachedEntity *ent) // Conditions esp if (show_conditions) { - const auto &clr = colors::EntityF(ent); + auto clr = colors::EntityF(ent); + if (RAW_ENT(ent)->IsDormant()) + { + clr.r *= 0.5f; + clr.g *= 0.5f; + clr.b *= 0.5f; + } // Invis if (IsPlayerInvisible(ent)) { @@ -1279,13 +1313,13 @@ void _FASTCALL Draw3DBox(CachedEntity *ent, const rgba_t &clr) if (!success) return; + rgba_t draw_clr = clr; // Draw the actual box for (int i = 1; i <= 4; i++) { - draw: - draw::Line((points[i - 1].x), (points[i - 1].y), (points[i % 4].x) - (points[i - 1].x), (points[i % 4].y) - (points[i - 1].y), clr, 0.5f); - draw::Line((points[i - 1].x), (points[i - 1].y), (points[i + 3].x) - (points[i - 1].x), (points[i + 3].y) - (points[i - 1].y), clr, 0.5f); - draw::Line((points[i + 3].x), (points[i + 3].y), (points[i % 4 + 4].x) - (points[i + 3].x), (points[i % 4 + 4].y) - (points[i + 3].y), clr, 0.5f); + draw::Line((points[i - 1].x), (points[i - 1].y), (points[i % 4].x) - (points[i - 1].x), (points[i % 4].y) - (points[i - 1].y), draw_clr, 0.5f); + draw::Line((points[i - 1].x), (points[i - 1].y), (points[i + 3].x) - (points[i - 1].x), (points[i + 3].y) - (points[i - 1].y), draw_clr, 0.5f); + draw::Line((points[i + 3].x), (points[i + 3].y), (points[i % 4 + 4].x) - (points[i + 3].x), (points[i % 4 + 4].y) - (points[i + 3].y), draw_clr, 0.5f); } } @@ -1312,7 +1346,6 @@ void _FASTCALL DrawBox(CachedEntity *ent, const rgba_t &clr) // Depending on whether the player is cloaked, we change the color // acordingly rgba_t border = ((ent->m_iClassID() == RCC_PLAYER) && IsPlayerInvisible(ent)) ? colors::FromRGBA8(160, 160, 160, clr.a * 255.0f) : colors::Transparent(colors::black, clr.a); - // With box corners, we draw differently if ((int) box_esp == 2) BoxCorners(min_x, min_y, max_x, max_y, clr, (clr.a != 1.0f)); diff --git a/src/hacks/FollowBot.cpp b/src/hacks/FollowBot.cpp index 0d65ae5a..3590b723 100644 --- a/src/hacks/FollowBot.cpp +++ b/src/hacks/FollowBot.cpp @@ -10,6 +10,7 @@ #include #include "navparser.hpp" #include "NavBot.hpp" +#include "soundcache.hpp" namespace hacks::shared::followbot { @@ -80,9 +81,9 @@ static void checkAFK() for (int i = 0; i < g_GlobalVars->maxClients; i++) { auto entity = ENTITY(i); - if (CE_BAD(entity)) + if (CE_INVALID(entity)) continue; - if (!CE_VECTOR(entity, netvar.vVelocity).IsZero(60.0f)) + if (!CE_VECTOR(entity, netvar.vVelocity).IsZero(60.0f) || (RAW_ENT(entity)->IsDormant() && !sound_cache[i].last_update.check(10000) && !sound_cache[i].sound.m_pOrigin.IsZero())) { afkTicks[i].update(); } @@ -113,8 +114,16 @@ static void addCrumbs(CachedEntity *target, Vector corner = g_pLocalPlayer->v_Or } } - Vector dist = target->m_vecOrigin() - corner; - int maxiterations = floor(corner.DistTo(target->m_vecOrigin())) / 40; + Vector position = target->m_vecOrigin(); + if (RAW_ENT(target)->IsDormant()) + { + if (!sound_cache[target->m_IDX].last_update.check(10000) && !sound_cache[target->m_IDX].sound.m_pOrigin.IsZero()) + position = sound_cache[target->m_IDX].sound.m_pOrigin; + else + return; + } + Vector dist = position - corner; + int maxiterations = floor(corner.DistTo(position)) / 40; for (int i = 0; i < maxiterations; i++) { breadcrumbs.push_back(corner + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1)); @@ -126,12 +135,30 @@ static void addCrumbPair(CachedEntity *player1, CachedEntity *player2, std::pair Vector corner1 = corners.first; Vector corner2 = corners.second; + Vector position1 = player1->m_vecOrigin(); + if (RAW_ENT(player1)->IsDormant()) { - Vector dist = corner1 - player1->m_vecOrigin(); - int maxiterations = floor(corner1.DistTo(player1->m_vecOrigin())) / 40; + if (!sound_cache[player1->m_IDX].last_update.check(10000) && !sound_cache[player1->m_IDX].sound.m_pOrigin.IsZero()) + position1 = sound_cache[player1->m_IDX].sound.m_pOrigin; + else + return; + } + + Vector position2 = player2->m_vecOrigin(); + if (RAW_ENT(player1)->IsDormant()) + { + if (!sound_cache[player2->m_IDX].last_update.check(10000) && !sound_cache[player2->m_IDX].sound.m_pOrigin.IsZero()) + position2 = sound_cache[player2->m_IDX].sound.m_pOrigin; + else + return; + } + + { + Vector dist = corner1 - position1; + int maxiterations = floor(corner1.DistTo(position1)) / 40; for (int i = 0; i < maxiterations; i++) { - breadcrumbs.push_back(player1->m_vecOrigin() + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1)); + breadcrumbs.push_back(position1 + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1)); } } { @@ -143,8 +170,8 @@ static void addCrumbPair(CachedEntity *player1, CachedEntity *player2, std::pair } } { - Vector dist = player2->m_vecOrigin() - corner2; - int maxiterations = floor(corner2.DistTo(player2->m_vecOrigin())) / 40; + Vector dist = position2 - corner2; + int maxiterations = floor(corner2.DistTo(position2)) / 40; for (int i = 0; i < maxiterations; i++) { breadcrumbs.push_back(corner2 + dist / vectorMax(vectorAbs(dist)) * 40.0f * (i + 1)); @@ -227,7 +254,13 @@ static bool startFollow(CachedEntity *entity, bool useNavbot) } if (useNavbot) { - if (nav::navTo(entity->m_vecOrigin(), 8, true, false)) + Vector position = entity->m_vecOrigin(); + if (RAW_ENT(entity)->IsDormant()) + { + if (!sound_cache[entity->m_IDX].last_update.check(10000) && !sound_cache[entity->m_IDX].sound.m_pOrigin.IsZero()) + position = sound_cache[entity->m_IDX].sound.m_pOrigin; + } + if (nav::navTo(position, 8, true, false)) { navtarget = entity->m_IDX; return true; @@ -264,7 +297,9 @@ static void cm() if (breadcrumbs.size() > crumb_limit) follow_target = 0; // Still good check - else if (CE_BAD(ENTITY(follow_target)) || IsPlayerInvisible(ENTITY(follow_target))) + else if (CE_INVALID(ENTITY(follow_target)) || IsPlayerInvisible(ENTITY(follow_target))) + follow_target = 0; + else if (RAW_ENT(ENTITY(follow_target))->IsDormant() && (sound_cache[follow_target].last_update.check(1000) || sound_cache[follow_target].sound.m_pOrigin.IsZero())) follow_target = 0; } @@ -283,7 +318,7 @@ static void cm() for (int i = 1; i < ent_count; i++) { auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant + if (CE_INVALID(entity)) // Exist + dormant continue; if (i == follow_target) continue; @@ -295,6 +330,8 @@ static void cm() continue; if (!entity->m_bAlivePlayer()) // Dont follow dead players continue; + if (RAW_ENT(entity)->IsDormant() && (sound_cache[i].last_update.check(10000) || sound_cache[i].sound.m_pOrigin.IsZero())) + continue; if (startFollow(entity, isNavBotCM)) { navinactivity.update(); @@ -315,7 +352,7 @@ static void cm() for (int i = 1; i < ent_count; i++) { auto entity = ENTITY(i); - if (CE_BAD(entity)) // Exist + dormant + if (CE_INVALID(entity)) // Exist + dormant continue; if (!followcart) if (entity->m_Type() != ENTITY_PLAYER) @@ -331,6 +368,8 @@ static void cm() continue; if (!entity->m_bAlivePlayer()) // Dont follow dead players continue; + if (RAW_ENT(entity)->IsDormant() && (sound_cache[i].last_update.check(10000) || sound_cache[i].sound.m_pOrigin.IsZero())) + continue; // const model_t *model = ENTITY(follow_target)->InternalEntity()->GetModel(); // FIXME follow cart/point /*if (followcart && model && @@ -370,7 +409,7 @@ static void cm() if (navtarget) { auto ent = ENTITY(navtarget); - if (CE_GOOD(ent) && startFollow(ent, false)) + if (CE_VALID(ent) && startFollow(ent, false)) { follow_target = navtarget; navtarget = 0; @@ -380,14 +419,19 @@ static void cm() breadcrumbs.clear(); follow_target = 0; static Timer navtimer{}; - if (CE_GOOD(ent)) + if (CE_VALID(ent)) { if (!ent->m_bAlivePlayer()) { navtarget = 0; } + if (RAW_ENT(ent)->IsDormant() && (sound_cache[ent->m_IDX].last_update.check(10000) || sound_cache[ent->m_IDX].sound.m_pOrigin.IsZero())) + navtarget = 0; if (navtimer.test_and_set(800)) { + Vector position = ent->m_vecOrigin(); + if (RAW_ENT(ent)->IsDormant() && !sound_cache[ent->m_IDX].last_update.check(10000) && !sound_cache[ent->m_IDX].sound.m_pOrigin.IsZero()) + position = sound_cache[ent->m_IDX].sound.m_pOrigin; if (nav::navTo(ent->m_vecOrigin(), 8, true, false)) navinactivity.update(); } @@ -413,7 +457,7 @@ static void cm() CachedEntity *followtar = ENTITY(follow_target); // wtf is this needed - if (CE_BAD(followtar) || !followtar->m_bAlivePlayer()) + if (CE_INVALID(followtar) || !followtar->m_bAlivePlayer()) { follow_target = 0; return; diff --git a/src/hacks/Tracers.cpp b/src/hacks/Tracers.cpp index 55e6be92..b9deab26 100644 --- a/src/hacks/Tracers.cpp +++ b/src/hacks/Tracers.cpp @@ -60,10 +60,10 @@ inline std::optional getColor(CachedEntity *ent) { if (!ent->m_bEnemy()) return std::nullopt; - float dist = ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()); + float dist = ent->m_vecDormantOrigin().DistTo(LOCAL_E->m_vecOrigin()); if (*max_dist && dist > *max_dist) return std::nullopt; - if (GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, ent->m_vecOrigin()) < *min_fov) + if (GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, ent->m_vecDormantOrigin()) < *min_fov) return std::nullopt; float hf = float(std::min(dist, *green_dist)) / float(*green_dist); rgba_t color(0.0f, 2.0f * hf, 2.0f * (1.0f - hf)); @@ -79,7 +79,7 @@ inline std::optional getColor(CachedEntity *ent) { if (!ent->m_bEnemy()) return std::nullopt; - float dist = ent->m_vecOrigin().DistTo(LOCAL_E->m_vecOrigin()); + float dist = ent->m_vecDormantOrigin().DistTo(LOCAL_E->m_vecOrigin()); if (*max_dist && dist > *max_dist) return std::nullopt; return colors::Health(std::min(dist, *green_dist), *green_dist); @@ -110,7 +110,10 @@ void draw() { // Get and check player auto ent = ENTITY(i); - if (CE_BAD(ent) || !ent->m_bAlivePlayer()) + if (CE_INVALID(ent) || !ent->m_bAlivePlayer()) + continue; + Vector origin = ent->m_vecDormantOrigin(); + if (origin == Vector(0.0f, 0.0f, 0.0f)) continue; if (*buildings) if (ent->m_Type() != ENTITY_PLAYER && ent->m_Type() != ENTITY_BUILDING) @@ -120,10 +123,12 @@ void draw() auto color = getColor(ent); if (!color) continue; + if (RAW_ENT(ent)->IsDormant()) + color = colors::FromRGBA8(160, 160, 160, 255); color->a = *opaque; Vector out; - if (!draw::WorldToScreen(ent->m_vecOrigin(), out)) + if (!draw::WorldToScreen(origin, out)) { // We need to flip on both x and y axis in case m_vecOrigin its not actually on screen out.x = draw::width - out.x; diff --git a/src/soundcache.cpp b/src/soundcache.cpp index d76ea7ba..485480ed 100644 --- a/src/soundcache.cpp +++ b/src/soundcache.cpp @@ -1,16 +1,5 @@ #include "common.hpp" - -struct CSndInfo_t -{ - Vector m_pOrigin; - int m_nSoundSource; -}; - -struct SoundStruct -{ - CSndInfo_t sound; - Timer last_update; -}; +#include "soundcache.hpp" std::map sound_cache; void CreateMove() @@ -21,8 +10,7 @@ void CreateMove() g_ISoundEngine->GetActiveSounds(sound_list); for (auto i : sound_list) { - sound_cache[i.m_nSoundSource].sound.m_pOrigin = *i.m_pOrigin; - sound_cache[i.m_nSoundSource].sound.m_nSoundSource = sound_cache[i.m_nSoundSource].sound.m_nSoundSource; + sound_cache[i.m_nSoundSource].sound.m_pOrigin = *i.m_pOrigin; sound_cache[i.m_nSoundSource].last_update.update(); } }