Skip to content

Commit e0225f6

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

File tree

1 file changed

+112
-49
lines changed

1 file changed

+112
-49
lines changed

api_player_model.sma

Lines changed: 112 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,44 @@
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

1010
#define MAX_SEQUENCES 101
11+
#define USER_NOT_CONNECTED_MESSAGE "User %d is not connected"
1112

12-
new g_iszModelClassname;
13+
new g_iszSubModelClassname;
1314

1415
new g_rgszDefaultPlayerModel[MAX_PLAYERS + 1][32];
1516
new g_rgszCurrentPlayerModel[MAX_PLAYERS + 1][256];
1617
new g_rgszCustomPlayerModel[MAX_PLAYERS + 1][256];
1718
new g_rgiPlayerAnimationIndex[MAX_PLAYERS + 1];
19+
new g_pPlayerSubModel[MAX_PLAYERS + 1];
1820
new bool:g_rgbPlayerUseCustomModel[MAX_PLAYERS + 1];
1921

2022
new Trie:g_itPlayerSequenceModelIndexes = Invalid_Trie;
2123
new Trie:g_itPlayerSequences = Invalid_Trie;
22-
new g_pPlayerSubModel[MAX_PLAYERS + 1];
23-
24-
new gmsgClCorpse;
2524

2625
public plugin_precache() {
27-
g_iszModelClassname = engfunc(EngFunc_AllocString, "info_target");
26+
g_iszSubModelClassname = engfunc(EngFunc_AllocString, "info_target");
2827
g_itPlayerSequenceModelIndexes = TrieCreate();
2928
g_itPlayerSequences = TrieCreate();
3029
}
3130

3231
public plugin_init() {
3332
register_plugin(PLUGIN, VERSION, AUTHOR);
3433

35-
gmsgClCorpse = get_user_msgid("ClCorpse");
36-
3734
register_forward(FM_SetClientKeyValue, "FMHook_SetClientKeyValue");
3835

3936
RegisterHamPlayer(Ham_Spawn, "HamHook_Player_Spawn_Post", .Post = 1);
4037
RegisterHamPlayer(Ham_Player_PostThink, "HamHook_Player_PostThink_Post", .Post = 1);
4138

4239
RegisterHookChain(RG_CBasePlayer_SetAnimation, "HC_Player_SetAnimation");
4340

44-
register_message(gmsgClCorpse, "Message_ClCorpse");
41+
register_message(get_user_msgid("ClCorpse"), "Message_ClCorpse");
4542
}
4643

4744
public plugin_natives() {
@@ -57,19 +54,43 @@ public plugin_natives() {
5754
register_native("PlayerModel_PrecacheAnimation", "Native_PrecacheAnimation");
5855
}
5956

57+
public plugin_end() {
58+
TrieDestroy(g_itPlayerSequenceModelIndexes);
59+
TrieDestroy(g_itPlayerSequences);
60+
}
61+
62+
// ANCHOR: Natives
63+
6064
public Native_GetPlayerModel(iPluginId, iArgc) {
6165
new pPlayer = get_param(1);
66+
67+
if (!is_user_connected(pPlayer)) {
68+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
69+
return;
70+
}
71+
6272
set_string(2, g_rgszCustomPlayerModel[pPlayer], get_param(3));
6373
}
6474

6575
public Native_GetCurrentPlayerModel(iPluginId, iArgc) {
6676
new pPlayer = get_param(1);
77+
78+
if (!is_user_connected(pPlayer)) {
79+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
80+
return;
81+
}
82+
6783
set_string(2, g_rgszCurrentPlayerModel[pPlayer], get_param(3));
6884
}
6985

7086
public Native_GetPlayerEntity(iPluginId, iArgc) {
7187
new pPlayer = get_param(1);
7288

89+
if (!is_user_connected(pPlayer)) {
90+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
91+
return 0;
92+
}
93+
7394
if (g_pPlayerSubModel[pPlayer] && @PlayerSubModel_IsActive(g_pPlayerSubModel[pPlayer])) {
7495
return g_pPlayerSubModel[pPlayer];
7596
}
@@ -80,27 +101,55 @@ public Native_GetPlayerEntity(iPluginId, iArgc) {
80101
public bool:Native_HasCustomPlayerModel(iPluginId, iArgc) {
81102
new pPlayer = get_param(1);
82103

104+
if (!is_user_connected(pPlayer)) {
105+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
106+
return false;
107+
}
108+
83109
return g_rgbPlayerUseCustomModel[pPlayer];
84110
}
85111

86112
public Native_SetPlayerModel(iPluginId, iArgc) {
87113
new pPlayer = get_param(1);
114+
115+
if (!is_user_connected(pPlayer)) {
116+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
117+
return;
118+
}
119+
88120
get_string(2, g_rgszCustomPlayerModel[pPlayer], charsmax(g_rgszCustomPlayerModel[]));
89121
}
90122

91123
public Native_ResetPlayerModel(iPluginId, iArgc) {
92124
new pPlayer = get_param(1);
125+
126+
if (!is_user_connected(pPlayer)) {
127+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
128+
return;
129+
}
130+
93131
@Player_ResetModel(pPlayer);
94132
}
95133

96134
public Native_UpdatePlayerModel(iPluginId, iArgc) {
97135
new pPlayer = get_param(1);
136+
137+
if (!is_user_connected(pPlayer)) {
138+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
139+
return;
140+
}
141+
98142
@Player_UpdateCurrentModel(pPlayer);
99143
}
100144

101145
public Native_SetPlayerSequence(iPluginId, iArgc) {
102146
new pPlayer = get_param(1);
103147

148+
if (!is_user_connected(pPlayer)) {
149+
log_error(AMX_ERR_NATIVE, USER_NOT_CONNECTED_MESSAGE, pPlayer);
150+
return 0;
151+
}
152+
104153
static szSequence[MAX_RESOURCE_PATH_LENGTH];
105154
get_string(2, szSequence, charsmax(szSequence));
106155

@@ -113,6 +162,8 @@ public Native_PrecacheAnimation(iPluginId, iArgc) {
113162
return PrecachePlayerAnimation(szAnimation);
114163
}
115164

165+
// ANCHOR: Hooks and Forwards
166+
116167
public client_connect(pPlayer) {
117168
copy(g_rgszCustomPlayerModel[pPlayer], charsmax(g_rgszCustomPlayerModel[]), NULL_STRING);
118169
copy(g_rgszDefaultPlayerModel[pPlayer], charsmax(g_rgszDefaultPlayerModel[]), NULL_STRING);
@@ -128,19 +179,24 @@ public client_disconnected(pPlayer) {
128179
}
129180
}
130181

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]);
182+
public FMHook_SetClientKeyValue(pPlayer, const szInfoBuffer[], const szKey[], const szValue[]) {
183+
if (equal(szKey, "model")) {
184+
copy(g_rgszDefaultPlayerModel[pPlayer], charsmax(g_rgszDefaultPlayerModel[]), szValue);
185+
186+
if (!equal(g_rgszCurrentPlayerModel[pPlayer], NULL_STRING)) {
187+
return FMRES_SUPERCEDE;
188+
}
189+
190+
return FMRES_HANDLED;
135191
}
192+
193+
return FMRES_IGNORED;
136194
}
137195

138196
public HamHook_Player_Spawn_Post(pPlayer) {
139-
if (!g_pPlayerSubModel[pPlayer]) {
140-
g_pPlayerSubModel[pPlayer] = @PlayerSubModel_Create(pPlayer);
141-
}
142-
143197
@Player_UpdateCurrentModel(pPlayer);
198+
199+
return HAM_HANDLED;
144200
}
145201

146202
public HamHook_Player_PostThink_Post(pPlayer) {
@@ -151,25 +207,20 @@ public HamHook_Player_PostThink_Post(pPlayer) {
151207
return HAM_HANDLED;
152208
}
153209

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-
}
210+
public HC_Player_SetAnimation(pPlayer) {
211+
@Player_UpdateAnimationModel(pPlayer);
212+
}
161213

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

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

172-
public @Player_UpdateAnimationModel(this) {
223+
@Player_UpdateAnimationModel(this) {
173224
static szAnimExt[32];
174225
get_member(this, m_szAnimExtention, szAnimExt, charsmax(szAnimExt));
175226

@@ -180,34 +231,44 @@ public @Player_UpdateAnimationModel(this) {
180231
}
181232
}
182233

183-
public @Player_UpdateCurrentModel(this) {
234+
@Player_UpdateCurrentModel(this) {
184235
new bool:bUsedCustom = g_rgbPlayerUseCustomModel[this];
185236

186237
g_rgbPlayerUseCustomModel[this] = !equal(g_rgszCustomPlayerModel[this], NULL_STRING);
187238

188239
if (g_rgbPlayerUseCustomModel[this]) {
189240
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-
}
241+
} else if (!equal(g_rgszDefaultPlayerModel[this], NULL_STRING)) {
242+
format(g_rgszCurrentPlayerModel[this], charsmax(g_rgszCurrentPlayerModel[]), "models/player/%s/%s.mdl", g_rgszDefaultPlayerModel[this], g_rgszDefaultPlayerModel[this]);
194243
}
195244

196245
@Player_UpdateModel(this, bUsedCustom && !g_rgbPlayerUseCustomModel[this]);
197246
}
198247

199-
public @Player_UpdateModel(this, bool:bForce) {
200-
if (bForce || (g_rgbPlayerUseCustomModel[this] || g_rgiPlayerAnimationIndex[this])) {
248+
@Player_UpdateModel(this, bool:bForceUpdate) {
249+
new iSubModelModelIndex = 0;
250+
251+
if (bForceUpdate || @Player_ShouldUseCurrentModel(this)) {
201252
new iAnimationIndex = g_rgiPlayerAnimationIndex[this];
202253
new iModelIndex = engfunc(EngFunc_ModelIndex, g_rgszCurrentPlayerModel[this]);
203254
@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);
255+
iSubModelModelIndex = iAnimationIndex ? iModelIndex : 0;
256+
}
257+
258+
if (iSubModelModelIndex && !g_pPlayerSubModel[this]) {
259+
g_pPlayerSubModel[this] = @PlayerSubModel_Create(this);
260+
}
261+
262+
if (g_pPlayerSubModel[this]) {
263+
set_pev(g_pPlayerSubModel[this], pev_modelindex, iSubModelModelIndex);
207264
}
208265
}
209266

210-
public @Player_ResetModel(this) {
267+
bool:@Player_ShouldUseCurrentModel(this) {
268+
return g_rgbPlayerUseCustomModel[this] || g_rgiPlayerAnimationIndex[this];
269+
}
270+
271+
@Player_ResetModel(this) {
211272
if (equal(g_rgszDefaultPlayerModel[this], NULL_STRING)) {
212273
return;
213274
}
@@ -219,13 +280,13 @@ public @Player_ResetModel(this) {
219280
@Player_UpdateCurrentModel(this);
220281
}
221282

222-
public @Player_SetModelIndex(this, iModelIndex) {
283+
@Player_SetModelIndex(this, iModelIndex) {
223284
set_user_info(this, "model", "");
224285
set_pev(this, pev_modelindex, iModelIndex);
225286
set_member(this, m_modelIndexPlayer, iModelIndex);
226287
}
227288

228-
public @Player_SetSequence(this, const szSequence[]) {
289+
@Player_SetSequence(this, const szSequence[]) {
229290
new iAnimationIndex = GetAnimationIndexBySequence(szSequence);
230291
if (!iAnimationIndex) {
231292
return -1;
@@ -239,22 +300,22 @@ public @Player_SetSequence(this, const szSequence[]) {
239300
return iSequence;
240301
}
241302

242-
public @PlayerSubModel_Create(pPlayer) {
243-
new this = engfunc(EngFunc_CreateNamedEntity, g_iszModelClassname);
303+
@PlayerSubModel_Create(pPlayer) {
304+
new this = engfunc(EngFunc_CreateNamedEntity, g_iszSubModelClassname);
244305
set_pev(this, pev_movetype, MOVETYPE_FOLLOW);
245306
set_pev(this, pev_aiment, pPlayer);
246307
set_pev(this, pev_owner, pPlayer);
247308

248309
return this;
249310
}
250311

251-
public @PlayerSubModel_Destroy(this) {
312+
@PlayerSubModel_Destroy(this) {
252313
set_pev(this, pev_modelindex, 0);
253314
set_pev(this, pev_flags, pev(this, pev_flags) | FL_KILLME);
254315
dllfunc(DLLFunc_Think, this);
255316
}
256317

257-
public @PlayerSubModel_Think(this) {
318+
@PlayerSubModel_Think(this) {
258319
if (!@PlayerSubModel_IsActive(this)) {
259320
set_entvar(this, var_effects, get_entvar(this, var_effects) | EF_NODRAW);
260321
return;
@@ -275,10 +336,12 @@ public @PlayerSubModel_Think(this) {
275336
set_entvar(this, var_rendercolor, rgflColor);
276337
}
277338

278-
public @PlayerSubModel_IsActive(this) {
339+
@PlayerSubModel_IsActive(this) {
279340
return (pev(this, pev_modelindex) > 0);
280341
}
281342

343+
// ANCHOR: Functions
344+
282345
GetAnimationIndexByAnimExt(const szAnimExt[]) {
283346
static szSequence[32];
284347
format(szSequence, charsmax(szSequence), "ref_aim_%s", szAnimExt);

0 commit comments

Comments
 (0)