Advertisement
mihay111

cartblue

Jul 13th, 2019
166
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 34.38 KB | None | 0 0
  1. /* AMX Mod X
  2. * [ZP] Extra: Cart Blue
  3. *
  4. * http://aghl.ru/forum/ - Russian Half-Life and Adrenaline Gamer Community
  5. *
  6. * This file is provided as is (no warranties)
  7. */
  8.  
  9. // Undefine for Zombie Plague 5.0 support.
  10. // #define _ZP50
  11.  
  12. // Don't touch this line, lol.
  13. // #define _DEBUG
  14.  
  15. #include <amxmodx>
  16. #include <fakemeta>
  17. #include <hamsandwich>
  18.  
  19. #if defined _DEBUG
  20. #define _DEBUG_CMD "say /cartblue"
  21. #else
  22. #if !defined _ZP50
  23. #tryinclude <zombieplague>
  24. #else
  25. #tryinclude <zp50_core>
  26. #tryinclude <zp50_items>
  27. #endif
  28. #endif
  29.  
  30. #include <xs>
  31.  
  32. #define PLUGIN "[ZP] Extra: Cart Blue"
  33. #define VERSION "1.0"
  34. #define AUTHOR "KORD_12.7"
  35.  
  36. #pragma semicolon 1
  37. #pragma ctrlchar '\'
  38.  
  39. //**********************************************
  40. //* Weapon Settings. *
  41. //**********************************************
  42.  
  43. // Main
  44. #define WEAPON_REFERANCE "weapon_m4a1"
  45.  
  46. #define WEAPON_NAME_C "weapon_cartbluec_aghlru"
  47. #define WEAPON_NAME_S "weapon_cartblues_aghlru"
  48.  
  49. #define WEAPON_MAX_CLIP 50
  50. #define WEAPON_DEFAULT_AMMO 90
  51.  
  52. #define WEAPON_FOV_ZOOM 20
  53. #define WEAPON_MAX_SPEED 230.0
  54.  
  55. #define WEAPON_MULTIPLIER_DAMAGE 1.0
  56.  
  57. #define WEAPON_TIME_NEXT_IDLE 5.46
  58. #define WEAPON_TIME_NEXT_ATTACK_C 0.0955
  59. #define WEAPON_TIME_NEXT_ATTACK_S 0.25
  60.  
  61. #define WEAPON_TIME_DELAY_DEPLOY 1.0
  62. #define WEAPON_TIME_DELAY_RELOAD 3.46
  63. #define WEAPON_TIME_DELAY_SWITCH 4.83
  64.  
  65. // Extra
  66. #define ZP_ITEM_NAME "Cart Blue"
  67. #define ZP_ITEM_COST 45
  68.  
  69. // Models
  70. #define MODEL_WORLD "models/aghlru/w_cartblue.mdl"
  71. #define MODEL_VIEW "models/aghlru/v_cartblue.mdl"
  72. #define MODEL_PLAYER "models/aghlru/p_cartblue.mdl"
  73. #define MODEL_SHELL "models/rshell.mdl"
  74.  
  75. // Sounds
  76. #define SOUND_FIRE_C "weapons/cartblue_l.wav"
  77. #define SOUND_FIRE_S "weapons/cartblue_h.wav"
  78.  
  79. // Sprites
  80. #define WEAPON_HUD_SPR_C "sprites/aghlru/cartblue.spr"
  81. #define WEAPON_HUD_SPR_S "sprites/aghlru/sniper_cartblue.spr"
  82.  
  83. #define WEAPON_HUD_TXT_C "sprites/weapon_cartbluec_aghlru.txt"
  84. #define WEAPON_HUD_TXT_S "sprites/weapon_cartblues_aghlru.txt"
  85.  
  86. // Animation
  87. #define ANIM_EXTENSION "carbine"
  88.  
  89. // Animation sequences
  90. enum
  91. {
  92. ANIM_IDLE,
  93. ANIM_RELOAD,
  94. ANIM_DRAW,
  95. ANIM_SHOOT_1,
  96. ANIM_SHOOT_2,
  97. ANIM_CHANGE,
  98.  
  99. ANIM_IDLE_EX,
  100. ANIM_RELOAD_EX,
  101. ANIM_DRAW_EX,
  102. ANIM_SHOOT_1_EX,
  103. ANIM_SHOOT_2_EX,
  104. ANIM_CHANGE_EX
  105. };
  106.  
  107. //**********************************************
  108. //* Some macroses. *
  109. //**********************************************
  110.  
  111. #define SET_MODEL(%0,%1) engfunc(EngFunc_SetModel, %0, %1)
  112. #define SET_ORIGIN(%0,%1) engfunc(EngFunc_SetOrigin, %0, %1)
  113.  
  114. #define PRECACHE_MODEL(%0) engfunc(EngFunc_PrecacheModel, %0)
  115. #define PRECACHE_SOUND(%0) engfunc(EngFunc_PrecacheSound, %0)
  116. #define PRECACHE_GENERIC(%0) engfunc(EngFunc_PrecacheGeneric, %0)
  117.  
  118. #define PRECACHE_MODEL2(%0) PrecacheSoundsFromModel(%0)
  119.  
  120. //**********************************************
  121. //* PvData Offsets. *
  122. //**********************************************
  123.  
  124. // Linux extra offsets
  125. #define extra_offset_weapon 4
  126. #define extra_offset_player 5
  127.  
  128. // CWeaponBox
  129. #define m_rgpPlayerItems_CWeaponBox 34
  130.  
  131. // CBasePlayerItem
  132. #define m_pPlayer 41
  133. #define m_pNext 42
  134. #define m_iId 43
  135.  
  136. // CBasePlayerWeapon
  137. #define m_flNextPrimaryAttack 46
  138. #define m_flNextSecondaryAttack 47
  139. #define m_flTimeWeaponIdle 48
  140. #define m_iPrimaryAmmoType 49
  141. #define m_iClip 51
  142. #define m_fInReload 54
  143. #define m_fInSpecialReload 55
  144. #define m_iDirection 60
  145. #define m_flLastFire 63
  146. #define m_iShotsFired 64
  147.  
  148. // CBaseMonster
  149. #define m_flNextAttack 83
  150.  
  151. // CBasePlayer
  152. #define m_iHideHUD 361
  153. #define m_iFOV 363
  154. #define m_rgpPlayerItems_CBasePlayer 367
  155. #define m_pActiveItem 373
  156. #define m_rgAmmo_CBasePlayer 376
  157. #define m_szAnimExtention 492
  158.  
  159. // Redefines
  160. #define m_flApplyMode m_flLastFire
  161. #define m_iCurrentMode m_fInSpecialReload
  162.  
  163. //**********************************************
  164. //* Let's code our weapon. *
  165. //**********************************************
  166.  
  167. Weapon_OnPrecache()
  168. {
  169. PRECACHE_MODEL(MODEL_VIEW);
  170. PRECACHE_MODEL2(MODEL_VIEW);
  171.  
  172. PRECACHE_MODEL(MODEL_WORLD);
  173. PRECACHE_MODEL(MODEL_PLAYER);
  174. PRECACHE_MODEL(MODEL_SHELL);
  175.  
  176. PRECACHE_SOUND(SOUND_FIRE_C);
  177. PRECACHE_SOUND(SOUND_FIRE_S);
  178.  
  179. PRECACHE_GENERIC(WEAPON_HUD_SPR_C);
  180. PRECACHE_GENERIC(WEAPON_HUD_SPR_S);
  181.  
  182. PRECACHE_GENERIC(WEAPON_HUD_TXT_C);
  183. PRECACHE_GENERIC(WEAPON_HUD_TXT_S);
  184. }
  185.  
  186. Weapon_OnSpawn(const iItem)
  187. {
  188. // Setting world model.
  189. SET_MODEL(iItem, MODEL_WORLD);
  190. }
  191.  
  192. Weapon_OnDeploy(const iItem, const iPlayer, const iClip, const iAmmoPrimary, const iCurrentMode)
  193. {
  194. #pragma unused iClip, iAmmoPrimary
  195.  
  196. static iszViewModel;
  197. if (iszViewModel || (iszViewModel = engfunc(EngFunc_AllocString, MODEL_VIEW)))
  198. {
  199. set_pev_string(iPlayer, pev_viewmodel2, iszViewModel);
  200. }
  201.  
  202. static iszPlayerModel;
  203. if (iszPlayerModel || (iszPlayerModel = engfunc(EngFunc_AllocString, MODEL_PLAYER)))
  204. {
  205. set_pev_string(iPlayer, pev_weaponmodel2, iszPlayerModel);
  206. }
  207.  
  208. Weapon_AdjustCrosshair(iPlayer, iCurrentMode);
  209.  
  210. set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_TIME_DELAY_DEPLOY, extra_offset_weapon);
  211. set_pdata_float(iPlayer, m_flNextAttack, WEAPON_TIME_DELAY_DEPLOY, extra_offset_player);
  212. set_pdata_string(iPlayer, m_szAnimExtention * 4, ANIM_EXTENSION, -1, extra_offset_player * 4);
  213.  
  214. Weapon_SendAnim(iPlayer, iCurrentMode ? ANIM_DRAW_EX : ANIM_DRAW);
  215. }
  216.  
  217. Weapon_OnHolster(iItem, const iPlayer, const iClip, const iAmmoPrimary, const iCurrentMode)
  218. {
  219. #pragma unused iPlayer, iClip, iAmmoPrimary, iCurrentMode
  220.  
  221. // Cancel any reload in progress.
  222. set_pdata_int(iItem, m_fInReload, 0, extra_offset_weapon);
  223.  
  224. // Cancel mode change.
  225. set_pdata_float(iItem , m_flApplyMode, 0.0, extra_offset_weapon);
  226.  
  227. // Restore croshair.
  228. Weapon_AdjustCrosshair(iPlayer, 0);
  229. }
  230.  
  231. Weapon_OnIdle(const iItem, const iPlayer, const iClip, const iAmmoPrimary, const iCurrentMode)
  232. {
  233. #pragma unused iClip, iAmmoPrimary
  234.  
  235. ExecuteHamB(Ham_Weapon_ResetEmptySound, iItem);
  236.  
  237. // Time to idle.
  238. if (get_pdata_int(iItem, m_flTimeWeaponIdle, extra_offset_weapon) > 0.0)
  239. {
  240. return;
  241. }
  242.  
  243. // Adjust crosshair.
  244. Weapon_AdjustCrosshair(iPlayer, iCurrentMode);
  245.  
  246. // Send animation.
  247. Weapon_SendAnim(iPlayer, iCurrentMode ? ANIM_IDLE_EX : ANIM_IDLE);
  248.  
  249. // Time to next idle.
  250. set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_TIME_NEXT_IDLE, extra_offset_weapon);
  251. }
  252.  
  253. Weapon_OnReload(const iItem, const iPlayer, const iClip, const iAmmoPrimary, const iCurrentMode)
  254. {
  255. if (min(WEAPON_MAX_CLIP - iClip, iAmmoPrimary) <= 0)
  256. {
  257. return;
  258. }
  259.  
  260. if (get_pdata_int(iPlayer, m_iFOV, extra_offset_player) != 90)
  261. {
  262. Weapon_OnSecondaryAttack(iItem, iPlayer, iClip, iAmmoPrimary, iCurrentMode);
  263. }
  264.  
  265. set_pdata_int(iItem, m_iClip, 0, extra_offset_weapon);
  266.  
  267. ExecuteHam(Ham_Weapon_Reload, iItem);
  268.  
  269. set_pdata_int(iItem, m_iClip, iClip, extra_offset_weapon);
  270.  
  271. set_pdata_float(iPlayer, m_flNextAttack, WEAPON_TIME_DELAY_RELOAD, extra_offset_player);
  272. set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_TIME_DELAY_RELOAD, extra_offset_weapon);
  273.  
  274. Weapon_SendAnim(iPlayer, iCurrentMode ? ANIM_RELOAD_EX : ANIM_RELOAD);
  275. }
  276.  
  277. Weapon_OnModeSwitch(const iItem, const iPlayer, const iClip, const iAmmoPrimary, const iNewMode)
  278. {
  279. #pragma unused iClip, iAmmoPrimary
  280.  
  281. // Wait for next attack time.
  282. if (get_pdata_float(iPlayer, m_flNextAttack, extra_offset_player) > 0.0)
  283. {
  284. return;
  285. }
  286.  
  287. // Already switching, ignore.
  288. if (get_pdata_float(iItem , m_flApplyMode, extra_offset_weapon))
  289. {
  290. return;
  291. }
  292.  
  293. // Mode is the same, ignore.
  294. if (get_pdata_int(iItem , m_iCurrentMode, extra_offset_weapon) == iNewMode)
  295. {
  296. return;
  297. }
  298.  
  299. // Zoom off
  300. if (get_pdata_int(iPlayer, m_iFOV, extra_offset_player) != 90)
  301. {
  302. Weapon_OnSecondaryAttack(iItem, iPlayer, iClip, iAmmoPrimary, !iNewMode);
  303. }
  304.  
  305. // Change crosshair status.
  306. Weapon_AdjustCrosshair(iPlayer, iNewMode);
  307.  
  308. // Play animation.
  309. Weapon_SendAnim(iPlayer, iNewMode ? ANIM_CHANGE : ANIM_CHANGE_EX);
  310.  
  311. // Set delays
  312. set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_TIME_DELAY_SWITCH, extra_offset_weapon);
  313. set_pdata_float(iItem, m_flApplyMode, WEAPON_TIME_DELAY_SWITCH + get_gametime() - 0.5, extra_offset_weapon);
  314. set_pdata_float(iPlayer, m_flNextAttack, WEAPON_TIME_DELAY_SWITCH, extra_offset_player);
  315. }
  316.  
  317. Weapon_OnPrimaryAttack(const iItem, const iPlayer, const iClip, const iAmmoPrimary, const iCurrentMode)
  318. {
  319. #pragma unused iAmmoPrimary
  320.  
  321. CallOrigFireBullets3(iItem, iPlayer);
  322.  
  323. if (iClip <= 0)
  324. {
  325. return;
  326. }
  327.  
  328. static iFlags, iShellModelIndex, Float: vecVelocity[3];
  329.  
  330. iFlags = pev(iPlayer, pev_flags);
  331. pev(iPlayer, pev_velocity, vecVelocity);
  332.  
  333. if (iShellModelIndex || (iShellModelIndex = PRECACHE_MODEL(MODEL_SHELL)))
  334. {
  335. EjectBrass(iPlayer, iShellModelIndex, 1, .flForwardScale = 9.0);
  336. }
  337.  
  338. set_pdata_float(iItem, m_flTimeWeaponIdle, WEAPON_TIME_NEXT_IDLE, extra_offset_weapon);
  339.  
  340. if (iCurrentMode)
  341. {
  342. Weapon_SendAnim(iPlayer, random_num(ANIM_SHOOT_1_EX, ANIM_SHOOT_2_EX));
  343.  
  344. set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_TIME_NEXT_ATTACK_S, extra_offset_weapon);
  345. set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_TIME_NEXT_ATTACK_S, extra_offset_weapon);
  346.  
  347. emit_sound(iPlayer, CHAN_WEAPON, SOUND_FIRE_S, 0.9, ATTN_NORM, 0, PITCH_NORM);
  348.  
  349. if (xs_vec_len(vecVelocity) > 0)
  350. {
  351. Weapon_KickBack(iItem, iPlayer, 1.5, 0.45, 0.225, 0.05, 6.5, 2.5, 7);
  352. }
  353. else if (!(iFlags & FL_ONGROUND))
  354. {
  355. Weapon_KickBack(iItem, iPlayer, 2.0, 1.0, 0.5, 0.35, 9.0, 6.0, 5);
  356. }
  357. else if (iFlags & FL_DUCKING)
  358. {
  359. Weapon_KickBack(iItem, iPlayer, 0.9, 0.35, 0.15, 0.025, 5.5, 1.5, 9);
  360. }
  361. else
  362. {
  363. Weapon_KickBack(iItem, iPlayer, 1.0, 0.375, 0.175, 0.0375, 5.75, 1.75, 8);
  364. }
  365. }
  366. else
  367. {
  368. Weapon_SendAnim(iPlayer, random_num(ANIM_SHOOT_1, ANIM_SHOOT_2));
  369.  
  370. set_pdata_float(iItem, m_flNextPrimaryAttack, WEAPON_TIME_NEXT_ATTACK_C, extra_offset_weapon);
  371. set_pdata_float(iItem, m_flNextSecondaryAttack, WEAPON_TIME_NEXT_ATTACK_C, extra_offset_weapon);
  372.  
  373. emit_sound(iPlayer, CHAN_WEAPON, SOUND_FIRE_C, 0.9, ATTN_NORM, 0, PITCH_NORM);
  374.  
  375. if (xs_vec_len(vecVelocity) > 0)
  376. {
  377. Weapon_KickBack(iItem, iPlayer, 1.0, 0.45, 0.28, 0.045, 3.75, 3.0, 7);
  378. }
  379. else if (!(iFlags & FL_ONGROUND))
  380. {
  381. Weapon_KickBack(iItem, iPlayer, 1.2, 0.5, 0.23, 0.15, 5.5, 3.5, 6);
  382. }
  383. else if (iFlags & FL_DUCKING)
  384. {
  385. Weapon_KickBack(iItem, iPlayer, 0.6, 0.3, 0.2, 0.0125, 3.25, 2.0, 7);
  386. }
  387. else
  388. {
  389. Weapon_KickBack(iItem, iPlayer, 0.65, 0.35, 0.25, 0.015, 3.5, 2.25, 7);
  390. }
  391. }
  392. }
  393.  
  394. Weapon_OnSecondaryAttack(const iItem, const iPlayer, const iClip, const iAmmoPrimary, const iCurrentMode)
  395. {
  396. #pragma unused iClip, iAmmoPrimary
  397.  
  398. if (iCurrentMode)
  399. {
  400. set_pdata_int(iPlayer, m_iFOV, get_pdata_int(iPlayer, m_iFOV, extra_offset_player) == 90 ? WEAPON_FOV_ZOOM : 90, extra_offset_player);
  401. }
  402.  
  403. set_pdata_float(iItem, m_flNextSecondaryAttack, 0.3, extra_offset_weapon);
  404. }
  405.  
  406. Weapon_AdjustCrosshair(const iPlayer, const iCurrentMode)
  407. {
  408. #define HIDEHUD_CROSSHAIR ( 1 << 6 )
  409.  
  410. if (iCurrentMode)
  411. {
  412. set_pdata_int(iPlayer, m_iHideHUD, get_pdata_int(iPlayer, m_iHideHUD, extra_offset_player) | HIDEHUD_CROSSHAIR, extra_offset_player);
  413. }
  414. else
  415. {
  416. set_pdata_int(iPlayer, m_iHideHUD, get_pdata_int(iPlayer, m_iHideHUD, extra_offset_player) & ~HIDEHUD_CROSSHAIR, extra_offset_player);
  417. }
  418. }
  419.  
  420. //*********************************************************************
  421. //* Don't modify the code below this line unless *
  422. //* you know _exactly_ what you are doing!!! *
  423. //*********************************************************************
  424.  
  425. #define CSW_DUMMY 2
  426. #define MSG_WEAPONLIST 78
  427.  
  428. #define _CALLFUNC(%0,%1,%2) \
  429. \
  430. Weapon_On%0 \
  431. ( \
  432. %1, \
  433. %2, \
  434. \
  435. get_pdata_int(%1, m_iClip, extra_offset_weapon), \
  436. GetAmmoInventory(%2, PrimaryAmmoIndex(%1)), \
  437. get_pdata_int(%1, m_iCurrentMode, extra_offset_weapon) \
  438. )
  439.  
  440. #define STATEMENT_FALLBACK(%0,%1,%2) public %0()<>{return %1;} public %0()<%2>{return %1;}
  441.  
  442. #define MESSAGE_BEGIN(%0,%1,%2,%3) engfunc(EngFunc_MessageBegin, %0, %1, %2, %3)
  443. #define MESSAGE_END() message_end()
  444.  
  445. #define WRITE_ANGLE(%0) engfunc(EngFunc_WriteAngle, %0)
  446. #define WRITE_BYTE(%0) write_byte(%0)
  447. #define WRITE_COORD(%0) engfunc(EngFunc_WriteCoord, %0)
  448. #define WRITE_STRING(%0) write_string(%0)
  449. #define WRITE_SHORT(%0) write_short(%0)
  450.  
  451. #define MDLL_Spawn(%0) dllfunc(DLLFunc_Spawn, %0)
  452. #define MDLL_Touch(%0,%1) dllfunc(DLLFunc_Touch, %0, %1)
  453.  
  454. //**********************************************
  455. //* Motor!. *
  456. //**********************************************
  457.  
  458. new g_iszWeaponKey;
  459. new g_iForwardDecalIndex;
  460.  
  461. #define IsValidPev(%0) (pev_valid(%0) == 2)
  462. #define IsCustomItem(%0) (pev(%0, pev_impulse) == g_iszWeaponKey)
  463.  
  464. public plugin_precache()
  465. {
  466. Weapon_OnPrecache();
  467. ExtraItem_Register();
  468.  
  469. g_iszWeaponKey = engfunc(EngFunc_AllocString, WEAPON_NAME_C);
  470. g_iForwardDecalIndex = register_forward(FM_DecalIndex, "FakeMeta_DecalIndex_Post", true);
  471.  
  472. register_clcmd(WEAPON_NAME_C, "Cmd_WeaponSelect");
  473. register_clcmd(WEAPON_NAME_S, "Cmd_WeaponSelectEx");
  474.  
  475. register_message(MSG_WEAPONLIST, /*get_user_msgid("WeaponList"),*/ "MsgHook_WeaponList");
  476. }
  477.  
  478. public plugin_init()
  479. {
  480. register_plugin(PLUGIN, VERSION, AUTHOR);
  481.  
  482. RegisterHam(Ham_Spawn, "weaponbox", "HamHook_Weaponbox_Spawn_Post", true);
  483.  
  484. RegisterHam(Ham_TraceAttack, "func_breakable", "HamHook_Entity_TraceAttack", false);
  485. RegisterHam(Ham_TraceAttack, "hostage_entity", "HamHook_Entity_TraceAttack", false);
  486. RegisterHam(Ham_TraceAttack, "info_target", "HamHook_Entity_TraceAttack", false);
  487. RegisterHam(Ham_TraceAttack, "player", "HamHook_Entity_TraceAttack", false);
  488.  
  489. RegisterHam(Ham_Item_Deploy, WEAPON_REFERANCE, "HamHook_Item_Deploy_Post", true);
  490. RegisterHam(Ham_Item_Holster, WEAPON_REFERANCE, "HamHook_Item_Holster", false);
  491. RegisterHam(Ham_Item_AddToPlayer, WEAPON_REFERANCE, "HamHook_Item_AddToPlayer_Post", true);
  492. RegisterHam(Ham_Item_PostFrame, WEAPON_REFERANCE, "HamHook_Item_PostFrame", false);
  493. RegisterHam(Ham_CS_Item_GetMaxSpeed, WEAPON_REFERANCE, "HamHook_Item_GetMaxSpeed", false);
  494.  
  495. RegisterHam(Ham_Weapon_Reload, WEAPON_REFERANCE, "HamHook_Item_Reload", false);
  496. RegisterHam(Ham_Weapon_WeaponIdle, WEAPON_REFERANCE, "HamHook_Item_WeaponIdle", false);
  497. RegisterHam(Ham_Weapon_PrimaryAttack, WEAPON_REFERANCE, "HamHook_Item_PrimaryAttack", false);
  498.  
  499. register_forward(FM_SetModel, "FakeMeta_SetModel", false);
  500. register_forward(FM_TraceLine, "FakeMeta_TraceLine_Post", true);
  501. register_forward(FM_PlaybackEvent, "FakeMeta_PlaybackEvent", false);
  502. register_forward(FM_UpdateClientData, "FakeMeta_UpdateClientData_Post", true);
  503.  
  504. register_message(get_user_msgid("DeathMsg"), "MsgHook_Death");
  505. register_message(get_user_msgid("CurWeapon"), "MsgHook_CurWeapon");
  506.  
  507. unregister_forward(FM_DecalIndex, g_iForwardDecalIndex, true);
  508. }
  509.  
  510. #if defined _DEBUG
  511.  
  512. ExtraItem_Register()
  513. {
  514. register_clcmd(_DEBUG_CMD, "Cmd_WeaponGive");
  515. }
  516.  
  517. public Cmd_WeaponGive(const iPlayer)
  518. {
  519. Weapon_Give(iPlayer);
  520. }
  521.  
  522. #else
  523.  
  524. new g_iItemID;
  525.  
  526. #if !defined _ZP50
  527.  
  528. ExtraItem_Register()
  529. {
  530. g_iItemID = zp_register_extra_item(ZP_ITEM_NAME, ZP_ITEM_COST, ZP_TEAM_HUMAN);
  531. }
  532.  
  533. public zp_extra_item_selected(id, itemid)
  534. {
  535. if (itemid == g_iItemID)
  536. {
  537. Weapon_Give(id);
  538. }
  539. }
  540.  
  541. #else
  542.  
  543. RegisterExtraItem()
  544. {
  545. g_iItemID = zp_items_register(ZP_ITEM_NAME, ZP_ITEM_COST);
  546. }
  547.  
  548. public zp_fw_items_select_pre(id, itemid, ignorecost)
  549. {
  550. if (itemid != g_iItemID)
  551. {
  552. return ZP_ITEM_AVAILABLE;
  553. }
  554.  
  555. if (zp_core_is_zombie(id))
  556. {
  557. return ZP_ITEM_DONT_SHOW;
  558. }
  559.  
  560. return ZP_ITEM_AVAILABLE;
  561. }
  562.  
  563. public zp_fw_items_select_post(id, itemid, ignorecost)
  564. {
  565. if (itemid == g_iItemID)
  566. {
  567. Weapon_Give(id);
  568. }
  569. }
  570.  
  571. #endif
  572.  
  573. #endif
  574.  
  575. //**********************************************
  576. //* Item (weapon) hooks. *
  577. //**********************************************
  578.  
  579. public FakeMeta_UpdateClientData_Post(const iPlayer, const iSendWeapons, const CD_Handle)
  580. {
  581. static iItem;
  582.  
  583. if (CheckItem2(iPlayer, iItem))
  584. {
  585. set_cd(CD_Handle, CD_flNextAttack, get_gametime() + 0.001);
  586. }
  587. }
  588.  
  589. public HamHook_Item_GetMaxSpeed(const iItem)
  590. {
  591. if (!IsValidPev(iItem) || !IsCustomItem(iItem))
  592. {
  593. return HAM_IGNORED;
  594. }
  595.  
  596. SetHamReturnFloat(WEAPON_MAX_SPEED);
  597. return HAM_OVERRIDE;
  598. }
  599.  
  600. public HamHook_Item_Deploy_Post(const iItem)
  601. {
  602. new iPlayer;
  603.  
  604. if (!CheckItem(iItem, iPlayer))
  605. {
  606. return HAM_IGNORED;
  607. }
  608.  
  609. _CALLFUNC(Deploy, iItem, iPlayer);
  610. return HAM_IGNORED;
  611. }
  612.  
  613. public HamHook_Item_Holster(const iItem)
  614. {
  615. new iPlayer;
  616.  
  617. if (!CheckItem(iItem, iPlayer))
  618. {
  619. return HAM_IGNORED;
  620. }
  621.  
  622. _CALLFUNC(Holster, iItem, iPlayer);
  623.  
  624. set_pev(iPlayer, pev_viewmodel, 0);
  625. set_pev(iPlayer, pev_weaponmodel, 0);
  626.  
  627. return HAM_SUPERCEDE;
  628. }
  629.  
  630. public HamHook_Item_WeaponIdle(const iItem)
  631. {
  632. static iPlayer;
  633.  
  634. if (!CheckItem(iItem, iPlayer))
  635. {
  636. return HAM_IGNORED;
  637. }
  638.  
  639. _CALLFUNC(Idle, iItem, iPlayer);
  640. return HAM_SUPERCEDE;
  641. }
  642.  
  643. public HamHook_Item_Reload(const iItem)
  644. {
  645. static iPlayer;
  646.  
  647. if (!CheckItem(iItem, iPlayer))
  648. {
  649. return HAM_IGNORED;
  650. }
  651.  
  652. _CALLFUNC(Reload, iItem, iPlayer);
  653. return HAM_SUPERCEDE;
  654. }
  655.  
  656. public HamHook_Item_PrimaryAttack(const iItem)
  657. {
  658. static iPlayer;
  659.  
  660. if (!CheckItem(iItem, iPlayer))
  661. {
  662. return HAM_IGNORED;
  663. }
  664.  
  665. _CALLFUNC(PrimaryAttack, iItem, iPlayer);
  666. return HAM_SUPERCEDE;
  667. }
  668.  
  669. public HamHook_Item_PostFrame(const iItem)
  670. {
  671. static iButton, iPlayer, Float: flApplyModeTime;
  672.  
  673. if (!CheckItem(iItem, iPlayer))
  674. {
  675. return HAM_IGNORED;
  676. }
  677.  
  678. flApplyModeTime = get_pdata_float(iItem, m_flApplyMode, extra_offset_weapon);
  679.  
  680. // Time to apply new mode.
  681. if (flApplyModeTime && flApplyModeTime <= get_gametime())
  682. {
  683. set_pdata_float(iItem, m_flApplyMode, 0.0, extra_offset_weapon);
  684. set_pdata_int(iItem, m_iCurrentMode, !get_pdata_int(iItem, m_iCurrentMode, extra_offset_weapon), extra_offset_weapon);
  685. }
  686.  
  687. // Complete reload
  688. if (get_pdata_int(iItem, m_fInReload, extra_offset_weapon))
  689. {
  690. new iClip = get_pdata_int(iItem, m_iClip, extra_offset_weapon);
  691. new iPrimaryAmmoIndex = PrimaryAmmoIndex(iItem);
  692. new iAmmoPrimary = GetAmmoInventory(iPlayer, iPrimaryAmmoIndex);
  693. new iAmount = min(WEAPON_MAX_CLIP - iClip, iAmmoPrimary);
  694.  
  695. set_pdata_int(iItem, m_iClip, iClip + iAmount, extra_offset_weapon);
  696. set_pdata_int(iItem, m_fInReload, false, extra_offset_weapon);
  697.  
  698. SetAmmoInventory(iPlayer, iPrimaryAmmoIndex, iAmmoPrimary - iAmount);
  699. }
  700.  
  701. // Call secondary attack
  702. if ((iButton = pev(iPlayer, pev_button)) & IN_ATTACK2
  703. && get_pdata_float(iItem, m_flNextSecondaryAttack, extra_offset_weapon) < 0.0)
  704. {
  705. _CALLFUNC(SecondaryAttack, iItem, iPlayer);
  706. set_pev(iPlayer, pev_button, iButton & ~IN_ATTACK2);
  707. }
  708.  
  709. return HAM_IGNORED;
  710. }
  711.  
  712. //**********************************************
  713. //* Weapon list update. *
  714. //**********************************************
  715.  
  716. public Cmd_WeaponSelect(const iPlayer)
  717. {
  718. Weapon_ModeSwitch(iPlayer, 0);
  719. return PLUGIN_HANDLED;
  720. }
  721.  
  722. public Cmd_WeaponSelectEx(const iPlayer)
  723. {
  724. Weapon_ModeSwitch(iPlayer, 1);
  725. return PLUGIN_HANDLED;
  726. }
  727.  
  728. public HamHook_Item_AddToPlayer_Post(const iItem, const iPlayer)
  729. {
  730. if (!IsValidPev(iItem) || !IsValidPev(iPlayer))
  731. {
  732. return HAM_IGNORED;
  733. }
  734.  
  735. MsgHook_WeaponList(MSG_WEAPONLIST, iItem, iPlayer);
  736. return HAM_IGNORED;
  737. }
  738.  
  739. public MsgHook_CurWeapon(const iMsgID, const iMsgDest, const iPlayer)
  740. {
  741. static iItem;
  742.  
  743. if (CheckItem2(iPlayer, iItem)
  744. && get_pdata_int(iItem, m_iId, extra_offset_weapon) == get_msg_arg_int(2))
  745. {
  746. MESSAGE_BEGIN(iMsgDest, iMsgID, {0.0, 0.0, 0.0}, iPlayer);
  747. WRITE_BYTE(get_msg_arg_int(1));
  748. WRITE_BYTE(CSW_DUMMY);
  749. WRITE_BYTE(get_msg_arg_int(3));
  750. MESSAGE_END();
  751. }
  752. }
  753.  
  754. public MsgHook_WeaponList(const iMsgID, const iMsgDest, const iMsgEntity)
  755. {
  756. static arrWeaponListData[8];
  757.  
  758. if (!iMsgEntity)
  759. {
  760. new szWeaponName[32];
  761. get_msg_arg_string(1, szWeaponName, charsmax(szWeaponName));
  762.  
  763. if (!strcmp(szWeaponName, WEAPON_REFERANCE))
  764. {
  765. for (new i, a = sizeof arrWeaponListData; i < a; i++)
  766. {
  767. arrWeaponListData[i] = get_msg_arg_int(i + 2);
  768. }
  769. }
  770.  
  771. return;
  772. }
  773.  
  774. new bool: bIsCustom = IsCustomItem(iMsgDest);
  775.  
  776. if (!bIsCustom && pev(iMsgDest, pev_impulse))
  777. {
  778. return;
  779. }
  780.  
  781. MESSAGE_BEGIN(MSG_ONE, iMsgID, {0.0, 0.0, 0.0}, iMsgEntity);
  782. WRITE_STRING(bIsCustom ? WEAPON_NAME_C : WEAPON_REFERANCE);
  783.  
  784. for (new i, a = sizeof arrWeaponListData; i < a; i++)
  785. {
  786. WRITE_BYTE(arrWeaponListData[i]);
  787. }
  788.  
  789. MESSAGE_END();
  790.  
  791. if (!bIsCustom)
  792. {
  793. return;
  794. }
  795.  
  796. user_has_weapon(iMsgEntity, CSW_DUMMY, 1);
  797.  
  798. MESSAGE_BEGIN(MSG_ONE, iMsgID, {0.0, 0.0, 0.0}, iMsgEntity);
  799. WRITE_STRING(WEAPON_NAME_S);
  800.  
  801. for (new i, a = sizeof arrWeaponListData; i < a; i++)
  802. {
  803. switch (i)
  804. {
  805. case 5: WRITE_BYTE(20);
  806. case 6: WRITE_BYTE(CSW_DUMMY);
  807.  
  808. default: WRITE_BYTE(arrWeaponListData[i]);
  809. }
  810. }
  811.  
  812. MESSAGE_END();
  813.  
  814. static msgWeapPickup;
  815. if (msgWeapPickup || (msgWeapPickup = get_user_msgid("WeapPickup")))
  816. {
  817. MESSAGE_BEGIN(MSG_ONE, msgWeapPickup, {0.0, 0.0, 0.0}, iMsgEntity);
  818. WRITE_BYTE(CSW_DUMMY);
  819. MESSAGE_END();
  820. }
  821. }
  822.  
  823. Weapon_ModeSwitch(const iPlayer, const iNewMode)
  824. {
  825. if (!IsValidPev(iPlayer))
  826. {
  827. return;
  828. }
  829.  
  830. new iItem;
  831.  
  832. if (!CheckItem2(iPlayer, iItem))
  833. {
  834. engclient_cmd(iPlayer, WEAPON_REFERANCE);
  835. }
  836. else
  837. {
  838. Weapon_OnModeSwitch
  839. (
  840. iItem,
  841. iPlayer,
  842.  
  843. get_pdata_int(iItem, m_iClip, extra_offset_weapon),
  844. GetAmmoInventory(iPlayer, PrimaryAmmoIndex(iItem)),
  845.  
  846. iNewMode
  847. );
  848. }
  849. }
  850.  
  851. //**********************************************
  852. //* Fire bullets. *
  853. //**********************************************
  854.  
  855. CallOrigFireBullets3(const iItem, const iPlayer)
  856. {
  857. static Float: vecPuncheAngle[3];
  858.  
  859. state stFireBullets: Enabled;
  860.  
  861. pev(iPlayer, pev_punchangle, vecPuncheAngle);
  862. ExecuteHam(Ham_Weapon_PrimaryAttack, iItem);
  863. set_pev(iPlayer, pev_punchangle, vecPuncheAngle);
  864.  
  865. state stFireBullets: Disabled;
  866. }
  867.  
  868. public FakeMeta_TraceLine_Post(const Float: vecTraceStart[3], const Float: vecTraceEnd[3], const fNoMonsters, const iEntToSkip, const iTrace) <stFireBullets: Enabled>
  869. {
  870. static Float: vecEndPos[3];
  871.  
  872. get_tr2(iTrace, TR_vecEndPos, vecEndPos);
  873. engfunc(EngFunc_TraceLine, vecEndPos, vecTraceStart, fNoMonsters, iEntToSkip, 0);
  874.  
  875. UTIL_GunshotDecalTrace(0);
  876. UTIL_GunshotDecalTrace(iTrace, true);
  877.  
  878. return FMRES_IGNORED;
  879. }
  880. STATEMENT_FALLBACK(FakeMeta_TraceLine_Post, FMRES_IGNORED, stFireBullets: Disabled)
  881.  
  882. public HamHook_Entity_TraceAttack(const iEntity, const iAttacker, const Float: flDamage) <stFireBullets: Enabled>
  883. {
  884. SetHamParamFloat(3, flDamage * WEAPON_MULTIPLIER_DAMAGE);
  885. return HAM_IGNORED;
  886. }
  887. STATEMENT_FALLBACK(HamHook_Entity_TraceAttack, HAM_IGNORED, stFireBullets: Disabled)
  888.  
  889. public MsgHook_Death() <stFireBullets: Enabled>
  890. {
  891. static szTruncatedWeaponName[32];
  892.  
  893. if (szTruncatedWeaponName[0] == EOS)
  894. {
  895. copy(szTruncatedWeaponName, charsmax(szTruncatedWeaponName), WEAPON_NAME_C);
  896. replace(szTruncatedWeaponName, charsmax(szTruncatedWeaponName), "weapon_", "");
  897. }
  898.  
  899. set_msg_arg_string(4, szTruncatedWeaponName);
  900. return PLUGIN_CONTINUE;
  901. }
  902. STATEMENT_FALLBACK(MsgHook_Death, PLUGIN_CONTINUE, stFireBullets: Disabled)
  903.  
  904. public FakeMeta_PlaybackEvent() <stFireBullets: Enabled>
  905. {
  906. return FMRES_SUPERCEDE;
  907. }
  908. STATEMENT_FALLBACK(FakeMeta_PlaybackEvent, FMRES_IGNORED, stFireBullets: Disabled)
  909.  
  910. //**********************************************
  911. //* Weaponbox world model. *
  912. //**********************************************
  913.  
  914. public HamHook_Weaponbox_Spawn_Post(const iWeaponBox)
  915. {
  916. if (IsValidPev(iWeaponBox))
  917. {
  918. state (IsValidPev(pev(iWeaponBox, pev_owner))) stWeaponBox: Enabled;
  919. }
  920.  
  921. return HAM_IGNORED;
  922. }
  923.  
  924. public FakeMeta_SetModel(const iEntity) <stWeaponBox: Enabled>
  925. {
  926. state stWeaponBox: Disabled;
  927.  
  928. if (!IsValidPev(iEntity))
  929. {
  930. return FMRES_IGNORED;
  931. }
  932.  
  933. #define MAX_ITEM_TYPES 6
  934.  
  935. for (new i, iItem; i < MAX_ITEM_TYPES; i++)
  936. {
  937. iItem = get_pdata_cbase(iEntity, m_rgpPlayerItems_CWeaponBox + i, extra_offset_weapon);
  938.  
  939. if (IsValidPev(iItem) && IsCustomItem(iItem))
  940. {
  941. user_has_weapon(pev(iEntity, pev_owner), CSW_DUMMY, 0);
  942.  
  943. SET_MODEL(iEntity, MODEL_WORLD);
  944. return FMRES_SUPERCEDE;
  945. }
  946. }
  947.  
  948. return FMRES_IGNORED;
  949. }
  950. STATEMENT_FALLBACK(FakeMeta_SetModel, FMRES_IGNORED, stWeaponBox: Disabled)
  951.  
  952. //**********************************************
  953. //* Create and check our custom weapon. *
  954. //**********************************************
  955.  
  956. new g_bitIsConnected;
  957.  
  958. #define BitSet(%0,%1) (%0 |= (1 << (%1 - 1)))
  959. #define BitClear(%0,%1) (%0 &= ~(1 << (%1 - 1)))
  960. #define BitCheck(%0,%1) (%0 & (1 << (%1 - 1)))
  961.  
  962. public client_putinserver(id)
  963. {
  964. BitSet(g_bitIsConnected, id);
  965. }
  966.  
  967. public client_disconnect(id)
  968. {
  969. BitClear(g_bitIsConnected, id);
  970. }
  971.  
  972. bool: CheckItem(const iItem, &iPlayer)
  973. {
  974. if (!IsValidPev(iItem) || !IsCustomItem(iItem))
  975. {
  976. return false;
  977. }
  978.  
  979. iPlayer = get_pdata_cbase(iItem, m_pPlayer, extra_offset_weapon);
  980.  
  981. if (!IsValidPev(iPlayer) || !BitCheck(g_bitIsConnected, iPlayer))
  982. {
  983. return false;
  984. }
  985.  
  986. return true;
  987. }
  988.  
  989. bool: CheckItem2(const iPlayer, &iItem)
  990. {
  991. if (!BitCheck(g_bitIsConnected, iPlayer) || !IsValidPev(iPlayer))
  992. {
  993. return false;
  994. }
  995.  
  996. iItem = get_pdata_cbase(iPlayer, m_pActiveItem, extra_offset_player);
  997.  
  998. if (!IsValidPev(iItem) || !IsCustomItem(iItem))
  999. {
  1000. return false;
  1001. }
  1002.  
  1003. return true;
  1004. }
  1005.  
  1006. Weapon_Create(const Float: vecOrigin[3] = {0.0, 0.0, 0.0}, const Float: vecAngles[3] = {0.0, 0.0, 0.0})
  1007. {
  1008. new iWeapon;
  1009.  
  1010. static iszAllocStringCached;
  1011. if (iszAllocStringCached || (iszAllocStringCached = engfunc(EngFunc_AllocString, WEAPON_REFERANCE)))
  1012. {
  1013. iWeapon = engfunc(EngFunc_CreateNamedEntity, iszAllocStringCached);
  1014. }
  1015.  
  1016. if (!IsValidPev(iWeapon))
  1017. {
  1018. return FM_NULLENT;
  1019. }
  1020.  
  1021. MDLL_Spawn(iWeapon);
  1022. SET_ORIGIN(iWeapon, vecOrigin);
  1023.  
  1024. set_pdata_int(iWeapon, m_iClip, WEAPON_MAX_CLIP, extra_offset_weapon);
  1025. set_pdata_int(iWeapon, m_iCurrentMode, 0, extra_offset_weapon);
  1026.  
  1027. set_pev(iWeapon, pev_impulse, g_iszWeaponKey);
  1028. set_pev(iWeapon, pev_angles, vecAngles);
  1029.  
  1030. Weapon_OnSpawn(iWeapon);
  1031.  
  1032. return iWeapon;
  1033. }
  1034.  
  1035. Weapon_Give(const iPlayer)
  1036. {
  1037. if (!IsValidPev(iPlayer))
  1038. {
  1039. return FM_NULLENT;
  1040. }
  1041.  
  1042. new iWeapon, Float: vecOrigin[3];
  1043. pev(iPlayer, pev_origin, vecOrigin);
  1044.  
  1045. if ((iWeapon = Weapon_Create(vecOrigin)) != FM_NULLENT)
  1046. {
  1047. Player_DropWeapons(iPlayer, ExecuteHamB(Ham_Item_ItemSlot, iWeapon));
  1048.  
  1049. set_pev(iWeapon, pev_spawnflags, pev(iWeapon, pev_spawnflags) | SF_NORESPAWN);
  1050. MDLL_Touch(iWeapon, iPlayer);
  1051.  
  1052. SetAmmoInventory(iPlayer, PrimaryAmmoIndex(iWeapon), WEAPON_DEFAULT_AMMO);
  1053.  
  1054. return iWeapon;
  1055. }
  1056.  
  1057. return FM_NULLENT;
  1058. }
  1059.  
  1060. Player_DropWeapons(const iPlayer, const iSlot)
  1061. {
  1062. new szWeaponName[32], iItem = get_pdata_cbase(iPlayer, m_rgpPlayerItems_CBasePlayer + iSlot, extra_offset_player);
  1063.  
  1064. while (IsValidPev(iItem))
  1065. {
  1066. pev(iItem, pev_classname, szWeaponName, charsmax(szWeaponName));
  1067. engclient_cmd(iPlayer, "drop", szWeaponName);
  1068.  
  1069. iItem = get_pdata_cbase(iItem, m_pNext, extra_offset_weapon);
  1070. }
  1071. }
  1072.  
  1073. Weapon_SendAnim(const iPlayer, const iAnim)
  1074. {
  1075. set_pev(iPlayer, pev_weaponanim, iAnim);
  1076.  
  1077. MESSAGE_BEGIN(MSG_ONE_UNRELIABLE, SVC_WEAPONANIM, {0.0, 0.0, 0.0}, iPlayer);
  1078. WRITE_BYTE(iAnim);
  1079. WRITE_BYTE(0);
  1080. MESSAGE_END();
  1081. }
  1082.  
  1083. //**********************************************
  1084. //* Brass ejection. *
  1085. //**********************************************
  1086.  
  1087. EjectBrass(const iPlayer, const iModelIndex, const iBounce, const Float:flUpScale = -9.0, const Float: flForwardScale = 16.0, const Float: flRightScale = 0.0)
  1088. {
  1089. static i, msgBrass;
  1090.  
  1091. static Float: vecUp[3];
  1092. static Float: vecRight[3];
  1093. static Float: vecForward[3];
  1094.  
  1095. static Float: vecAngle[3];
  1096. static Float: vecOrigin[3];
  1097. static Float: vecViewOfs[3];
  1098. static Float: vecVelocity[3];
  1099.  
  1100. pev(iPlayer, pev_v_angle, vecAngle);
  1101. pev(iPlayer, pev_punchangle, vecOrigin);
  1102.  
  1103. xs_vec_add(vecAngle, vecOrigin, vecOrigin);
  1104. engfunc(EngFunc_MakeVectors, vecOrigin);
  1105.  
  1106. pev(iPlayer, pev_origin, vecOrigin);
  1107. pev(iPlayer, pev_view_ofs, vecViewOfs);
  1108. pev(iPlayer, pev_velocity, vecVelocity);
  1109.  
  1110. global_get(glb_v_up, vecUp);
  1111. global_get(glb_v_right, vecRight);
  1112. global_get(glb_v_forward, vecForward);
  1113.  
  1114. for (i = 0; i < 3; i++)
  1115. {
  1116. vecOrigin[i] = vecOrigin[i] + vecViewOfs[i] + vecForward[i] * flForwardScale + vecUp[i] * flUpScale + vecRight[i] * flRightScale;
  1117. vecVelocity[i] = vecVelocity[i] + vecForward[i] * 25.0 + vecUp[i] * random_float(80.0, 100.0) + vecRight[i] * random_float(50.0, 70.0);
  1118. }
  1119.  
  1120. if (msgBrass || (msgBrass = get_user_msgid("Brass")))
  1121. {
  1122. MESSAGE_BEGIN(MSG_PVS, msgBrass, vecOrigin, 0);
  1123. WRITE_BYTE(0 /* dummy */);
  1124. WRITE_COORD(vecOrigin[0]);
  1125. WRITE_COORD(vecOrigin[1]);
  1126. WRITE_COORD(vecOrigin[2]);
  1127. WRITE_COORD(0.0 /* dummy */);
  1128. WRITE_COORD(0.0 /* dummy */);
  1129. WRITE_COORD(0.0 /* dummy */);
  1130. WRITE_COORD(vecVelocity[0]);
  1131. WRITE_COORD(vecVelocity[1]);
  1132. WRITE_COORD(vecVelocity[2]);
  1133. WRITE_ANGLE(vecAngle[1]);
  1134. WRITE_SHORT(iModelIndex);
  1135. WRITE_BYTE(iBounce);
  1136. WRITE_BYTE(0 /* dummy */);
  1137. WRITE_BYTE(iPlayer);
  1138. MESSAGE_END();
  1139. }
  1140. }
  1141.  
  1142. //**********************************************
  1143. //* Kick back. *
  1144. //**********************************************
  1145.  
  1146. Weapon_KickBack(const iItem, const iPlayer, Float: upBase, Float: lateralBase, const Float: upMod, const Float: lateralMod, Float: upMax, Float: lateralMax, const directionChange)
  1147. {
  1148. static iDirection;
  1149. static iShotsFired;
  1150.  
  1151. static Float: vecPunchangle[3];
  1152. pev(iPlayer, pev_punchangle, vecPunchangle);
  1153.  
  1154. if ((iShotsFired = get_pdata_int(iItem, m_iShotsFired, extra_offset_weapon)) != 1)
  1155. {
  1156. upBase += iShotsFired * upMod;
  1157. lateralBase += iShotsFired * lateralMod;
  1158. }
  1159.  
  1160. upMax *= -1.0;
  1161. vecPunchangle[0] -= upBase;
  1162.  
  1163. if (upMax >= vecPunchangle[0])
  1164. {
  1165. vecPunchangle[0] = upMax;
  1166. }
  1167.  
  1168. if ((iDirection = get_pdata_int(iItem, m_iDirection, extra_offset_weapon)))
  1169. {
  1170. vecPunchangle[1] += lateralBase;
  1171.  
  1172. if (lateralMax < vecPunchangle[1])
  1173. {
  1174. vecPunchangle[1] = lateralMax;
  1175. }
  1176. }
  1177. else
  1178. {
  1179. lateralMax *= -1.0;
  1180. vecPunchangle[1] -= lateralBase;
  1181.  
  1182. if (lateralMax > vecPunchangle[1])
  1183. {
  1184. vecPunchangle[1] = lateralMax;
  1185. }
  1186. }
  1187.  
  1188. if (!random_num(0, directionChange))
  1189. {
  1190. set_pdata_int(iItem, m_iDirection, !iDirection, extra_offset_weapon);
  1191. }
  1192.  
  1193. set_pev(iPlayer, pev_punchangle, vecPunchangle);
  1194. }
  1195.  
  1196. //**********************************************
  1197. //* Decals. *
  1198. //**********************************************
  1199.  
  1200. #define INSTANCE(%0) ((%0 == -1) ? 0 : %0)
  1201.  
  1202. new Array: g_hDecals;
  1203.  
  1204. public FakeMeta_DecalIndex_Post()
  1205. {
  1206. if (!g_hDecals)
  1207. {
  1208. g_hDecals = ArrayCreate(1, 1);
  1209. }
  1210.  
  1211. ArrayPushCell(g_hDecals, get_orig_retval());
  1212. }
  1213.  
  1214. UTIL_GunshotDecalTrace(const iTrace, const bool: bIsGunshot = false)
  1215. {
  1216. static iHit;
  1217. static iMessage;
  1218. static iDecalIndex;
  1219.  
  1220. static Float: flFraction;
  1221. static Float: vecEndPos[3];
  1222.  
  1223. iHit = INSTANCE(get_tr2(iTrace, TR_pHit));
  1224.  
  1225. if (iHit && !IsValidPev(iHit) || (pev(iHit, pev_flags) & FL_KILLME))
  1226. {
  1227. return;
  1228. }
  1229.  
  1230. if (pev(iHit, pev_solid) != SOLID_BSP && pev(iHit, pev_movetype) != MOVETYPE_PUSHSTEP)
  1231. {
  1232. return;
  1233. }
  1234.  
  1235. iDecalIndex = ExecuteHamB(Ham_DamageDecal, iHit, 0);
  1236.  
  1237. if (iDecalIndex < 0 || iDecalIndex >= ArraySize(g_hDecals))
  1238. {
  1239. return;
  1240. }
  1241.  
  1242. iDecalIndex = ArrayGetCell(g_hDecals, iDecalIndex);
  1243.  
  1244. get_tr2(iTrace, TR_flFraction, flFraction);
  1245. get_tr2(iTrace, TR_vecEndPos, vecEndPos);
  1246.  
  1247. if (iDecalIndex < 0 || flFraction >= 1.0)
  1248. {
  1249. return;
  1250. }
  1251.  
  1252. if (bIsGunshot)
  1253. {
  1254. iMessage = TE_GUNSHOTDECAL;
  1255. }
  1256. else
  1257. {
  1258. iMessage = TE_DECAL;
  1259.  
  1260. if (iHit != 0)
  1261. {
  1262. if (iDecalIndex > 255)
  1263. {
  1264. iMessage = TE_DECALHIGH;
  1265. iDecalIndex -= 256;
  1266. }
  1267. }
  1268. else
  1269. {
  1270. iMessage = TE_WORLDDECAL;
  1271.  
  1272. if (iDecalIndex > 255)
  1273. {
  1274. iMessage = TE_WORLDDECALHIGH;
  1275. iDecalIndex -= 256;
  1276. }
  1277. }
  1278. }
  1279.  
  1280. MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, vecEndPos, 0);
  1281. WRITE_BYTE(iMessage);
  1282. WRITE_COORD(vecEndPos[0]);
  1283. WRITE_COORD(vecEndPos[1]);
  1284. WRITE_COORD(vecEndPos[2]);
  1285.  
  1286. if (bIsGunshot)
  1287. {
  1288. WRITE_SHORT(iHit);
  1289. WRITE_BYTE(iDecalIndex);
  1290. }
  1291. else
  1292. {
  1293. WRITE_BYTE(iDecalIndex);
  1294.  
  1295. if (iHit)
  1296. {
  1297. WRITE_SHORT(iHit);
  1298. }
  1299. }
  1300.  
  1301. MESSAGE_END();
  1302. }
  1303.  
  1304. //**********************************************
  1305. //* Get and precache sounds from weapon model. *
  1306. //**********************************************
  1307.  
  1308. PrecacheSoundsFromModel(const szModelPath[])
  1309. {
  1310. new iFile;
  1311.  
  1312. if ((iFile = fopen(szModelPath, "rt")))
  1313. {
  1314. new szSoundPath[64];
  1315.  
  1316. new iNumSeq, iSeqIndex;
  1317. new iEvent, iNumEvents, iEventIndex;
  1318.  
  1319. fseek(iFile, 164, SEEK_SET);
  1320. fread(iFile, iNumSeq, BLOCK_INT);
  1321. fread(iFile, iSeqIndex, BLOCK_INT);
  1322.  
  1323. for (new k, i = 0; i < iNumSeq; i++)
  1324. {
  1325. fseek(iFile, iSeqIndex + 48 + 176 * i, SEEK_SET);
  1326. fread(iFile, iNumEvents, BLOCK_INT);
  1327. fread(iFile, iEventIndex, BLOCK_INT);
  1328. fseek(iFile, iEventIndex + 176 * i, SEEK_SET);
  1329.  
  1330. for (k = 0; k < iNumEvents; k++)
  1331. {
  1332. fseek(iFile, iEventIndex + 4 + 76 * k, SEEK_SET);
  1333. fread(iFile, iEvent, BLOCK_INT);
  1334. fseek(iFile, 4, SEEK_CUR);
  1335.  
  1336. if (iEvent != 5004)
  1337. {
  1338. continue;
  1339. }
  1340.  
  1341. fread_blocks(iFile, szSoundPath, 64, BLOCK_CHAR);
  1342.  
  1343. if (strlen(szSoundPath))
  1344. {
  1345. strtolower(szSoundPath);
  1346. PRECACHE_SOUND(szSoundPath);
  1347. }
  1348.  
  1349. // server_print(" * Sound: %s", szSoundPath);
  1350. }
  1351. }
  1352. }
  1353.  
  1354. fclose(iFile);
  1355. }
  1356.  
  1357. //**********************************************
  1358. //* Ammo Inventory. *
  1359. //**********************************************
  1360.  
  1361. PrimaryAmmoIndex(const iItem)
  1362. {
  1363. return get_pdata_int(iItem, m_iPrimaryAmmoType, extra_offset_weapon);
  1364. }
  1365.  
  1366. GetAmmoInventory(const iPlayer, const iAmmoIndex)
  1367. {
  1368. if (iAmmoIndex == -1)
  1369. {
  1370. return -1;
  1371. }
  1372.  
  1373. return get_pdata_int(iPlayer, m_rgAmmo_CBasePlayer + iAmmoIndex, extra_offset_player);
  1374. }
  1375.  
  1376. SetAmmoInventory(const iPlayer, const iAmmoIndex, const iAmount)
  1377. {
  1378. if (iAmmoIndex == -1)
  1379. {
  1380. return 0;
  1381. }
  1382.  
  1383. set_pdata_int(iPlayer, m_rgAmmo_CBasePlayer + iAmmoIndex, iAmount, extra_offset_player);
  1384. return 1;
  1385. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement