diff --git a/data/menu/nullifiedcat/visuals/world.xml b/data/menu/nullifiedcat/visuals/world.xml
index 816e8975..37f3f5c1 100755
--- a/data/menu/nullifiedcat/visuals/world.xml
+++ b/data/menu/nullifiedcat/visuals/world.xml
@@ -25,6 +25,7 @@
+
diff --git a/include/core/netvars.hpp b/include/core/netvars.hpp
index f5b8e37e..be4fb062 100644
--- a/include/core/netvars.hpp
+++ b/include/core/netvars.hpp
@@ -174,6 +174,7 @@ public:
offset_t m_iTauntConcept;
offset_t m_iTauntIndex;
+ offset_t m_bViewingCYOAPDA;
offset_t m_angEyeAnglesLocal;
offset_t m_nSequence;
offset_t m_flSimulationTime;
diff --git a/src/core/netvars.cpp b/src/core/netvars.cpp
index db81ebfc..84e54551 100644
--- a/src/core/netvars.cpp
+++ b/src/core/netvars.cpp
@@ -59,12 +59,13 @@ void NetVars::Init()
this->m_nChargeResistType = gNetvars.get_offset("DT_WeaponMedigun", "m_nChargeResistType");
this->m_hHealingTarget = gNetvars.get_offset("DT_WeaponMedigun", "m_hHealingTarget");
this->m_flChargeLevel = gNetvars.get_offset("DT_WeaponMedigun", "NonLocalTFWeaponMedigunData", "m_flChargeLevel");
- m_bFeignDeathReady = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_bFeignDeathReady");
- m_bCarryingObject = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_bCarryingObject");
- m_hCarriedObject = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_hCarriedObject");
- m_nSequence = gNetvars.get_offset("DT_BaseAnimating", "m_nSequence");
- m_iTauntIndex = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_iTauntIndex");
- m_iTauntConcept = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_iTauntConcept");
+ this->m_bFeignDeathReady = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_bFeignDeathReady");
+ this->m_bCarryingObject = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_bCarryingObject");
+ this->m_hCarriedObject = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_hCarriedObject");
+ this->m_nSequence = gNetvars.get_offset("DT_BaseAnimating", "m_nSequence");
+ this->m_iTauntIndex = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_iTauntIndex");
+ this->m_iTauntConcept = gNetvars.get_offset("DT_TFPlayer", "m_Shared", "m_iTauntConcept");
+ this->m_bViewingCYOAPDA = gNetvars.get_offset("DT_TFPlayer", "m_bViewingCYOAPDA");
}
this->res_iScore = gNetvars.get_offset("DT_TFPlayerResource", "baseclass", "m_iScore");
IF_GAME(IsTF())
diff --git a/src/hacks/AutoBackstab.cpp b/src/hacks/AutoBackstab.cpp
index 375b37eb..9be9f99a 100644
--- a/src/hacks/AutoBackstab.cpp
+++ b/src/hacks/AutoBackstab.cpp
@@ -173,7 +173,7 @@ static bool doRageBackstab()
Ray_t ray;
trace::filter_default.SetSelf(RAW_ENT(g_pLocalPlayer->entity));
ray.Init(g_pLocalPlayer->v_Eye, GetForwardVector(g_pLocalPlayer->v_Eye, angle, swingrange, LOCAL_E));
- g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default, &trace);
+ g_ITrace->TraceRay(ray, MASK_SOLID, &trace::filter_default, &trace);
if (trace.m_pEnt)
{
int index = reinterpret_cast(trace.m_pEnt)->entindex();
@@ -199,7 +199,7 @@ static bool doRageBackstab()
Ray_t ray;
trace::filter_default.SetSelf(RAW_ENT(g_pLocalPlayer->entity));
ray.Init(g_pLocalPlayer->v_Eye, GetForwardVector(g_pLocalPlayer->v_Eye, newangle, swingrange, LOCAL_E));
- g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default, &trace);
+ g_ITrace->TraceRay(ray, MASK_SOLID, &trace::filter_default, &trace);
if (trace.m_pEnt)
{
int index = reinterpret_cast(trace.m_pEnt)->entindex();
diff --git a/src/hacks/ESP.cpp b/src/hacks/ESP.cpp
index 32b0cdcf..0f3a098f 100644
--- a/src/hacks/ESP.cpp
+++ b/src/hacks/ESP.cpp
@@ -467,7 +467,7 @@ void _FASTCALL ProcessEntityPT(CachedEntity *ent)
Ray_t ray;
ray.Init(eye_position, forward);
trace_t trace;
- g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_no_player, &trace);
+ g_ITrace->TraceRay(ray, MASK_SOLID, &trace::filter_no_player, &trace);
// Screen vectors
Vector scn1, scn2;
diff --git a/src/hacks/Misc.cpp b/src/hacks/Misc.cpp
index ad716dce..fa3968f2 100644
--- a/src/hacks/Misc.cpp
+++ b/src/hacks/Misc.cpp
@@ -48,6 +48,12 @@ static settings::Boolean misc_drawhitboxes{ "misc.draw-hitboxes", "false" };
static settings::Boolean misc_drawhitboxes_dead{ "misc.draw-hitboxes.dead-players", "false" };
#endif
+#if ENABLE_TEXTMODE
+static settings::Boolean fix_cyoaanim{ "remove.contracker", "true" };
+#else
+static settings::Boolean fix_cyoaanim{ "remove.contracker", "false" };
+#endif
+
#if !ENFORCE_STREAM_SAFETY && ENABLE_VISUALS
static void tryPatchLocalPlayerShouldDraw(bool after)
{
@@ -879,7 +885,24 @@ void Shutdown()
#endif
}
+static ProxyFnHook cyoa_anim_hook{};
+
+void cyoaview_nethook(const CRecvProxyData *data, void *pPlayer, void *out)
+{
+ int value = data->m_Value.m_Int;
+ int *value_out = (int *) out;
+ if (!fix_cyoaanim)
+ {
+ *value_out = value;
+ return;
+ }
+ // Mark as not doing cyoa thing
+ if (CE_BAD(LOCAL_E) || pPlayer != RAW_ENT(LOCAL_E))
+ *value_out = false;
+}
+
static InitRoutine init([]() {
+ HookNetvar({ "DT_TFPlayer", "m_bViewingCYOAPDA" }, cyoa_anim_hook, cyoaview_nethook);
teammatesPushaway = g_ICvar->FindVar("tf_avoidteammates_pushaway");
EC::Register(EC::Shutdown, Shutdown, "draw_local_player", EC::average);
EC::Register(EC::CreateMove, CreateMove, "cm_misc_hacks", EC::average);
diff --git a/src/trace.cpp b/src/trace.cpp
index 6fc2cf01..017742ae 100644
--- a/src/trace.cpp
+++ b/src/trace.cpp
@@ -46,6 +46,32 @@ bool trace::FilterDefault::ShouldHitEntity(IHandleEntity *handle, int mask)
case CL_CLASS(CTFMedigunShield):
case CL_CLASS(CFuncAreaPortalWindow):
return false;
+ // Sniper rifles can shoot through teammates!
+ case CL_CLASS(CTFPlayer):
+ {
+ if (m_pSelf)
+ {
+ // If what we hit is an enemy it does not matter
+ if (entity && CE_VALID(ENTITY(entity->entindex())) && ENTITY(entity->entindex())->m_iTeam() == ENTITY(m_pSelf->entindex())->m_iTeam())
+ {
+ auto ent = ENTITY(m_pSelf->entindex());
+ if (CE_GOOD(ent) && ent->m_bAlivePlayer())
+ {
+ // Get held weapon
+ auto weapon_idx = CE_INT(ent, netvar.hActiveWeapon) & 0xFFF;
+ // Check if weapon is valid
+ if (IDX_GOOD(weapon_idx))
+ {
+ auto weapon = ENTITY(weapon_idx);
+ // If holding sniper rifle
+ if (weapon->m_iClassID() == CL_CLASS(CTFSniperRifle) || weapon->m_iClassID() == CL_CLASS(CTFSniperRifleDecap))
+ return false;
+ }
+ }
+ }
+ }
+ break;
+ }
}
/* Do not hit yourself. Idiot. */
if (entity == m_pSelf)