HalfLife
June 5

Вид от третьего лица со смещением в Goldsrc

Суть: Вид от третьего лица со смещением в Goldsrc. Half-Life SDK.

Задумка и код: ScriptedSnark. А также немного мелочи от меня.

Я добавил включение смещения камеры (и "прицела") только при виде от третьего лица. Т.е. если переменная "thirdperson" равна 0, то будет обычный вид от первого лица, но если переменная равна 1, то получим и смещение камеры и правильно смещённый прицел.


1) В "./cl_dll/in_defs.h" добавить:

#define CAM_SHIFT_RIGHT 12.0f

Например, если мы хотим сделать смещение камеры на 12 единиц.

2) В "./dlls/player.cpp" в конце секции включений (includes) добавить:

#include "../cl_dll/in_defs.h"

3) В "./dlls/player.cpp" "CBasePlayer::GetGunPosition" привести к следующему виду:

Vector CBasePlayer::GetGunPosition()
{
	Vector origin;
	if (cam_thirdperson == true)
	{
		origin = pev->origin + pev->view_ofs + gpGlobals->v_right * CAM_SHIFT_RIGHT;
	}
	else
	{
		origin = pev->origin + pev->view_ofs;
	}

	return origin;
}

4) В "./dlls/player.h" классу "CBasePlayer" дать переменную:

bool cam_thirdperson;

5) В "./dlls/client.cpp" в "CliendCommand" добавить:

	else if (FStrEq(pcmd, "thirdperson"))
	{
		if (CMD_ARGC() < 2)
		{
			player->cam_thirdperson = false;
			return;

		}
		player->cam_thirdperson = atoi(CMD_ARGV(1)) ? true : false;
	}

6) В "./cl_dll/view.cpp" найти "V_CalcNormalRefdef" и в нём найти условие с таким следующим комментарием:

    // Treating cam_ofs[2] as the distance
    if (0 != CL_IsThirdPerson())

Приводим к такому виду:

    // Treating cam_ofs[2] as the distance
    if (0 != CL_IsThirdPerson())
    {
        Vector ofs;

        ofs[0] = ofs[1] = ofs[2] = 0.0;

        CL_CameraOffset((float*)&ofs);

        VectorCopy(ofs, camAngles);
        camAngles[ROLL] = 0;

        AngleVectors(camAngles, camForward, camRight, camUp);

        for (i = 0; i < 3; i++)
        {
            pparams->vieworg[i] += -ofs[2] * camForward[i];
            pparams->vieworg[i] += CAM_SHIFT_RIGHT * camRight[i]; // Добавляем это
        }
    }

7) В "./cl_dll/ev_common.cpp" в конце секции с включений добавить:

#include "in_defs.h"

8) Там же перед "void EV_GetGunPosition" добавить:

extern Vector v_angles;
extern bool cam_thirdperson;

9) В "EV_GetGunPosition" добавить:

	if (0 != cam_thirdperson)
	{
		Vector forward, right, up;
		AngleVectors(v_angles, forward, right, up);

		VectorAdd(origin, (view_ofs + right * CAM_SHIFT_RIGHT), pos);
	}
	else
	{
		VectorAdd(origin, view_ofs, pos);
	}

Здесь добавлена проверка на вид от третьего лица.

В итоге функция выглядит так:

void EV_GetGunPosition(event_args_t* args, float* pos, float* origin)
{
	int idx;

	idx = args->entindex;

	Vector view_ofs = VEC_VIEW;

	if (EV_IsPlayer(idx))
	{
		// in spec mode use entity viewheigh, not own
		if (EV_IsLocal(idx) && !IS_FIRSTPERSON_SPEC)
		{
			// Grab predicted result for local player
			gEngfuncs.pEventAPI->EV_LocalPlayerViewheight(view_ofs);
		}
		else if (args->ducking == 1)
		{
			view_ofs = VEC_DUCK_VIEW;
		}
	}

	if (0 != cam_thirdperson)
	{
		Vector forward, right, up;
		AngleVectors(v_angles, forward, right, up);

		VectorAdd(origin, (view_ofs + right * CAM_SHIFT_RIGHT), pos);
	}
	else
	{
		VectorAdd(origin, view_ofs, pos);
	}
}

Всё. Можно собирать код и смотреть результат.

Я в своей модификации (Half Effect) временно добавил такие строки в "userconfig.cfg":

alias tps tps1 
alias "tps1" "thirdperson 1; cam_idealdist 25; cam_idealyaw 0; alias tps tps2"
alias "tps2" "firstperson; alias tps tps1"
bind "tab" "tps"

По ним по клавише "TAB" происходит переход в вид от третьего лица с расстоянием в 25 и выравниванием угла камеры. При повторном нажатии клавиши "TAB" происходит возврат в вид от первого лица.