FollowBot things
This commit is contained in:
parent
84ebf0b9ad
commit
8872e0a317
@ -39,7 +39,7 @@
|
||||
</List>
|
||||
</Box>
|
||||
<Box name="Followbot" width="content" height="content" padding="12 6 6 6" x="210">
|
||||
<List width="200">
|
||||
<List width="170">
|
||||
<AutoVariable width="fill" target="follow-bot.enable" label="Enable FB"/>
|
||||
<AutoVariable width="fill" target="follow-bot.roaming" label="Roaming"/>
|
||||
<AutoVariable width="fill" target="follow-bot.change-roaming-target" label="Change when possible"/>
|
||||
@ -54,13 +54,27 @@
|
||||
<AutoVariable width="fill" target="follow-bot.corners" label="Corner activate"/>
|
||||
</List>
|
||||
</Box>
|
||||
<Box name="NavBot" width="content" height="content" padding="12 6 6 6" x="210" y="233">
|
||||
<List width="200">
|
||||
<Box name="NavBot" width="content" height="content" padding="12 6 6 6" x="390">
|
||||
<List width="170">
|
||||
<AutoVariable width="fill" target="misc.pathing" label="Enable Pathing"/>
|
||||
<AutoVariable width="fill" target="navbot.enable" label="Enable NavBot"/>
|
||||
<AutoVariable width="fill" target="misc.pathing.draw" label="Draw Path"/>
|
||||
<AutoVariable width="fill" target="navbot.enable" label="Enable NavBot (Not for Nav Followbot)"/>
|
||||
<AutoVariable width="fill" target="navbot.spy-mode" label="Enable Spy Mode"/>
|
||||
<AutoVariable width="fill" target="navbot.heavy-mode" label="Enable Heavy Mode"/>
|
||||
<AutoVariable width="fill" target="navbot.primary-only" label="Best Weapon only"/>
|
||||
</List>
|
||||
<Box name="Nav FollowBot" width="content" height="content" padding="12 6 6 6" y="90">
|
||||
<List width="170">
|
||||
<AutoVariable width="fill" target="navbot.medbot" label="Enable Nav Followbot"/>
|
||||
<AutoVariable width="fill" target="navbot.roaming" label="Roaming"/>
|
||||
<AutoVariable width="fill" target="navbot.max-range" label="Max range" min="0" max="100000"/>
|
||||
<AutoVariable width="fill" target="navbot.mimic-slot" label="Mimic slot"/>
|
||||
<AutoVariable width="fill" target="navbot.always-medigun" label="Always Medigun"/>
|
||||
<AutoVariable width="fill" target="navbot.taunt-sync" label="Taunt sync"/>
|
||||
<AutoVariable width="fill" target="navbot.change-roaming-target" label="Change Roaming Target"/>
|
||||
<AutoVariable width="fill" target="navbot.switch-afk" label="Switch target if target AFK"/>
|
||||
<AutoVariable width="fill" target="navbot.afk-time" label="Max AFK time"/>
|
||||
</List>
|
||||
</Box>
|
||||
</Box>
|
||||
</Tab>
|
||||
|
@ -8,5 +8,6 @@
|
||||
namespace hacks::tf2::NavBot
|
||||
{
|
||||
void Init();
|
||||
void initonce();
|
||||
void CreateMove();
|
||||
}
|
||||
} // namespace hacks::tf2::NavBot
|
@ -159,14 +159,15 @@ void CreateMove()
|
||||
// If zoomed only is on, check if zoomed
|
||||
if (zoomed_only && g_pLocalPlayer->holding_sniper_rifle)
|
||||
{
|
||||
if (!g_pLocalPlayer->bZoomed && !(current_user_cmd->buttons & IN_ATTACK))
|
||||
if (!g_pLocalPlayer->bZoomed &&
|
||||
!(current_user_cmd->buttons & IN_ATTACK))
|
||||
return;
|
||||
}
|
||||
// Minigun spun up handler
|
||||
if (g_pLocalPlayer->weapon()->m_iClassID() == CL_CLASS(CTFMinigun))
|
||||
{
|
||||
int weapon_state =
|
||||
CE_INT(g_pLocalPlayer->weapon(), netvar.iWeaponState);
|
||||
CE_INT(g_pLocalPlayer->weapon(), netvar.iWeaponState);
|
||||
// If user setting for autospin isnt true, then we check if minigun
|
||||
// is already zoomed
|
||||
if ((weapon_state == MinigunState_t::AC_STATE_IDLE ||
|
||||
|
@ -38,7 +38,8 @@ void CreateMove()
|
||||
return;
|
||||
|
||||
// Check if player is using a flame thrower
|
||||
if (g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFFlameThrower) && CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) != 528)
|
||||
if (g_pLocalPlayer->weapon()->m_iClassID() != CL_CLASS(CTFFlameThrower) &&
|
||||
CE_INT(LOCAL_W, netvar.iItemDefinitionIndex) != 528)
|
||||
return;
|
||||
|
||||
// Check for phlogistinator, which is item 594
|
||||
|
@ -259,16 +259,22 @@ bool ValidTick(BacktrackData &i, CachedEntity *ent)
|
||||
return true;
|
||||
if (istickinvalid[ent->m_IDX][i.index])
|
||||
return false;
|
||||
if (hacks::shared::aimbot::IsBacktracking()) {
|
||||
if (IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxes[head].center, true))
|
||||
if (fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) * 1000.0f -
|
||||
getLatency() - i.simtime * 1000.0f) <= 200.0f) {
|
||||
if (hacks::shared::aimbot::IsBacktracking())
|
||||
{
|
||||
if (IsVectorVisible(g_pLocalPlayer->v_Eye, i.hitboxes[head].center,
|
||||
true))
|
||||
if (fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) *
|
||||
1000.0f -
|
||||
getLatency() - i.simtime * 1000.0f) <= 200.0f)
|
||||
{
|
||||
istickvalid[ent->m_IDX][i.index] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) * 1000.0f -
|
||||
getLatency() - i.simtime * 1000.0f) <= 200.0f) {
|
||||
else if (fabsf(NET_FLOAT(RAW_ENT(ent), netvar.m_flSimulationTime) *
|
||||
1000.0f -
|
||||
getLatency() - i.simtime * 1000.0f) <= 200.0f)
|
||||
{
|
||||
istickvalid[ent->m_IDX][i.index] = true;
|
||||
return true;
|
||||
}
|
||||
|
@ -142,8 +142,8 @@ int ClassPriority(CachedEntity *ent)
|
||||
{
|
||||
switch (g_pPlayerResource->GetClass(ent))
|
||||
{
|
||||
if (g_pPlayerResource->GetClass(ent) == tf_spy)
|
||||
return 0;
|
||||
case tf_spy:
|
||||
return 0;
|
||||
case tf_engineer:
|
||||
return 1;
|
||||
case tf_medic:
|
||||
@ -223,11 +223,11 @@ void WorldTick()
|
||||
Vector indirectOrigin =
|
||||
VischeckCorner(LOCAL_E, entity, *follow_activation / 2,
|
||||
true); // get the corner location that the
|
||||
// future target is visible from
|
||||
// future target is visible from
|
||||
std::pair<Vector, Vector> corners;
|
||||
if (!indirectOrigin.z &&
|
||||
entity->m_IDX == lastent) // if we couldn't find it, run
|
||||
// wallcheck instead
|
||||
// wallcheck instead
|
||||
{
|
||||
corners = VischeckWall(LOCAL_E, entity,
|
||||
float(follow_activation) / 2, true);
|
||||
@ -314,13 +314,13 @@ void WorldTick()
|
||||
Vector indirectOrigin =
|
||||
VischeckCorner(LOCAL_E, entity, 250,
|
||||
true); // get the corner location that the
|
||||
// future target is visible from
|
||||
// future target is visible from
|
||||
std::pair<Vector, Vector> corners;
|
||||
corners.first.z = 0;
|
||||
corners.second.z = 0;
|
||||
if (!indirectOrigin.z &&
|
||||
entity->m_IDX == lastent) // if we couldn't find it, run
|
||||
// wallcheck instead
|
||||
// wallcheck instead
|
||||
{
|
||||
corners = VischeckWall(LOCAL_E, entity, 250, true);
|
||||
if (!corners.first.z || !corners.second.z)
|
||||
|
@ -2,7 +2,10 @@
|
||||
// Created by bencat07 on 17.08.18.
|
||||
//
|
||||
#include "common.hpp"
|
||||
#include <glez/draw.hpp>
|
||||
#include <glez/color.hpp>
|
||||
#include "navparser.hpp"
|
||||
#include "FollowBot.hpp"
|
||||
#include "NavBot.hpp"
|
||||
|
||||
namespace hacks::tf2::NavBot
|
||||
@ -12,6 +15,45 @@ static settings::Bool spy_mode("navbot.spy-mode", "false");
|
||||
static settings::Bool heavy_mode("navbot.heavy-mode", "false");
|
||||
static settings::Bool primary_only("navbot.primary-only", "true");
|
||||
|
||||
static settings::Bool enable_fb{ "navbot.medbot", "false" };
|
||||
static settings::Bool roambot{ "navbot.roaming", "true" };
|
||||
static settings::Float follow_activation{ "navbot.max-range", "1000" };
|
||||
static settings::Bool mimic_slot{ "navbot.mimic-slot", "false" };
|
||||
static settings::Bool always_medigun{ "navbot.always-medigun", "false" };
|
||||
static settings::Bool sync_taunt{ "navbot.taunt-sync", "false" };
|
||||
static settings::Bool change_tar{ "navbot.change-roaming-target", "false" };
|
||||
static settings::Bool autojump{ "navbot.jump-if-stuck", "true" };
|
||||
static settings::Bool afk{ "navbot.switch-afk", "true" };
|
||||
static settings::Int afktime{ "navbot.afk-time", "15000" };
|
||||
|
||||
unsigned steamid = 0x0;
|
||||
CatCommand follow_steam("navbot_steam", "Follow Steam Id",
|
||||
[](const CCommand &args) {
|
||||
if (args.ArgC() < 1)
|
||||
{
|
||||
steamid = 0x0;
|
||||
return;
|
||||
}
|
||||
steamid = atol(args.Arg(1));
|
||||
});
|
||||
Timer lastTaunt{}; // time since taunt was last executed, used to avoid kicks
|
||||
Timer lastJump{};
|
||||
std::array<Timer, 32> afkTicks; // for how many ms the player hasn't been moving
|
||||
|
||||
void checkAFK()
|
||||
{
|
||||
for (int i = 0; i < g_GlobalVars->maxClients; i++)
|
||||
{
|
||||
auto entity = ENTITY(i);
|
||||
if (CE_BAD(entity))
|
||||
continue;
|
||||
if (!CE_VECTOR(entity, netvar.vVelocity).IsZero(60.0f))
|
||||
{
|
||||
afkTicks[i].update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HasLowAmmo()
|
||||
{
|
||||
int *weapon_list =
|
||||
@ -115,6 +157,12 @@ void Init()
|
||||
hide.IsExposed())
|
||||
sniper_spots.push_back(hide.m_pos);
|
||||
}
|
||||
void initonce()
|
||||
{
|
||||
for (int i = 0; i < afkTicks.size(); i++)
|
||||
afkTicks[i].update();
|
||||
return;
|
||||
}
|
||||
|
||||
Timer slot_timer{};
|
||||
void UpdateSlot()
|
||||
@ -140,13 +188,14 @@ void UpdateSlot()
|
||||
Timer cdr{};
|
||||
Timer cd2{};
|
||||
Timer cd3{};
|
||||
int follow_target = 0;
|
||||
void CreateMove()
|
||||
{
|
||||
if (!enable || !nav::Prepare())
|
||||
if ((!enable && !enable_fb) || !nav::Prepare())
|
||||
return;
|
||||
if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer())
|
||||
return;
|
||||
if (primary_only)
|
||||
if (primary_only && enable)
|
||||
UpdateSlot();
|
||||
if (HasLowHealth() && cdr.test_and_set(5000))
|
||||
{
|
||||
@ -164,47 +213,287 @@ void CreateMove()
|
||||
nav::NavTo(ammo->m_vecOrigin(), true, true, 6);
|
||||
}
|
||||
}
|
||||
if (!nav::ReadyForCommands && !spy_mode && !heavy_mode)
|
||||
cd3.update();
|
||||
bool isready = (spy_mode || heavy_mode) ? 1 : nav::ReadyForCommands;
|
||||
int waittime = (spy_mode || heavy_mode) ? 100 : 5000;
|
||||
if (isready && cd3.test_and_set(waittime))
|
||||
if (enable)
|
||||
{
|
||||
if (!spy_mode && !heavy_mode)
|
||||
{
|
||||
if (!nav::ReadyForCommands && !spy_mode && !heavy_mode)
|
||||
cd3.update();
|
||||
Vector random_spot;
|
||||
if (sniper_spots.empty())
|
||||
{
|
||||
if (cd2.test_and_set(5000))
|
||||
Init();
|
||||
return;
|
||||
}
|
||||
int rng = rand() % sniper_spots.size();
|
||||
random_spot = sniper_spots.at(rng);
|
||||
if (random_spot.z)
|
||||
nav::NavTo(random_spot, true, true);
|
||||
}
|
||||
else if (cdr.check(5000))
|
||||
bool isready = (spy_mode || heavy_mode) ? 1 : nav::ReadyForCommands;
|
||||
int waittime = (spy_mode || heavy_mode) ? 100 : 5000;
|
||||
if (isready && cd3.test_and_set(waittime))
|
||||
{
|
||||
CachedEntity *tar = NearestEnemy();
|
||||
if (CE_BAD(tar))
|
||||
if (!spy_mode && !heavy_mode)
|
||||
{
|
||||
cd3.update();
|
||||
Vector random_spot;
|
||||
if (sniper_spots.empty())
|
||||
{
|
||||
if (cd2.test_and_set(5000))
|
||||
Init();
|
||||
if (cd2.test_and_set(20000))
|
||||
Init();
|
||||
if (!sniper_spots.size())
|
||||
return;
|
||||
}
|
||||
int rng = rand() % sniper_spots.size();
|
||||
random_spot = sniper_spots.at(rng);
|
||||
if (random_spot.z)
|
||||
nav::NavTo(random_spot, false);
|
||||
nav::NavTo(random_spot, true, true);
|
||||
}
|
||||
else if (cdr.check(5000))
|
||||
{
|
||||
CachedEntity *tar = NearestEnemy();
|
||||
if (CE_BAD(tar))
|
||||
{
|
||||
Vector random_spot;
|
||||
if (cd2.test_and_set(20000))
|
||||
Init();
|
||||
if (!sniper_spots.size())
|
||||
return;
|
||||
int rng = rand() % sniper_spots.size();
|
||||
random_spot = sniper_spots.at(rng);
|
||||
if (random_spot.z)
|
||||
nav::NavTo(random_spot, false);
|
||||
return;
|
||||
}
|
||||
nav::NavTo(tar->m_vecOrigin(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (enable_fb)
|
||||
{
|
||||
// We need a local player to control
|
||||
if (CE_BAD(LOCAL_E) || !LOCAL_E->m_bAlivePlayer())
|
||||
{
|
||||
follow_target = 0;
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
if (afk)
|
||||
checkAFK();
|
||||
|
||||
// Still good check
|
||||
if (follow_target)
|
||||
if (CE_BAD(ENTITY(follow_target)))
|
||||
follow_target = 0;
|
||||
|
||||
if (!follow_target)
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true,
|
||||
false); // no target == no path
|
||||
// Target Selection
|
||||
if (steamid)
|
||||
{
|
||||
// Find a target with the steam id, as it is prioritized
|
||||
auto ent_count = HIGHEST_ENTITY;
|
||||
for (int i = 0; i < ent_count; i++)
|
||||
{
|
||||
auto entity = ENTITY(i);
|
||||
if (CE_BAD(entity)) // Exist + dormant
|
||||
continue;
|
||||
if (i == follow_target)
|
||||
break;
|
||||
if (entity->m_Type() != ENTITY_PLAYER)
|
||||
continue;
|
||||
if (steamid != entity->player_info.friendsID) // steamid check
|
||||
continue;
|
||||
|
||||
if (!entity->m_bAlivePlayer()) // Dont follow dead players
|
||||
continue;
|
||||
follow_target = entity->m_IDX;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If we dont have a follow target from that, we look again for someone
|
||||
// else who is suitable
|
||||
if ((!follow_target || change_tar ||
|
||||
(hacks::shared::followbot::ClassPriority(ENTITY(follow_target)) <
|
||||
6 &&
|
||||
ENTITY(follow_target)->player_info.friendsID != steamid)) &&
|
||||
roambot)
|
||||
{
|
||||
// Try to get a new target
|
||||
auto ent_count = g_IEngine->GetMaxClients();
|
||||
for (int i = 0; i < ent_count; i++)
|
||||
{
|
||||
auto entity = ENTITY(i);
|
||||
if (CE_BAD(entity)) // Exist + dormant
|
||||
continue;
|
||||
if (entity->m_Type() != ENTITY_PLAYER)
|
||||
continue;
|
||||
if (entity == LOCAL_E) // Follow self lol
|
||||
continue;
|
||||
if (entity->m_bEnemy())
|
||||
continue;
|
||||
if (afk &&
|
||||
afkTicks[i].check(int(afktime))) // don't follow target that
|
||||
// was determined afk
|
||||
continue;
|
||||
if (IsPlayerDisguised(entity) || IsPlayerInvisible(entity))
|
||||
continue;
|
||||
if (!entity->m_bAlivePlayer()) // Dont follow dead players
|
||||
continue;
|
||||
if (follow_activation &&
|
||||
entity->m_flDistance() > (float) follow_activation)
|
||||
continue;
|
||||
const model_t *model =
|
||||
ENTITY(follow_target)->InternalEntity()->GetModel();
|
||||
// FIXME follow cart/point
|
||||
/*if (followcart && model &&
|
||||
(lagexploit::pointarr[0] || lagexploit::pointarr[1] ||
|
||||
lagexploit::pointarr[2] || lagexploit::pointarr[3] ||
|
||||
lagexploit::pointarr[4]) &&
|
||||
(model == lagexploit::pointarr[0] ||
|
||||
model == lagexploit::pointarr[1] ||
|
||||
model == lagexploit::pointarr[2] ||
|
||||
model == lagexploit::pointarr[3] ||
|
||||
model == lagexploit::pointarr[4]))
|
||||
follow_target = entity->m_IDX;*/
|
||||
if (entity->m_Type() != ENTITY_PLAYER)
|
||||
continue;
|
||||
// favor closer entitys
|
||||
if (follow_target &&
|
||||
ENTITY(follow_target)->m_flDistance() <
|
||||
entity->m_flDistance()) // favor closer entitys
|
||||
continue;
|
||||
// check if new target has a higher priority than current target
|
||||
if (hacks::shared::followbot::ClassPriority(
|
||||
ENTITY(follow_target)) >=
|
||||
hacks::shared::followbot::ClassPriority(ENTITY(i)))
|
||||
continue;
|
||||
// ooooo, a target
|
||||
follow_target = i;
|
||||
afkTicks[i].update(); // set afk time to 0
|
||||
}
|
||||
}
|
||||
// last check for entity before we continue
|
||||
if (!follow_target)
|
||||
{
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
CachedEntity *followtar = ENTITY(follow_target);
|
||||
// wtf is this needed
|
||||
if (CE_BAD(followtar) || !followtar->m_bAlivePlayer())
|
||||
{
|
||||
follow_target = 0;
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4);
|
||||
return;
|
||||
}
|
||||
// Check if we are following a disguised/spy
|
||||
if (IsPlayerDisguised(followtar) || IsPlayerInvisible(followtar))
|
||||
{
|
||||
follow_target = 0;
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4);
|
||||
return;
|
||||
}
|
||||
// check if target is afk
|
||||
if (afk)
|
||||
{
|
||||
if (afkTicks[follow_target].check(int(afktime)))
|
||||
{
|
||||
follow_target = 0;
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4);
|
||||
return;
|
||||
}
|
||||
nav::NavTo(tar->m_vecOrigin(), false);
|
||||
}
|
||||
|
||||
// Update timer on new target
|
||||
static Timer idle_time{};
|
||||
if (nav::ReadyForCommands)
|
||||
idle_time.update();
|
||||
|
||||
// If the player is close enough, we dont need to follow the path
|
||||
auto tar_orig = followtar->m_vecOrigin();
|
||||
auto loc_orig = LOCAL_E->m_vecOrigin();
|
||||
auto dist_to_target = loc_orig.DistTo(tar_orig);
|
||||
if (!CE_VECTOR(followtar, netvar.vVelocity).IsZero(20.0f))
|
||||
idle_time.update();
|
||||
|
||||
// Tauntsync
|
||||
if (sync_taunt && HasCondition<TFCond_Taunting>(followtar) &&
|
||||
lastTaunt.test_and_set(1000))
|
||||
g_IEngine->ClientCmd("taunt");
|
||||
|
||||
// Check for jump
|
||||
if (autojump && lastJump.check(1000) && idle_time.check(2000))
|
||||
{
|
||||
current_user_cmd->buttons |= IN_JUMP;
|
||||
lastJump.update();
|
||||
}
|
||||
// Check if still moving. 70 HU = Sniper Zoomed Speed
|
||||
if (idle_time.check(3000) &&
|
||||
CE_VECTOR(g_pLocalPlayer->entity, netvar.vVelocity).IsZero(60.0f))
|
||||
{
|
||||
follow_target = 0;
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4);
|
||||
return;
|
||||
}
|
||||
// Basic idle check
|
||||
if (idle_time.test_and_set(5000))
|
||||
{
|
||||
follow_target = 0;
|
||||
nav::NavTo(LOCAL_E->m_vecOrigin(), true, false, 4);
|
||||
return;
|
||||
}
|
||||
|
||||
static float last_slot_check = 0.0f;
|
||||
if (g_GlobalVars->curtime < last_slot_check)
|
||||
last_slot_check = 0.0f;
|
||||
if (follow_target && (always_medigun || mimic_slot) &&
|
||||
(g_GlobalVars->curtime - last_slot_check > 1.0f) &&
|
||||
!g_pLocalPlayer->life_state &&
|
||||
!CE_BYTE(ENTITY(follow_target), netvar.iLifeState))
|
||||
{
|
||||
|
||||
// We are checking our slot so reset the timer
|
||||
last_slot_check = g_GlobalVars->curtime;
|
||||
|
||||
// Get the follow targets active weapon
|
||||
int owner_weapon_eid =
|
||||
(CE_INT(ENTITY(follow_target), netvar.hActiveWeapon) & 0xFFF);
|
||||
IClientEntity *owner_weapon =
|
||||
g_IEntityList->GetClientEntity(owner_weapon_eid);
|
||||
|
||||
// If both the follow targets and the local players weapons arnt
|
||||
// null or
|
||||
// dormant
|
||||
if (owner_weapon && CE_GOOD(g_pLocalPlayer->weapon()))
|
||||
{
|
||||
|
||||
// IsBaseCombatWeapon()
|
||||
if (re::C_BaseCombatWeapon::IsBaseCombatWeapon(
|
||||
RAW_ENT(g_pLocalPlayer->weapon())) &&
|
||||
re::C_BaseCombatWeapon::IsBaseCombatWeapon(owner_weapon))
|
||||
{
|
||||
|
||||
// Get the players slot numbers and store in some vars
|
||||
int my_slot = re::C_BaseCombatWeapon::GetSlot(
|
||||
RAW_ENT(g_pLocalPlayer->weapon()));
|
||||
int owner_slot =
|
||||
re::C_BaseCombatWeapon::GetSlot(owner_weapon);
|
||||
|
||||
// If the local player is a medic and user settings allow,
|
||||
// then
|
||||
// keep the medigun out
|
||||
if (g_pLocalPlayer->clazz == tf_medic && always_medigun)
|
||||
{
|
||||
if (my_slot != 1)
|
||||
{
|
||||
g_IEngine->ExecuteClientCmd("slot2");
|
||||
}
|
||||
|
||||
// Else we attemt to keep our weapon mimiced with our
|
||||
// follow
|
||||
// target
|
||||
}
|
||||
else
|
||||
{
|
||||
if (my_slot != owner_slot)
|
||||
{
|
||||
g_IEngine->ExecuteClientCmd(
|
||||
format("slot", owner_slot + 1).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nav::NavTo(tar_orig, false, true, 5);
|
||||
}
|
||||
}
|
||||
} // namespace hacks::tf2::NavBot
|
||||
|
@ -128,6 +128,7 @@ DEFINE_HOOKED_METHOD(CreateMove, bool, void *this_, float input_sample_time,
|
||||
{
|
||||
DelayTimer.update();
|
||||
hacks::tf2::NavBot::Init();
|
||||
hacks::tf2::NavBot::initonce();
|
||||
firstcm = false;
|
||||
}
|
||||
tickcount++;
|
||||
|
@ -182,7 +182,7 @@ DEFINE_HOOKED_METHOD(DispatchUserMessage, bool, void *this_, int type,
|
||||
retrun = true;
|
||||
lastfilter = format(filter);
|
||||
lastname = format(name);
|
||||
gitgud.update();
|
||||
gitgud.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,7 +210,7 @@ DEFINE_HOOKED_METHOD(DispatchUserMessage, bool, void *this_, int type,
|
||||
retrun = true;
|
||||
lastfilter = format(filter);
|
||||
lastname = format(name);
|
||||
gitgud.update();
|
||||
gitgud.update();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,23 +13,25 @@ DEFINE_HOOKED_METHOD(SendDatagram, int, INetChannel *ch, bf_write *buf)
|
||||
#if !LAGBOT_MODE
|
||||
int in;
|
||||
int state;
|
||||
if (CE_GOOD(LOCAL_E)) {
|
||||
in = ch->m_nInSequenceNr;
|
||||
if (CE_GOOD(LOCAL_E))
|
||||
{
|
||||
in = ch->m_nInSequenceNr;
|
||||
state = ch->m_nInReliableState;
|
||||
|
||||
float latencysend =
|
||||
round((round((hacks::shared::backtrack::getLatency() - 0.5f) /
|
||||
15.1515151515f) -
|
||||
0.5f) *
|
||||
15.1515151515f);
|
||||
round((round((hacks::shared::backtrack::getLatency() - 0.5f) /
|
||||
15.1515151515f) -
|
||||
0.5f) *
|
||||
15.1515151515f);
|
||||
hacks::shared::backtrack::AddLatencyToNetchan(ch, latencysend);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ret = original::SendDatagram(ch, buf);
|
||||
#if !LAGBOT_MODE
|
||||
if (CE_GOOD(LOCAL_E)) {
|
||||
ch->m_nInSequenceNr = in;
|
||||
if (CE_GOOD(LOCAL_E))
|
||||
{
|
||||
ch->m_nInSequenceNr = in;
|
||||
ch->m_nInReliableState = state;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user