const ClCorpse_ModelName = 1
const ClCorpse_PlayerID = 12
const g_ulModelIndexPlayer = 491
new const MODEL[] = "model"
new const g_szMapEntitys[][] = {"cycler_sprite", "cycler", "armoury_entity"}
new const g_szDefaultModels[][] = {"", "urban", "terror", "leet", "arctic",
"gsg9", "gign", "sas", "guerilla", "vip", "militia", "spetsnaz"
new const g_szWeaponNames[CSW_P90+1][] = {"","p228","","scout","hegrenade","xm1014","c4","mac10",
"aug","smokegrenade","elite","fiveseven","ump45","sg550","galil","famas","usp","glock18","awp",
"mp5navy","m249","m3","m4a1","tmp","g3sg1","flashbang","deagle","sg552","ak47","knife","p90"
new g_iWeaponIds[CSW_P90+1]
new Trie:g_tDefaultModels, Trie:g_tModelIndexes, Trie:g_tMapModels
new Trie:g_tViewModels, Trie:g_tWeaponModels, Trie:g_tWorldModels
new g_bConnected, g_bModeled, g_iMaxPlayers, bool:g_bPlayerModels
new g_szCurrentModel[MAX_PLAYERS+1][MAX_MODEL_LEN]
register_plugin("Models Replacement", VERSION, "ConnorMcLeod | Vaqtincha")
register_forward(FM_SetClientKeyValue, "SetClientKeyValue_Pre", 0)
register_message(get_user_msgid("ClCorpse"), "Message_ClCorpse")
register_forward(FM_SetModel, "SetModel_Pre", 0)
g_iMaxPlayers = get_maxplayers()
new szConfigFile[MAX_PATH_LEN]
get_localinfo("amxx_configsdir", szConfigFile, charsmax(szConfigFile))
add(szConfigFile, charsmax(szConfigFile), "/models_replacement.ini")
if(file_exists(szConfigFile))
new iFile = fopen(szConfigFile, "rt")
set_fail_state("[MODELS_REPLACEMENT] ERROR: Failed reading file!")
new szDatas[MAX_BUFFER_LEN + 10], szWeaponClass[32], iId, c
new szOldModel[MAX_MODEL_LEN], szNewModel[MAX_MODEL_LEN]
new Trie:tRegisterWeaponDeploy = TrieCreate()
new Trie:tWeaponsIds = TrieCreate()
g_tModelIndexes = TrieCreate()
g_tDefaultModels = TrieCreate()
for(new i = 1; i<sizeof(g_szDefaultModels); i++)
TrieSetCell(g_tDefaultModels, g_szDefaultModels[i], i)
for(new i = CSW_P228; i <= CSW_P90; i++)
TrieSetCell(tWeaponsIds, g_szWeaponNames[i], g_iWeaponIds[i])
fgets(iFile, szDatas, charsmax(szDatas))
if(!(c = szDatas[0]) || c == ';' || c == '#')
if(parse(szDatas, szOldModel, charsmax(szOldModel), szNewModel, charsmax(szNewModel)) != 2)
if(!szOldModel[0] || !szNewModel[0] || equal(szNewModel, szOldModel))
if(TrieKeyExists(g_tDefaultModels, szOldModel))
if(PrecachePlayerModel(szNewModel))
TrieSetString(g_tDefaultModels, szOldModel, szNewModel)
if(((c = szOldModel[0]) == 'p' || c == 'v' ) && szOldModel[1] == '_')
if(equal(szOldModel[2], "mp5", 3))
copy(szWeaponClass, charsmax(szWeaponClass), "weapon_mp5navy")
formatex(szWeaponClass, charsmax(szWeaponClass), "weapon_%s", szOldModel[2])
if(!TrieGetCell(tWeaponsIds, szWeaponClass[7], iId))
server_print("[MODELS_REPLACEMENT] WARNING: Invalid weapon class ^"%s^" will be skipped!", szWeaponClass)
if(!TrieKeyExists(tRegisterWeaponDeploy, szWeaponClass))
RegisterHam(Ham_Item_Deploy, szWeaponClass, "ItemDeploy_Post", true)
format(szNewModel, charsmax(szNewModel), "models/%s.mdl", szNewModel)
g_tViewModels = TrieCreate()
if(PrecacheWeaponModel(szNewModel))
TrieSetCell(g_tViewModels, szWeaponClass, AllocString(szNewModel))
g_tWeaponModels = TrieCreate()
if(PrecacheWeaponModel(szNewModel))
TrieSetCell(g_tWeaponModels, szWeaponClass, AllocString(szNewModel))
format(szOldModel, charsmax(szOldModel), "models/%s.mdl", szOldModel)
format(szNewModel, charsmax(szNewModel), "models/%s.mdl", szNewModel)
g_tWorldModels = TrieCreate()
else if(TrieKeyExists(g_tWorldModels, szOldModel))
if(PrecacheWeaponModel(szNewModel))
TrieSetString(g_tWorldModels, szOldModel, szNewModel)
g_tMapModels = TrieCreate()
if(PrecacheWeaponModel(szNewModel))
TrieSetString(g_tMapModels, szOldModel, szNewModel)
TrieDestroy(tRegisterWeaponDeploy)
new iFile = fopen(szConfigFile, "w")
set_fail_state("[MODELS_REPLACEMENT] ERROR: Failed creating file!")
fputs(iFile, "^n; Format: ^"old model^" ^"new model^" (without 'models/' & '.mdl')^n;^n; Examples:^n")
fputs(iFile, "^n; ^"arctic^" ^"vip^"^n; ^"chick^" ^"winebottle^"")
fputs(iFile, "^n; ^"v_awp^" ^"custom/v_awp^"^n; ^"p_awp^" ^"custom/p_awp^"^n; ^"w_awp^" ^"custom/w_awp^"")
public client_putinserver(id)
public client_disconnect(id)
public ItemDeploy_Post(wEnt)
new id = get_pdata_cbase(wEnt, m_pPlayer, .linuxdiff = 4)
new iszNewModel, szWeaponClass[32]
pev(wEnt, pev_classname, szWeaponClass, charsmax(szWeaponClass))
if(g_tViewModels && TrieGetCell(g_tViewModels, szWeaponClass, iszNewModel))
set_pev(id, pev_viewmodel, iszNewModel)
if(g_tWeaponModels && TrieGetCell(g_tWeaponModels, szWeaponClass, iszNewModel))
set_pev(id, pev_weaponmodel, iszNewModel)
public SetModel_Pre(iEnt, const szModel[])
new szNewModel[MAX_MODEL_LEN]
if(TrieGetString(g_tWorldModels, szModel, szNewModel, charsmax(szNewModel)))
SetModel(iEnt, szNewModel)
public SetClientKeyValue_Pre(id, const szInfoBuffer[], const szKey[], const szValue[])
if(!equal(szKey, MODEL) || !IsUserConnected(id) || !UserValidTeam(id))
new szSupposedModel[MAX_MODEL_LEN]
if(TrieGetString(g_tDefaultModels, szValue, szSupposedModel, charsmax(szSupposedModel)))
if(!IsUserModeled(id) || !equal(g_szCurrentModel[id], szSupposedModel) || !equal(szValue, szSupposedModel))
copy(g_szCurrentModel[id], MAX_MODEL_LEN-1, szSupposedModel)
set_user_info(id, MODEL, szSupposedModel)
TrieGetCell(g_tModelIndexes, szSupposedModel, iModelIndex)
// set_pev(id, pev_modelindex, iModelIndex); // is this needed ?
set_pdata_int(id, g_ulModelIndexPlayer, iModelIndex)
g_szCurrentModel[id][0] = 0
public Message_ClCorpse()
new id = get_msg_arg_int(ClCorpse_PlayerID)
set_msg_arg_string(ClCorpse_ModelName, g_szCurrentModel[id])
TrieDestroy(g_tModelIndexes)
TrieDestroy(g_tViewModels)
TrieDestroy(g_tWeaponModels)
TrieDestroy(g_tWorldModels)
TrieDestroy(g_tMapModels)
new szSupposedModel[MAX_MODEL_LEN], szModel[MAX_MODEL_LEN]
for(new i = 0; i <sizeof(g_szMapEntitys); i++)
while((iEnt = engfunc(EngFunc_FindEntityByString, iEnt, "classname", g_szMapEntitys[i])))
pev(iEnt, pev_model, szModel, charsmax(szModel))
if(TrieGetString(g_tMapModels, szModel, szSupposedModel, charsmax(szSupposedModel)))
SetModel(iEnt, szSupposedModel)
PrecacheWeaponModel(const szModel[])
new szMsg[MAX_MODEL_LEN + 64]
if(!file_exists(szModel))
formatex(szMsg, charsmax(szMsg), "[MODELS_REPLACEMENT] ERROR: Model ^"%s^" not found!", szModel)
PrecachePlayerModel(const szModel[])
if(TrieKeyExists(g_tModelIndexes, szModel) || TrieKeyExists(g_tDefaultModels, szModel))
new szFileToPrecache[64], szMsg[MAX_MODEL_LEN + 64]
formatex(szFileToPrecache, charsmax(szFileToPrecache), "models/player/%s/%s.mdl", szModel, szModel)
if(!file_exists(szFileToPrecache))
formatex(szMsg, charsmax(szMsg), "[MODELS_REPLACEMENT] ERROR: Player model ^"%s^" not found!", szFileToPrecache)
TrieSetCell(g_tModelIndexes, szModel, precache_model(szFileToPrecache))
formatex(szFileToPrecache, charsmax(szFileToPrecache), "models/player/%s/%st.mdl", szModel, szModel)
if(file_exists(szFileToPrecache))
precache_model(szFileToPrecache)
formatex(szFileToPrecache, charsmax(szFileToPrecache), "models/player/%s/%sT.mdl", szModel, szModel)
if(file_exists(szFileToPrecache))
precache_model(szFileToPrecache)