void Visuals::ThirdpersonThink() {
ang_t offset;
vec3_t origin,forward;
static CTraceFilterSimple_game filter {};
CGameTrace tr;
static float progress {};
// for whatever reason overrideview also gets called from the main menu.
if (!g_csgo.m_engine->IsInGame())
return;
// check if we have a local player and he is alive.
bool alive = g_cl.m_local && g_cl.m_local->alive();
// camera should be in thirdperson.
if (m_thirdperson || !g_cl.m_processing) {
// if alive and not in thirdperson already switch to thirdperson.
if (alive && !g_csgo.m_input->m_camera_in_third_person) {
g_csgo.m_input->m_camera_in_third_person = true;
}
// if dead and spectating in firstperson switch to thirdperson.
else if (g_cl.m_local->m_iObserverMode() == 4) {
// if in thirdperson, switch to firstperson.
// we need to disable thirdperson to spectate properly.
if (g_csgo.m_input->m_camera_in_third_person) {
g_csgo.m_input->m_camera_in_third_person = false;
g_csgo.m_input->m_camera_offset.z = 0.f;
}
g_cl.m_local->m_iObserverMode() = 5;
}
}
// camera should be in firstperson.
else if (g_csgo.m_input->m_camera_in_third_person) {
// animate backwards.
progress -= g_csgo.m_globals->m_frametime * 5.f + (progress / 100);
// clamp.
math::clamp(progress,0.f,1.f);
g_csgo.m_input->m_camera_offset.z = g_cfg[XOR("misc_thirdperson_distance")].get< float >() * progress;
// set to first person.
if (!progress)
g_csgo.m_input->m_camera_in_third_person = false;
}
// if after all of this we are still in thirdperson.
if (g_csgo.m_input->m_camera_in_third_person) {
// get camera angles.
g_csgo.m_engine->GetViewAngles(offset);
// get our viewangle's forward directional vector.
math::AngleVectors(offset,&forward);
// start the animation.
if (m_thirdperson)
progress += g_csgo.m_globals->m_frametime * 5.f + (progress / 100);
// clamp.
math::clamp(progress,0.f,1.f);
// cam_idealdist convar.
offset.z = g_cfg[XOR("misc_thirdperson_distance")].get< float >() * progress;
// start pos.
origin = g_cl.m_shoot_pos;
// setup trace filter and trace.
filter.SetPassEntity(g_cl.m_local);
g_csgo.m_engine_trace->TraceRay(
Ray(origin,origin - (forward * offset.z),{-16.f,-16.f,-16.f},{16.f,16.f,16.f}),
MASK_NPCWORLDSTATIC,
(ITraceFilter*) &filter,
&tr
);
// adapt distance to travel time.
math::clamp(tr.m_fraction,0.f,1.f);
offset.z *= tr.m_fraction;
// override camera angles.
g_csgo.m_input->m_camera_offset = {offset.x,offset.y,offset.z};
}
// update the old value.
m_old_thirdperson = m_thirdperson;
}