Мелочь, но приятно. Сделано примерно как в нл.
В hooked_overrideview.cpp (Тема взята с другого форума)
Пример работы:
В hooked_overrideview.cpp (Тема взята с другого форума)
void Thirdperson_Init(bool fakeducking, float progress) {
/* our current fraction. */
static float current_fraction = 0.0f;
auto distance = ((float)g_cfg.misc.thirdperson_distance) * progress;
Vector angles, inverse_angles;
// get camera angles.
m_engine()->GetViewAngles(angles);
m_engine()->GetViewAngles(inverse_angles);
// cam_idealdist convar.
inverse_angles.z = distance;
// set camera direction.
Vector forward, right, up;
math::angle_vectors(inverse_angles, &forward, &right, &up);
// various fixes to camera when fakeducking.
auto eye_pos = fakeducking ? g_ctx.local()->GetAbsOrigin() + m_gamemovement()->GetPlayerViewOffset(false) : g_ctx.local()->GetAbsOrigin() + g_ctx.local()->m_vecViewOffset();
auto offset = eye_pos + forward * -distance + right + up;
// setup trace filter and trace.
CTraceFilterWorldOnly filter;
trace_t tr;
// tracing to camera angles.
m_trace()->TraceRay(Ray_t(eye_pos, offset, Vector(-16.0f, -16.0f, -16.0f), Vector(16.0f, 16.0f, 16.0f)), 131083, &filter, &tr);
// interpolate camera speed if something behind our camera.
if (current_fraction > tr.fraction)
current_fraction = tr.fraction;
else if (current_fraction > 0.9999f)
current_fraction = 1.0f;
// adapt distance to travel time.
current_fraction = math::interpolate(current_fraction, tr.fraction, m_globals()->m_frametime * 10.0f);
angles.z = distance * current_fraction;
// override camera angles.
m_input()->m_vecCameraOffset = angles;
}
void thirdperson(bool fakeducking)
{
/* thirdperson code. */
{
static float progress;
static bool in_transition;
static auto in_thirdperson = false;
if (!in_thirdperson && g_ctx.globals.in_thirdperson)
{
in_thirdperson = true;
}
else if (in_thirdperson && !g_ctx.globals.in_thirdperson)
in_thirdperson = false;
if (g_ctx.local()->is_alive() && in_thirdperson)
{
in_transition = false;
if (!m_input()->m_fCameraInThirdPerson)
{
m_input()->m_fCameraInThirdPerson = true;
}
}
else
{
progress -= m_globals()->m_frametime * 8.f + (progress / 100);
progress = std::clamp(progress, 0.f, 1.f);
if (!progress)
m_input()->m_fCameraInThirdPerson = false;
else
{
in_transition = true;
m_input()->m_fCameraInThirdPerson = true;
}
}
if (m_input()->m_fCameraInThirdPerson && !in_transition)
{
progress += m_globals()->m_frametime * 8.f + (progress / 100);
progress = std::clamp(progress, 0.f, 1.f);
}
Thirdperson_Init(fakeducking, progress);
}
/* thirdperson on death code. */
{
static auto require_reset = false;
if (g_ctx.local()->is_alive())
{
require_reset = false;
return;
}
if (g_cfg.misc.thirdperson_when_spectating)
{
if (require_reset)
g_ctx.local()->m_iObserverMode() = OBS_MODE_CHASE;
if (g_ctx.local()->m_iObserverMode() == OBS_MODE_IN_EYE)
require_reset = true;
}
}
}
/* our current fraction. */
static float current_fraction = 0.0f;
auto distance = ((float)g_cfg.misc.thirdperson_distance) * progress;
Vector angles, inverse_angles;
// get camera angles.
m_engine()->GetViewAngles(angles);
m_engine()->GetViewAngles(inverse_angles);
// cam_idealdist convar.
inverse_angles.z = distance;
// set camera direction.
Vector forward, right, up;
math::angle_vectors(inverse_angles, &forward, &right, &up);
// various fixes to camera when fakeducking.
auto eye_pos = fakeducking ? g_ctx.local()->GetAbsOrigin() + m_gamemovement()->GetPlayerViewOffset(false) : g_ctx.local()->GetAbsOrigin() + g_ctx.local()->m_vecViewOffset();
auto offset = eye_pos + forward * -distance + right + up;
// setup trace filter and trace.
CTraceFilterWorldOnly filter;
trace_t tr;
// tracing to camera angles.
m_trace()->TraceRay(Ray_t(eye_pos, offset, Vector(-16.0f, -16.0f, -16.0f), Vector(16.0f, 16.0f, 16.0f)), 131083, &filter, &tr);
// interpolate camera speed if something behind our camera.
if (current_fraction > tr.fraction)
current_fraction = tr.fraction;
else if (current_fraction > 0.9999f)
current_fraction = 1.0f;
// adapt distance to travel time.
current_fraction = math::interpolate(current_fraction, tr.fraction, m_globals()->m_frametime * 10.0f);
angles.z = distance * current_fraction;
// override camera angles.
m_input()->m_vecCameraOffset = angles;
}
void thirdperson(bool fakeducking)
{
/* thirdperson code. */
{
static float progress;
static bool in_transition;
static auto in_thirdperson = false;
if (!in_thirdperson && g_ctx.globals.in_thirdperson)
{
in_thirdperson = true;
}
else if (in_thirdperson && !g_ctx.globals.in_thirdperson)
in_thirdperson = false;
if (g_ctx.local()->is_alive() && in_thirdperson)
{
in_transition = false;
if (!m_input()->m_fCameraInThirdPerson)
{
m_input()->m_fCameraInThirdPerson = true;
}
}
else
{
progress -= m_globals()->m_frametime * 8.f + (progress / 100);
progress = std::clamp(progress, 0.f, 1.f);
if (!progress)
m_input()->m_fCameraInThirdPerson = false;
else
{
in_transition = true;
m_input()->m_fCameraInThirdPerson = true;
}
}
if (m_input()->m_fCameraInThirdPerson && !in_transition)
{
progress += m_globals()->m_frametime * 8.f + (progress / 100);
progress = std::clamp(progress, 0.f, 1.f);
}
Thirdperson_Init(fakeducking, progress);
}
/* thirdperson on death code. */
{
static auto require_reset = false;
if (g_ctx.local()->is_alive())
{
require_reset = false;
return;
}
if (g_cfg.misc.thirdperson_when_spectating)
{
if (require_reset)
g_ctx.local()->m_iObserverMode() = OBS_MODE_CHASE;
if (g_ctx.local()->m_iObserverMode() == OBS_MODE_IN_EYE)
require_reset = true;
}
}
}