Skip to content

Commit

Permalink
add player camera api
Browse files Browse the repository at this point in the history
  • Loading branch information
Hedgefog committed Mar 25, 2023
1 parent 3084e8d commit ba30b4b
Show file tree
Hide file tree
Showing 2 changed files with 239 additions and 0 deletions.
227 changes: 227 additions & 0 deletions api_player_camera.sma
Original file line number Diff line number Diff line change
@@ -0,0 +1,227 @@
#pragma semicolon 1

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <xs>

new g_rgpPlayerCamera[MAX_PLAYERS];
new Float:g_rgflPlayerCameraDistance[MAX_PLAYERS];
new Float:g_rgflPlayerCameraAngles[MAX_PLAYERS][3];
new Float:g_rgflPlayerCamerOffset[MAX_PLAYERS][3];
new Float:g_rgflPlayerCameraThinkDelay[MAX_PLAYERS];
new Float:g_rgflPlayerCameraNextThink[MAX_PLAYERS];

new g_iszTriggerCameraClassname;

new g_iCameraModelIndex;

public plugin_precache() {
g_iszTriggerCameraClassname = engfunc(EngFunc_AllocString, "trigger_camera");

g_iCameraModelIndex = precache_model("models/rpgrocket.mdl");
}

public plugin_init() {
register_plugin("[API] Player Camerea", "1.0.0", "Hedgehog Fog");

RegisterHamPlayer(Ham_Spawn, "HamHook_Player_Spawn_Post", .Post = 1);
RegisterHamPlayer(Ham_Player_PreThink, "HamHook_Player_PreThink_Post", .Post = 1);
}

public plugin_natives() {
register_library("api_player_camera");
register_native("PlayerCamera_Activate", "Native_Activate");
register_native("PlayerCamera_Deactivate", "Native_Deactivate");
register_native("PlayerCamera_IsActive", "Native_IsActive");
register_native("PlayerCamera_SetOffset", "Native_SetOffset");
register_native("PlayerCamera_SetAngles", "Native_SetAngles");
register_native("PlayerCamera_SetDistance", "Native_SetDistance");
register_native("PlayerCamera_SetThinkDelay", "Native_SetThinkDelay");
}

public bool:Native_Activate(iPluginId, iArgc) {
new pPlayer = get_param(1);

ActivatePlayerCamera(pPlayer);
}

public Native_Deactivate(iPluginId, iArgc) {
new pPlayer = get_param(1);

DeactivatePlayerCamera(pPlayer);
}

public Native_IsActive(iPluginId, iArgc) {
new pPlayer = get_param(1);

return g_rgpPlayerCamera[pPlayer] != -1;
}

public Native_SetOffset(iPluginId, iArgc) {
new pPlayer = get_param(1);

static Float:vecOffset[3];
get_array_f(2, vecOffset, 3);

SetCameraOffset(pPlayer, vecOffset);
}

public Native_SetAngles(iPluginId, iArgc) {
new pPlayer = get_param(1);

static Float:vecAngles[3];
get_array_f(2, vecAngles, 3);

SetCameraAngles(pPlayer, vecAngles);
}

public Native_SetDistance(iPluginId, iArgc) {
new pPlayer = get_param(1);
new Float:flDistance = get_param_f(2);

SetCameraDistance(pPlayer, flDistance);
}

public Native_SetThinkDelay(iPluginId, iArgc) {
new pPlayer = get_param(1);
new Float:flThinkDelay = get_param_f(2);

SetCameraThinkDelay(pPlayer, flThinkDelay);
}

public HamHook_Player_Spawn_Post(pPlayer) {
ReattachCamera(pPlayer);
}

public HamHook_Player_PreThink_Post(pPlayer) {
PlayerCameraThink(pPlayer);
}

public client_connect(pPlayer) {
g_rgpPlayerCamera[pPlayer] = -1;
SetCameraDistance(pPlayer, 200.0);
SetCameraAngles(pPlayer, Float:{0.0, 0.0, 0.0});
SetCameraOffset(pPlayer, Float:{0.0, 0.0, 0.0});
SetCameraThinkDelay(pPlayer, 0.01);
}

public client_disconnected(pPlayer) {
DeactivatePlayerCamera(pPlayer);
}

ActivatePlayerCamera(pPlayer) {
if (g_rgpPlayerCamera[pPlayer] != -1) {
return;
}

g_rgpPlayerCamera[pPlayer] = CreatePlayerCamera(pPlayer);
g_rgflPlayerCameraNextThink[pPlayer] = 0.0;

engfunc(EngFunc_SetView, pPlayer, g_rgpPlayerCamera[pPlayer]);
}

DeactivatePlayerCamera(pPlayer) {
if (g_rgpPlayerCamera[pPlayer] == -1) {
return;
}

engfunc(EngFunc_RemoveEntity, g_rgpPlayerCamera[pPlayer]);
g_rgpPlayerCamera[pPlayer] = -1;

if (is_user_connected(pPlayer)) {
engfunc(EngFunc_SetView, pPlayer, pPlayer);
}
}

SetCameraOffset(pPlayer, const Float:vecOffset[3]) {
xs_vec_copy(vecOffset, g_rgflPlayerCamerOffset[pPlayer]);
}

SetCameraAngles(pPlayer, const Float:vecAngles[3]) {
xs_vec_copy(vecAngles, g_rgflPlayerCameraAngles[pPlayer]);
}

SetCameraDistance(pPlayer, Float:flDistance) {
g_rgflPlayerCameraDistance[pPlayer] = flDistance;
}

SetCameraThinkDelay(pPlayer, Float:flThinkDelay) {
g_rgflPlayerCameraThinkDelay[pPlayer] = flThinkDelay;
}

CreatePlayerCamera(pPlayer) {
new pCamera = engfunc(EngFunc_CreateNamedEntity, g_iszTriggerCameraClassname);

set_pev(pCamera, pev_classname, "trigger_camera");
set_pev(pCamera, pev_modelindex, g_iCameraModelIndex);
set_pev(pCamera, pev_owner, pPlayer);
set_pev(pCamera, pev_solid, SOLID_NOT);
set_pev(pCamera, pev_movetype, MOVETYPE_FLY);
set_pev(pCamera, pev_rendermode, kRenderTransTexture);

return pCamera;
}

PlayerCameraThink(pPlayer) {
if (g_rgflPlayerCameraNextThink[pPlayer] > get_gametime()) {
return;
}

g_rgflPlayerCameraNextThink[pPlayer] = get_gametime() + g_rgflPlayerCameraThinkDelay[pPlayer];

if (g_rgpPlayerCamera[pPlayer] == -1) {
return;
}

if (!is_user_alive(pPlayer)) {
return;
}

static Float:vecOrigin[3];
pev(pPlayer, pev_origin, vecOrigin);
xs_vec_add(vecOrigin, g_rgflPlayerCamerOffset[pPlayer], vecOrigin);

static Float:vecAngles[3];
pev(pPlayer, pev_angles, vecAngles);
vecAngles[0] = vecAngles[2] = 0.0;
xs_vec_add(vecAngles, g_rgflPlayerCameraAngles[pPlayer], vecAngles);

static Float:vecBack[3];
angle_vector(vecAngles, ANGLEVECTOR_FORWARD, vecBack);
xs_vec_neg(vecBack, vecBack);

static Float:vecVelocity[3];
pev(pPlayer, pev_velocity, vecVelocity);

static Float:vecCameraOrigin[3];
for (new i = 0; i < 3; ++i) {
vecCameraOrigin[i] = vecOrigin[i] + (vecBack[i] * g_rgflPlayerCameraDistance[pPlayer]);
}

new pTr = create_tr2();
engfunc(EngFunc_TraceLine, vecOrigin, vecCameraOrigin, IGNORE_MONSTERS, pPlayer, pTr);

static Float:flFraction;
get_tr2(pTr, TR_flFraction, flFraction);

free_tr2(pTr);

if(flFraction != 1.0) {
for (new i = 0; i < 3; ++i) {
vecCameraOrigin[i] = vecOrigin[i] + (vecBack[i] * (g_rgflPlayerCameraDistance[pPlayer] * flFraction));
}
}

set_pev(g_rgpPlayerCamera[pPlayer], pev_origin, vecCameraOrigin);
set_pev(g_rgpPlayerCamera[pPlayer], pev_angles, vecAngles);
set_pev(g_rgpPlayerCamera[pPlayer], pev_velocity, vecVelocity);
}

ReattachCamera(pPlayer) {
if (g_rgpPlayerCamera[pPlayer] == -1) {
return;
}

engfunc(EngFunc_SetView, pPlayer, g_rgpPlayerCamera[pPlayer]);
}
12 changes: 12 additions & 0 deletions include/api_player_camera.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#if defined _api_player_camera_included
#endinput
#endif
#define _api_player_camera_included

native PlayerCamera_Activate(pPlayer);
native PlayerCamera_Deactivate(pPlayer);
native bool:PlayerCamera_IsActive(pPlayer);
native PlayerCamera_SetOffset(pPlayer, const Float:vecOffset[3]);
native PlayerCamera_SetAngles(pPlayer, const Float:vecAngles[3]);
native PlayerCamera_SetDistance(pPlayer, Float:flDistance);
native PlayerCamera_SetThinkDelay(pPlayer, Float:flThinkDelay);

0 comments on commit ba30b4b

Please sign in to comment.