Alot of small fixes and improvements

Closes #535, #939, #894, #996, #1117 and a crash in backtrack.

Additionally some projectile weapons have also been fixed
This commit is contained in:
BenCat07 2020-10-09 20:22:07 +02:00 committed by LightCat
parent b9daa94a73
commit 24e166f610
15 changed files with 119 additions and 50 deletions

View File

@ -12,6 +12,7 @@
</Select> </Select>
</LabeledObject> </LabeledObject>
<AutoVariable width="fill" target="aimbot.silent" label="Silent" tooltip="Stops your crosshair from moving on your screen."/> <AutoVariable width="fill" target="aimbot.silent" label="Silent" tooltip="Stops your crosshair from moving on your screen."/>
<AutoVariable width="fill" target="aimbot.projectile-silent" label="pSilent" tooltip="Stops snapping of projectile weapons on the screen of others."/>
<AutoVariable width="fill" target="aimbot.slow" label="Slow aimbot" min="0" max="30"/> <AutoVariable width="fill" target="aimbot.slow" label="Slow aimbot" min="0" max="30"/>
<AutoVariable width="fill" target="aimbot.fov" label="FOV" tooltip="Restricts the aimbot to a certain FOV from the crosshair."/> <AutoVariable width="fill" target="aimbot.fov" label="FOV" tooltip="Restricts the aimbot to a certain FOV from the crosshair."/>
<AutoVariable width="fill" target="aimbot.fov-circle.enable" label="FOV circle" tooltip="Shows the Aimbot's FOV."/> <AutoVariable width="fill" target="aimbot.fov-circle.enable" label="FOV circle" tooltip="Shows the Aimbot's FOV."/>
@ -23,7 +24,7 @@
<AutoVariable width="fill" target="misc.auto-flip-viewmodel" label="Flip Viewmodel" tooltip="Automatically flip the viewmodel for projectile weapons."/> <AutoVariable width="fill" target="misc.auto-flip-viewmodel" label="Flip Viewmodel" tooltip="Automatically flip the viewmodel for projectile weapons."/>
</List> </List>
</Box> </Box>
<Box padding="12 6 6 6" width="content" height="content" name="Autoshoot" y="225"> <Box padding="12 6 6 6" width="content" height="content" name="Autoshoot" y="235">
<List width="150"> <List width="150">
<AutoVariable width="fill" target="aimbot.autoshoot" label="Enable autoshoot"/> <AutoVariable width="fill" target="aimbot.autoshoot" label="Enable autoshoot"/>
<AutoVariable width="fill" target="aimbot.wait-for-charge" label="Wait for charge" tooltip="Hold fire until a single shot is enough to kill the target."/> <AutoVariable width="fill" target="aimbot.wait-for-charge" label="Wait for charge" tooltip="Hold fire until a single shot is enough to kill the target."/>
@ -99,6 +100,7 @@
<List width="150"> <List width="150">
<AutoVariable width="fill" target="aimbot.projectile.enable" label="Enable projectile aimbot"/> <AutoVariable width="fill" target="aimbot.projectile.enable" label="Enable projectile aimbot"/>
<AutoVariable width="fill" target="aimbot.projectile.gravity" label="Gravity override"/> <AutoVariable width="fill" target="aimbot.projectile.gravity" label="Gravity override"/>
<AutoVariable width="fill" target="aimbot.projectile.initial-velocity" label="Initial Velocity"/>
<AutoVariable width="fill" target="aimbot.projectile.speed" label="Velocity override"/> <AutoVariable width="fill" target="aimbot.projectile.speed" label="Velocity override"/>
<AutoVariable width="fill" target="aimbot.projectile.huntsman-autoshoot" label="Bow threshold"/> <AutoVariable width="fill" target="aimbot.projectile.huntsman-autoshoot" label="Bow threshold"/>
<AutoVariable width="fill" target="aimbot.projectile.sticky-autoshoot" label="Sticky threshold"/> <AutoVariable width="fill" target="aimbot.projectile.sticky-autoshoot" label="Sticky threshold"/>

View File

@ -84,6 +84,7 @@
<AutoVariable width="fill" target="player-tools.ignore.online.friendly-software" label="Ignore friendly software"/> <AutoVariable width="fill" target="player-tools.ignore.online.friendly-software" label="Ignore friendly software"/>
<AutoVariable width="fill" target="player-tools.ignore.online.only-verified-accounts" label="Only ignore verified accounts"/> <AutoVariable width="fill" target="player-tools.ignore.online.only-verified-accounts" label="Only ignore verified accounts"/>
<AutoVariable width="fill" target="player-tools.ignore.taunting" label="Ignore taunting players"/> <AutoVariable width="fill" target="player-tools.ignore.taunting" label="Ignore taunting players"/>
<AutoVariable width="fill" target="player-tools.auto-party" label="Automatically add party state"/>
<AutoVariable width="fill" target="killstreak.enable" label="Enable killstreak"/> <AutoVariable width="fill" target="killstreak.enable" label="Enable killstreak"/>
<AutoVariable width="fill" target="misc.backpack-expander.enabled" label="Expand backpack"/> <AutoVariable width="fill" target="misc.backpack-expander.enabled" label="Expand backpack"/>
<AutoVariable width="fill" target="misc.backpack-expander.slot-count" label="Backpack slots" min="1" max="3000"/> <AutoVariable width="fill" target="misc.backpack-expander.slot-count" label="Backpack slots" min="1" max="3000"/>

View File

@ -8,6 +8,7 @@
<AutoVariable width="fill" target="autoheal.steamid" label="SteamID" tooltip="SteamID for the above."/> <AutoVariable width="fill" target="autoheal.steamid" label="SteamID" tooltip="SteamID for the above."/>
<AutoVariable width="fill" target="autoheal.uber.enable" label="Auto uber"/> <AutoVariable width="fill" target="autoheal.uber.enable" label="Auto uber"/>
<AutoVariable width="fill" target="autoheal.uber.share" label="Share uber"/> <AutoVariable width="fill" target="autoheal.uber.share" label="Share uber"/>
<AutoVariable width="fill" target="autoheal.disguised" label="Disguised spies"/>
<AutoVariable width="fill" target="autoheal.uber.health-below-ratio" label="Ratio trigger" min="0" max="100"/> <AutoVariable width="fill" target="autoheal.uber.health-below-ratio" label="Ratio trigger" min="0" max="100"/>
<AutoVariable width="fill" target="autoheal.popvoice" label="Pop on voicecommand"/> <AutoVariable width="fill" target="autoheal.popvoice" label="Pop on voicecommand"/>
<AutoVariable width="fill" target="autoheal.friends-only" label="Only heal friends"/> <AutoVariable width="fill" target="autoheal.friends-only" label="Only heal friends"/>

View File

@ -224,4 +224,8 @@ struct offsets
{ {
return PlatformOffset(18, undefined, undefined); return PlatformOffset(18, undefined, undefined);
} }
static constexpr uint32_t m_bUsingActionSlot()
{
return PlatformOffset(0x2fb8, undefined, undefined);
}
}; };

View File

@ -113,7 +113,7 @@ bool LineIntersectsBox(Vector &bmin, Vector &bmax, Vector &lmin, Vector &lmax);
float DistToSqr(CachedEntity *entity); float DistToSqr(CachedEntity *entity);
void fClampAngle(Vector &qaAng); void fClampAngle(Vector &qaAng);
// const char* MakeInfoString(IClientEntity* player); // const char* MakeInfoString(IClientEntity* player);
bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity); bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity, float &start_velocity);
bool IsVectorVisible(Vector a, Vector b, bool enviroment_only = false, CachedEntity *self = LOCAL_E, unsigned int mask = MASK_SHOT_HULL); bool IsVectorVisible(Vector a, Vector b, bool enviroment_only = false, CachedEntity *self = LOCAL_E, unsigned int mask = MASK_SHOT_HULL);
// A Special function for navparser to check if a Vector is visible. // A Special function for navparser to check if a Vector is visible.
bool IsVectorVisibleNavigation(Vector a, Vector b, unsigned int mask = MASK_SHOT_HULL); bool IsVectorVisibleNavigation(Vector a, Vector b, unsigned int mask = MASK_SHOT_HULL);

View File

@ -18,9 +18,9 @@ Vector SimpleLatencyPrediction(CachedEntity *ent, int hb);
bool PerformProjectilePrediction(CachedEntity *target, int hitbox); bool PerformProjectilePrediction(CachedEntity *target, int hitbox);
Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity); Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity, float proj_startvelocity = 0.0f);
Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod); Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod, float proj_startvelocity = 0.0f);
Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */); Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */, float proj_startvelocity = 0.0f);
std::vector<Vector> Predict(Vector pos, float offset, Vector vel, Vector acceleration, std::pair<Vector, Vector> minmax, float time, int count, bool vischeck = true); std::vector<Vector> Predict(Vector pos, float offset, Vector vel, Vector acceleration, std::pair<Vector, Vector> minmax, float time, int count, bool vischeck = true);
float PlayerGravityMod(CachedEntity *player); float PlayerGravityMod(CachedEntity *player);

View File

@ -38,6 +38,7 @@ static settings::Float normal_fov{ "aimbot.fov", "0" };
static settings::Int priority_mode{ "aimbot.priority-mode", "0" }; static settings::Int priority_mode{ "aimbot.priority-mode", "0" };
static settings::Boolean wait_for_charge{ "aimbot.wait-for-charge", "0" }; static settings::Boolean wait_for_charge{ "aimbot.wait-for-charge", "0" };
static settings::Boolean proj_silent("aimbot.projectile-silent", "1");
static settings::Boolean silent{ "aimbot.silent", "1" }; static settings::Boolean silent{ "aimbot.silent", "1" };
static settings::Boolean target_lock{ "aimbot.lock-target", "0" }; static settings::Boolean target_lock{ "aimbot.lock-target", "0" };
#if ENABLE_VISUALS #if ENABLE_VISUALS
@ -54,6 +55,7 @@ static settings::Int miss_chance{ "aimbot.miss-chance", "0" };
static settings::Boolean projectile_aimbot{ "aimbot.projectile.enable", "true" }; static settings::Boolean projectile_aimbot{ "aimbot.projectile.enable", "true" };
static settings::Float proj_gravity{ "aimbot.projectile.gravity", "0" }; static settings::Float proj_gravity{ "aimbot.projectile.gravity", "0" };
static settings::Float proj_speed{ "aimbot.projectile.speed", "0" }; static settings::Float proj_speed{ "aimbot.projectile.speed", "0" };
static settings::Float proj_start_vel{ "aimbot.projectile.initial-velocity", "0" };
static settings::Float sticky_autoshoot{ "aimbot.projectile.sticky-autoshoot", "0.5" }; static settings::Float sticky_autoshoot{ "aimbot.projectile.sticky-autoshoot", "0.5" };
@ -153,6 +155,7 @@ settings::Boolean ignore_cloak{ "aimbot.target.ignore-cloaked-spies", "1" };
bool projectile_mode{ false }; bool projectile_mode{ false };
float cur_proj_speed{ 0.0f }; float cur_proj_speed{ 0.0f };
float cur_proj_grav{ 0.0f }; float cur_proj_grav{ 0.0f };
float cur_proj_start_vel{ 0.0f };
bool shouldBacktrack() bool shouldBacktrack()
{ {
@ -266,13 +269,15 @@ static void CreateMove()
// Refresh projectile info // Refresh projectile info
if (projectileAimbotRequired) if (projectileAimbotRequired)
{ {
projectile_mode = GetProjectileData(g_pLocalPlayer->weapon(), cur_proj_speed, cur_proj_grav); projectile_mode = GetProjectileData(g_pLocalPlayer->weapon(), cur_proj_speed, cur_proj_grav, cur_proj_start_vel);
if (!projectile_mode) if (!projectile_mode)
return; return;
if (proj_speed) if (proj_speed)
cur_proj_speed = float(proj_speed); cur_proj_speed = *proj_speed;
if (proj_gravity) if (proj_gravity)
cur_proj_grav = float(proj_gravity); cur_proj_grav = *proj_gravity;
if (proj_start_vel)
cur_proj_start_vel = *proj_start_vel;
} }
// Refresh our best target // Refresh our best target
CachedEntity *target_entity = RetrieveBestTarget(aimkey_status); CachedEntity *target_entity = RetrieveBestTarget(aimkey_status);
@ -340,14 +345,14 @@ static void CreateMove()
} }
else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFPipebombLauncher)) else if (LOCAL_W->m_iClassID() == CL_CLASS(CTFPipebombLauncher))
{ {
float chargebegin = *((float *) ((uintptr_t) RAW_ENT(LOCAL_W) + 3152)); float chargebegin = CE_FLOAT(LOCAL_W, netvar.flChargeBeginTime);
float chargetime = g_GlobalVars->curtime - chargebegin; float chargetime = g_GlobalVars->curtime - chargebegin;
DoAutoshoot(); DoAutoshoot();
static bool currently_charging_pipe = false; static bool currently_charging_pipe = false;
// Grenade started charging // Grenade started charging
if (chargetime < 6.0f && chargetime) if (chargetime < 6.0f && chargetime && chargebegin)
currently_charging_pipe = true; currently_charging_pipe = true;
// Grenade was released // Grenade was released
@ -968,8 +973,11 @@ void DoAutoshoot(CachedEntity *target_entity)
current_user_cmd->buttons &= ~IN_ATTACK; current_user_cmd->buttons &= ~IN_ATTACK;
hacks::shared::antiaim::SetSafeSpace(5); hacks::shared::antiaim::SetSafeSpace(5);
begancharge = false; begancharge = false;
// Pull string if charge isnt enough // Projectile silent logic
if (proj_silent)
*bSendPackets = false;
} }
// Pull string if charge isnt enough
else else
{ {
current_user_cmd->buttons |= IN_ATTACK; current_user_cmd->buttons |= IN_ATTACK;
@ -981,16 +989,19 @@ void DoAutoshoot(CachedEntity *target_entity)
begancharge = false; begancharge = false;
if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFPipebombLauncher)) if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFPipebombLauncher))
{ {
float chargebegin = *((float *) ((unsigned) RAW_ENT(LOCAL_W) + 3152)); float chargebegin = CE_FLOAT(LOCAL_W, netvar.flChargeBeginTime);
float chargetime = g_GlobalVars->curtime - chargebegin; float chargetime = g_GlobalVars->curtime - chargebegin;
// Release Sticky if > chargetime, 3.85 is the max second chargetime, // Release Sticky if > chargetime, 3.85 is the max second chargetime,
// but we want a percent so here we go // but we also need to consider the release time supplied by the user
if ((chargetime >= 3.85f * *sticky_autoshoot) && begansticky > 3) if ((chargetime >= 3.85f * *sticky_autoshoot) && begansticky > 3)
{ {
current_user_cmd->buttons &= ~IN_ATTACK; current_user_cmd->buttons &= ~IN_ATTACK;
hacks::shared::antiaim::SetSafeSpace(5); hacks::shared::antiaim::SetSafeSpace(5);
begansticky = 0; begansticky = 0;
// Projectile silent logic
if (proj_silent)
*bSendPackets = false;
} }
// Else just keep charging // Else just keep charging
else else
@ -1047,7 +1058,11 @@ void DoAutoshoot(CachedEntity *target_entity)
auto hitbox = calculated_data_array[target_entity->m_IDX].hitbox; auto hitbox = calculated_data_array[target_entity->m_IDX].hitbox;
hitrate::AimbotShot(target_entity->m_IDX, hitbox != head); hitrate::AimbotShot(target_entity->m_IDX, hitbox != head);
} }
*bSendPackets = true; // Projectile silent logic
if (projectileAimbotRequired && proj_silent)
*bSendPackets = false;
else
*bSendPackets = true;
} }
if (LOCAL_W->m_iClassID() == CL_CLASS(CTFLaserPointer)) if (LOCAL_W->m_iClassID() == CL_CLASS(CTFLaserPointer))
current_user_cmd->buttons |= IN_ATTACK2; current_user_cmd->buttons |= IN_ATTACK2;
@ -1072,9 +1087,9 @@ const Vector &PredictEntity(CachedEntity *entity)
{ {
// Use prediction engine if user settings allow // Use prediction engine if user settings allow
if (engine_projpred) if (engine_projpred)
result = ProjectilePrediction_Engine(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, 0); result = ProjectilePrediction_Engine(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, 0, cur_proj_start_vel);
else else
result = ProjectilePrediction(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, PlayerGravityMod(entity)); result = ProjectilePrediction(entity, cd.hitbox, cur_proj_speed, cur_proj_grav, PlayerGravityMod(entity), cur_proj_start_vel);
} }
else else
{ {
@ -1090,7 +1105,7 @@ const Vector &PredictEntity(CachedEntity *entity)
else if (entity->m_Type() == ENTITY_BUILDING || entity->m_iClassID() != CL_CLASS(CTFTankBoss)) else if (entity->m_Type() == ENTITY_BUILDING || entity->m_iClassID() != CL_CLASS(CTFTankBoss))
{ {
if (cur_proj_grav || cur_proj_grav) if (cur_proj_grav || cur_proj_grav)
result = BuildingPrediction(entity, GetBuildingPosition(entity), cur_proj_speed, cur_proj_grav); result = BuildingPrediction(entity, GetBuildingPosition(entity), cur_proj_speed, cur_proj_grav, cur_proj_start_vel);
else else
result = GetBuildingPosition(entity); result = GetBuildingPosition(entity);
// Other // Other
@ -1160,12 +1175,12 @@ int BestHitbox(CachedEntity *target)
// Rocket launcher // Rocket launcher
} }
// These weapons should aim at the foot if the target is grounded // These weapons should aim at the foot if the target is grounded
else if (ci == CL_CLASS(CTFRocketLauncher) || ci == CL_CLASS(CTFRocketLauncher_AirStrike) || ci == CL_CLASS(CTFRocketLauncher_Mortar)) else if (ci == CL_CLASS(CTFPipebombLauncher) || ci == CL_CLASS(CTFRocketLauncher) || ci == CL_CLASS(CTFParticleCannon) || ci == CL_CLASS(CTFRocketLauncher_AirStrike) || ci == CL_CLASS(CTFRocketLauncher_Mortar))
{ {
preferred = hitbox_t::foot_L; preferred = hitbox_t::foot_L;
} }
// These weapons should aim at the center of mass due to little/no splash // These weapons should aim at the center of mass due to little/no splash
else if (ci == CL_CLASS(CTFPipebombLauncher) || ci == CL_CLASS(CTFRocketLauncher_DirectHit) || ci == CL_CLASS(CTFGrenadeLauncher)) else if (ci == CL_CLASS(CTFRocketLauncher_DirectHit) || ci == CL_CLASS(CTFGrenadeLauncher))
{ {
preferred = hitbox_t::spine_3; preferred = hitbox_t::spine_3;
} }

View File

@ -276,7 +276,7 @@ static bool doBacktrackStab(bool legit = false)
{ {
CachedEntity *ent = ENTITY(i); CachedEntity *ent = ENTITY(i);
// Targeting checks // Targeting checks
if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy() || !player_tools::shouldTarget(ent)|| IsPlayerInvulnerable(ent)) if (CE_BAD(ent) || !ent->m_bAlivePlayer() || !ent->m_bEnemy() || !player_tools::shouldTarget(ent) || IsPlayerInvulnerable(ent))
continue; continue;
// Get the best tick for that ent // Get the best tick for that ent
@ -304,11 +304,18 @@ static bool doBacktrackStab(bool legit = false)
return false; return false;
} }
inline bool HasKnife()
{
if (re::C_TFWeaponBase::GetWeaponID(RAW_ENT(LOCAL_W)) == 7)
return true;
return false;
}
void CreateMove() void CreateMove()
{ {
if (!enabled) if (!enabled)
return; return;
if (CE_BAD(LOCAL_E) || g_pLocalPlayer->life_state || g_pLocalPlayer->clazz != tf_spy || CE_BAD(LOCAL_W) || GetWeaponMode() != weapon_melee || IsPlayerInvisible(LOCAL_E) || CE_BYTE(LOCAL_E, netvar.m_bFeignDeathReady)) if (CE_BAD(LOCAL_E) || g_pLocalPlayer->life_state || CE_BAD(LOCAL_W) || !HasKnife() || IsPlayerInvisible(LOCAL_E) || CE_BYTE(LOCAL_E, netvar.m_bFeignDeathReady))
return; return;
if (!CanShoot()) if (!CanShoot())
return; return;

View File

@ -23,6 +23,7 @@ static settings::Boolean pop_uber_auto{ "autoheal.uber.enable", "true" };
static settings::Boolean pop_uber_voice{ "autoheal.popvoice", "true" }; static settings::Boolean pop_uber_voice{ "autoheal.popvoice", "true" };
static settings::Float pop_uber_percent{ "autoheal.uber.health-below-ratio", "0" }; static settings::Float pop_uber_percent{ "autoheal.uber.health-below-ratio", "0" };
static settings::Boolean share_uber{ "autoheal.uber.share", "false" }; static settings::Boolean share_uber{ "autoheal.uber.share", "false" };
static settings::Boolean heal_disguised{ "autoheal.disguised", "false" };
static settings::Boolean auto_vacc{ "autoheal.vacc.enable", "false" }; static settings::Boolean auto_vacc{ "autoheal.vacc.enable", "false" };
@ -493,6 +494,8 @@ bool CanHeal(int idx)
return false; return false;
if (friendsonly && !playerlist::IsFriend(ent)) if (friendsonly && !playerlist::IsFriend(ent))
return false; return false;
if (!heal_disguised && IsPlayerDisguised(ent))
return false;
return true; return true;
} }

View File

@ -21,7 +21,7 @@ static int lastincomingsequence{ 0 };
static float latency_rampup = 0.0f; static float latency_rampup = 0.0f;
// Which data to apply in the late CreateMove // Which data to apply in the late CreateMove
static CachedEntity *bt_ent; static CachedEntity *bt_ent = nullptr;
static std::optional<BacktrackData> bt_data; static std::optional<BacktrackData> bt_data;
static bool isEnabled(); static bool isEnabled();
@ -51,7 +51,7 @@ void ApplyBacktrack()
{ {
if (!isBacktrackEnabled) if (!isBacktrackEnabled)
return; return;
if (bt_ent) if (bt_ent && bt_data)
{ {
current_user_cmd->tick_count = (*bt_data).tickcount; current_user_cmd->tick_count = (*bt_data).tickcount;
CE_FLOAT(bt_ent, netvar.m_angEyeAngles) = (*bt_data).m_vecAngles.x; CE_FLOAT(bt_ent, netvar.m_angEyeAngles) = (*bt_data).m_vecAngles.x;

View File

@ -36,8 +36,8 @@ static settings::Boolean nopush_enabled{ "misc.no-push", "false" };
static settings::Boolean dont_hide_stealth_kills{ "misc.dont-hide-stealth-kills", "true" }; static settings::Boolean dont_hide_stealth_kills{ "misc.dont-hide-stealth-kills", "true" };
static settings::Boolean unlimit_bumpercart_movement{ "misc.bumpercarthax.enable", "true" }; static settings::Boolean unlimit_bumpercart_movement{ "misc.bumpercarthax.enable", "true" };
static settings::Boolean ping_reducer{ "misc.ping-reducer.enable", "false" }; static settings::Boolean ping_reducer{ "misc.ping-reducer.enable", "false" };
static settings::Int force_ping{ "misc.ping-reducer.target", "0" }; static settings::Int force_ping{ "misc.ping-reducer.target", "0" };
static settings::Boolean force_wait{ "misc.force-enable-wait", "true" };
#if ENABLE_VISUALS #if ENABLE_VISUALS
static settings::Boolean god_mode{ "misc.god-mode", "false" }; static settings::Boolean god_mode{ "misc.god-mode", "false" };
@ -908,8 +908,37 @@ void cyoaview_nethook(const CRecvProxyData *data, void *pPlayer, void *out)
*value_out = false; *value_out = false;
} }
// This function does two things.
// 1. It patches the check that's supposed to update the "isWaitCommandEnabled" on the cvar buffer to always skip
// 2. It sets the wait command to enabled
// The Former is the main logic, the latter is so you don't accidentally perma disable it either
inline void force_wait_func(bool after)
{
static auto enable_wait_signature = gSignatures.GetEngineSignature("74 ? A2 ? ? ? ? C7 44 24 ? 01 00 00 00");
// Jump if not overflow, aka always jump in this case
static BytePatch patch_wait(enable_wait_signature, { 0x71 });
if (after)
{
// Enable the wait command
int **enable_wait = (int **) (enable_wait_signature + 3);
**enable_wait = true;
patch_wait.Patch();
}
else
patch_wait.Shutdown();
}
void callback_force_wait(settings::VariableBase<bool> &, bool after)
{
force_wait_func(after);
}
static InitRoutine init([]() { static InitRoutine init([]() {
HookNetvar({ "DT_TFPlayer", "m_bViewingCYOAPDA" }, cyoa_anim_hook, cyoaview_nethook); HookNetvar({ "DT_TFPlayer", "m_bViewingCYOAPDA" }, cyoa_anim_hook, cyoaview_nethook);
force_wait.installChangeCallback(callback_force_wait);
force_wait_func(true);
teammatesPushaway = g_ICvar->FindVar("tf_avoidteammates_pushaway"); teammatesPushaway = g_ICvar->FindVar("tf_avoidteammates_pushaway");
EC::Register(EC::Shutdown, Shutdown, "draw_local_player", EC::average); EC::Register(EC::Shutdown, Shutdown, "draw_local_player", EC::average);
EC::Register(EC::CreateMove, CreateMove, "cm_misc_hacks", EC::average); EC::Register(EC::CreateMove, CreateMove, "cm_misc_hacks", EC::average);
@ -944,6 +973,7 @@ static InitRoutine init([]() {
stealth_kill.Shutdown(); stealth_kill.Shutdown();
cyoa_patch.Shutdown(); cyoa_patch.Shutdown();
tryPatchLocalPlayerShouldDraw(false); tryPatchLocalPlayerShouldDraw(false);
force_wait_func(false);
}, },
"shutdown_stealthkill"); "shutdown_stealthkill");
dont_hide_stealth_kills.installChangeCallback([](settings::VariableBase<bool> &, bool after) { dont_hide_stealth_kills.installChangeCallback([](settings::VariableBase<bool> &, bool after) {

View File

@ -18,9 +18,10 @@ static settings::Boolean sandwichaim_enabled{ "sandwichaim.enable", "false" };
static settings::Button sandwichaim_aimkey{ "sandwichaim.aimkey", "<null>" }; static settings::Button sandwichaim_aimkey{ "sandwichaim.aimkey", "<null>" };
static settings::Int sandwichaim_aimkey_mode{ "sandwichaim.aimkey-mode", "0" }; static settings::Int sandwichaim_aimkey_mode{ "sandwichaim.aimkey-mode", "0" };
float sandwich_speed = 350.0f; constexpr float sandwich_speed = 350.0f;
float grav = 0.25f; constexpr float grav = 0.25f;
int prevent = -1; constexpr float initial_vel = 200.0f;
int prevent = -1;
static Timer previous_entity_delay{}; static Timer previous_entity_delay{};
// TODO: Refactor this jank // TODO: Refactor this jank
@ -47,7 +48,7 @@ std::pair<CachedEntity *, Vector> FindBestEnt(bool teammate, bool Predict, bool
continue; continue;
Vector target{}; Vector target{};
if (Predict) if (Predict)
target = ProjectilePrediction(ent, 1, sandwich_speed, grav, PlayerGravityMod(ent)); target = ProjectilePrediction(ent, 1, sandwich_speed, grav, PlayerGravityMod(ent), initial_vel);
else else
target = ent->hitboxes.GetHitbox(1)->center; target = ent->hitboxes.GetHitbox(1)->center;
if (!hacks::tf2::backtrack::isBacktrackEnabled && !IsEntityVectorVisible(ent, target)) if (!hacks::tf2::backtrack::isBacktrackEnabled && !IsEntityVectorVisible(ent, target))

View File

@ -1229,16 +1229,17 @@ bool LineIntersectsBox(Vector &bmin, Vector &bmax, Vector &lmin, Vector &lmax)
return true; return true;
} }
bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity) bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity, float &start_velocity)
{ {
float rspeed, rgrav; float rspeed, rgrav, rinitial_vel;
IF_GAME(!IsTF()) return false; IF_GAME(!IsTF()) return false;
if (CE_BAD(weapon)) if (CE_BAD(weapon))
return false; return false;
rspeed = 0.0f; rspeed = 0.0f;
rgrav = 0.0f; rgrav = 0.0f;
rinitial_vel = 0.0f;
typedef float(GetProjectileData)(IClientEntity *); typedef float(GetProjectileData)(IClientEntity *);
switch (weapon->m_iClassID()) switch (weapon->m_iClassID())
@ -1265,25 +1266,24 @@ bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity)
} }
case CL_CLASS(CTFGrenadeLauncher): case CL_CLASS(CTFGrenadeLauncher):
{ {
rspeed = 1200.0f; rspeed = 1200.0f;
rgrav = 0.4f; rgrav = 1.0f;
rinitial_vel = 200.0f;
IF_GAME(IsTF2()) IF_GAME(IsTF2())
{ {
// Loch'n Load // Loch'n Load
if (CE_INT(weapon, netvar.iItemDefinitionIndex) == 308) if (CE_INT(weapon, netvar.iItemDefinitionIndex) == 308)
rspeed *= 1.25f; rspeed *= 1.25f;
} }
IF_GAME(IsTF2C())
{
rgrav = 0.5f;
}
break; break;
} }
case CL_CLASS(CTFPipebombLauncher): case CL_CLASS(CTFPipebombLauncher):
{ {
float chargetime = g_GlobalVars->curtime - CE_FLOAT(weapon, netvar.flChargeBeginTime); float chargetime = g_GlobalVars->curtime - CE_FLOAT(weapon, netvar.flChargeBeginTime);
rspeed = RemapValClamped(chargetime, 0.0f, 4.0f, 900, 2400); if (!CE_FLOAT(weapon, netvar.flChargeBeginTime))
rgrav = 0.4f; chargetime = 0.0f;
rspeed = RemapValClamped(chargetime, 0.0f, 4.0f, 900, 2400);
rgrav = 0.4f;
break; break;
} }
case CL_CLASS(CTFCompoundBow): case CL_CLASS(CTFCompoundBow):
@ -1346,9 +1346,10 @@ bool GetProjectileData(CachedEntity *weapon, float &speed, float &gravity)
} }
} }
speed = rspeed; speed = rspeed;
gravity = rgrav; gravity = rgrav;
return (rspeed || rgrav); start_velocity = rinitial_vel;
return (rspeed || rgrav || rinitial_vel);
} }
constexpr unsigned developer_list[] = { 306902159 }; constexpr unsigned developer_list[] = { 306902159 };

View File

@ -228,7 +228,7 @@ Vector EnginePrediction(CachedEntity *entity, float time)
return result; return result;
} }
Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */) Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod /* ignored */, float proj_startvelocity)
{ {
Vector origin = ent->m_vecOrigin(); Vector origin = ent->m_vecOrigin();
Vector hitbox; Vector hitbox;
@ -238,6 +238,8 @@ Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float
if (speed == 0.0f) if (speed == 0.0f)
return Vector(); return Vector();
static ConVar *sv_gravity = g_ICvar->FindVar("sv_gravity");
// TODO ProjAim // TODO ProjAim
float medianTime = g_pLocalPlayer->v_Eye.DistTo(hitbox) / speed; float medianTime = g_pLocalPlayer->v_Eye.DistTo(hitbox) / speed;
float range = 1.5f; float range = 1.5f;
@ -283,14 +285,14 @@ Vector ProjectilePrediction_Engine(CachedEntity *ent, int hb, float speed, float
CE_VECTOR(ent, 0x354) = origin; CE_VECTOR(ent, 0x354) = origin;
// Compensate for ping // Compensate for ping
besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat(); besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat();
bestpos.z += (400 * besttime * besttime * gravitymod); bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravitymod - proj_startvelocity * besttime);
// S = at^2/2 ; t = sqrt(2S/a)*/ // S = at^2/2 ; t = sqrt(2S/a)*/
Vector result = bestpos + hitbox_offset; Vector result = bestpos + hitbox_offset;
/*logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x, /*logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x,
result.y - origin.y, result.z - origin.z);*/ result.y - origin.y, result.z - origin.z);*/
return result; return result;
} }
Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity) Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float gravity, float proj_startvelocity)
{ {
if (!vec.z || CE_BAD(building)) if (!vec.z || CE_BAD(building))
return Vector(); return Vector();
@ -303,6 +305,7 @@ Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float
if (speed == 0.0f) if (speed == 0.0f)
return Vector(); return Vector();
static ConVar *sv_gravity = g_ICvar->FindVar("sv_gravity");
trace::filter_no_player.SetSelf(RAW_ENT(building)); trace::filter_no_player.SetSelf(RAW_ENT(building));
float dtg = DistanceToGround(vec, RAW_ENT(building)->GetCollideable()->OBBMins(), RAW_ENT(building)->GetCollideable()->OBBMaxs()); float dtg = DistanceToGround(vec, RAW_ENT(building)->GetCollideable()->OBBMins(), RAW_ENT(building)->GetCollideable()->OBBMaxs());
// TODO ProjAim // TODO ProjAim
@ -335,12 +338,12 @@ Vector BuildingPrediction(CachedEntity *building, Vector vec, float speed, float
} }
// Compensate for ping // Compensate for ping
besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat(); besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat();
bestpos.z += (400 * besttime * besttime * gravity); bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravity - proj_startvelocity * besttime);
// S = at^2/2 ; t = sqrt(2S/a)*/ // S = at^2/2 ; t = sqrt(2S/a)*/
return bestpos; return bestpos;
} }
Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod) Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravitymod, float entgmod, float proj_startvelocity)
{ {
Vector origin = ent->m_vecOrigin(); Vector origin = ent->m_vecOrigin();
Vector hitbox; Vector hitbox;
@ -405,7 +408,7 @@ Vector ProjectilePrediction(CachedEntity *ent, int hb, float speed, float gravit
} }
// Compensate for ping // Compensate for ping
besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat(); besttime += g_IEngine->GetNetChannelInfo()->GetLatency(FLOW_OUTGOING) + cl_interp->GetFloat();
bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravitymod); bestpos.z += (sv_gravity->GetFloat() / 2.0f * besttime * besttime * gravitymod - proj_startvelocity * besttime);
// S = at^2/2 ; t = sqrt(2S/a)*/ // S = at^2/2 ; t = sqrt(2S/a)*/
Vector result = bestpos + hitbox_offset; Vector result = bestpos + hitbox_offset;
/*logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x, /*logging::Info("[Pred][%d] delta: %.2f %.2f %.2f", result.x - origin.x,

View File

@ -10,6 +10,7 @@
#include "hacks/AutoJoin.hpp" #include "hacks/AutoJoin.hpp"
#include "hack.hpp" #include "hack.hpp"
static settings::Boolean auto_party{ "player-tools.set-party-state", "true" };
settings::Int queue{ "autoqueue.mode", "7" }; settings::Int queue{ "autoqueue.mode", "7" };
CatCommand cmd_queue_start("mm_queue_casual", "Start casual queue", []() { tfmm::startQueue(); }); CatCommand cmd_queue_start("mm_queue_casual", "Start casual queue", []() { tfmm::startQueue(); });
@ -171,7 +172,7 @@ void abandon()
static Timer friend_party_t{}; static Timer friend_party_t{};
void friend_party() void friend_party()
{ {
if (friend_party_t.test_and_set(10000)) if (auto_party && friend_party_t.test_and_set(10000))
{ {
re::CTFPartyClient *pc = re::CTFPartyClient::GTFPartyClient(); re::CTFPartyClient *pc = re::CTFPartyClient::GTFPartyClient();
if (pc) if (pc)