HLMOD.HU Forrás Megtekintés - www.hlmod.hu
  1. #include <amxmodx>
  2. #include <amxmisc>
  3. #include <engine>
  4. #include <cstrike>
  5. #include <fakemeta_util>
  6. #include <hamsandwich>
  7.  
  8. #define CSW_THIGHPACK 0
  9. #define CSW_SHIELD 2
  10. #define CSW_BACKPACK 32
  11.  
  12. // Offsets
  13. const OFFSET_USE_STOPPED = 0;
  14. const OFFSET_PDATA = 2;
  15. const OFFSET_LINUX_WEAPONS = 4;
  16. const OFFSET_LINUX = 5;
  17. const OFFSET_WEAPON_OWNER = 41;
  18. const OFFSET_ID = 43;
  19. const OFFSET_NEXT_PRIMARY_ATTACK = 46;
  20. const OFFSET_NEXT_SECONDARY_ATTACK = 47;
  21. const OFFSET_TIME_WEAPON_IDLE = 48;
  22. const OFFSET_IN_RELOAD = 54;
  23. const OFFSET_IN_SPECIAL_RELOAD = 55;
  24. const OFFSET_NEXT_ATTACK = 83;
  25. const OFFSET_FOV = 363;
  26. const OFFSET_ACTIVE_ITEM = 373;
  27.  
  28. new const g_customization_file_cfg[] = "weapon_modifier.cfg"
  29. new const g_customization_file_ini[] = "weapon_modifier.ini"
  30.  
  31. new const g_weapon_ent_names[][] = {"", "weapon_p228", "", "weapon_scout", "", "weapon_xm1014", "", "weapon_mac10",
  32. "weapon_aug", "", "weapon_elite", "weapon_fiveseven", "weapon_ump45", "weapon_sg550", "weapon_galil", "weapon_famas", "weapon_usp", "weapon_glock18",
  33. "weapon_awp", "weapon_mp5navy", "weapon_m249", "weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "", "weapon_deagle", "weapon_sg552",
  34. "weapon_ak47", "weapon_knife", "weapon_p90", "all"};
  35.  
  36. new const g_weapon_ent_names_all[][] = {"weapon_thighpack", "weapon_p228", "weapon_shield", "weapon_scout", "weapon_hegrenade", "weapon_xm1014", "weapon_c4",
  37. "weapon_mac10", "weapon_aug", "weapon_smokegrenade", "weapon_elite", "weapon_fiveseven", "weapon_ump45", "weapon_sg550", "weapon_galil", "weapon_famas", "weapon_usp",
  38. "weapon_glock18", "weapon_awp", "weapon_mp5navy", "weapon_m249", "weapon_m3", "weapon_m4a1", "weapon_tmp", "weapon_g3sg1", "weapon_flashbang", "weapon_deagle",
  39. "weapon_sg552", "weapon_ak47", "weapon_knife", "weapon_p90", "w_backpack"};
  40.  
  41. new const g_model_default[][] = {"models/w_thighpack.mdl", "models/w_p228.mdl", "models/w_shield.mdl", "models/w_scout.mdl", "models/w_hegrenade.mdl",
  42. "models/w_xm1014.mdl", "models/w_c4.mdl", "models/w_mac10.mdl", "models/w_aug.mdl", "models/w_smokegrenade.mdl", "models/w_elite.mdl", "models/w_fiveseven.mdl",
  43. "models/w_ump45.mdl", "models/w_sg550.mdl", "models/w_galil.mdl", "models/w_famas.mdl", "models/w_usp.mdl", "models/w_glock18.mdl", "models/w_awp.mdl",
  44. "models/w_mp5.mdl", "models/w_m249.mdl", "models/w_m3.mdl", "models/w_m4a1.mdl", "models/w_tmp.mdl", "models/w_g3sg1.mdl", "models/w_flashbang.mdl",
  45. "models/w_deagle.mdl", "models/w_sg552.mdl", "models/w_ak47.mdl", "models/w_knife.mdl", "models/w_p90.mdl", "models/w_backpack.mdl"};
  46.  
  47. new const g_max_bpammo[] = {-1, 52, -1, 90, 1, 32, 1, 100, 90, 1, 120, 100, 100, 90, 90, 90, 100, 120, 30, 120, 200, 32, 90, 120, 90, 2, 35, 90, 90, -1, 100};
  48. new const g_max_clip[] = {-1, 13, -1, 10, -1, 7, -1, 30, 30, -1, 30, 20, 25, 30, 35, 25, 12, 20, 10, 30, 100, 8, 30, 30, 20, -1, 7, 30, 30, -1, 50};
  49. new const g_ammo_type[][] = {"", "357sig", "", "762nato", "", "buckshot", "", "45acp", "556nato", "", "9mm", "57mm", "45acp", "556nato", "556nato", "556nato", "45acp",
  50. "9mm", "338magnum", "9mm", "556natobox", "buckshot", "556nato", "9mm", "762nato", "", "50ae", "556nato", "762nato", "", "57mm"};
  51. new const g_ammo_weapon[] = {0, CSW_AWP, CSW_SCOUT, CSW_M249, CSW_AUG, CSW_XM1014, CSW_MAC10, CSW_FIVESEVEN, CSW_DEAGLE, CSW_P228, CSW_ELITE, CSW_FLASHBANG,
  52. CSW_HEGRENADE, CSW_SMOKEGRENADE, CSW_C4};
  53. new const SECONDARY_WEAPONS_BIT_SUM = (1 << CSW_P228)|(1 << CSW_ELITE)|(1 << CSW_FIVESEVEN)|(1 << CSW_USP)|(1 << CSW_GLOCK18)|(1 << CSW_DEAGLE)
  54. new const SHOTGUN_WEAPONS_BIT_SUM = (1 << CSW_M3)|(1 << CSW_XM1014)
  55. new const ALREADY_SECONDARY_ATTACK = (1 << CSW_KNIFE)|(1 << CSW_USP)|(1 << CSW_GLOCK18)|(1 << CSW_FAMAS)|(1 << CSW_M4A1)
  56.  
  57. new const g_sound_knife_default[][] = {
  58. "weapons/knife_deploy1.wav",
  59. "weapons/knife_hit1.wav",
  60. "weapons/knife_hit2.wav",
  61. "weapons/knife_hit3.wav",
  62. "weapons/knife_hit4.wav",
  63. "weapons/knife_hitwall1.wav",
  64. "weapons/knife_slash1.wav",
  65. "weapons/knife_slash2.wav",
  66. "weapons/knife_stab.wav"
  67. };
  68.  
  69. enum()
  70. {
  71. WEAPON_DAMAGE = 0,
  72. WEAPON_RECOIL,
  73. WEAPON_SPEED,
  74. WEAPON_W_GLOW,
  75. WEAPON_P_GLOW,
  76. WEAPON_UNLIMITED_CLIP,
  77. WEAPON_UNLIMITED_BPAMMO,
  78. WEAPON_KNOCKBACK,
  79. WEAPON_AUTO_FIRE,
  80. WEAPON_ZOOM,
  81.  
  82. MAX_WM
  83. };
  84. new g_cvar_weapon[CSW_P90+3][MAX_WM];
  85. new g_cvar_knockback;
  86. new g_cvar_knockback_zvel;
  87. new g_cvar_knockback_dist;
  88. new g_pcvar_ff;
  89.  
  90. enum()
  91. {
  92. V_ = 0,
  93. P_,
  94. W_,
  95.  
  96. ALL_MODELS
  97. };
  98. new g_model_weapon[ALL_MODELS][CSW_P90+2][128];
  99. new g_sound_weapon[sizeof(g_sound_knife_default)][128];
  100.  
  101. new g_ent_weaponmodel[33];
  102. new g_has_ammo[33];
  103. new g_weapon[33];
  104.  
  105. new Trie:g_trie_wmodel;
  106.  
  107. new g_msg_curweapon;
  108. new g_msg_ammopickup;
  109.  
  110. new g_maxplayers;
  111.  
  112. #define is_user_valid_connected(%1) (1 <= %1 <= g_maxplayers && is_user_connected(%1))
  113. public plugin_precache()
  114. {
  115. fn_load_customization();
  116. }
  117. public plugin_init()
  118. {
  119. new plugin_name[] = "Weapon Modifier";
  120. new plugin_version[] = "v1.56";
  121. new plugin_author[] = "Kiske";
  122.  
  123. new i;
  124. new j;
  125. new buffer[64];
  126.  
  127. new wm_cvars[][] = {"damage", "recoil", "speed", "wglow", "pglow", "unclip", "unbpammo", "kb", "autofire", "zoom"};
  128.  
  129. register_plugin(plugin_name, plugin_version, plugin_author);
  130.  
  131. register_event("AmmoX", "event_AmmoX", "be");
  132.  
  133. RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage");
  134. RegisterHam(Ham_Killed, "player", "fw_PlayerKilled");
  135. RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack");
  136. RegisterHam(Ham_AddPlayerItem, "player", "fw_AddPlayerItem");
  137. RegisterHam(Ham_Use, "func_tank", "fw_UseStationary_Post", 1);
  138. RegisterHam(Ham_Use, "func_tankmortar", "fw_UseStationary_Post", 1);
  139. RegisterHam(Ham_Use, "func_tankrocket", "fw_UseStationary_Post", 1);
  140. RegisterHam(Ham_Use, "func_tanklaser", "fw_UseStationary_Post", 1);
  141.  
  142. // Register CVARS
  143. for(i = 0; i < CSW_P90+2; i++)
  144. {
  145. // Get Weapon and Change Models
  146. if(i != 0 && i != 2 && i != 31) // weapon_thighpack(0) , weapon_shield (2) and w_backpack(31)
  147. RegisterHam(Ham_Item_Deploy, g_weapon_ent_names_all[i], "fw_Item_Deploy_Post", 1);
  148.  
  149. if(g_weapon_ent_names[i][0])
  150. {
  151. // Recoil , Speed , Auto Fire Pistol and Zoom
  152. if(i != 31) // all is 31
  153. {
  154. RegisterHam(Ham_Weapon_PrimaryAttack, g_weapon_ent_names[i], "fw_Weapon_PrimaryAttack_Post", 1); // Recoil , Speed and Auto Fire Pistol
  155.  
  156. // Zoom
  157. if(!((1 << i) & ALREADY_SECONDARY_ATTACK))
  158. {
  159. RegisterHam(Ham_Item_PostFrame, g_weapon_ent_names[i], "fw_Item_PostFrame");
  160. RegisterHam(Ham_Item_Holster, g_weapon_ent_names[i], "fw_Item_Holster");
  161. RegisterHam(Ham_CS_Item_GetMaxSpeed, g_weapon_ent_names[i], "fw_CS_Item_GetMaxSpeed");
  162. RegisterHam(Ham_Weapon_Reload, g_weapon_ent_names[i], ((1 << i) & SHOTGUN_WEAPONS_BIT_SUM) ? "fw_Weapon_Shotgun_Reload_Post" : "fw_Weapon_Reload_Post", 1);
  163. }
  164. }
  165.  
  166. // Remove weapon_ from the names
  167. replace(g_weapon_ent_names[i], 17, "weapon_", "");
  168.  
  169. for(j = 0; j < MAX_WM; j++)
  170. {
  171. formatex(buffer, charsmax(buffer), "wm_%s_%s", wm_cvars[j], g_weapon_ent_names[i]);
  172.  
  173. switch(j)
  174. {
  175. case WEAPON_KNOCKBACK: g_cvar_weapon[i][j] = register_cvar(buffer, "0.00");
  176. case WEAPON_AUTO_FIRE:
  177. {
  178. if(i == 31) // all is 31
  179. {
  180. g_cvar_weapon[i][j] = register_cvar(buffer, "0");
  181. continue;
  182. }
  183.  
  184. if((1 << i) & SECONDARY_WEAPONS_BIT_SUM)
  185. g_cvar_weapon[i][j] = register_cvar(buffer, "0");
  186. }
  187. case WEAPON_ZOOM:
  188. {
  189. if(!((1 << i) & ALREADY_SECONDARY_ATTACK))
  190. g_cvar_weapon[i][j] = register_cvar(buffer, "off");
  191. }
  192. default: g_cvar_weapon[i][j] = register_cvar(buffer, "off");
  193. }
  194. }
  195. }
  196. }
  197.  
  198. // Extra Cvars for W_ models glow :)
  199. g_cvar_weapon[CSW_THIGHPACK][WEAPON_W_GLOW] = register_cvar("wm_wglow_thighpack", "off");
  200. g_cvar_weapon[CSW_SHIELD][WEAPON_W_GLOW] = register_cvar("wm_wglow_shield", "off");
  201. g_cvar_weapon[CSW_HEGRENADE][WEAPON_W_GLOW] = register_cvar("wm_wglow_hegrenade", "off");
  202. g_cvar_weapon[CSW_C4][WEAPON_W_GLOW] = register_cvar("wm_wglow_c4", "off");
  203. g_cvar_weapon[CSW_SMOKEGRENADE][WEAPON_W_GLOW] = register_cvar("wm_wglow_smokegrenade", "off");
  204. g_cvar_weapon[CSW_FLASHBANG][WEAPON_W_GLOW] = register_cvar("wm_wglow_flashbang", "off");
  205. g_cvar_weapon[CSW_BACKPACK][WEAPON_W_GLOW] = register_cvar("wm_wglow_backpack", "off");
  206.  
  207. // Extra Cvars for P_ models glow :)
  208. g_cvar_weapon[CSW_HEGRENADE][WEAPON_P_GLOW] = register_cvar("wm_pglow_hegrenade", "off");
  209. g_cvar_weapon[CSW_C4][WEAPON_P_GLOW] = register_cvar("wm_pglow_c4", "off");
  210. g_cvar_weapon[CSW_SMOKEGRENADE][WEAPON_P_GLOW] = register_cvar("wm_pglow_smokegrenade", "off");
  211. g_cvar_weapon[CSW_FLASHBANG][WEAPON_P_GLOW] = register_cvar("wm_pglow_flashbang", "off");
  212.  
  213. // Cvars for knockback
  214. g_cvar_knockback = register_cvar("wm_knockback", "0");
  215. g_cvar_knockback_zvel = register_cvar("wm_kb_zvel", "1");
  216. g_cvar_knockback_dist = register_cvar("wm_kb_dist", "500");
  217. g_pcvar_ff = get_cvar_pointer("mp_friendlyfire");
  218.  
  219. new wmodels[][] = {"models/w_shield.mdl", "models/w_thighpack.mdl", "models/w_c4.mdl", "models/w_backpack.mdl"};
  220.  
  221. g_trie_wmodel = TrieCreate();
  222.  
  223. for(i = 0; i < sizeof(wmodels); i++)
  224. TrieSetCell(g_trie_wmodel, wmodels[i], 1);
  225.  
  226. register_forward(FM_SetModel, "fw_SetModel");
  227. register_forward(FM_EmitSound, "fw_EmitSound");
  228. register_forward(FM_CmdStart, "fw_CmdStart");
  229.  
  230. g_msg_curweapon = get_user_msgid("CurWeapon");
  231. g_msg_ammopickup = get_user_msgid("AmmoPickup");
  232.  
  233. register_message(g_msg_curweapon, "message_CurWeapon");
  234.  
  235. g_maxplayers = get_maxplayers();
  236. }
  237.  
  238. public plugin_cfg()
  239. {
  240. new cfgdir[32];
  241. get_configsdir(cfgdir, charsmax(cfgdir));
  242.  
  243. server_cmd("exec %s/%s", cfgdir, g_customization_file_cfg);
  244. }
  245.  
  246. public plugin_end()
  247. {
  248. TrieDestroy(g_trie_wmodel);
  249. }
  250.  
  251. public client_disconnect(id)
  252. {
  253. g_has_ammo[id] = 0;
  254.  
  255. fm_remove_model_ents(id);
  256. }
  257.  
  258. public event_AmmoX(id)
  259. {
  260. static bpammo_cvar[10];
  261. static bpammo_cvar_temp[10];
  262. static bpammo_cvar_int;
  263. static mode;
  264. mode = 0;
  265.  
  266. get_pcvar_string(g_cvar_weapon[g_weapon[id]][WEAPON_UNLIMITED_BPAMMO], bpammo_cvar, charsmax(bpammo_cvar));
  267. get_pcvar_string(g_cvar_weapon[31][WEAPON_UNLIMITED_BPAMMO], bpammo_cvar_temp, charsmax(bpammo_cvar_temp));
  268.  
  269. bpammo_cvar_int = str_to_num(bpammo_cvar);
  270.  
  271. if(!equali(bpammo_cvar_temp, "off") || bpammo_cvar_int)
  272. mode = 1;
  273.  
  274. if(!mode)
  275. return;
  276.  
  277. static type;
  278. type = read_data(1);
  279.  
  280. if(type >= sizeof(g_ammo_weapon))
  281. return;
  282.  
  283. static weapon;
  284. weapon = g_ammo_weapon[type];
  285.  
  286. if(g_max_bpammo[weapon] <= 2)
  287. return;
  288.  
  289. static amount;
  290. amount = read_data(2);
  291.  
  292. if(amount < g_max_bpammo[weapon])
  293. {
  294. // The BP Ammo refill code causes the engine to send a message, but we
  295. // can't have that in this forward or we risk getting some recursion bugs.
  296. // For more info see: https://bugs.alliedmods.net/show_bug.cgi?id=3664
  297.  
  298. static args[1];
  299. args[0] = weapon;
  300.  
  301. set_task(0.1, "fn_refill_bpammo", id, args, sizeof(args));
  302. }
  303. }
  304.  
  305. public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
  306. {
  307. if(victim == attacker || !is_user_valid_connected(attacker))
  308. return HAM_IGNORED;
  309.  
  310. static dmg_cvar[10];
  311. static dmg_cvar_k[10];
  312. static dmg_cvar_temp[10];
  313. static dmg_cvar_temp_k[10];
  314.  
  315. get_pcvar_string(g_cvar_weapon[g_weapon[attacker]][WEAPON_DAMAGE], dmg_cvar, charsmax(dmg_cvar));
  316. get_pcvar_string(g_cvar_weapon[31][WEAPON_DAMAGE], dmg_cvar_temp, charsmax(dmg_cvar_temp));
  317.  
  318. copy(dmg_cvar_k, charsmax(dmg_cvar_k), dmg_cvar);
  319. copy(dmg_cvar_temp_k, charsmax(dmg_cvar_temp_k), dmg_cvar_temp);
  320.  
  321. if(fn_contain_words(dmg_cvar_k) || fn_contain_words(dmg_cvar_temp_k))
  322. {
  323. fn_replace_words(dmg_cvar_k, charsmax(dmg_cvar_k));
  324. fn_replace_words(dmg_cvar_temp_k, charsmax(dmg_cvar_temp_k));
  325.  
  326. static Float:dmg;
  327.  
  328. if(equali(dmg_cvar_temp, "off")) dmg = str_to_float(dmg_cvar_k);
  329. else dmg = str_to_float(dmg_cvar_temp_k);
  330.  
  331. switch((equali(dmg_cvar_temp, "off")) ? dmg_cvar[0] : dmg_cvar_temp[0])
  332. {
  333. case '+':
  334. {
  335. if(dmg < 1.00) return HAM_IGNORED;
  336. damage += dmg;
  337. }
  338. case '-':
  339. {
  340. if(dmg < 1.00) return HAM_IGNORED;
  341. damage -= dmg;
  342. }
  343. case '*':
  344. {
  345. if(dmg == 1.00) return HAM_IGNORED;
  346. damage *= dmg;
  347. }
  348. case '/':
  349. {
  350. if(dmg == 0.00) return HAM_IGNORED; // Can't divide by 0
  351. damage /= dmg;
  352. }
  353. case '=':
  354. {
  355. if(dmg < 1.00) return HAM_IGNORED;
  356. damage = dmg;
  357. }
  358. }
  359.  
  360. SetHamParamFloat(4, damage);
  361. }
  362.  
  363. return HAM_IGNORED;
  364. }
  365.  
  366. public fw_PlayerKilled(victim, attacker, shouldgib)
  367. {
  368. fm_remove_model_ents(victim);
  369. }
  370.  
  371. public fw_TraceAttack(victim, attacker, Float:damage, Float:direction[3], trace_handle, damage_type)
  372. {
  373. if(victim == attacker || !is_user_valid_connected(attacker))
  374. return HAM_IGNORED;
  375.  
  376. if(!get_pcvar_num(g_cvar_knockback))
  377. return HAM_IGNORED;
  378.  
  379. if(!(damage_type & DMG_BULLET))
  380. return HAM_IGNORED;
  381.  
  382. if(!get_pcvar_num(g_pcvar_ff) && (cs_get_user_team(attacker) == cs_get_user_team(victim)))
  383. return HAM_IGNORED;
  384.  
  385. static kb_duck;
  386. static origin1[3];
  387. static origin2[3];
  388.  
  389. kb_duck = entity_get_int(victim, EV_INT_flags) & (FL_DUCKING | FL_ONGROUND) == (FL_DUCKING | FL_ONGROUND);
  390.  
  391. get_user_origin(victim, origin1);
  392. get_user_origin(attacker, origin2);
  393.  
  394. if(get_distance(origin1, origin2) > get_pcvar_num(g_cvar_knockback_dist))
  395. return HAM_IGNORED;
  396.  
  397. static Float:velocity[3];
  398. entity_get_vector(victim, EV_VEC_velocity, velocity);
  399.  
  400. xs_vec_mul_scalar(direction, damage, direction);
  401.  
  402. static Float:kb_cvar;
  403.  
  404. if(get_pcvar_float(g_cvar_weapon[31][WEAPON_KNOCKBACK]) == 0.00) kb_cvar = get_pcvar_float(g_cvar_weapon[g_weapon[attacker]][WEAPON_KNOCKBACK]);
  405. else kb_cvar = get_pcvar_float(g_cvar_weapon[31][WEAPON_KNOCKBACK]);
  406.  
  407. if(kb_cvar > 0.00)
  408. xs_vec_mul_scalar(direction, kb_cvar, direction);
  409.  
  410. if(kb_duck)
  411. xs_vec_mul_scalar(direction, 0.2, direction);
  412.  
  413. xs_vec_add(velocity, direction, direction);
  414.  
  415. if(!get_pcvar_num(g_cvar_knockback_zvel))
  416. direction[2] = velocity[2];
  417.  
  418. entity_set_vector(victim, EV_VEC_velocity, direction);
  419.  
  420. return HAM_IGNORED;
  421. }
  422.  
  423. public fw_AddPlayerItem(id, weapon_ent)
  424. {
  425. static extra_ammo;
  426. extra_ammo = entity_get_int(weapon_ent, EV_INT_iuser1);
  427.  
  428. if(extra_ammo)
  429. {
  430. static weaponid;
  431. weaponid = cs_get_weapon_id(weapon_ent);
  432.  
  433. ExecuteHamB(Ham_GiveAmmo, id, extra_ammo, g_ammo_type[weaponid], g_max_bpammo[weaponid]);
  434. entity_set_int(weapon_ent, EV_INT_iuser1, 0);
  435. }
  436. }
  437.  
  438. public fw_UseStationary_Post(entity, caller, activator, use_type)
  439. {
  440. if(use_type == OFFSET_USE_STOPPED && is_user_valid_connected(caller))
  441. {
  442. fm_remove_model_ents(caller);
  443. fn_replace_weapon_models(caller, g_weapon[caller]);
  444. }
  445. }
  446.  
  447. public fw_Item_Deploy_Post(weapon_ent)
  448. {
  449. if(!pev_valid(weapon_ent))
  450. return;
  451.  
  452. static id;
  453. id = fm_get_weapon_ent_owner(weapon_ent);
  454.  
  455. if(!pev_valid(id))
  456. return;
  457.  
  458. fm_remove_model_ents(id);
  459.  
  460. static weaponid;
  461. weaponid = cs_get_weapon_id(weapon_ent);
  462.  
  463. if(weaponid != CSW_C4 &&
  464. weaponid != CSW_SHIELD &&
  465. weaponid != CSW_HEGRENADE &&
  466. weaponid != CSW_FLASHBANG &&
  467. weaponid != CSW_SMOKEGRENADE)
  468. g_weapon[id] = weaponid;
  469.  
  470. // Replace Weapon Models
  471. fn_replace_weapon_models(id, weaponid);
  472. }
  473.  
  474. public fw_Weapon_PrimaryAttack_Post(weapon_ent) // Recoil , Speed and Auto Fire Pistol
  475. {
  476. if(!pev_valid(weapon_ent))
  477. return HAM_IGNORED;
  478.  
  479. static id;
  480. id = fm_get_weapon_ent_owner(weapon_ent);
  481.  
  482. if(!pev_valid(id) || cs_get_weapon_ammo(weapon_ent) < 1)
  483. return HAM_IGNORED;
  484.  
  485. // Recoil
  486. static Float:def_recoil[3];
  487. entity_get_vector(id, EV_VEC_punchangle, def_recoil);
  488.  
  489. static recoil_cvar[10];
  490. static recoil_cvar_k[10];
  491. static recoil_cvar_temp[10];
  492. static recoil_cvar_temp_k[10];
  493.  
  494. get_pcvar_string(g_cvar_weapon[g_weapon[id]][WEAPON_RECOIL], recoil_cvar, charsmax(recoil_cvar));
  495. get_pcvar_string(g_cvar_weapon[31][WEAPON_RECOIL], recoil_cvar_temp, charsmax(recoil_cvar_temp));
  496.  
  497. copy(recoil_cvar_k, charsmax(recoil_cvar_k), recoil_cvar);
  498. copy(recoil_cvar_temp_k, charsmax(recoil_cvar_temp_k), recoil_cvar_temp);
  499.  
  500. if(fn_contain_words(recoil_cvar_k) || fn_contain_words(recoil_cvar_temp_k))
  501. {
  502. fn_replace_words(recoil_cvar_k, charsmax(recoil_cvar_k));
  503. fn_replace_words(recoil_cvar_temp_k, charsmax(recoil_cvar_temp_k));
  504.  
  505. static Float:recoil;
  506.  
  507. if(equali(recoil_cvar_temp, "off")) recoil = str_to_float(recoil_cvar_k);
  508. else recoil = str_to_float(recoil_cvar_temp_k);
  509.  
  510. switch((equali(recoil_cvar_temp, "off")) ? recoil_cvar[0] : recoil_cvar_temp[0])
  511. {
  512. case '+':
  513. {
  514. if(recoil == 0.00) return HAM_IGNORED;
  515. def_recoil[0] += recoil;
  516. }
  517. case '-':
  518. {
  519. if(recoil == 0.00) return HAM_IGNORED;
  520. def_recoil[0] -= recoil;
  521. }
  522. case '*':
  523. {
  524. if(recoil == 1.00) return HAM_IGNORED;
  525. def_recoil[0] *= recoil;
  526. }
  527. case '/':
  528. {
  529. if(recoil == 0.00) return HAM_IGNORED; // Can't divide by 0
  530. def_recoil[0] /= recoil;
  531. }
  532. case '=':
  533. {
  534. def_recoil[0] = recoil;
  535. if(recoil == 0)
  536. def_recoil[1] = def_recoil[2] = recoil;
  537. }
  538. }
  539.  
  540. entity_set_vector(id, EV_VEC_punchangle, def_recoil);
  541. }
  542.  
  543. // Speed
  544. static Float:def_speed[3];
  545. def_speed[0] = get_pdata_float(weapon_ent, OFFSET_NEXT_PRIMARY_ATTACK, OFFSET_LINUX_WEAPONS);
  546. def_speed[1] = get_pdata_float(weapon_ent, OFFSET_NEXT_SECONDARY_ATTACK, OFFSET_LINUX_WEAPONS);
  547. def_speed[2] = get_pdata_float(weapon_ent, OFFSET_TIME_WEAPON_IDLE, OFFSET_LINUX_WEAPONS);
  548.  
  549. static speed_cvar[10];
  550. static speed_cvar_k[10];
  551. static speed_cvar_temp[10];
  552. static speed_cvar_temp_k[10];
  553.  
  554. get_pcvar_string(g_cvar_weapon[g_weapon[id]][WEAPON_SPEED], speed_cvar, charsmax(speed_cvar));
  555. get_pcvar_string(g_cvar_weapon[31][WEAPON_SPEED], speed_cvar_temp, charsmax(speed_cvar_temp));
  556.  
  557. copy(speed_cvar_k, charsmax(speed_cvar_k), speed_cvar);
  558. copy(speed_cvar_temp_k, charsmax(speed_cvar_temp_k), speed_cvar_temp);
  559.  
  560. if(fn_contain_words(speed_cvar_k) || fn_contain_words(speed_cvar_temp_k))
  561. {
  562. fn_replace_words(speed_cvar_k, charsmax(speed_cvar_k));
  563. fn_replace_words(speed_cvar_temp_k, charsmax(speed_cvar_temp_k));
  564.  
  565. static Float:speed;
  566.  
  567. if(equali(speed_cvar_temp, "off")) speed = str_to_float(speed_cvar_k);
  568. else speed = str_to_float(speed_cvar_temp_k);
  569.  
  570. switch((equali(speed_cvar_temp, "off")) ? speed_cvar[0] : speed_cvar_temp[0])
  571. {
  572. case '+':
  573. {
  574. if(speed == 0.00) return HAM_IGNORED;
  575. def_speed[0] += speed;
  576. def_speed[1] += speed;
  577. def_speed[2] += speed;
  578. }
  579. case '-':
  580. {
  581. if(speed == 0.00) return HAM_IGNORED;
  582. def_speed[0] -= speed;
  583. def_speed[1] -= speed;
  584. def_speed[2] -= speed;
  585. }
  586. case '*':
  587. {
  588. if(speed == 1.00) return HAM_IGNORED;
  589. def_speed[0] *= speed;
  590. def_speed[1] *= speed;
  591. def_speed[2] *= speed;
  592. }
  593. case '/':
  594. {
  595. if(speed == 0.00) return HAM_IGNORED; // Can't divide by 0
  596. def_speed[0] /= speed;
  597. def_speed[1] /= speed;
  598. def_speed[2] /= speed;
  599. }
  600. case '=': def_speed[0] = def_speed[1] = def_speed[2] = speed;
  601. }
  602.  
  603. set_pdata_float(weapon_ent, OFFSET_NEXT_PRIMARY_ATTACK, def_speed[0], OFFSET_LINUX_WEAPONS)
  604. set_pdata_float(weapon_ent, OFFSET_NEXT_SECONDARY_ATTACK, def_speed[1], OFFSET_LINUX_WEAPONS)
  605. set_pdata_float(weapon_ent, OFFSET_TIME_WEAPON_IDLE, def_speed[2], OFFSET_LINUX_WEAPONS)
  606. }
  607.  
  608. // Auto Fire Pistol
  609. if((1 << g_weapon[id]) & SECONDARY_WEAPONS_BIT_SUM)
  610. {
  611. static autofire_cvar;
  612.  
  613. if(!get_pcvar_num(g_cvar_weapon[31][WEAPON_AUTO_FIRE])) autofire_cvar = get_pcvar_num(g_cvar_weapon[g_weapon[id]][WEAPON_AUTO_FIRE]);
  614. else autofire_cvar = 1;
  615.  
  616. g_has_ammo[id] = autofire_cvar;
  617. }
  618.  
  619. return HAM_IGNORED;
  620. }
  621.  
  622. public fw_Item_PostFrame(weapon_ent)
  623. {
  624. if(!pev_valid(weapon_ent))
  625. return HAM_IGNORED;
  626.  
  627. static id;
  628. id = fm_get_weapon_ent_owner(weapon_ent);
  629.  
  630. if(!pev_valid(id))
  631. return HAM_IGNORED;
  632.  
  633. static button;
  634. button = entity_get_int(id, EV_INT_button);
  635.  
  636. if(button & IN_ATTACK2)
  637. {
  638. static zoom_cvar[32];
  639. static zoom_delay[9];
  640. static zoom_speed[1]; // not interesting here
  641. static zoom_1[3];
  642. static zoom_2[3];
  643. static Float:f_zoom_delay;
  644. static i_zoom_1;
  645. static i_zoom_2;
  646.  
  647. get_pcvar_string(g_cvar_weapon[31][WEAPON_ZOOM], zoom_cvar, charsmax(zoom_cvar));
  648.  
  649. if(equali(zoom_cvar, "off"))
  650. {
  651. get_pcvar_string(g_cvar_weapon[g_weapon[id]][WEAPON_ZOOM], zoom_cvar, charsmax(zoom_cvar));
  652.  
  653. if(equali(zoom_cvar, "off"))
  654. return HAM_IGNORED;
  655. }
  656.  
  657. parse(zoom_cvar, zoom_delay, charsmax(zoom_delay), zoom_speed, charsmax(zoom_speed), zoom_1, charsmax(zoom_1), zoom_2, charsmax(zoom_2));
  658.  
  659. f_zoom_delay = str_to_float(zoom_delay);
  660. i_zoom_1 = clamp(str_to_num(zoom_1), 0, 255);
  661. i_zoom_2 = clamp(str_to_num(zoom_2), 0, 255);
  662.  
  663. static fov;
  664. fov = get_pdata_int(id, OFFSET_FOV, OFFSET_LINUX);
  665.  
  666. if(fov == 90) fn_SetFov(id, i_zoom_1);
  667. else if(fov == i_zoom_1) fn_SetFov(id, i_zoom_2);
  668. else fn_SetFov(id, 90);
  669.  
  670. ExecuteHamB(Ham_Item_PreFrame, id);
  671.  
  672. emit_sound(id, CHAN_ITEM, "weapons/zoom.wav", 0.20, 2.40, 0, 100);
  673. set_pdata_float(id, OFFSET_NEXT_ATTACK, f_zoom_delay, OFFSET_LINUX);
  674.  
  675. return HAM_SUPERCEDE;
  676. }
  677.  
  678. return HAM_IGNORED;
  679. }
  680.  
  681. public fw_Item_Holster(weapon_ent)
  682. {
  683. if(pev_valid(weapon_ent))
  684. {
  685. if(ExecuteHamB(Ham_Item_CanHolster, weapon_ent))
  686. fn_ResetFov(fm_get_weapon_ent_owner(weapon_ent));
  687. }
  688. }
  689.  
  690. public fw_CS_Item_GetMaxSpeed(weapon_ent)
  691. {
  692. if(!pev_valid(weapon_ent))
  693. return HAM_IGNORED;
  694.  
  695. static id;
  696. id = fm_get_weapon_ent_owner(weapon_ent);
  697.  
  698. if(!pev_valid(id))
  699. return HAM_IGNORED;
  700.  
  701. if(get_pdata_int(id, OFFSET_FOV, OFFSET_LINUX) == 90)
  702. return HAM_IGNORED;
  703.  
  704. static zoom_cvar[32];
  705. static zoom_delay[1]; // not interesting here
  706. static zoom_speed[9];
  707. static zoom_1[1]; // not interesting here
  708. static zoom_2[1]; // not interesting here
  709. static Float:f_zoom_speed;
  710.  
  711. get_pcvar_string(g_cvar_weapon[31][WEAPON_ZOOM], zoom_cvar, charsmax(zoom_cvar));
  712.  
  713. if(equali(zoom_cvar, "off"))
  714. {
  715. get_pcvar_string(g_cvar_weapon[g_weapon[id]][WEAPON_ZOOM], zoom_cvar, charsmax(zoom_cvar));
  716.  
  717. if(equali(zoom_cvar, "off"))
  718. return HAM_IGNORED;
  719. }
  720.  
  721. parse(zoom_cvar, zoom_delay, charsmax(zoom_delay), zoom_speed, charsmax(zoom_speed), zoom_1, charsmax(zoom_1), zoom_2, charsmax(zoom_2));
  722. f_zoom_speed = str_to_float(zoom_speed);
  723.  
  724. static Float:f_MaxSpeed;
  725. f_MaxSpeed = f_zoom_speed;
  726.  
  727. if(f_MaxSpeed > 0.00)
  728. {
  729. SetHamReturnFloat(f_MaxSpeed);
  730. return HAM_SUPERCEDE;
  731. }
  732.  
  733. return HAM_IGNORED;
  734. }
  735.  
  736. public fw_Weapon_Reload_Post(weapon_ent)
  737. {
  738. if(pev_valid(weapon_ent))
  739. {
  740. if(get_pdata_int(weapon_ent, OFFSET_IN_RELOAD, OFFSET_LINUX_WEAPONS))
  741. fn_ResetFov(fm_get_weapon_ent_owner(weapon_ent))
  742. }
  743. }
  744.  
  745. public fw_Weapon_Shotgun_Reload_Post(weapon_ent)
  746. {
  747. if(pev_valid(weapon_ent))
  748. {
  749. if(get_pdata_int(weapon_ent, OFFSET_IN_SPECIAL_RELOAD, OFFSET_LINUX_WEAPONS) == 1)
  750. fn_ResetFov(fm_get_weapon_ent_owner(weapon_ent))
  751. }
  752. }
  753.  
  754. fn_SetFov(id, fov)
  755. {
  756. entity_set_float(id, EV_FL_fov, float(fov));
  757. set_pdata_int(id, OFFSET_FOV, fov, OFFSET_LINUX);
  758. }
  759.  
  760. fn_ResetFov(id)
  761. {
  762. if(0 <= get_pdata_int(id, OFFSET_FOV, OFFSET_LINUX) <= 90)
  763. {
  764. entity_set_float(id, EV_FL_fov, 90.0);
  765. set_pdata_int(id, OFFSET_FOV, 90, OFFSET_LINUX);
  766. }
  767. }
  768.  
  769. public fw_SetModel(entity, const model[])
  770. {
  771. if(strlen(model) < 8 || model[7] != 'w' || model[8] != '_')
  772. return FMRES_IGNORED;
  773.  
  774. static classname[10];
  775. static color_all[21];
  776.  
  777. entity_get_string(entity, EV_SZ_classname, classname, charsmax(classname));
  778. get_pcvar_string(g_cvar_weapon[31][WEAPON_W_GLOW], color_all, charsmax(color_all));
  779.  
  780. if(equal(classname, "weaponbox") ||
  781. TrieKeyExists(g_trie_wmodel, model))
  782. {
  783. static i;
  784. static color[21];
  785. static p_rgb[3][4];
  786. static i_rgb[3];
  787.  
  788. for(i = 0; i < CSW_P90+2; i++)
  789. {
  790. if(equali(model, g_model_default[i]))
  791. {
  792. get_pcvar_string(g_cvar_weapon[i][WEAPON_W_GLOW], color, charsmax(color));
  793. if(!equali(color, "off") || !equali(color_all, "off"))
  794. {
  795. if(equali(color_all, "off")) parse(color, p_rgb[0], charsmax(p_rgb[]), p_rgb[1], charsmax(p_rgb[]), p_rgb[2], charsmax(p_rgb[]));
  796. else parse(color_all, p_rgb[0], charsmax(p_rgb[]), p_rgb[1], charsmax(p_rgb[]), p_rgb[2], charsmax(p_rgb[]));
  797.  
  798. i_rgb[0] = clamp(str_to_num(p_rgb[0]), 0, 255);
  799. i_rgb[1] = clamp(str_to_num(p_rgb[1]), 0, 255);
  800. i_rgb[2] = clamp(str_to_num(p_rgb[2]), 0, 255);
  801.  
  802. fm_set_rendering(entity, kRenderFxGlowShell, i_rgb[0], i_rgb[1], i_rgb[2], kRenderNormal, 16);
  803. }
  804.  
  805. if(g_model_weapon[W_][i][0])
  806. {
  807. entity_set_model(entity, g_model_weapon[W_][i]);
  808. return FMRES_SUPERCEDE;
  809. }
  810. }
  811. }
  812.  
  813. return FMRES_IGNORED;
  814. }
  815.  
  816. static Float:dmg_time;
  817. dmg_time = entity_get_float(entity, EV_FL_dmgtime);
  818.  
  819. if(dmg_time == 0.0)
  820. return FMRES_IGNORED;
  821.  
  822. static pg_rgb[3][3][4];
  823. static ig_rgb[3][3];
  824. if(equali(color_all, "off"))
  825. {
  826. static color_grenades[3][21];
  827.  
  828. get_pcvar_string(g_cvar_weapon[CSW_HEGRENADE][WEAPON_W_GLOW], color_grenades[0], charsmax(color_grenades[]));
  829. get_pcvar_string(g_cvar_weapon[CSW_FLASHBANG][WEAPON_W_GLOW], color_grenades[1], charsmax(color_grenades[]));
  830. get_pcvar_string(g_cvar_weapon[CSW_SMOKEGRENADE][WEAPON_W_GLOW], color_grenades[2], charsmax(color_grenades[]));
  831.  
  832. if(!equali(color_grenades[0], "off"))
  833. {
  834. parse(color_grenades[0], pg_rgb[0][0], charsmax(pg_rgb[][]), pg_rgb[1][0], charsmax(pg_rgb[][]), pg_rgb[2][0], charsmax(pg_rgb[][]));
  835.  
  836. ig_rgb[0][0] = clamp(str_to_num(pg_rgb[0][0]), 0, 255);
  837. ig_rgb[1][0] = clamp(str_to_num(pg_rgb[1][0]), 0, 255);
  838. ig_rgb[2][0] = clamp(str_to_num(pg_rgb[2][0]), 0, 255);
  839. }
  840. if(!equali(color_grenades[1], "off"))
  841. {
  842. parse(color_grenades[1], pg_rgb[0][1], charsmax(pg_rgb[][]), pg_rgb[1][1], charsmax(pg_rgb[][]), pg_rgb[2][1], charsmax(pg_rgb[][]));
  843.  
  844. ig_rgb[0][1] = clamp(str_to_num(pg_rgb[0][1]), 0, 255);
  845. ig_rgb[1][1] = clamp(str_to_num(pg_rgb[1][1]), 0, 255);
  846. ig_rgb[2][1] = clamp(str_to_num(pg_rgb[2][1]), 0, 255);
  847. }
  848. if(!equali(color_grenades[2], "off"))
  849. {
  850. parse(color_grenades[2], pg_rgb[0][2], charsmax(pg_rgb[][]), pg_rgb[1][2], charsmax(pg_rgb[][]), pg_rgb[2][2], charsmax(pg_rgb[][]));
  851.  
  852. ig_rgb[0][2] = clamp(str_to_num(pg_rgb[0][2]), 0, 255);
  853. ig_rgb[1][2] = clamp(str_to_num(pg_rgb[1][2]), 0, 255);
  854. ig_rgb[2][2] = clamp(str_to_num(pg_rgb[2][2]), 0, 255);
  855. }
  856. }
  857. else
  858. {
  859. parse(color_all, pg_rgb[0][0], charsmax(pg_rgb[][]), pg_rgb[1][0], charsmax(pg_rgb[][]), pg_rgb[2][0], charsmax(pg_rgb[][]));
  860.  
  861. ig_rgb[0][0] = ig_rgb[0][1] = ig_rgb[0][2] = clamp(str_to_num(pg_rgb[0][0]), 0, 255);
  862. ig_rgb[1][0] = ig_rgb[1][1] = ig_rgb[1][2] = clamp(str_to_num(pg_rgb[1][0]), 0, 255);
  863. ig_rgb[2][0] = ig_rgb[2][1] = ig_rgb[2][2] = clamp(str_to_num(pg_rgb[2][0]), 0, 255);
  864. }
  865.  
  866. if(model[9] == 'h' && model[10] == 'e') // HE Grenade
  867. {
  868. // Give it a glow
  869. fm_set_rendering(entity, kRenderFxGlowShell, ig_rgb[0][0], ig_rgb[1][0], ig_rgb[2][0], kRenderNormal, 16);
  870.  
  871. // Change Model
  872. if(g_model_weapon[W_][CSW_HEGRENADE][0])
  873. {
  874. entity_set_model(entity, g_model_weapon[W_][CSW_HEGRENADE]);
  875. return FMRES_SUPERCEDE;
  876. }
  877. }
  878. else if(model[9] == 'f' && model[10] == 'l') // Flash Grenade
  879. {
  880. // Give it a glow
  881. fm_set_rendering(entity, kRenderFxGlowShell, ig_rgb[0][1], ig_rgb[1][1], ig_rgb[2][1], kRenderNormal, 16);
  882.  
  883. // Change Model
  884. if(g_model_weapon[W_][CSW_FLASHBANG][0])
  885. {
  886. entity_set_model(entity, g_model_weapon[W_][CSW_FLASHBANG]);
  887. return FMRES_SUPERCEDE;
  888. }
  889. }
  890. else if(model[9] == 's' && model[10] == 'm') // Smoke Grenade
  891. {
  892. // Give it a glow
  893. fm_set_rendering(entity, kRenderFxGlowShell, ig_rgb[0][2], ig_rgb[1][2], ig_rgb[2][2], kRenderNormal, 16);
  894.  
  895. // Change Model
  896. if(g_model_weapon[W_][CSW_SMOKEGRENADE][0])
  897. {
  898. entity_set_model(entity, g_model_weapon[W_][CSW_SMOKEGRENADE]);
  899. return FMRES_SUPERCEDE;
  900. }
  901. }
  902.  
  903. return FMRES_IGNORED;
  904. }
  905.  
  906. public fw_EmitSound(id, channel, const sample[], Float:volume, Float:attn, flags, pitch)
  907. {
  908. if(!is_user_valid_connected(id))
  909. return FMRES_IGNORED;
  910.  
  911. new i;
  912. for(i = 0; i < sizeof(g_sound_knife_default); i++)
  913. {
  914. if(equal(sample, g_sound_knife_default[i]) && g_sound_weapon[i][0])
  915. {
  916. emit_sound(id, channel, g_sound_weapon[i], volume, attn, flags, pitch);
  917. return FMRES_SUPERCEDE;
  918. }
  919. }
  920.  
  921. return FMRES_IGNORED;
  922. }
  923.  
  924. public fw_CmdStart(id, handle)
  925. {
  926. if(!is_user_alive(id))
  927. return;
  928.  
  929. if((1 << g_weapon[id]) & SECONDARY_WEAPONS_BIT_SUM)
  930. {
  931. static autofire_cvar;
  932.  
  933. if(!get_pcvar_num(g_cvar_weapon[31][WEAPON_AUTO_FIRE])) autofire_cvar = get_pcvar_num(g_cvar_weapon[g_weapon[id]][WEAPON_AUTO_FIRE]);
  934. else autofire_cvar = 1;
  935.  
  936. if(autofire_cvar)
  937. {
  938. static button;
  939. button = get_uc(handle, UC_Buttons);
  940.  
  941. if((button & IN_ATTACK) && g_has_ammo[id])
  942. {
  943. set_uc(handle, UC_Buttons, button & ~IN_ATTACK);
  944. g_has_ammo[id] = 0;
  945. }
  946. }
  947. }
  948. }
  949.  
  950. public message_CurWeapon(msg_id, msg_dest, msg_entity)
  951. {
  952. if(!is_user_alive(msg_entity) || get_msg_arg_int(1) != 1)
  953. return;
  954.  
  955. static clip_cvar[10];
  956. static clip_cvar_temp[10];
  957. static clip_cvar_int;
  958. static mode;
  959. static weapon;
  960.  
  961. mode = 0;
  962. weapon = get_msg_arg_int(2);
  963.  
  964. get_pcvar_string(g_cvar_weapon[g_weapon[msg_entity]][WEAPON_UNLIMITED_CLIP], clip_cvar, charsmax(clip_cvar));
  965. get_pcvar_string(g_cvar_weapon[31][WEAPON_UNLIMITED_CLIP], clip_cvar_temp, charsmax(clip_cvar_temp));
  966.  
  967. clip_cvar_int = str_to_num(clip_cvar);
  968.  
  969. if(!equali(clip_cvar_temp, "off") || clip_cvar_int)
  970. mode = 1;
  971.  
  972. if(!mode)
  973. return;
  974.  
  975. if(g_max_bpammo[weapon] > 2)
  976. {
  977. static weapon_ent;
  978. weapon_ent = get_pdata_cbase(msg_entity, OFFSET_ACTIVE_ITEM, OFFSET_LINUX);
  979.  
  980. if(pev_valid(weapon_ent))
  981. cs_set_weapon_ammo(weapon_ent, g_max_clip[weapon])
  982.  
  983. set_msg_arg_int(3, get_msg_argtype(3), g_max_clip[weapon]);
  984. }
  985. }
  986.  
  987. // Functions
  988. fn_contain_words(const string[])
  989. {
  990. if(contain(string, "+") != -1 ||
  991. contain(string, "-") != -1 ||
  992. contain(string, "*") != -1 ||
  993. contain(string, "/") != -1 ||
  994. contain(string, "=") != -1)
  995. return 1;
  996.  
  997. return 0;
  998. }
  999. fn_replace_words(string[], len)
  1000. {
  1001. replace(string, len, "+", "");
  1002. replace(string, len, "-", "");
  1003. replace(string, len, "*", "");
  1004. replace(string, len, "/", "");
  1005. replace(string, len, "=", "");
  1006. }
  1007. fn_load_customization()
  1008. {
  1009. new path[64];
  1010. get_configsdir(path, charsmax(path));
  1011.  
  1012. format(path, charsmax(path), "%s/%s", path, g_customization_file_ini);
  1013.  
  1014. if(!file_exists(path)) return;
  1015.  
  1016. new linedata[1024];
  1017. new key[64];
  1018. new value[960];
  1019. new weaponname[32];
  1020. new file = fopen(path, "rt");
  1021. new i;
  1022. new const soundname[][] = {
  1023. "KNIFE_DEPLOY",
  1024. "KNIFE_HIT_1",
  1025. "KNIFE_HIT_2",
  1026. "KNIFE_HIT_3",
  1027. "KNIFE_HIT_4",
  1028. "KNIFE_HIT_WALL",
  1029. "KNIFE_SLASH_1",
  1030. "KNIFE_SLASH_2",
  1031. "KNIFE_STAB"
  1032. }
  1033.  
  1034. while(file && !feof(file))
  1035. {
  1036. fgets(file, linedata, charsmax(linedata));
  1037. replace(linedata, charsmax(linedata), "^n", "");
  1038.  
  1039. if(!linedata[0] || linedata[0] == ';') continue;
  1040.  
  1041. strtok(linedata, key, charsmax(key), value, charsmax(value), '=');
  1042. trim(key);
  1043. trim(value);
  1044.  
  1045. // Models
  1046. for(i = 0; i < CSW_P90+2; i++)
  1047. {
  1048. if(g_weapon_ent_names_all[i][0])
  1049. {
  1050. // Remove weapon_ from the names
  1051. copy(weaponname, charsmax(weaponname), g_weapon_ent_names_all[i]);
  1052.  
  1053. // Get and precache V_ model
  1054. replace(weaponname, charsmax(weaponname), "weapon_", "V_");
  1055. if(!equali(g_weapon_ent_names_all[i], "weapon_thighpack"))
  1056. {
  1057. if(equali(key, weaponname)) copy(g_model_weapon[V_][i], charsmax(g_model_weapon[][]), value);
  1058. if(g_model_weapon[V_][i][0]) precache_model(g_model_weapon[V_][i]);
  1059. }
  1060.  
  1061. // Get and precache P_ model
  1062. replace(weaponname, charsmax(weaponname), "V_", "P_");
  1063. if(equali(key, weaponname)) copy(g_model_weapon[P_][i], charsmax(g_model_weapon[][]), value);
  1064. if(g_model_weapon[P_][i][0]) precache_model(g_model_weapon[P_][i]);
  1065.  
  1066. // Get and precache W_ model
  1067. replace(weaponname, charsmax(weaponname), "P_", "W_");
  1068. if(equali(key, weaponname)) copy(g_model_weapon[W_][i], charsmax(g_model_weapon[][]), value);
  1069. if(g_model_weapon[W_][i][0]) precache_model(g_model_weapon[W_][i]);
  1070. }
  1071. }
  1072.  
  1073. // Knife Sounds
  1074. for(i = 0; i < sizeof(g_sound_knife_default); i++)
  1075. {
  1076. if(equali(key, soundname[i])) copy(g_sound_weapon[i], charsmax(g_sound_weapon[]), value);
  1077. if(g_sound_weapon[i][0]) precache_model(g_sound_weapon[i]);
  1078. }
  1079. }
  1080.  
  1081. if(file)
  1082. fclose(file);
  1083. }
  1084. fn_replace_weapon_models(id, weaponid)
  1085. {
  1086. if(!is_user_alive(id))
  1087. return;
  1088.  
  1089. if(g_model_weapon[V_][weaponid][0]) entity_set_string(id, EV_SZ_viewmodel, g_model_weapon[V_][weaponid]);
  1090. if(g_model_weapon[P_][weaponid][0]) entity_set_string(id, EV_SZ_weaponmodel, g_model_weapon[P_][weaponid]);
  1091.  
  1092. new color[21];
  1093. new color_all[21];
  1094.  
  1095. get_pcvar_string(g_cvar_weapon[weaponid][WEAPON_P_GLOW], color, charsmax(color));
  1096. get_pcvar_string(g_cvar_weapon[31][WEAPON_P_GLOW], color_all, charsmax(color_all));
  1097.  
  1098. if(!equali(color, "off") || !equali(color_all, "off"))
  1099. {
  1100. new p_rgb[3][4];
  1101. new i_rgb[3];
  1102.  
  1103. if(equali(color_all, "off")) parse(color, p_rgb[0], charsmax(p_rgb[]), p_rgb[1], charsmax(p_rgb[]), p_rgb[2], charsmax(p_rgb[]));
  1104. else parse(color_all, p_rgb[0], charsmax(p_rgb[]), p_rgb[1], charsmax(p_rgb[]), p_rgb[2], charsmax(p_rgb[]));
  1105.  
  1106. i_rgb[0] = clamp(str_to_num(p_rgb[0]), 0, 255);
  1107. i_rgb[1] = clamp(str_to_num(p_rgb[1]), 0, 255);
  1108. i_rgb[2] = clamp(str_to_num(p_rgb[2]), 0, 255);
  1109.  
  1110. fm_set_weaponmodel_ent(id, i_rgb[0], i_rgb[1], i_rgb[2]);
  1111. }
  1112. }
  1113. public fn_refill_bpammo(const args[], id)
  1114. {
  1115. if(!is_user_alive(id))
  1116. return;
  1117.  
  1118. set_msg_block(g_msg_ammopickup, BLOCK_ONCE);
  1119. ExecuteHamB(Ham_GiveAmmo, id, g_max_bpammo[args[0]], g_ammo_type[args[0]], g_max_bpammo[args[0]]);
  1120. }
  1121.  
  1122. // Stocks
  1123. stock fm_set_weaponmodel_ent(id, red = -1, green = -1, blue = -1) // Thanks MeRcyLeZZ for the stock!
  1124. {
  1125. static model[128];
  1126. entity_get_string(id, EV_SZ_weaponmodel, model, charsmax(model));
  1127.  
  1128. if(!pev_valid(g_ent_weaponmodel[id]))
  1129. {
  1130. g_ent_weaponmodel[id] = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "info_target"));
  1131. if(!pev_valid(g_ent_weaponmodel[id])) return;
  1132.  
  1133. entity_set_string(g_ent_weaponmodel[id], EV_SZ_classname, "weapon_model");
  1134. entity_set_int(g_ent_weaponmodel[id], EV_INT_movetype, MOVETYPE_FOLLOW);
  1135. entity_set_edict(g_ent_weaponmodel[id], EV_ENT_aiment, id);
  1136. entity_set_edict(g_ent_weaponmodel[id], EV_ENT_owner, id);
  1137.  
  1138. if(red != -1 || green != -1 || blue != -1)
  1139. fm_set_rendering(g_ent_weaponmodel[id], kRenderFxGlowShell, red, green, blue, kRenderNormal, 16);
  1140. }
  1141.  
  1142. engfunc(EngFunc_SetModel, g_ent_weaponmodel[id], model);
  1143. }
  1144. stock fm_remove_model_ents(id) // Thanks MeRcyLeZZ for the stock!
  1145. {
  1146. if(pev_valid(g_ent_weaponmodel[id]))
  1147. {
  1148. remove_entity(g_ent_weaponmodel[id]);
  1149. g_ent_weaponmodel[id] = 0;
  1150. }
  1151. }
  1152. stock cs_weapon_name_to_id(const weapon[]) // Simplified get_weaponid (CS only) -- Thanks MeRcyLeZZ for the stock!
  1153. {
  1154. static i;
  1155. for(i = 0; i < sizeof(g_weapon_ent_names) - 1; i++)
  1156. {
  1157. if(equal(weapon, g_weapon_ent_names[i]))
  1158. return i;
  1159. }
  1160.  
  1161. return 0;
  1162. }
  1163. stock fm_get_weapon_ent_owner(ent)
  1164. {
  1165. if(pev_valid(ent) != OFFSET_PDATA)
  1166. return -1;
  1167.  
  1168. return get_pdata_cbase(ent, OFFSET_WEAPON_OWNER, OFFSET_LINUX_WEAPONS);
  1169. }