static const float s_fStickyMaxDmg = 120;
static const float s_fStickyMaxDistance = 150;
static const float s_fDmgRamp = s_fStickyMaxDistance / s_fStickyMaxDmg / 2;
inline float ApproxStickyDamage(float distance)
{
if (distance > s_fStickyMaxDistance)
return 0;
return (s_fStickyMaxDistance - distance) * s_fDmgRamp + s_fStickyMaxDmg / 2;
};
void Stickybot(CUserCmd* cmd)
{
if (!CONFIG.m_bStickyTrigger)
return;
static float prevEstimatedDmg = 0;
float estimatedDmg = 0;
for (auto sticky = LOGIC.m_vOwnedStickies.begin(); sticky != LOGIC.m_vOwnedStickies.end(); ++sticky)
{
NetVar::CTFGrenadePipebombProjectile* pSticky = *sticky;
if (!IsStickyArmed(pSticky))
continue;
for (auto player = LOGIC.m_vEnemyTeam.begin(); player != LOGIC.m_vEnemyTeam.end(); ++player)
{
NetVar::CTFPlayer* pPlayer = *player;
if (!CanBeDamaged(pPlayer))
continue;
Vector targetpoint = GetEyePosition(pPlayer);
Vector startpoint = pSticky->GetAbsOrigin();
Vector min, max;
pPlayer->GetRenderBoundsWorldspace(min, max);
// may be excessive
if (!IsBoxIntersectingSphere(min, max, startpoint, s_fStickyMaxDistance))
continue;
float dist = pPlayer->GetAbsOrigin().DistTo(startpoint);
if (dist > s_fStickyMaxDistance)
continue;
trace_t tr;
MYUTIL_TraceLine(startpoint, targetpoint, MASK_EXPLOSION, pSticky, &tr);
bool traceable = (tr.m_pEnt == pPlayer);
if (traceable)
estimatedDmg += ApproxStickyDamage(dist);
if (traceable && CONFIG.m_bStickyTriggetAtBest && (dist > CONFIG.m_fStickyTriggerBound))
{
__log("Trigger'd @ best!\n");
cmd->buttons |= IN_ATTACK2;
return;
};
};
};
if (prevEstimatedDmg > estimatedDmg)
{
__log("Trigger'd!\n");
cmd->buttons |= IN_ATTACK2;
prevEstimatedDmg = 0;
}
else
prevEstimatedDmg = estimatedDmg;
};
