Skip to content

Commit f277b98

Browse files
committed
update player model api
1 parent e509948 commit f277b98

File tree

1 file changed

+113
-49
lines changed

1 file changed

+113
-49
lines changed

api_player_model.sma

+113-49
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,45 @@
11
#include <amxmodx>
2-
#include <hamsandwich>
32
#include <fakemeta>
3+
#include <hamsandwich>
44
#include <reapi>
55

66
#define PLUGIN "[API] Player Model"
77
#define VERSION "1.0.0"
88
#define AUTHOR "Hedgehog Fog"
99

10+
#define ERROR_MSG_NOT_CONNECTED "User %d is not connected"
11+
1012
#define MAX_SEQUENCES 101
1113

12-
new g_iszModelClassname;
14+
new g_iszSubModelClassname;
1315

1416
new g_rgszDefaultPlayerModel[MAX_PLAYERS + 1][32];
1517
new g_rgszCurrentPlayerModel[MAX_PLAYERS + 1][256];
1618
new g_rgszCustomPlayerModel[MAX_PLAYERS + 1][256];
1719
new g_rgiPlayerAnimationIndex[MAX_PLAYERS + 1];
20+
new g_pPlayerSubModel[MAX_PLAYERS + 1];
1821
new bool:g_rgbPlayerUseCustomModel[MAX_PLAYERS + 1];
1922

2023
new Trie:g_itPlayerSequenceModelIndexes = Invalid_Trie;
2124
new Trie:g_itPlayerSequences = Invalid_Trie;
22-
new g_pPlayerSubModel[MAX_PLAYERS + 1];
23-
24-
new gmsgClCorpse;
2525

2626
public plugin_precache() {
27-
g_iszModelClassname = engfunc(EngFunc_AllocString, "info_target");
27+
g_iszSubModelClassname = engfunc(EngFunc_AllocString, "info_target");
2828
g_itPlayerSequenceModelIndexes = TrieCreate();
2929
g_itPlayerSequences = TrieCreate();
3030
}
3131

3232
public plugin_init() {
3333
register_plugin(PLUGIN, VERSION, AUTHOR);
3434

35-
gmsgClCorpse = get_user_msgid("ClCorpse");
36-
3735
register_forward(FM_SetClientKeyValue, "FMHook_SetClientKeyValue");
3836

3937
RegisterHamPlayer(Ham_Spawn, "HamHook_Player_Spawn_Post", .Post = 1);
4038
RegisterHamPlayer(Ham_Player_PostThink, "HamHook_Player_PostThink_Post", .Post = 1);
4139

4240
RegisterHookChain(RG_CBasePlayer_SetAnimation, "HC_Player_SetAnimation");
4341

44-
register_message(gmsgClCorpse, "Message_ClCorpse");
42+
register_message(get_user_msgid("ClCorpse"), "Message_ClCorpse");
4543
}
4644

4745
public plugin_natives() {
@@ -57,19 +55,43 @@ public plugin_natives() {
5755
register_native("PlayerModel_PrecacheAnimation", "Native_PrecacheAnimation");
5856
}
5957

58+
public plugin_end() {
59+
TrieDestroy(g_itPlayerSequenceModelIndexes);
60+
TrieDestroy(g_itPlayerSequences);
61+
}
62+
63+
// ANCHOR: Natives
64+
6065
public Native_GetPlayerModel(iPluginId, iArgc) {
6166
new pPlayer = get_param(1);
67+
68+
if (!is_user_connected(pPlayer)) {
69+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
70+
return;
71+
}
72+
6273
set_string(2, g_rgszCustomPlayerModel[pPlayer], get_param(3));
6374
}
6475

6576
public Native_GetCurrentPlayerModel(iPluginId, iArgc) {
6677
new pPlayer = get_param(1);
78+
79+
if (!is_user_connected(pPlayer)) {
80+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
81+
return;
82+
}
83+
6784
set_string(2, g_rgszCurrentPlayerModel[pPlayer], get_param(3));
6885
}
6986

7087
public Native_GetPlayerEntity(iPluginId, iArgc) {
7188
new pPlayer = get_param(1);
7289

90+
if (!is_user_connected(pPlayer)) {
91+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
92+
return 0;
93+
}
94+
7395
if (g_pPlayerSubModel[pPlayer] && @PlayerSubModel_IsActive(g_pPlayerSubModel[pPlayer])) {
7496
return g_pPlayerSubModel[pPlayer];
7597
}
@@ -80,27 +102,55 @@ public Native_GetPlayerEntity(iPluginId, iArgc) {
80102
public bool:Native_HasCustomPlayerModel(iPluginId, iArgc) {
81103
new pPlayer = get_param(1);
82104

105+
if (!is_user_connected(pPlayer)) {
106+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
107+
return false;
108+
}
109+
83110
return g_rgbPlayerUseCustomModel[pPlayer];
84111
}
85112

86113
public Native_SetPlayerModel(iPluginId, iArgc) {
87114
new pPlayer = get_param(1);
115+
116+
if (!is_user_connected(pPlayer)) {
117+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
118+
return;
119+
}
120+
88121
get_string(2, g_rgszCustomPlayerModel[pPlayer], charsmax(g_rgszCustomPlayerModel[]));
89122
}
90123

91124
public Native_ResetPlayerModel(iPluginId, iArgc) {
92125
new pPlayer = get_param(1);
126+
127+
if (!is_user_connected(pPlayer)) {
128+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
129+
return;
130+
}
131+
93132
@Player_ResetModel(pPlayer);
94133
}
95134

96135
public Native_UpdatePlayerModel(iPluginId, iArgc) {
97136
new pPlayer = get_param(1);
137+
138+
if (!is_user_connected(pPlayer)) {
139+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
140+
return;
141+
}
142+
98143
@Player_UpdateCurrentModel(pPlayer);
99144
}
100145

101146
public Native_SetPlayerSequence(iPluginId, iArgc) {
102147
new pPlayer = get_param(1);
103148

149+
if (!is_user_connected(pPlayer)) {
150+
log_error(AMX_ERR_NATIVE, ERROR_MSG_NOT_CONNECTED, pPlayer);
151+
return 0;
152+
}
153+
104154
static szSequence[MAX_RESOURCE_PATH_LENGTH];
105155
get_string(2, szSequence, charsmax(szSequence));
106156

@@ -113,6 +163,8 @@ public Native_PrecacheAnimation(iPluginId, iArgc) {
113163
return PrecachePlayerAnimation(szAnimation);
114164
}
115165

166+
// ANCHOR: Hooks and Forwards
167+
116168
public client_connect(pPlayer) {
117169
copy(g_rgszCustomPlayerModel[pPlayer], charsmax(g_rgszCustomPlayerModel[]), NULL_STRING);
118170
copy(g_rgszDefaultPlayerModel[pPlayer], charsmax(g_rgszDefaultPlayerModel[]), NULL_STRING);
@@ -128,19 +180,24 @@ public client_disconnected(pPlayer) {
128180
}
129181
}
130182

131-
public Message_ClCorpse(iMsgId, iMsgDest, pPlayer) {
132-
new pTargetPlayer = get_msg_arg_int(12);
133-
if (g_rgbPlayerUseCustomModel[pTargetPlayer] || g_rgiPlayerAnimationIndex[pTargetPlayer]) {
134-
set_msg_arg_string(1, g_rgszCurrentPlayerModel[pTargetPlayer]);
183+
public FMHook_SetClientKeyValue(pPlayer, const szInfoBuffer[], const szKey[], const szValue[]) {
184+
if (equal(szKey, "model")) {
185+
copy(g_rgszDefaultPlayerModel[pPlayer], charsmax(g_rgszDefaultPlayerModel[]), szValue);
186+
187+
if (!equal(g_rgszCurrentPlayerModel[pPlayer], NULL_STRING)) {
188+
return FMRES_SUPERCEDE;
189+
}
190+
191+
return FMRES_HANDLED;
135192
}
193+
194+
return FMRES_IGNORED;
136195
}
137196

138197
public HamHook_Player_Spawn_Post(pPlayer) {
139-
if (!g_pPlayerSubModel[pPlayer]) {
140-
g_pPlayerSubModel[pPlayer] = @PlayerSubModel_Create(pPlayer);
141-
}
142-
143198
@Player_UpdateCurrentModel(pPlayer);
199+
200+
return HAM_HANDLED;
144201
}
145202

146203
public HamHook_Player_PostThink_Post(pPlayer) {
@@ -151,25 +208,20 @@ public HamHook_Player_PostThink_Post(pPlayer) {
151208
return HAM_HANDLED;
152209
}
153210

154-
public FMHook_SetClientKeyValue(pPlayer, const szInfoBuffer[], const szKey[], const szValue[]) {
155-
if (equal(szKey, "model")) {
156-
copy(g_rgszDefaultPlayerModel[pPlayer], charsmax(g_rgszDefaultPlayerModel[]), szValue);
157-
158-
if (!equal(g_rgszCurrentPlayerModel[pPlayer], NULL_STRING)) {
159-
return FMRES_SUPERCEDE;
160-
}
211+
public HC_Player_SetAnimation(pPlayer) {
212+
@Player_UpdateAnimationModel(pPlayer);
213+
}
161214

162-
return FMRES_IGNORED;
215+
public Message_ClCorpse(iMsgId, iMsgDest, pPlayer) {
216+
new pTargetPlayer = get_msg_arg_int(12);
217+
if (@Player_ShouldUseCurrentModel(pTargetPlayer)) {
218+
set_msg_arg_string(1, g_rgszCurrentPlayerModel[pTargetPlayer]);
163219
}
164-
165-
return FMRES_IGNORED;
166220
}
167221

168-
public HC_Player_SetAnimation(pPlayer) {
169-
@Player_UpdateAnimationModel(pPlayer);
170-
}
222+
// ANCHOR: Methods
171223

172-
public @Player_UpdateAnimationModel(this) {
224+
@Player_UpdateAnimationModel(this) {
173225
static szAnimExt[32];
174226
get_member(this, m_szAnimExtention, szAnimExt, charsmax(szAnimExt));
175227

@@ -180,34 +232,44 @@ public @Player_UpdateAnimationModel(this) {
180232
}
181233
}
182234

183-
public @Player_UpdateCurrentModel(this) {
235+
@Player_UpdateCurrentModel(this) {
184236
new bool:bUsedCustom = g_rgbPlayerUseCustomModel[this];
185237

186238
g_rgbPlayerUseCustomModel[this] = !equal(g_rgszCustomPlayerModel[this], NULL_STRING);
187239

188240
if (g_rgbPlayerUseCustomModel[this]) {
189241
copy(g_rgszCurrentPlayerModel[this], charsmax(g_rgszCurrentPlayerModel[]), g_rgszCustomPlayerModel[this]);
190-
} else {
191-
if (!equal(g_rgszDefaultPlayerModel[this], NULL_STRING)) {
192-
format(g_rgszCurrentPlayerModel[this], charsmax(g_rgszCurrentPlayerModel[]), "models/player/%s/%s.mdl", g_rgszDefaultPlayerModel[this], g_rgszDefaultPlayerModel[this]);
193-
}
242+
} else if (!equal(g_rgszDefaultPlayerModel[this], NULL_STRING)) {
243+
format(g_rgszCurrentPlayerModel[this], charsmax(g_rgszCurrentPlayerModel[]), "models/player/%s/%s.mdl", g_rgszDefaultPlayerModel[this], g_rgszDefaultPlayerModel[this]);
194244
}
195245

196246
@Player_UpdateModel(this, bUsedCustom && !g_rgbPlayerUseCustomModel[this]);
197247
}
198248

199-
public @Player_UpdateModel(this, bool:bForce) {
200-
if (bForce || (g_rgbPlayerUseCustomModel[this] || g_rgiPlayerAnimationIndex[this])) {
249+
@Player_UpdateModel(this, bool:bForceUpdate) {
250+
new iSubModelModelIndex = 0;
251+
252+
if (bForceUpdate || @Player_ShouldUseCurrentModel(this)) {
201253
new iAnimationIndex = g_rgiPlayerAnimationIndex[this];
202254
new iModelIndex = engfunc(EngFunc_ModelIndex, g_rgszCurrentPlayerModel[this]);
203255
@Player_SetModelIndex(this, iAnimationIndex ? iAnimationIndex : iModelIndex);
204-
set_pev(g_pPlayerSubModel[this], pev_modelindex, iAnimationIndex ? iModelIndex : 0);
205-
} else {
206-
set_pev(g_pPlayerSubModel[this], pev_modelindex, 0);
256+
iSubModelModelIndex = iAnimationIndex ? iModelIndex : 0;
257+
}
258+
259+
if (iSubModelModelIndex && !g_pPlayerSubModel[this]) {
260+
g_pPlayerSubModel[this] = @PlayerSubModel_Create(this);
261+
}
262+
263+
if (g_pPlayerSubModel[this]) {
264+
set_pev(g_pPlayerSubModel[this], pev_modelindex, iSubModelModelIndex);
207265
}
208266
}
209267

210-
public @Player_ResetModel(this) {
268+
bool:@Player_ShouldUseCurrentModel(this) {
269+
return g_rgbPlayerUseCustomModel[this] || g_rgiPlayerAnimationIndex[this];
270+
}
271+
272+
@Player_ResetModel(this) {
211273
if (equal(g_rgszDefaultPlayerModel[this], NULL_STRING)) {
212274
return;
213275
}
@@ -219,13 +281,13 @@ public @Player_ResetModel(this) {
219281
@Player_UpdateCurrentModel(this);
220282
}
221283

222-
public @Player_SetModelIndex(this, iModelIndex) {
284+
@Player_SetModelIndex(this, iModelIndex) {
223285
set_user_info(this, "model", "");
224286
set_pev(this, pev_modelindex, iModelIndex);
225287
set_member(this, m_modelIndexPlayer, iModelIndex);
226288
}
227289

228-
public @Player_SetSequence(this, const szSequence[]) {
290+
@Player_SetSequence(this, const szSequence[]) {
229291
new iAnimationIndex = GetAnimationIndexBySequence(szSequence);
230292
if (!iAnimationIndex) {
231293
return -1;
@@ -239,22 +301,22 @@ public @Player_SetSequence(this, const szSequence[]) {
239301
return iSequence;
240302
}
241303

242-
public @PlayerSubModel_Create(pPlayer) {
243-
new this = engfunc(EngFunc_CreateNamedEntity, g_iszModelClassname);
304+
@PlayerSubModel_Create(pPlayer) {
305+
new this = engfunc(EngFunc_CreateNamedEntity, g_iszSubModelClassname);
244306
set_pev(this, pev_movetype, MOVETYPE_FOLLOW);
245307
set_pev(this, pev_aiment, pPlayer);
246308
set_pev(this, pev_owner, pPlayer);
247309

248310
return this;
249311
}
250312

251-
public @PlayerSubModel_Destroy(this) {
313+
@PlayerSubModel_Destroy(this) {
252314
set_pev(this, pev_modelindex, 0);
253315
set_pev(this, pev_flags, pev(this, pev_flags) | FL_KILLME);
254316
dllfunc(DLLFunc_Think, this);
255317
}
256318

257-
public @PlayerSubModel_Think(this) {
319+
@PlayerSubModel_Think(this) {
258320
if (!@PlayerSubModel_IsActive(this)) {
259321
set_entvar(this, var_effects, get_entvar(this, var_effects) | EF_NODRAW);
260322
return;
@@ -275,10 +337,12 @@ public @PlayerSubModel_Think(this) {
275337
set_entvar(this, var_rendercolor, rgflColor);
276338
}
277339

278-
public @PlayerSubModel_IsActive(this) {
340+
@PlayerSubModel_IsActive(this) {
279341
return (pev(this, pev_modelindex) > 0);
280342
}
281343

344+
// ANCHOR: Functions
345+
282346
GetAnimationIndexByAnimExt(const szAnimExt[]) {
283347
static szSequence[32];
284348
format(szSequence, charsmax(szSequence), "ref_aim_%s", szAnimExt);

0 commit comments

Comments
 (0)