From 19b6ff3cfd30448edaf9a23edbfcc85e981052b7 Mon Sep 17 00:00:00 2001 From: julianacat Date: Thu, 29 Jun 2017 11:38:48 -0500 Subject: [PATCH] Auto-Reflect Improvements --- src/hacks/Aimbot.cpp | 3 + src/hacks/AutoReflect.cpp | 122 +++++++++++++++++++++++++++++++------- src/hacks/AutoReflect.h | 1 + src/helpers.cpp | 114 +++++++---------------------------- src/helpers.h | 3 +- tf-settings/menu.json | 3 +- 6 files changed, 128 insertions(+), 118 deletions(-) diff --git a/src/hacks/Aimbot.cpp b/src/hacks/Aimbot.cpp index a837f5f0..95ba177c 100644 --- a/src/hacks/Aimbot.cpp +++ b/src/hacks/Aimbot.cpp @@ -840,6 +840,9 @@ float EffectiveTargetingRange() { // Melees use a close range, TODO add dynamic range for demoknight swords if (GetWeaponMode() == weapon_melee) { return 100.0f; + // Pyros only have so much untill their flames hit + } else if ( g_pLocalPlayer->weapon()->m_iClassID == CL_CLASS(CTFFlameThrower) ) { + return 185.0f; } // Else return user settings return (float)max_range; diff --git a/src/hacks/AutoReflect.cpp b/src/hacks/AutoReflect.cpp index aeb7ec36..1377cfa1 100644 --- a/src/hacks/AutoReflect.cpp +++ b/src/hacks/AutoReflect.cpp @@ -12,56 +12,132 @@ namespace hacks { namespace tf { namespace autoreflect { -CatVar enabled(CV_SWITCH, "reflect_enabled", "0", "AutoReflect", "Master AutoReflect switch"); +// Vars for user settings +CatVar enabled(CV_SWITCH, "reflect_enabled", "0", "Auto Reflect", "Master AutoReflect switch"); CatVar idle_only(CV_SWITCH, "reflect_only_idle", "0", "Only when not shooting", "Don't AutoReflect if you're holding M1"); +CatVar legit(CV_SWITCH, "reflect_legit", "0", "Legit Reflect", "Only Auto-airblasts projectiles that you can see, doesnt move your crosshair"); +CatVar dodgeball(CV_SWITCH, "reflect_dodgeball", "0", "Dodgeball Mode", "Allows auto-reflect to work in dodgeball servers"); + CatVar stickies(CV_SWITCH, "reflect_stickybombs", "0", "Reflect stickies", "Reflect Stickybombs"); -CatVar max_distance(CV_INT, "reflect_distance", "200", "Distance", "Maximum distance to reflect at", true, 300.0f); +// TODO setup proj sorting +// TODO CatVar bigProj(CV_SWITCH, "reflect_big_projectile", "0", "Reflect big projectiles", "Reflect Rockets"); +// TODO CatVar smallProj(CV_SWITCH, "reflect_small_projectile", "0", "Reflect small projectiles", "Reflect Huntsman arrows, Crusaders bolts"); +// TODO CatVar miscProj(CV_SWITCH, "reflect_misc_projectile", "0", "Reflect other", "Reflect jarate, milk"); + +// Function called by game for movement void CreateMove() { + // Check if user settings allow Auto Reflect if (!enabled) return; + + // Check if player is using a flame thrower if (g_pLocalPlayer->weapon()->m_iClassID != CL_CLASS(CTFFlameThrower)) return; + // If user settings allow, return if local player is in attack if (idle_only && (g_pUserCmd->buttons & IN_ATTACK)) return; - CachedEntity* closest = 0; + // Create some book-keeping vars float closest_dist = 0.0f; + Vector closest_vec; + // Loop to find the closest entity for (int i = 0; i < HIGHEST_ENTITY; i++) { + + // Find an ent from the for loops current tick CachedEntity* ent = ENTITY(i); + + // Check if null or dormant if (CE_BAD(ent)) continue; + + // Check if ent should be reflected if (!ShouldReflect(ent)) continue; - //if (ent->Var(eoffsets.vVelocity).IsZero(1.0f)) continue; - float dist = ent->m_vecOrigin.DistToSqr(g_pLocalPlayer->v_Origin); - if (dist < closest_dist || !closest) { - closest = ent; + + // Grab latency + float latency = g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_INCOMING) + g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING); + // Create a vector variable to store our velocity + Vector velocity; + // Grab Velocity of projectile + velocity::EstimateAbsVelocity(RAW_ENT(ent), velocity); + // Predict a vector for where the projectile will be + Vector predictedProj = ent->m_vecOrigin + (velocity * latency);; + + // Dont vischeck if ent is stickybomb or if dodgeball mode is enabled + if (!IsEntStickyBomb(ent) && !dodgeball) { + // Vis check the predicted vector + if (!IsVectorVisible(g_pLocalPlayer->v_Origin, predictedProj)) continue; + } /*else { + // Stickys are weird, we use a different way to vis check them + // Vis checking stickys are wonky, I quit, just ignore the check >_> + //if (!VisCheckEntFromEnt(ent, LOCAL_E)) continue; + }*/ + + // Calculate distance + float dist = predictedProj.DistToSqr(g_pLocalPlayer->v_Origin); + + // If legit mode is on, we check to see if reflecting will work if we dont aim at the projectile + if (legit) { + if ( GetFov(g_pLocalPlayer->v_OrigViewangles, g_pLocalPlayer->v_Eye, predictedProj) > 85.0f ) continue; + } + + // Compare our info to the others and determine if its the best, if we dont have a projectile already, then we save it here + if (dist < closest_dist || closest_dist == 0.0f) { closest_dist = dist; + closest_vec = predictedProj; } } - if (CE_BAD(closest)) return; - if (closest_dist == 0 || closest_dist > SQR((int)max_distance)) return; - Vector tr = (closest->m_vecOrigin - g_pLocalPlayer->v_Eye); - Vector angles; - VectorAngles(tr, angles); - fClampAngle(angles); - g_pUserCmd->viewangles = angles; - g_pLocalPlayer->bUseSilentAngles = true; + // Determine whether the closest projectile is whithin our parameters, preferably 185 units should be our limit, sqr is around the number below + if (closest_dist == 0 || closest_dist > 34650) return; + + // We dont want to aim if legit is true + if (!legit) { + // Aim at predicted projectile + AimAt(g_pLocalPlayer->v_Eye, closest_vec, g_pUserCmd); + // Use silent angles + g_pLocalPlayer->bUseSilentAngles = true; + } + + // Airblast g_pUserCmd->buttons |= IN_ATTACK2; + + // Function is finished, return return; } +// Function to determine whether an ent is good to reflect bool ShouldReflect(CachedEntity* ent) { - if (CE_BAD(ent)) return false; + // Check if the entity is a projectile if (ent->m_Type != ENTITY_PROJECTILE) return false; - if (CE_INT(ent, netvar.iTeamNum) == g_pLocalPlayer->team) return false; - // If projectile is already deflected, don't deflect it again. - if (CE_INT(ent, (ent->m_bGrenadeProjectile ? - /* NetVar for grenades */ netvar.Grenade_iDeflected : - /* For rockets */ netvar.Rocket_iDeflected))) return false; + logging::Info("Is projectile"); + + // We dont want to do these checks in dodgeball, it breakes if we do + if (!dodgeball) { + // Check if the projectile is your own teams + if (!ent->m_bEnemy) return false; + logging::Info("isnt team"); + + // If projectile is already deflected, don't deflect it again. + if (CE_INT(ent, (ent->m_bGrenadeProjectile ? + /* NetVar for grenades */ netvar.Grenade_iDeflected : + /* For rockets */ netvar.Rocket_iDeflected))) return false; + logging::Info("pass already reflect"); + } + + // Check if the projectile is a sticky bomb and if the user settings allow it to be reflected + if (IsEntStickyBomb(ent) && !stickies) return false; + + // Target passed the test, return true + return true; +} + +bool IsEntStickyBomb(CachedEntity* ent) { + // Check if the projectile is a sticky bomb if (ent->m_iClassID == CL_CLASS(CTFGrenadePipebombProjectile)) { if (CE_INT(ent, netvar.iPipeType) == 1) { - if (!stickies) return false; + // Ent passed and should be reflected + return true; } } - return true; + // Ent didnt pass the test so return false + return false; } }}} diff --git a/src/hacks/AutoReflect.h b/src/hacks/AutoReflect.h index baa767f2..71111bc5 100644 --- a/src/hacks/AutoReflect.h +++ b/src/hacks/AutoReflect.h @@ -19,6 +19,7 @@ extern CatVar max_distance; void CreateMove(); bool ShouldReflect(CachedEntity* ent); +bool IsEntStickyBomb(CachedEntity* ent); }}} diff --git a/src/helpers.cpp b/src/helpers.cpp index abce74ce..8fc35a67 100644 --- a/src/helpers.cpp +++ b/src/helpers.cpp @@ -316,6 +316,7 @@ bool IsEntityVectorVisible(CachedEntity* entity, Vector endpos) { return (trace_object.fraction >= 0.99f || (((IClientEntity*)trace_object.m_pEnt)) == RAW_ENT(entity)); } +// For when you need to vis check something that isnt the local player bool VisCheckEntFromEnt(CachedEntity* startEnt, CachedEntity* endEnt) { // We setSelf as the starting ent as we dont want to hit it, we want the other ent trace_t trace; @@ -336,6 +337,27 @@ bool VisCheckEntFromEnt(CachedEntity* startEnt, CachedEntity* endEnt) { return false; } +// Use when you need to vis check something but its not the ent origin that you use, so we check from the vector to the ent, ignoring the first just in case +bool VisCheckEntFromEntVector(Vector startVector, CachedEntity* startEnt, CachedEntity* endEnt) { + // We setSelf as the starting ent as we dont want to hit it, we want the other ent + trace_t trace; + trace::filter_default.SetSelf(RAW_ENT(startEnt)); + + // Setup the trace starting with the origin of the starting ent attemting to hit the origin of the end ent + Ray_t ray; + ray.Init(startVector, endEnt->m_vecOrigin); + { + PROF_SECTION(IEVV_TraceRay); + g_ITrace->TraceRay(ray, MASK_SHOT_HULL, &trace::filter_default, &trace); + } + // Is the entity that we hit our target ent? if so, the vis check passes + if (trace.m_pEnt) { + if ((((IClientEntity*)trace.m_pEnt)) == RAW_ENT(endEnt)) return true; + } + // Since we didnt hit our target ent, the vis check failed so return false + return false; +} + Vector GetBuildingPosition(CachedEntity* ent) { Vector res; res = ent->m_vecOrigin; @@ -688,98 +710,6 @@ bool IsEntityVisiblePenetration(CachedEntity* entity, int hb) { return false; } - -class CMoveData; - -/*void RunEnginePrediction(IClientEntity* ent, CUserCmd *ucmd) { - // we are going to require some helper functions for this to work - // notably SetupMove, FinishMove and ProcessMovement - - - // setup the types of the functions - typedef void(*SetupMoveFn)(IClientEntity *, CUserCmd *, class IMoveHelper *, CMoveData *); - typedef void(*FinishMoveFn)(IClientEntity *, CUserCmd*, CMoveData*); - typedef void(*ProcessMovementFn)(IClientEntity *, CMoveData *); - typedef void(*StartTrackPredictionErrorsFn)(IClientEntity *); - typedef void(*FinishTrackPredictionErrorsFn)(IClientEntity *); - - // get the vtable - void **predictionVtable = *(void ***)prediction; - logging::Info("predictionVtable 0x%08x", predictionVtable); - // get the functions - SetupMoveFn oSetupMove = (SetupMoveFn) predictionVtable[19]; - FinishMoveFn oFinishMove = (FinishMoveFn) predictionVtable[20]; - - // get the vtable - void **gameMovementVtable = *(void ***)gamemovement; - logging::Info("gameMovementVtable 0x%08x", gameMovementVtable); - // get the functions - ProcessMovementFn oProcessMovement = (ProcessMovementFn) gameMovementVtable[2]; - StartTrackPredictionErrorsFn oStartTrackPredictionErrors = (StartTrackPredictionErrorsFn) gameMovementVtable[3]; - FinishTrackPredictionErrorsFn oFinishTrackPredictionErrors = (FinishTrackPredictionErrorsFn) gameMovementVtable[4]; - - // use this as movedata (should be big enough - otherwise the stack will die!) - unsigned char moveData[2048]; - CMoveData *pMoveData = (CMoveData *)&(moveData[0]); - logging::Info("pMoveData 0x%08x", pMoveData); - - // back up globals - float frameTime = gvars->frametime; - float curTime = gvars->curtime; - - CUserCmd defaultCmd; - if(ucmd == NULL) - { - ucmd = &defaultCmd; - } - - // set the current command - NET_VAR(ent, 0x105C, void*) = ucmd; - - // set up the globals - gvars->curtime = gvars->interval_per_tick * NET_INT(ent, netvar.nTickBase); - gvars->frametime = gvars->interval_per_tick; - - oStartTrackPredictionErrors(ent); - - logging::Info("StartTrackPredictionErrors(ent)"); - oSetupMove(ent, ucmd, NULL, pMoveData); - logging::Info("oSetupMove"); - oProcessMovement(ent, pMoveData); - logging::Info("oProcessMovement"); - oFinishMove(ent, ucmd, pMoveData); - logging::Info("oFinishMove"); - - oFinishTrackPredictionErrors(ent); - logging::Info("oFinishTrackPredictionErrors"); - // reset the current command - NET_VAR(ent, 0x105C, void *) = 0; - - // restore globals - gvars->frametime = frameTime; - gvars->curtime = curTime; - - return; -} - -float oldCurtime; -float oldFrametime; - -void StartPrediction(CUserCmd* cmd) { - oldCurtime = gvars->curtime; - oldFrametime = gvars->frametime; - gvars->curtime = NET_INT(g_pLocalPlayer->entity, netvar.nTickBase) * gvars->interval_per_tick; - gvars->frametime = gvars->interval_per_tick; - //gamemovement-> -} - -void EndPrediction() { - gvars->curtime = oldCurtime; - gvars->frametime = oldFrametime; -}*/ - - - void PrintChat(const char* fmt, ...) { CHudBaseChat* chat = (CHudBaseChat*)g_CHUD->FindElement("CHudChat"); if (chat) { diff --git a/src/helpers.h b/src/helpers.h index ae37735d..6f24827a 100644 --- a/src/helpers.h +++ b/src/helpers.h @@ -74,7 +74,8 @@ void VectorAngles(Vector &forward, Vector &angles); bool IsEntityVisible(CachedEntity* entity, int hb); bool IsEntityVectorVisible(CachedEntity* entity, Vector endpos); bool VisCheckEntFromEnt(CachedEntity* startEnt, CachedEntity* endEnt); - +bool VisCheckEntFromEntVector(Vector startVector, CachedEntity* startEnt, CachedEntity* endEnt); + bool LineIntersectsBox(Vector& bmin, Vector& bmax, Vector& lmin, Vector& lmax); float DistToSqr(CachedEntity* entity); diff --git a/tf-settings/menu.json b/tf-settings/menu.json index 66d62ef8..53aa4790 100644 --- a/tf-settings/menu.json +++ b/tf-settings/menu.json @@ -100,9 +100,8 @@ "name": "Auto Sticky", "list": [ "sticky_enabled", - "sticky_distance", "sticky_buildings", - "sticky_visable" + "sticky_legit" ] }, {