diff --git a/data/menu/nullifiedcat/aimbot.xml b/data/menu/nullifiedcat/aimbot.xml
index 11b69b30..cd427f05 100755
--- a/data/menu/nullifiedcat/aimbot.xml
+++ b/data/menu/nullifiedcat/aimbot.xml
@@ -20,6 +20,7 @@
+
diff --git a/include/reclasses/C_TFWeaponBase.hpp b/include/reclasses/C_TFWeaponBase.hpp
index 0488e147..dd1714f3 100644
--- a/include/reclasses/C_TFWeaponBase.hpp
+++ b/include/reclasses/C_TFWeaponBase.hpp
@@ -42,6 +42,11 @@ public:
typedef int (*fn_t)(IClientEntity *);
return vfunc(self, offsets::PlatformOffset(445, offsets::undefined, 445), 0)(self);
}
+ inline static bool IsViewModelFlipped(IClientEntity *self)
+ {
+ typedef bool (*fn_t)(IClientEntity *);
+ return vfunc(self, offsets::PlatformOffset(494, offsets::undefined, 494), 0)(self);
+ }
inline static IClientEntity *GetOwnerViaInterface(IClientEntity *self)
{
typedef IClientEntity *(*fn_t)(IClientEntity *);
diff --git a/src/hacks/AutoViewmodel.cpp b/src/hacks/AutoViewmodel.cpp
new file mode 100644
index 00000000..d53e9b94
--- /dev/null
+++ b/src/hacks/AutoViewmodel.cpp
@@ -0,0 +1,61 @@
+#include "common.hpp"
+
+static settings::Boolean auto_viewmodel_flipper{ "misc.auto-flip-viewmodel", "false" };
+
+void CreateMove()
+{
+ if (!auto_viewmodel_flipper)
+ return;
+ static auto cl_flipviewmodels = g_ICvar->FindVar("cl_flipviewmodels");
+ if (!cl_flipviewmodels)
+ {
+ cl_flipviewmodels = g_ICvar->FindVar("cl_flipviewmodels");
+ return;
+ }
+ static bool defaults = cl_flipviewmodels->GetBool();
+
+ // Should we test if a flip would help?
+ bool should_test_viewmodel = true;
+ for (int i = 1; i <= g_IEngine->GetMaxClients(); i++)
+ {
+ CachedEntity *ent = ENTITY(i);
+ if (CE_BAD(ent) || !ent->m_bEnemy() || !ent->m_bAlivePlayer() || ent == LOCAL_E)
+ continue;
+ auto eye = g_pLocalPlayer->v_Eye;
+ auto angle = GetAimAtAngles(eye, ent->m_vecOrigin());
+ eye = getShootPos(angle);
+
+ if (IsVectorVisible(eye, ent->m_vecOrigin()))
+ {
+ should_test_viewmodel = false;
+ break;
+ }
+ }
+ bool keep_flipped = false;
+ // Noone is visible, test if flipping helps
+ if (should_test_viewmodel)
+ {
+ cl_flipviewmodels->SetValue(!cl_flipviewmodels->GetBool());
+ for (int i = 0; i <= g_IEngine->GetMaxClients(); i++)
+ {
+ CachedEntity *ent = ENTITY(i);
+ if (CE_BAD(ent) || !ent->m_bEnemy() || !ent->m_bAlivePlayer() || ent == LOCAL_E)
+ continue;
+ auto eye = g_pLocalPlayer->v_Eye;
+ auto angle = GetAimAtAngles(eye, ent->m_vecOrigin());
+ eye = getShootPos(angle);
+
+ if (IsVectorVisible(eye, ent->m_vecOrigin()))
+ {
+ keep_flipped = true;
+ break;
+ }
+ }
+ }
+
+ // Reset status as noone is in range
+ if (!keep_flipped && should_test_viewmodel)
+ cl_flipviewmodels->SetValue(defaults);
+}
+
+static InitRoutine init([]() { EC::Register(EC::CreateMove, CreateMove, "viewmodel_flip_cm"); });