Skip to content

Commit ba30b4b

Browse files
committed
add player camera api
1 parent 3084e8d commit ba30b4b

File tree

2 files changed

+239
-0
lines changed

2 files changed

+239
-0
lines changed

api_player_camera.sma

Lines changed: 227 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,227 @@
1+
#pragma semicolon 1
2+
3+
#include <amxmodx>
4+
#include <fakemeta>
5+
#include <hamsandwich>
6+
#include <xs>
7+
8+
new g_rgpPlayerCamera[MAX_PLAYERS];
9+
new Float:g_rgflPlayerCameraDistance[MAX_PLAYERS];
10+
new Float:g_rgflPlayerCameraAngles[MAX_PLAYERS][3];
11+
new Float:g_rgflPlayerCamerOffset[MAX_PLAYERS][3];
12+
new Float:g_rgflPlayerCameraThinkDelay[MAX_PLAYERS];
13+
new Float:g_rgflPlayerCameraNextThink[MAX_PLAYERS];
14+
15+
new g_iszTriggerCameraClassname;
16+
17+
new g_iCameraModelIndex;
18+
19+
public plugin_precache() {
20+
g_iszTriggerCameraClassname = engfunc(EngFunc_AllocString, "trigger_camera");
21+
22+
g_iCameraModelIndex = precache_model("models/rpgrocket.mdl");
23+
}
24+
25+
public plugin_init() {
26+
register_plugin("[API] Player Camerea", "1.0.0", "Hedgehog Fog");
27+
28+
RegisterHamPlayer(Ham_Spawn, "HamHook_Player_Spawn_Post", .Post = 1);
29+
RegisterHamPlayer(Ham_Player_PreThink, "HamHook_Player_PreThink_Post", .Post = 1);
30+
}
31+
32+
public plugin_natives() {
33+
register_library("api_player_camera");
34+
register_native("PlayerCamera_Activate", "Native_Activate");
35+
register_native("PlayerCamera_Deactivate", "Native_Deactivate");
36+
register_native("PlayerCamera_IsActive", "Native_IsActive");
37+
register_native("PlayerCamera_SetOffset", "Native_SetOffset");
38+
register_native("PlayerCamera_SetAngles", "Native_SetAngles");
39+
register_native("PlayerCamera_SetDistance", "Native_SetDistance");
40+
register_native("PlayerCamera_SetThinkDelay", "Native_SetThinkDelay");
41+
}
42+
43+
public bool:Native_Activate(iPluginId, iArgc) {
44+
new pPlayer = get_param(1);
45+
46+
ActivatePlayerCamera(pPlayer);
47+
}
48+
49+
public Native_Deactivate(iPluginId, iArgc) {
50+
new pPlayer = get_param(1);
51+
52+
DeactivatePlayerCamera(pPlayer);
53+
}
54+
55+
public Native_IsActive(iPluginId, iArgc) {
56+
new pPlayer = get_param(1);
57+
58+
return g_rgpPlayerCamera[pPlayer] != -1;
59+
}
60+
61+
public Native_SetOffset(iPluginId, iArgc) {
62+
new pPlayer = get_param(1);
63+
64+
static Float:vecOffset[3];
65+
get_array_f(2, vecOffset, 3);
66+
67+
SetCameraOffset(pPlayer, vecOffset);
68+
}
69+
70+
public Native_SetAngles(iPluginId, iArgc) {
71+
new pPlayer = get_param(1);
72+
73+
static Float:vecAngles[3];
74+
get_array_f(2, vecAngles, 3);
75+
76+
SetCameraAngles(pPlayer, vecAngles);
77+
}
78+
79+
public Native_SetDistance(iPluginId, iArgc) {
80+
new pPlayer = get_param(1);
81+
new Float:flDistance = get_param_f(2);
82+
83+
SetCameraDistance(pPlayer, flDistance);
84+
}
85+
86+
public Native_SetThinkDelay(iPluginId, iArgc) {
87+
new pPlayer = get_param(1);
88+
new Float:flThinkDelay = get_param_f(2);
89+
90+
SetCameraThinkDelay(pPlayer, flThinkDelay);
91+
}
92+
93+
public HamHook_Player_Spawn_Post(pPlayer) {
94+
ReattachCamera(pPlayer);
95+
}
96+
97+
public HamHook_Player_PreThink_Post(pPlayer) {
98+
PlayerCameraThink(pPlayer);
99+
}
100+
101+
public client_connect(pPlayer) {
102+
g_rgpPlayerCamera[pPlayer] = -1;
103+
SetCameraDistance(pPlayer, 200.0);
104+
SetCameraAngles(pPlayer, Float:{0.0, 0.0, 0.0});
105+
SetCameraOffset(pPlayer, Float:{0.0, 0.0, 0.0});
106+
SetCameraThinkDelay(pPlayer, 0.01);
107+
}
108+
109+
public client_disconnected(pPlayer) {
110+
DeactivatePlayerCamera(pPlayer);
111+
}
112+
113+
ActivatePlayerCamera(pPlayer) {
114+
if (g_rgpPlayerCamera[pPlayer] != -1) {
115+
return;
116+
}
117+
118+
g_rgpPlayerCamera[pPlayer] = CreatePlayerCamera(pPlayer);
119+
g_rgflPlayerCameraNextThink[pPlayer] = 0.0;
120+
121+
engfunc(EngFunc_SetView, pPlayer, g_rgpPlayerCamera[pPlayer]);
122+
}
123+
124+
DeactivatePlayerCamera(pPlayer) {
125+
if (g_rgpPlayerCamera[pPlayer] == -1) {
126+
return;
127+
}
128+
129+
engfunc(EngFunc_RemoveEntity, g_rgpPlayerCamera[pPlayer]);
130+
g_rgpPlayerCamera[pPlayer] = -1;
131+
132+
if (is_user_connected(pPlayer)) {
133+
engfunc(EngFunc_SetView, pPlayer, pPlayer);
134+
}
135+
}
136+
137+
SetCameraOffset(pPlayer, const Float:vecOffset[3]) {
138+
xs_vec_copy(vecOffset, g_rgflPlayerCamerOffset[pPlayer]);
139+
}
140+
141+
SetCameraAngles(pPlayer, const Float:vecAngles[3]) {
142+
xs_vec_copy(vecAngles, g_rgflPlayerCameraAngles[pPlayer]);
143+
}
144+
145+
SetCameraDistance(pPlayer, Float:flDistance) {
146+
g_rgflPlayerCameraDistance[pPlayer] = flDistance;
147+
}
148+
149+
SetCameraThinkDelay(pPlayer, Float:flThinkDelay) {
150+
g_rgflPlayerCameraThinkDelay[pPlayer] = flThinkDelay;
151+
}
152+
153+
CreatePlayerCamera(pPlayer) {
154+
new pCamera = engfunc(EngFunc_CreateNamedEntity, g_iszTriggerCameraClassname);
155+
156+
set_pev(pCamera, pev_classname, "trigger_camera");
157+
set_pev(pCamera, pev_modelindex, g_iCameraModelIndex);
158+
set_pev(pCamera, pev_owner, pPlayer);
159+
set_pev(pCamera, pev_solid, SOLID_NOT);
160+
set_pev(pCamera, pev_movetype, MOVETYPE_FLY);
161+
set_pev(pCamera, pev_rendermode, kRenderTransTexture);
162+
163+
return pCamera;
164+
}
165+
166+
PlayerCameraThink(pPlayer) {
167+
if (g_rgflPlayerCameraNextThink[pPlayer] > get_gametime()) {
168+
return;
169+
}
170+
171+
g_rgflPlayerCameraNextThink[pPlayer] = get_gametime() + g_rgflPlayerCameraThinkDelay[pPlayer];
172+
173+
if (g_rgpPlayerCamera[pPlayer] == -1) {
174+
return;
175+
}
176+
177+
if (!is_user_alive(pPlayer)) {
178+
return;
179+
}
180+
181+
static Float:vecOrigin[3];
182+
pev(pPlayer, pev_origin, vecOrigin);
183+
xs_vec_add(vecOrigin, g_rgflPlayerCamerOffset[pPlayer], vecOrigin);
184+
185+
static Float:vecAngles[3];
186+
pev(pPlayer, pev_angles, vecAngles);
187+
vecAngles[0] = vecAngles[2] = 0.0;
188+
xs_vec_add(vecAngles, g_rgflPlayerCameraAngles[pPlayer], vecAngles);
189+
190+
static Float:vecBack[3];
191+
angle_vector(vecAngles, ANGLEVECTOR_FORWARD, vecBack);
192+
xs_vec_neg(vecBack, vecBack);
193+
194+
static Float:vecVelocity[3];
195+
pev(pPlayer, pev_velocity, vecVelocity);
196+
197+
static Float:vecCameraOrigin[3];
198+
for (new i = 0; i < 3; ++i) {
199+
vecCameraOrigin[i] = vecOrigin[i] + (vecBack[i] * g_rgflPlayerCameraDistance[pPlayer]);
200+
}
201+
202+
new pTr = create_tr2();
203+
engfunc(EngFunc_TraceLine, vecOrigin, vecCameraOrigin, IGNORE_MONSTERS, pPlayer, pTr);
204+
205+
static Float:flFraction;
206+
get_tr2(pTr, TR_flFraction, flFraction);
207+
208+
free_tr2(pTr);
209+
210+
if(flFraction != 1.0) {
211+
for (new i = 0; i < 3; ++i) {
212+
vecCameraOrigin[i] = vecOrigin[i] + (vecBack[i] * (g_rgflPlayerCameraDistance[pPlayer] * flFraction));
213+
}
214+
}
215+
216+
set_pev(g_rgpPlayerCamera[pPlayer], pev_origin, vecCameraOrigin);
217+
set_pev(g_rgpPlayerCamera[pPlayer], pev_angles, vecAngles);
218+
set_pev(g_rgpPlayerCamera[pPlayer], pev_velocity, vecVelocity);
219+
}
220+
221+
ReattachCamera(pPlayer) {
222+
if (g_rgpPlayerCamera[pPlayer] == -1) {
223+
return;
224+
}
225+
226+
engfunc(EngFunc_SetView, pPlayer, g_rgpPlayerCamera[pPlayer]);
227+
}

include/api_player_camera.inc

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#if defined _api_player_camera_included
2+
#endinput
3+
#endif
4+
#define _api_player_camera_included
5+
6+
native PlayerCamera_Activate(pPlayer);
7+
native PlayerCamera_Deactivate(pPlayer);
8+
native bool:PlayerCamera_IsActive(pPlayer);
9+
native PlayerCamera_SetOffset(pPlayer, const Float:vecOffset[3]);
10+
native PlayerCamera_SetAngles(pPlayer, const Float:vecAngles[3]);
11+
native PlayerCamera_SetDistance(pPlayer, Float:flDistance);
12+
native PlayerCamera_SetThinkDelay(pPlayer, Float:flThinkDelay);

0 commit comments

Comments
 (0)