Daemon666 / CSB Weapon Models Public

Replaces view and world weapon models from a simple ini file, applied on CurWeapon, with a per-player toggle back to default models.

v1.0.0 168 downloads GPL-3.0 Last updated Aug 23, 2026
csb_weapon_models.sma v1.0.0 164 lines · 4.5 KB Raw
1 /*
2 * CSB Weapon Models
3 * Copyright (C) 2026 counter-strike-boost.com
4 *
5 * Replaces the view (v_) and world/weapon (p_) models per weapon from a simple
6 * ini file. Models are precached at map start; on every CurWeapon the plugin
7 * writes the custom model into pev_viewmodel2 / pev_weaponmodel2. Players can
8 * toggle back to the default models for themselves.
9 *
10 * Inspired by "Weapon Model Replacement" by Emp`. This is an independent GPL
11 * re-implementation; no original code is reused.
12 *
13 * This program is free software: you can redistribute it and/or modify it under
14 * the terms of the GNU General Public License as published by the Free Software
15 * Foundation, either version 3 of the License, or (at your option) any later
16 * version. It is distributed in the hope that it will be useful, but WITHOUT ANY
17 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 * A PARTICULAR PURPOSE. See <https://www.gnu.org/licenses/> for details.
19 */
20
21 #include <amxmodx>
22 #include <amxmisc>
23 #include <fakemeta>
24
25 new const PLUGIN[] = "CSB Weapon Models"
26 new const VERSION[] = "1.0.0"
27 new const AUTHOR[] = "counter-strike-boost.com"
28
29 #define MAX_WEAPONS 31
30 #define INI_FILE "csb_weapon_models.ini"
31
32 new g_szView[MAX_WEAPONS + 1][64]
33 new g_szWorld[MAX_WEAPONS + 1][64]
34 new bool:g_bDefault[33]
35
36 new g_pEnabled
37
38 /* human-friendly names accepted in the ini, mapped to CSW_* ids */
39 new const g_szNames[][] =
40 {
41 "knife", "usp", "glock", "glock18", "deagle", "p228", "elite",
42 "fiveseven", "m4a1", "ak47", "awp", "scout", "aug", "sg552",
43 "galil", "famas", "m3", "xm1014", "mp5", "mp5navy", "tmp", "mac10",
44 "ump45", "p90", "m249", "sg550", "g3sg1"
45 }
46
47 new const g_iNameCsw[] =
48 {
49 CSW_KNIFE, CSW_USP, CSW_GLOCK18, CSW_GLOCK18, CSW_DEAGLE, CSW_P228, CSW_ELITE,
50 CSW_FIVESEVEN, CSW_M4A1, CSW_AK47, CSW_AWP, CSW_SCOUT, CSW_AUG, CSW_SG552,
51 CSW_GALIL, CSW_FAMAS, CSW_M3, CSW_XM1014, CSW_MP5NAVY, CSW_MP5NAVY, CSW_TMP, CSW_MAC10,
52 CSW_UMP45, CSW_P90, CSW_M249, CSW_SG550, CSW_G3SG1
53 }
54
55 public plugin_init()
56 {
57 register_plugin(PLUGIN, VERSION, AUTHOR)
58
59 g_pEnabled = register_cvar("csb_wmodels_enabled", "1")
60
61 register_clcmd("say /wmodels", "cmdToggle")
62 register_clcmd("say_team /wmodels", "cmdToggle")
63
64 register_event("CurWeapon", "fwCurWeapon", "be", "1=1")
65 }
66
67 public plugin_precache()
68 {
69 loadModels()
70 }
71
72 loadModels()
73 {
74 new configsDir[128], path[192]
75 get_configsdir(configsDir, charsmax(configsDir))
76 formatex(path, charsmax(path), "%s/%s", configsDir, INI_FILE)
77
78 if (!file_exists(path))
79 {
80 log_amx("[CSB Weapon Models] %s not found - no custom models loaded.", path)
81 return
82 }
83
84 new line[192], name[32], vmodel[64], pmodel[64], lineNum = 0, loaded = 0, tlen
85
86 while (read_file(path, lineNum++, line, charsmax(line), tlen))
87 {
88 trim(line)
89
90 if (!line[0] || line[0] == ';' || line[0] == '/' || line[0] == '#')
91 continue
92
93 /* format: <weaponname> <v_model.mdl> <p_model.mdl> */
94 new count = parse(line, name, charsmax(name), vmodel, charsmax(vmodel), pmodel, charsmax(pmodel))
95
96 if (count < 2)
97 continue
98
99 new csw = nameToCsw(name)
100
101 if (csw < 0)
102 continue
103
104 if (vmodel[0] && file_exists(vmodel))
105 {
106 precache_model(vmodel)
107 copy(g_szView[csw], charsmax(g_szView[]), vmodel)
108 }
109
110 if (count >= 3 && pmodel[0] && file_exists(pmodel))
111 {
112 precache_model(pmodel)
113 copy(g_szWorld[csw], charsmax(g_szWorld[]), pmodel)
114 }
115
116 loaded++
117 }
118
119 log_amx("[CSB Weapon Models] loaded %d weapon model entries.", loaded)
120 }
121
122 nameToCsw(const name[])
123 {
124 for (new i = 0; i < sizeof(g_szNames); i++)
125 {
126 if (equali(name, g_szNames[i]))
127 return g_iNameCsw[i]
128 }
129
130 return -1
131 }
132
133 public client_putinserver(id)
134 {
135 g_bDefault[id] = false
136 }
137
138 public cmdToggle(id)
139 {
140 g_bDefault[id] = !g_bDefault[id]
141
142 client_print(id, print_chat, "[CSB] Custom weapon models are now %s for you.",
143 g_bDefault[id] ? "OFF (default models)" : "ON")
144
145 return PLUGIN_HANDLED
146 }
147
148 public fwCurWeapon(id)
149 {
150 if (!get_pcvar_num(g_pEnabled) || g_bDefault[id] || !is_user_alive(id))
151 return
152
153 new csw = read_data(2)
154
155 if (csw < 1 || csw > MAX_WEAPONS)
156 return
157
158 if (g_szView[csw][0])
159 set_pev(id, pev_viewmodel2, engfunc(EngFunc_AllocString, g_szView[csw]))
160
161 if (g_szWorld[csw][0])
162 set_pev(id, pev_weaponmodel2, engfunc(EngFunc_AllocString, g_szWorld[csw]))
163 }
164