Guest User

Untitled

a guest
Jan 6th, 2016
159
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 57.20 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "Weapon.h"
  3. #include "ParticlesObject.h"
  4. #include "entity_alive.h"
  5. #include "inventory_item_impl.h"
  6. #include "inventory.h"
  7. #include "xrserver_objects_alife_items.h"
  8. #include "actor.h"
  9. #include "actoreffector.h"
  10. #include "level.h"
  11. #include "xr_level_controller.h"
  12. #include "game_cl_base.h"
  13. #include "../Include/xrRender/Kinematics.h"
  14. #include "ai_object_location.h"
  15. #include "../xrphysics/mathutils.h"
  16. #include "object_broker.h"
  17. #include "player_hud.h"
  18. #include "gamepersistent.h"
  19. #include "effectorFall.h"
  20. #include "debug_renderer.h"
  21. #include "static_cast_checked.hpp"
  22. #include "clsid_game.h"
  23. #include "weaponBinocularsVision.h"
  24. #include "ui/UIWindow.h"
  25. #include "ui/UIXmlInit.h"
  26. #include "Torch.h"
  27.  
  28. #define WEAPON_REMOVE_TIME 60000
  29. #define ROTATION_TIME 0.25f
  30.  
  31. BOOL b_toggle_weapon_aim = FALSE;
  32. extern CUIXml* pWpnScopeXml;
  33.  
  34. CWeapon::CWeapon()
  35. {
  36. SetState(eHidden);
  37. SetNextState(eHidden);
  38. m_sub_state = eSubstateReloadBegin;
  39. m_bTriStateReload = false;
  40. SetDefaults();
  41.  
  42. m_Offset.identity();
  43. m_StrapOffset.identity();
  44.  
  45. m_iAmmoCurrentTotal = 0;
  46. m_BriefInfo_CalcFrame = 0;
  47.  
  48. iAmmoElapsed = -1;
  49. iMagazineSize = -1;
  50. m_ammoType = 0;
  51.  
  52. eHandDependence = hdNone;
  53.  
  54. m_zoom_params.m_fCurrentZoomFactor = g_fov;
  55. m_zoom_params.m_fZoomRotationFactor = 0.f;
  56. m_zoom_params.m_pVision = NULL;
  57. m_zoom_params.m_pNight_vision = NULL;
  58.  
  59. m_pCurrentAmmo = NULL;
  60.  
  61. m_pFlameParticles2 = NULL;
  62. m_sFlameParticles2 = NULL;
  63.  
  64. m_fCurrentCartirdgeDisp = 1.f;
  65.  
  66. m_strap_bone0 = 0;
  67. m_strap_bone1 = 0;
  68. m_StrapOffset.identity();
  69. m_strapped_mode = false;
  70. m_can_be_strapped = false;
  71. m_ef_main_weapon_type = u32(-1);
  72. m_ef_weapon_type = u32(-1);
  73. m_UIScope = NULL;
  74. m_set_next_ammoType_on_reload = undefined_ammo_type;
  75. m_crosshair_inertion = 0.f;
  76. m_activation_speed_is_overriden = false;
  77. m_cur_scope = NULL;
  78. m_bRememberActorNVisnStatus = false;
  79. }
  80.  
  81. CWeapon::~CWeapon()
  82. {
  83. xr_delete(m_UIScope);
  84. delete_data(m_scopes);
  85. }
  86.  
  87. void CWeapon::Hit(SHit* pHDS)
  88. {
  89. inherited::Hit(pHDS);
  90. }
  91.  
  92. void CWeapon::UpdateXForm()
  93. {
  94. if (Device.dwFrame == dwXF_Frame)
  95. return;
  96.  
  97. dwXF_Frame = Device.dwFrame;
  98.  
  99. if (!H_Parent())
  100. return;
  101.  
  102. // Get access to entity and its visual
  103. CEntityAlive* E = smart_cast<CEntityAlive*>(H_Parent());
  104.  
  105. if (!E)
  106. {
  107. if (!IsGameTypeSingle())
  108. UpdatePosition(H_Parent()->XFORM());
  109.  
  110. return;
  111. }
  112.  
  113. const CInventoryOwner *parent = smart_cast<const CInventoryOwner*>(E);
  114. if (parent && parent->use_simplified_visual())
  115. return;
  116.  
  117. if (parent->attached(this))
  118. return;
  119.  
  120. IKinematics* V = smart_cast<IKinematics*> (E->Visual());
  121. VERIFY(V);
  122.  
  123. // Get matrices
  124. int boneL = -1, boneR = -1, boneR2 = -1;
  125.  
  126. // this ugly case is possible in case of a CustomMonster, not a Stalker, nor an Actor
  127. E->g_WeaponBones(boneL, boneR, boneR2);
  128.  
  129. if (boneR == -1) return;
  130.  
  131. if ((HandDependence() == hd1Hand) || (GetState() == eReload) || (!E->g_Alive()))
  132. boneL = boneR2;
  133.  
  134. V->CalculateBones();
  135. Fmatrix& mL = V->LL_GetTransform(u16(boneL));
  136. Fmatrix& mR = V->LL_GetTransform(u16(boneR));
  137. // Calculate
  138. Fmatrix mRes;
  139. Fvector R, D, N;
  140. D.sub(mL.c, mR.c);
  141.  
  142. if (fis_zero(D.magnitude()))
  143. {
  144. mRes.set(E->XFORM());
  145. mRes.c.set(mR.c);
  146. }
  147. else
  148. {
  149. D.normalize();
  150. R.crossproduct(mR.j, D);
  151.  
  152. N.crossproduct(D, R);
  153. N.normalize();
  154.  
  155. mRes.set(R, N, D, mR.c);
  156. mRes.mulA_43(E->XFORM());
  157. }
  158.  
  159. UpdatePosition(mRes);
  160. }
  161.  
  162. void CWeapon::UpdateFireDependencies_internal()
  163. {
  164. if (Device.dwFrame != dwFP_Frame)
  165. {
  166. dwFP_Frame = Device.dwFrame;
  167.  
  168. UpdateXForm();
  169.  
  170. if (GetHUDmode())
  171. {
  172. HudItemData()->setup_firedeps(m_current_firedeps);
  173. VERIFY(_valid(m_current_firedeps.m_FireParticlesXForm));
  174. }
  175. else
  176. {
  177. // 3rd person or no parent
  178. Fmatrix& parent = XFORM();
  179. Fvector& fp = vLoadedFirePoint;
  180. Fvector& fp2 = vLoadedFirePoint2;
  181. Fvector& sp = vLoadedShellPoint;
  182.  
  183. parent.transform_tiny(m_current_firedeps.vLastFP, fp);
  184. parent.transform_tiny(m_current_firedeps.vLastFP2, fp2);
  185. parent.transform_tiny(m_current_firedeps.vLastSP, sp);
  186.  
  187. m_current_firedeps.vLastFD.set(0.f, 0.f, 1.f);
  188. parent.transform_dir(m_current_firedeps.vLastFD);
  189.  
  190. m_current_firedeps.m_FireParticlesXForm.set(parent);
  191. VERIFY(_valid(m_current_firedeps.m_FireParticlesXForm));
  192. }
  193. }
  194. }
  195.  
  196. void CWeapon::ForceUpdateFireParticles()
  197. {
  198. if (!GetHUDmode())
  199. {//update particlesXFORM real bullet direction
  200. if (!H_Parent()) return;
  201.  
  202. Fvector p, d;
  203. smart_cast<CEntity*>(H_Parent())->g_fireParams(this, p, d);
  204.  
  205. Fmatrix _pxf;
  206. _pxf.k = d;
  207. _pxf.i.crossproduct(Fvector().set(0.0f, 1.0f, 0.0f), _pxf.k);
  208. _pxf.j.crossproduct(_pxf.k, _pxf.i);
  209. _pxf.c = XFORM().c;
  210.  
  211. m_current_firedeps.m_FireParticlesXForm.set(_pxf);
  212. }
  213. }
  214.  
  215. void CWeapon::Load(LPCSTR section)
  216. {
  217. inherited::Load(section);
  218. CShootingObject::Load(section);
  219.  
  220. if (pSettings->line_exist(section, "flame_particles_2"))
  221. m_sFlameParticles2 = pSettings->r_string(section, "flame_particles_2");
  222.  
  223. // load ammo classes
  224. m_ammoTypes.clear();
  225. LPCSTR S = pSettings->r_string(section, "ammo_class");
  226. if (S && S[0])
  227. {
  228. string128 _ammoItem;
  229. int count = _GetItemCount(S);
  230. for (int it = 0; it < count; ++it)
  231. {
  232. _GetItem(S, it, _ammoItem);
  233. m_ammoTypes.push_back(_ammoItem);
  234. }
  235. }
  236.  
  237. iAmmoElapsed = pSettings->r_s32(section, "ammo_elapsed");
  238. iMagazineSize = pSettings->r_s32(section, "ammo_mag_size");
  239.  
  240. ////////////////////////////////////////////////////
  241. // дисперсия стрельбы
  242.  
  243. //подбрасывание камеры во время отдачи
  244. u8 rm = READ_IF_EXISTS(pSettings, r_u8, section, "cam_return", 1);
  245. cam_recoil.ReturnMode = (rm == 1);
  246.  
  247. rm = READ_IF_EXISTS(pSettings, r_u8, section, "cam_return_stop", 0);
  248. cam_recoil.StopReturn = (rm == 1);
  249.  
  250. float temp_f = 0.0f;
  251. temp_f = pSettings->r_float(section, "cam_relax_speed");
  252. cam_recoil.RelaxSpeed = _abs(deg2rad(temp_f));
  253. //AVO: commented out as very minor and is clashing with weapon mods
  254. //UNDONE after non fatal VERIFY implementation
  255. VERIFY(!fis_zero(cam_recoil.RelaxSpeed));
  256. if (fis_zero(cam_recoil.RelaxSpeed))
  257. {
  258. cam_recoil.RelaxSpeed = EPS_L;
  259. }
  260.  
  261. cam_recoil.RelaxSpeed_AI = cam_recoil.RelaxSpeed;
  262. if (pSettings->line_exist(section, "cam_relax_speed_ai"))
  263. {
  264. temp_f = pSettings->r_float(section, "cam_relax_speed_ai");
  265. cam_recoil.RelaxSpeed_AI = _abs(deg2rad(temp_f));
  266. VERIFY(!fis_zero(cam_recoil.RelaxSpeed_AI));
  267. if (fis_zero(cam_recoil.RelaxSpeed_AI))
  268. {
  269. cam_recoil.RelaxSpeed_AI = EPS_L;
  270. }
  271. }
  272. temp_f = pSettings->r_float(section, "cam_max_angle");
  273. cam_recoil.MaxAngleVert = _abs(deg2rad(temp_f));
  274. VERIFY(!fis_zero(cam_recoil.MaxAngleVert));
  275. if (fis_zero(cam_recoil.MaxAngleVert))
  276. {
  277. cam_recoil.MaxAngleVert = EPS;
  278. }
  279.  
  280. temp_f = pSettings->r_float(section, "cam_max_angle_horz");
  281. cam_recoil.MaxAngleHorz = _abs(deg2rad(temp_f));
  282. VERIFY(!fis_zero(cam_recoil.MaxAngleHorz));
  283. if (fis_zero(cam_recoil.MaxAngleHorz))
  284. {
  285. cam_recoil.MaxAngleHorz = EPS;
  286. }
  287.  
  288. temp_f = pSettings->r_float(section, "cam_step_angle_horz");
  289. cam_recoil.StepAngleHorz = deg2rad(temp_f);
  290.  
  291. cam_recoil.DispersionFrac = _abs(READ_IF_EXISTS(pSettings, r_float, section, "cam_dispersion_frac", 0.7f));
  292.  
  293. //подбрасывание камеры во время отдачи в режиме zoom ==> ironsight or scope
  294. //zoom_cam_recoil.Clone( cam_recoil ); ==== нельзя !!!!!!!!!!
  295. zoom_cam_recoil.RelaxSpeed = cam_recoil.RelaxSpeed;
  296. zoom_cam_recoil.RelaxSpeed_AI = cam_recoil.RelaxSpeed_AI;
  297. zoom_cam_recoil.DispersionFrac = cam_recoil.DispersionFrac;
  298. zoom_cam_recoil.MaxAngleVert = cam_recoil.MaxAngleVert;
  299. zoom_cam_recoil.MaxAngleHorz = cam_recoil.MaxAngleHorz;
  300. zoom_cam_recoil.StepAngleHorz = cam_recoil.StepAngleHorz;
  301.  
  302. zoom_cam_recoil.ReturnMode = cam_recoil.ReturnMode;
  303. zoom_cam_recoil.StopReturn = cam_recoil.StopReturn;
  304.  
  305. if (pSettings->line_exist(section, "zoom_cam_relax_speed"))
  306. {
  307. zoom_cam_recoil.RelaxSpeed = _abs(deg2rad(pSettings->r_float(section, "zoom_cam_relax_speed")));
  308. VERIFY(!fis_zero(zoom_cam_recoil.RelaxSpeed));
  309. if (fis_zero(zoom_cam_recoil.RelaxSpeed))
  310. {
  311. zoom_cam_recoil.RelaxSpeed = EPS_L;
  312. }
  313. }
  314. if (pSettings->line_exist(section, "zoom_cam_relax_speed_ai"))
  315. {
  316. zoom_cam_recoil.RelaxSpeed_AI = _abs(deg2rad(pSettings->r_float(section, "zoom_cam_relax_speed_ai")));
  317. VERIFY(!fis_zero(zoom_cam_recoil.RelaxSpeed_AI));
  318. if (fis_zero(zoom_cam_recoil.RelaxSpeed_AI))
  319. {
  320. zoom_cam_recoil.RelaxSpeed_AI = EPS_L;
  321. }
  322. }
  323. if (pSettings->line_exist(section, "zoom_cam_max_angle"))
  324. {
  325. zoom_cam_recoil.MaxAngleVert = _abs(deg2rad(pSettings->r_float(section, "zoom_cam_max_angle")));
  326. VERIFY(!fis_zero(zoom_cam_recoil.MaxAngleVert));
  327. if (fis_zero(zoom_cam_recoil.MaxAngleVert))
  328. {
  329. zoom_cam_recoil.MaxAngleVert = EPS;
  330. }
  331. }
  332. if (pSettings->line_exist(section, "zoom_cam_max_angle_horz"))
  333. {
  334. zoom_cam_recoil.MaxAngleHorz = _abs(deg2rad(pSettings->r_float(section, "zoom_cam_max_angle_horz")));
  335. VERIFY(!fis_zero(zoom_cam_recoil.MaxAngleHorz));
  336. if (fis_zero(zoom_cam_recoil.MaxAngleHorz))
  337. {
  338. zoom_cam_recoil.MaxAngleHorz = EPS;
  339. }
  340. }
  341. if (pSettings->line_exist(section, "zoom_cam_step_angle_horz"))
  342. {
  343. zoom_cam_recoil.StepAngleHorz = deg2rad(pSettings->r_float(section, "zoom_cam_step_angle_horz"));
  344. }
  345. if (pSettings->line_exist(section, "zoom_cam_dispersion_frac"))
  346. {
  347. zoom_cam_recoil.DispersionFrac = _abs(pSettings->r_float(section, "zoom_cam_dispersion_frac"));
  348. }
  349.  
  350. m_pdm.m_fPDM_disp_base = pSettings->r_float(section, "PDM_disp_base");
  351. m_pdm.m_fPDM_disp_vel_factor = pSettings->r_float(section, "PDM_disp_vel_factor");
  352. m_pdm.m_fPDM_disp_accel_factor = pSettings->r_float(section, "PDM_disp_accel_factor");
  353. m_pdm.m_fPDM_disp_crouch = pSettings->r_float(section, "PDM_disp_crouch");
  354. m_pdm.m_fPDM_disp_crouch_no_acc = pSettings->r_float(section, "PDM_disp_crouch_no_acc");
  355. m_crosshair_inertion = READ_IF_EXISTS(pSettings, r_float, section, "crosshair_inertion", 5.91f);
  356. m_first_bullet_controller.load(section);
  357. fireDispersionConditionFactor = pSettings->r_float(section, "fire_dispersion_condition_factor");
  358.  
  359. // modified by Peacemaker [17.10.08]
  360. // misfireProbability = pSettings->r_float(section,"misfire_probability");
  361. // misfireConditionK = READ_IF_EXISTS(pSettings, r_float, section, "misfire_condition_k", 1.0f);
  362. misfireStartCondition = pSettings->r_float(section, "misfire_start_condition");
  363. misfireEndCondition = READ_IF_EXISTS(pSettings, r_float, section, "misfire_end_condition", 0.f);
  364. misfireStartProbability = READ_IF_EXISTS(pSettings, r_float, section, "misfire_start_prob", 0.f);
  365. misfireEndProbability = pSettings->r_float(section, "misfire_end_prob");
  366. conditionDecreasePerShot = pSettings->r_float(section, "condition_shot_dec");
  367. conditionDecreasePerQueueShot = READ_IF_EXISTS(pSettings, r_float, section, "condition_queue_shot_dec", conditionDecreasePerShot);
  368.  
  369. vLoadedFirePoint = pSettings->r_fvector3(section, "fire_point");
  370.  
  371. if (pSettings->line_exist(section, "fire_point2"))
  372. vLoadedFirePoint2 = pSettings->r_fvector3(section, "fire_point2");
  373. else
  374. vLoadedFirePoint2 = vLoadedFirePoint;
  375.  
  376. // hands
  377. eHandDependence = EHandDependence(pSettings->r_s32(section, "hand_dependence"));
  378. m_bIsSingleHanded = true;
  379. if (pSettings->line_exist(section, "single_handed"))
  380. m_bIsSingleHanded = !!pSettings->r_bool(section, "single_handed");
  381. //
  382. m_fMinRadius = pSettings->r_float(section, "min_radius");
  383. m_fMaxRadius = pSettings->r_float(section, "max_radius");
  384.  
  385. // информация о возможных апгрейдах и их визуализации в инвентаре
  386. m_eScopeStatus = (ALife::EWeaponAddonStatus)pSettings->r_s32(section, "scope_status");
  387. m_eSilencerStatus = (ALife::EWeaponAddonStatus)pSettings->r_s32(section, "silencer_status");
  388. m_eGrenadeLauncherStatus = (ALife::EWeaponAddonStatus)pSettings->r_s32(section, "grenade_launcher_status");
  389.  
  390. m_zoom_params.m_bZoomEnabled = !!pSettings->r_bool(section, "zoom_enabled");
  391. m_zoom_params.m_fZoomRotateTime = pSettings->r_float(section, "zoom_rotate_time");
  392.  
  393. if (m_eScopeStatus == ALife::eAddonAttachable)
  394. {
  395. if (pSettings->line_exist(section, "scopes_sect"))
  396. {
  397. LPCSTR str = pSettings->r_string(section, "scopes_sect");
  398. for (int i = 0, count = _GetItemCount(str); i < count; ++i)
  399. {
  400. string128 scope_section;
  401. _GetItem(str, i, scope_section);
  402. m_scopes.push_back(scope_section);
  403. }
  404. }
  405. else
  406. {
  407. m_scopes.push_back(section);
  408. }
  409. }
  410. else if (m_eScopeStatus == ALife::eAddonPermanent)
  411. {
  412. shared_str scope_tex_name = pSettings->r_string(cNameSect(), "scope_texture");
  413. m_zoom_params.m_fScopeZoomFactor = pSettings->r_float(cNameSect(), "scope_zoom_factor");
  414. if (!g_dedicated_server)
  415. {
  416. m_UIScope = xr_new<CUIWindow>();
  417. if (!pWpnScopeXml)
  418. {
  419. pWpnScopeXml = xr_new<CUIXml>();
  420. pWpnScopeXml->Load(CONFIG_PATH, UI_PATH, "scopes.xml");
  421. }
  422. CUIXmlInit::InitWindow(*pWpnScopeXml, scope_tex_name.c_str(), 0, m_UIScope);
  423. }
  424. }
  425.  
  426. if (m_eSilencerStatus == ALife::eAddonAttachable)
  427. {
  428. m_sSilencerName = pSettings->r_string(section, "silencer_name");
  429. m_iSilencerX = pSettings->r_s32(section, "silencer_x");
  430. m_iSilencerY = pSettings->r_s32(section, "silencer_y");
  431. }
  432.  
  433. if (m_eGrenadeLauncherStatus == ALife::eAddonAttachable)
  434. {
  435. m_sGrenadeLauncherName = pSettings->r_string(section, "grenade_launcher_name");
  436. m_iGrenadeLauncherX = pSettings->r_s32(section, "grenade_launcher_x");
  437. m_iGrenadeLauncherY = pSettings->r_s32(section, "grenade_launcher_y");
  438. }
  439.  
  440. InitAddons();
  441. if (pSettings->line_exist(section, "weapon_remove_time"))
  442. m_dwWeaponRemoveTime = pSettings->r_u32(section, "weapon_remove_time");
  443. else
  444. m_dwWeaponRemoveTime = WEAPON_REMOVE_TIME;
  445.  
  446. if (pSettings->line_exist(section, "auto_spawn_ammo"))
  447. m_bAutoSpawnAmmo = pSettings->r_bool(section, "auto_spawn_ammo");
  448. else
  449. m_bAutoSpawnAmmo = TRUE;
  450.  
  451. m_zoom_params.m_bHideCrosshairInZoom = true;
  452.  
  453. if (pSettings->line_exist(hud_sect, "zoom_hide_crosshair"))
  454. m_zoom_params.m_bHideCrosshairInZoom = !!pSettings->r_bool(hud_sect, "zoom_hide_crosshair");
  455.  
  456. Fvector def_dof;
  457. def_dof.set(-1, -1, -1);
  458. m_zoom_params.m_ZoomDof = READ_IF_EXISTS(pSettings, r_fvector3, section, "zoom_dof", Fvector().set(-1, -1, -1));
  459. m_zoom_params.m_bZoomDofEnabled = !def_dof.similar(m_zoom_params.m_ZoomDof);
  460.  
  461. m_zoom_params.m_ReloadDof = READ_IF_EXISTS(pSettings, r_fvector4, section, "reload_dof", Fvector4().set(-1, -1, -1, -1));
  462.  
  463. //Swartz: empty reload
  464. m_zoom_params.m_ReloadEmptyDof = READ_IF_EXISTS(pSettings, r_fvector4, section, "reload_empty_dof", Fvector4().set(-1, -1, -1, -1));
  465. //-Swartz
  466.  
  467. m_bHasTracers = !!READ_IF_EXISTS(pSettings, r_bool, section, "tracers", true);
  468. m_u8TracerColorID = READ_IF_EXISTS(pSettings, r_u8, section, "tracers_color_ID", u8(-1));
  469.  
  470. string256 temp;
  471. for (int i = egdNovice; i < egdCount; ++i)
  472. {
  473. strconcat(sizeof(temp), temp, "hit_probability_", get_token_name(difficulty_type_token, i));
  474. m_hit_probability[i] = READ_IF_EXISTS(pSettings, r_float, section, temp, 1.f);
  475. }
  476.  
  477. m_zoom_params.m_bUseDynamicZoom = READ_IF_EXISTS(pSettings, r_bool, section, "scope_dynamic_zoom", FALSE);
  478. m_zoom_params.m_sUseZoomPostprocess = 0;
  479. m_zoom_params.m_sUseBinocularVision = 0;
  480. }
  481.  
  482. void CWeapon::LoadFireParams(LPCSTR section)
  483. {
  484. cam_recoil.Dispersion = deg2rad(pSettings->r_float(section, "cam_dispersion"));
  485. cam_recoil.DispersionInc = 0.0f;
  486.  
  487. if (pSettings->line_exist(section, "cam_dispersion_inc"))
  488. {
  489. cam_recoil.DispersionInc = deg2rad(pSettings->r_float(section, "cam_dispersion_inc"));
  490. }
  491.  
  492. zoom_cam_recoil.Dispersion = cam_recoil.Dispersion;
  493. zoom_cam_recoil.DispersionInc = cam_recoil.DispersionInc;
  494.  
  495. if (pSettings->line_exist(section, "zoom_cam_dispersion"))
  496. {
  497. zoom_cam_recoil.Dispersion = deg2rad(pSettings->r_float(section, "zoom_cam_dispersion"));
  498. }
  499. if (pSettings->line_exist(section, "zoom_cam_dispersion_inc"))
  500. {
  501. zoom_cam_recoil.DispersionInc = deg2rad(pSettings->r_float(section, "zoom_cam_dispersion_inc"));
  502. }
  503.  
  504. CShootingObject::LoadFireParams(section);
  505. };
  506.  
  507. BOOL CWeapon::net_Spawn(CSE_Abstract* DC)
  508. {
  509. m_fRTZoomFactor = m_zoom_params.m_fScopeZoomFactor;
  510. BOOL bResult = inherited::net_Spawn(DC);
  511. CSE_Abstract *e = (CSE_Abstract*) (DC);
  512. CSE_ALifeItemWeapon *E = smart_cast<CSE_ALifeItemWeapon*>(e);
  513.  
  514. //iAmmoCurrent = E->a_current;
  515. iAmmoElapsed = E->a_elapsed;
  516. m_flagsAddOnState = E->m_addon_flags.get();
  517. m_ammoType = E->ammo_type;
  518. SetState(E->wpn_state);
  519. SetNextState(E->wpn_state);
  520.  
  521. m_DefaultCartridge.Load(m_ammoTypes[m_ammoType].c_str(), m_ammoType);
  522. if (iAmmoElapsed)
  523. {
  524. m_fCurrentCartirdgeDisp = m_DefaultCartridge.param_s.kDisp;
  525. for (int i = 0; i < iAmmoElapsed; ++i)
  526. m_magazine.push_back(m_DefaultCartridge);
  527. }
  528.  
  529. UpdateAddonsVisibility();
  530. InitAddons();
  531.  
  532. m_dwWeaponIndependencyTime = 0;
  533.  
  534. VERIFY((u32) iAmmoElapsed == m_magazine.size());
  535. m_bAmmoWasSpawned = false;
  536.  
  537. return bResult;
  538. }
  539.  
  540. void CWeapon::net_Destroy()
  541. {
  542. inherited::net_Destroy();
  543.  
  544. //удалить объекты партиклов
  545. StopFlameParticles();
  546. StopFlameParticles2();
  547. StopLight();
  548. Light_Destroy();
  549.  
  550. while (m_magazine.size()) m_magazine.pop_back();
  551. }
  552.  
  553. BOOL CWeapon::IsUpdating()
  554. {
  555. bool bIsActiveItem = m_pInventory && m_pInventory->ActiveItem() == this;
  556. return bIsActiveItem || bWorking;// || IsPending() || getVisible();
  557. }
  558.  
  559. void CWeapon::net_Export(NET_Packet& P)
  560. {
  561. inherited::net_Export(P);
  562.  
  563. P.w_float_q8(GetCondition(), 0.0f, 1.0f);
  564.  
  565. u8 need_upd = IsUpdating() ? 1 : 0;
  566. P.w_u8(need_upd);
  567. P.w_u16(u16(iAmmoElapsed));
  568. P.w_u8(m_flagsAddOnState);
  569. P.w_u8(m_ammoType);
  570. P.w_u8((u8) GetState());
  571. P.w_u8((u8) IsZoomed());
  572. }
  573.  
  574. void CWeapon::net_Import(NET_Packet& P)
  575. {
  576. inherited::net_Import(P);
  577.  
  578. float _cond;
  579. P.r_float_q8(_cond, 0.0f, 1.0f);
  580. SetCondition(_cond);
  581.  
  582. u8 flags = 0;
  583. P.r_u8(flags);
  584.  
  585. u16 ammo_elapsed = 0;
  586. P.r_u16(ammo_elapsed);
  587.  
  588. u8 NewAddonState;
  589. P.r_u8(NewAddonState);
  590.  
  591. m_flagsAddOnState = NewAddonState;
  592. UpdateAddonsVisibility();
  593.  
  594. u8 ammoType, wstate;
  595. P.r_u8(ammoType);
  596. P.r_u8(wstate);
  597.  
  598. u8 Zoom;
  599. P.r_u8((u8) Zoom);
  600.  
  601. if (H_Parent() && H_Parent()->Remote())
  602. {
  603. if (Zoom) OnZoomIn();
  604. else OnZoomOut();
  605. };
  606. switch (wstate)
  607. {
  608. case eFire:
  609. case eFire2:
  610. case eSwitch:
  611. case eReload:
  612. {
  613. }break;
  614. default:
  615. {
  616. if (ammoType >= m_ammoTypes.size())
  617. Msg("!! Weapon [%d], State - [%d]", ID(), wstate);
  618. else
  619. {
  620. m_ammoType = ammoType;
  621. SetAmmoElapsed((ammo_elapsed));
  622. }
  623. }break;
  624. }
  625.  
  626. VERIFY((u32) iAmmoElapsed == m_magazine.size());
  627. }
  628.  
  629. void CWeapon::save(NET_Packet &output_packet)
  630. {
  631. inherited::save(output_packet);
  632. save_data(iAmmoElapsed, output_packet);
  633. save_data(m_cur_scope, output_packet);
  634. save_data(m_flagsAddOnState, output_packet);
  635. save_data(m_ammoType, output_packet);
  636. save_data(m_zoom_params.m_bIsZoomModeNow, output_packet);
  637. save_data(m_bRememberActorNVisnStatus, output_packet);
  638. }
  639.  
  640. void CWeapon::load(IReader &input_packet)
  641. {
  642. inherited::load(input_packet);
  643. load_data(iAmmoElapsed, input_packet);
  644. load_data(m_cur_scope, input_packet);
  645. load_data(m_flagsAddOnState, input_packet);
  646. UpdateAddonsVisibility();
  647. load_data(m_ammoType, input_packet);
  648. load_data(m_zoom_params.m_bIsZoomModeNow, input_packet);
  649.  
  650. if (m_zoom_params.m_bIsZoomModeNow)
  651. OnZoomIn();
  652. else
  653. OnZoomOut();
  654.  
  655. load_data(m_bRememberActorNVisnStatus, input_packet);
  656. }
  657.  
  658. void CWeapon::OnEvent(NET_Packet& P, u16 type)
  659. {
  660. switch (type)
  661. {
  662. case GE_ADDON_CHANGE:
  663. {
  664. P.r_u8(m_flagsAddOnState);
  665. InitAddons();
  666. UpdateAddonsVisibility();
  667. }break;
  668.  
  669. case GE_WPN_STATE_CHANGE:
  670. {
  671. u8 state;
  672. P.r_u8(state);
  673. P.r_u8(m_sub_state);
  674. // u8 NewAmmoType =
  675. P.r_u8();
  676. u8 AmmoElapsed = P.r_u8();
  677. u8 NextAmmo = P.r_u8();
  678. if (NextAmmo == undefined_ammo_type)
  679. m_set_next_ammoType_on_reload = undefined_ammo_type;
  680. else
  681. m_set_next_ammoType_on_reload = NextAmmo;
  682.  
  683. if (OnClient()) SetAmmoElapsed(int(AmmoElapsed));
  684. OnStateSwitch(u32(state));
  685. }
  686. break;
  687. default:
  688. {
  689. inherited::OnEvent(P, type);
  690. }break;
  691. }
  692. };
  693.  
  694. void CWeapon::shedule_Update(u32 dT)
  695. {
  696. // Queue shrink
  697. // u32 dwTimeCL = Level().timeServer()-NET_Latency;
  698. // while ((NET.size()>2) && (NET[1].dwTimeStamp<dwTimeCL)) NET.pop_front();
  699.  
  700. // Inherited
  701. inherited::shedule_Update(dT);
  702. }
  703.  
  704. void CWeapon::OnH_B_Independent(bool just_before_destroy)
  705. {
  706. RemoveShotEffector();
  707.  
  708. inherited::OnH_B_Independent(just_before_destroy);
  709.  
  710. FireEnd();
  711. SetPending(FALSE);
  712. SwitchState(eHidden);
  713.  
  714. m_strapped_mode = false;
  715. m_zoom_params.m_bIsZoomModeNow = false;
  716. UpdateXForm();
  717. }
  718.  
  719. void CWeapon::OnH_A_Independent()
  720. {
  721. m_dwWeaponIndependencyTime = Level().timeServer();
  722. inherited::OnH_A_Independent();
  723. Light_Destroy();
  724. UpdateAddonsVisibility();
  725. };
  726.  
  727. void CWeapon::OnH_A_Chield()
  728. {
  729. inherited::OnH_A_Chield();
  730. UpdateAddonsVisibility();
  731. };
  732.  
  733. void CWeapon::OnActiveItem()
  734. {
  735. //. from Activate
  736. UpdateAddonsVisibility();
  737. m_BriefInfo_CalcFrame = 0;
  738.  
  739. //. Show
  740. SwitchState(eShowing);
  741. //-
  742.  
  743. inherited::OnActiveItem();
  744. //если мы занружаемся и оружие было в руках
  745. //. SetState (eIdle);
  746. //. SetNextState (eIdle);
  747. }
  748.  
  749. void CWeapon::OnHiddenItem()
  750. {
  751. m_BriefInfo_CalcFrame = 0;
  752.  
  753. if (IsGameTypeSingle())
  754. SwitchState(eHiding);
  755. else
  756. SwitchState(eHidden);
  757.  
  758. OnZoomOut();
  759. inherited::OnHiddenItem();
  760.  
  761. m_set_next_ammoType_on_reload = undefined_ammo_type;
  762. }
  763.  
  764. void CWeapon::SendHiddenItem()
  765. {
  766. if (!CHudItem::object().getDestroy() && m_pInventory)
  767. {
  768. // !!! Just single entry for given state !!!
  769. NET_Packet P;
  770. CHudItem::object().u_EventGen(P, GE_WPN_STATE_CHANGE, CHudItem::object().ID());
  771. P.w_u8(u8(eHiding));
  772. P.w_u8(u8(m_sub_state));
  773. P.w_u8(m_ammoType);
  774. P.w_u8(u8(iAmmoElapsed & 0xff));
  775. P.w_u8(m_set_next_ammoType_on_reload);
  776. CHudItem::object().u_EventSend(P, net_flags(TRUE, TRUE, FALSE, TRUE));
  777. SetPending(TRUE);
  778. }
  779. }
  780.  
  781. void CWeapon::OnH_B_Chield()
  782. {
  783. m_dwWeaponIndependencyTime = 0;
  784. inherited::OnH_B_Chield();
  785.  
  786. OnZoomOut();
  787. m_set_next_ammoType_on_reload = undefined_ammo_type;
  788. }
  789.  
  790. extern u32 hud_adj_mode;
  791. bool CWeapon::AllowBore()
  792. {
  793. return true;
  794. }
  795.  
  796. void CWeapon::UpdateCL()
  797. {
  798. inherited::UpdateCL();
  799. UpdateHUDAddonsVisibility();
  800. //подсветка от выстрела
  801. UpdateLight();
  802.  
  803. //нарисовать партиклы
  804. UpdateFlameParticles();
  805. UpdateFlameParticles2();
  806.  
  807. if (!IsGameTypeSingle())
  808. make_Interpolation();
  809.  
  810. if ((GetNextState() == GetState()) && IsGameTypeSingle() && H_Parent() == Level().CurrentEntity())
  811. {
  812. CActor* pActor = smart_cast<CActor*>(H_Parent());
  813. if (pActor && !pActor->AnyMove() && this == pActor->inventory().ActiveItem())
  814. {
  815. if (hud_adj_mode == 0 &&
  816. GetState() == eIdle &&
  817. (Device.dwTimeGlobal - m_dw_curr_substate_time > 20000) &&
  818. !IsZoomed() &&
  819. g_player_hud->attached_item(1) == NULL)
  820. {
  821. if (AllowBore())
  822. SwitchState(eBore);
  823.  
  824. ResetSubStateTime();
  825. }
  826. }
  827. }
  828.  
  829. if (m_zoom_params.m_pNight_vision && !need_renderable())
  830. {
  831. if (!m_zoom_params.m_pNight_vision->IsActive())
  832. {
  833. CActor *pA = smart_cast<CActor *>(H_Parent());
  834. R_ASSERT(pA);
  835. CTorch* pTorch = smart_cast<CTorch*>(pA->inventory().ItemFromSlot(TORCH_SLOT));
  836. if (pTorch && pTorch->GetNightVisionStatus())
  837. {
  838. m_bRememberActorNVisnStatus = pTorch->GetNightVisionStatus();
  839. pTorch->SwitchNightVision(false, false);
  840. }
  841. m_zoom_params.m_pNight_vision->Start(m_zoom_params.m_sUseZoomPostprocess, pA, false);
  842. }
  843. }
  844. else if (m_bRememberActorNVisnStatus)
  845. {
  846. m_bRememberActorNVisnStatus = false;
  847. EnableActorNVisnAfterZoom();
  848. }
  849.  
  850. if (m_zoom_params.m_pVision)
  851. m_zoom_params.m_pVision->Update();
  852. }
  853. void CWeapon::EnableActorNVisnAfterZoom()
  854. {
  855. CActor *pA = smart_cast<CActor *>(H_Parent());
  856. if (IsGameTypeSingle() && !pA)
  857. pA = g_actor;
  858.  
  859. if (pA)
  860. {
  861. CTorch* pTorch = smart_cast<CTorch*>(pA->inventory().ItemFromSlot(TORCH_SLOT));
  862. if (pTorch)
  863. {
  864. pTorch->SwitchNightVision(true, false);
  865. pTorch->GetNightVision()->PlaySounds(CNightVisionEffector::eIdleSound);
  866. }
  867. }
  868. }
  869.  
  870. bool CWeapon::need_renderable()
  871. {
  872. return !(IsZoomed() && ZoomTexture() && !IsRotatingToZoom());
  873. }
  874.  
  875. void CWeapon::renderable_Render()
  876. {
  877. UpdateXForm();
  878.  
  879. //нарисовать подсветку
  880.  
  881. RenderLight();
  882.  
  883. //если мы в режиме снайперки, то сам HUD рисовать не надо
  884. if (IsZoomed() && !IsRotatingToZoom() && ZoomTexture())
  885. RenderHud(FALSE);
  886. else
  887. RenderHud(TRUE);
  888.  
  889. inherited::renderable_Render();
  890. }
  891.  
  892. void CWeapon::signal_HideComplete()
  893. {
  894. if (H_Parent())
  895. setVisible(FALSE);
  896. SetPending(FALSE);
  897. }
  898.  
  899. void CWeapon::SetDefaults()
  900. {
  901. SetPending(FALSE);
  902.  
  903. m_flags.set(FUsingCondition, TRUE);
  904. bMisfire = false;
  905. m_flagsAddOnState = 0;
  906. m_zoom_params.m_bIsZoomModeNow = false;
  907. }
  908.  
  909. void CWeapon::UpdatePosition(const Fmatrix& trans)
  910. {
  911. Position().set(trans.c);
  912. XFORM().mul(trans, m_strapped_mode ? m_StrapOffset : m_Offset);
  913. VERIFY(!fis_zero(DET(renderable.xform)));
  914. }
  915.  
  916. bool CWeapon::Action(u16 cmd, u32 flags)
  917. {
  918. if (inherited::Action(cmd, flags)) return true;
  919.  
  920. switch (cmd)
  921. {
  922. case kWPN_FIRE:
  923. {
  924. //если оружие чем-то занято, то ничего не делать
  925. {
  926. if (IsPending())
  927. return false;
  928.  
  929. if (flags&CMD_START)
  930. FireStart();
  931. else
  932. FireEnd();
  933. };
  934. }
  935. return true;
  936. case kWPN_NEXT:
  937. {
  938. return SwitchAmmoType(flags);
  939. }
  940.  
  941. case kWPN_ZOOM:
  942. if (IsZoomEnabled())
  943. {
  944. if (b_toggle_weapon_aim)
  945. {
  946. if (flags&CMD_START)
  947. {
  948. if (!IsZoomed())
  949. {
  950. if (!IsPending())
  951. {
  952. if (GetState() != eIdle)
  953. SwitchState(eIdle);
  954. OnZoomIn();
  955. }
  956. }
  957. else
  958. OnZoomOut();
  959. }
  960. }
  961. else
  962. {
  963. if (flags&CMD_START)
  964. {
  965. if (!IsZoomed() && !IsPending())
  966. {
  967. if (GetState() != eIdle)
  968. SwitchState(eIdle);
  969. OnZoomIn();
  970. }
  971. }
  972. else
  973. if (IsZoomed())
  974. OnZoomOut();
  975. }
  976. return true;
  977. }
  978. else
  979. return false;
  980.  
  981. case kWPN_ZOOM_INC:
  982. case kWPN_ZOOM_DEC:
  983. if (IsZoomEnabled() && IsZoomed())
  984. {
  985. if (cmd == kWPN_ZOOM_INC) ZoomInc();
  986. else ZoomDec();
  987. return true;
  988. }
  989. else
  990. return false;
  991. }
  992. return false;
  993. }
  994.  
  995. bool CWeapon::SwitchAmmoType(u32 flags)
  996. {
  997. if (IsPending() || OnClient())
  998. return false;
  999.  
  1000. if (!(flags & CMD_START))
  1001. return false;
  1002.  
  1003. u8 l_newType = m_ammoType;
  1004. bool b1, b2;
  1005. do
  1006. {
  1007. l_newType = u8((u32(l_newType + 1)) % m_ammoTypes.size());
  1008. b1 = (l_newType != m_ammoType);
  1009. b2 = unlimited_ammo() ? false : (!m_pInventory->GetAny(m_ammoTypes[l_newType].c_str()));
  1010. } while (b1 && b2);
  1011.  
  1012. if (l_newType != m_ammoType)
  1013. {
  1014. m_set_next_ammoType_on_reload = l_newType;
  1015. if (OnServer())
  1016. {
  1017. Reload();
  1018. }
  1019. }
  1020. return true;
  1021. }
  1022.  
  1023. void CWeapon::SpawnAmmo(u32 boxCurr, LPCSTR ammoSect, u32 ParentID)
  1024. {
  1025. if (!m_ammoTypes.size()) return;
  1026. if (OnClient()) return;
  1027. m_bAmmoWasSpawned = true;
  1028.  
  1029. int l_type = 0;
  1030. l_type %= m_ammoTypes.size();
  1031.  
  1032. if (!ammoSect) ammoSect = m_ammoTypes[l_type].c_str();
  1033.  
  1034. ++l_type;
  1035. l_type %= m_ammoTypes.size();
  1036.  
  1037. CSE_Abstract *D = F_entity_Create(ammoSect);
  1038.  
  1039. {
  1040. CSE_ALifeItemAmmo *l_pA = smart_cast<CSE_ALifeItemAmmo*>(D);
  1041. R_ASSERT(l_pA);
  1042. l_pA->m_boxSize = (u16) pSettings->r_s32(ammoSect, "box_size");
  1043. D->s_name = ammoSect;
  1044. D->set_name_replace("");
  1045. //. D->s_gameid = u8(GameID());
  1046. D->s_RP = 0xff;
  1047. D->ID = 0xffff;
  1048. if (ParentID == 0xffffffff)
  1049. D->ID_Parent = (u16) H_Parent()->ID();
  1050. else
  1051. D->ID_Parent = (u16) ParentID;
  1052.  
  1053. D->ID_Phantom = 0xffff;
  1054. D->s_flags.assign(M_SPAWN_OBJECT_LOCAL);
  1055. D->RespawnTime = 0;
  1056. l_pA->m_tNodeID = g_dedicated_server ? u32(-1) : ai_location().level_vertex_id();
  1057.  
  1058. if (boxCurr == 0xffffffff)
  1059. boxCurr = l_pA->m_boxSize;
  1060.  
  1061. while (boxCurr)
  1062. {
  1063. l_pA->a_elapsed = (u16) (boxCurr > l_pA->m_boxSize ? l_pA->m_boxSize : boxCurr);
  1064. NET_Packet P;
  1065. D->Spawn_Write(P, TRUE);
  1066. Level().Send(P, net_flags(TRUE));
  1067.  
  1068. if (boxCurr > l_pA->m_boxSize)
  1069. boxCurr -= l_pA->m_boxSize;
  1070. else
  1071. boxCurr = 0;
  1072. }
  1073. }
  1074. F_entity_Destroy(D);
  1075. }
  1076.  
  1077. int CWeapon::GetSuitableAmmoTotal(bool use_item_to_spawn) const
  1078. {
  1079. int ae_count = iAmmoElapsed;
  1080. if (!m_pInventory)
  1081. {
  1082. return ae_count;
  1083. }
  1084.  
  1085. //чтоб не делать лишних пересчетов
  1086. if (m_pInventory->ModifyFrame() <= m_BriefInfo_CalcFrame)
  1087. {
  1088. return ae_count + m_iAmmoCurrentTotal;
  1089. }
  1090. m_BriefInfo_CalcFrame = Device.dwFrame;
  1091.  
  1092. m_iAmmoCurrentTotal = 0;
  1093. for (u8 i = 0; i < u8(m_ammoTypes.size()); ++i)
  1094. {
  1095. m_iAmmoCurrentTotal += GetAmmoCount_forType(m_ammoTypes[i]);
  1096.  
  1097. if (!use_item_to_spawn)
  1098. {
  1099. continue;
  1100. }
  1101. if (!inventory_owner().item_to_spawn())
  1102. {
  1103. continue;
  1104. }
  1105. m_iAmmoCurrentTotal += inventory_owner().ammo_in_box_to_spawn();
  1106. }
  1107. return ae_count + m_iAmmoCurrentTotal;
  1108. }
  1109.  
  1110. int CWeapon::GetAmmoCount(u8 ammo_type) const
  1111. {
  1112. VERIFY(m_pInventory);
  1113. R_ASSERT(ammo_type < m_ammoTypes.size());
  1114.  
  1115. return GetAmmoCount_forType(m_ammoTypes[ammo_type]);
  1116. }
  1117.  
  1118. int CWeapon::GetAmmoCount_forType(shared_str const& ammo_type) const
  1119. {
  1120. int res = 0;
  1121.  
  1122. TIItemContainer::iterator itb = m_pInventory->m_belt.begin();
  1123. TIItemContainer::iterator ite = m_pInventory->m_belt.end();
  1124. for (; itb != ite; ++itb)
  1125. {
  1126. CWeaponAmmo* pAmmo = smart_cast<CWeaponAmmo*>(*itb);
  1127. if (pAmmo && (pAmmo->cNameSect() == ammo_type))
  1128. {
  1129. res += pAmmo->m_boxCurr;
  1130. }
  1131. }
  1132.  
  1133. itb = m_pInventory->m_ruck.begin();
  1134. ite = m_pInventory->m_ruck.end();
  1135. for (; itb != ite; ++itb)
  1136. {
  1137. CWeaponAmmo* pAmmo = smart_cast<CWeaponAmmo*>(*itb);
  1138. if (pAmmo && (pAmmo->cNameSect() == ammo_type))
  1139. {
  1140. res += pAmmo->m_boxCurr;
  1141. }
  1142. }
  1143. return res;
  1144. }
  1145.  
  1146. float CWeapon::GetConditionMisfireProbability() const
  1147. {
  1148. // modified by Peacemaker [17.10.08]
  1149. // if(GetCondition() > 0.95f)
  1150. // return 0.0f;
  1151. if (GetCondition() > misfireStartCondition)
  1152. return 0.0f;
  1153. if (GetCondition() < misfireEndCondition)
  1154. return misfireEndProbability;
  1155. // float mis = misfireProbability+powf(1.f-GetCondition(), 3.f)*misfireConditionK;
  1156. float mis = misfireStartProbability + (
  1157. (misfireStartCondition - GetCondition()) * // condition goes from 1.f to 0.f
  1158. (misfireEndProbability - misfireStartProbability) / // probability goes from 0.f to 1.f
  1159. ((misfireStartCondition == misfireEndCondition) ? // !!!say "No" to devision by zero
  1160. misfireStartCondition :
  1161. (misfireStartCondition - misfireEndCondition))
  1162. );
  1163. clamp(mis, 0.0f, 0.99f);
  1164. return mis;
  1165. }
  1166.  
  1167. BOOL CWeapon::CheckForMisfire()
  1168. {
  1169. if (OnClient()) return FALSE;
  1170.  
  1171. float rnd = ::Random.randF(0.f, 1.f);
  1172. float mp = GetConditionMisfireProbability();
  1173. if (rnd < mp)
  1174. {
  1175. FireEnd();
  1176.  
  1177. bMisfire = true;
  1178. SwitchState(eMisfire);
  1179.  
  1180. return TRUE;
  1181. }
  1182. else
  1183. {
  1184. return FALSE;
  1185. }
  1186. }
  1187.  
  1188. BOOL CWeapon::IsMisfire() const
  1189. {
  1190. return bMisfire;
  1191. }
  1192. void CWeapon::Reload()
  1193. {
  1194. OnZoomOut();
  1195. }
  1196.  
  1197. bool CWeapon::IsGrenadeLauncherAttached() const
  1198. {
  1199. return (ALife::eAddonAttachable == m_eGrenadeLauncherStatus &&
  1200. 0 != (m_flagsAddOnState&CSE_ALifeItemWeapon::eWeaponAddonGrenadeLauncher)) ||
  1201. ALife::eAddonPermanent == m_eGrenadeLauncherStatus;
  1202. }
  1203.  
  1204. bool CWeapon::IsScopeAttached() const
  1205. {
  1206. return (ALife::eAddonAttachable == m_eScopeStatus &&
  1207. 0 != (m_flagsAddOnState&CSE_ALifeItemWeapon::eWeaponAddonScope)) ||
  1208. ALife::eAddonPermanent == m_eScopeStatus;
  1209. }
  1210.  
  1211. bool CWeapon::IsSilencerAttached() const
  1212. {
  1213. return (ALife::eAddonAttachable == m_eSilencerStatus &&
  1214. 0 != (m_flagsAddOnState&CSE_ALifeItemWeapon::eWeaponAddonSilencer)) ||
  1215. ALife::eAddonPermanent == m_eSilencerStatus;
  1216. }
  1217.  
  1218. bool CWeapon::GrenadeLauncherAttachable()
  1219. {
  1220. return (ALife::eAddonAttachable == m_eGrenadeLauncherStatus);
  1221. }
  1222. bool CWeapon::ScopeAttachable()
  1223. {
  1224. return (ALife::eAddonAttachable == m_eScopeStatus);
  1225. }
  1226. bool CWeapon::SilencerAttachable()
  1227. {
  1228. return (ALife::eAddonAttachable == m_eSilencerStatus);
  1229. }
  1230.  
  1231. shared_str wpn_scope = "wpn_scope";
  1232. shared_str wpn_silencer = "wpn_silencer";
  1233. shared_str wpn_grenade_launcher = "wpn_launcher";
  1234.  
  1235. void CWeapon::UpdateHUDAddonsVisibility()
  1236. {//actor only
  1237. if (!GetHUDmode()) return;
  1238.  
  1239. //. return;
  1240.  
  1241. if (ScopeAttachable())
  1242. {
  1243. HudItemData()->set_bone_visible(wpn_scope, IsScopeAttached());
  1244. }
  1245.  
  1246. if (m_eScopeStatus == ALife::eAddonDisabled)
  1247. {
  1248. HudItemData()->set_bone_visible(wpn_scope, FALSE, TRUE);
  1249. }
  1250. else
  1251. if (m_eScopeStatus == ALife::eAddonPermanent)
  1252. HudItemData()->set_bone_visible(wpn_scope, TRUE, TRUE);
  1253.  
  1254. if (SilencerAttachable())
  1255. {
  1256. HudItemData()->set_bone_visible(wpn_silencer, IsSilencerAttached());
  1257. }
  1258. if (m_eSilencerStatus == ALife::eAddonDisabled)
  1259. {
  1260. HudItemData()->set_bone_visible(wpn_silencer, FALSE, TRUE);
  1261. }
  1262. else
  1263. if (m_eSilencerStatus == ALife::eAddonPermanent)
  1264. HudItemData()->set_bone_visible(wpn_silencer, TRUE, TRUE);
  1265.  
  1266. if (GrenadeLauncherAttachable())
  1267. {
  1268. HudItemData()->set_bone_visible(wpn_grenade_launcher, IsGrenadeLauncherAttached());
  1269. }
  1270. if (m_eGrenadeLauncherStatus == ALife::eAddonDisabled)
  1271. {
  1272. HudItemData()->set_bone_visible(wpn_grenade_launcher, FALSE, TRUE);
  1273. }
  1274. else
  1275. if (m_eGrenadeLauncherStatus == ALife::eAddonPermanent)
  1276. HudItemData()->set_bone_visible(wpn_grenade_launcher, TRUE, TRUE);
  1277. }
  1278.  
  1279. void CWeapon::UpdateAddonsVisibility()
  1280. {
  1281. IKinematics* pWeaponVisual = smart_cast<IKinematics*>(Visual()); R_ASSERT(pWeaponVisual);
  1282.  
  1283. u16 bone_id;
  1284. UpdateHUDAddonsVisibility();
  1285.  
  1286. pWeaponVisual->CalculateBones_Invalidate();
  1287.  
  1288. bone_id = pWeaponVisual->LL_BoneID(wpn_scope);
  1289. if (ScopeAttachable())
  1290. {
  1291. if (IsScopeAttached())
  1292. {
  1293. if (!pWeaponVisual->LL_GetBoneVisible(bone_id))
  1294. pWeaponVisual->LL_SetBoneVisible(bone_id, TRUE, TRUE);
  1295. }
  1296. else
  1297. {
  1298. if (pWeaponVisual->LL_GetBoneVisible(bone_id))
  1299. pWeaponVisual->LL_SetBoneVisible(bone_id, FALSE, TRUE);
  1300. }
  1301. }
  1302. if (m_eScopeStatus == ALife::eAddonDisabled && bone_id != BI_NONE &&
  1303. pWeaponVisual->LL_GetBoneVisible(bone_id))
  1304. {
  1305. pWeaponVisual->LL_SetBoneVisible(bone_id, FALSE, TRUE);
  1306. // Log("scope", pWeaponVisual->LL_GetBoneVisible (bone_id));
  1307. }
  1308. bone_id = pWeaponVisual->LL_BoneID(wpn_silencer);
  1309. if (SilencerAttachable())
  1310. {
  1311. if (IsSilencerAttached())
  1312. {
  1313. if (!pWeaponVisual->LL_GetBoneVisible(bone_id))
  1314. pWeaponVisual->LL_SetBoneVisible(bone_id, TRUE, TRUE);
  1315. }
  1316. else
  1317. {
  1318. if (pWeaponVisual->LL_GetBoneVisible(bone_id))
  1319. pWeaponVisual->LL_SetBoneVisible(bone_id, FALSE, TRUE);
  1320. }
  1321. }
  1322. if (m_eSilencerStatus == ALife::eAddonDisabled && bone_id != BI_NONE &&
  1323. pWeaponVisual->LL_GetBoneVisible(bone_id))
  1324. {
  1325. pWeaponVisual->LL_SetBoneVisible(bone_id, FALSE, TRUE);
  1326. // Log("silencer", pWeaponVisual->LL_GetBoneVisible (bone_id));
  1327. }
  1328.  
  1329. bone_id = pWeaponVisual->LL_BoneID(wpn_grenade_launcher);
  1330. if (GrenadeLauncherAttachable())
  1331. {
  1332. if (IsGrenadeLauncherAttached())
  1333. {
  1334. if (!pWeaponVisual->LL_GetBoneVisible(bone_id))
  1335. pWeaponVisual->LL_SetBoneVisible(bone_id, TRUE, TRUE);
  1336. }
  1337. else
  1338. {
  1339. if (pWeaponVisual->LL_GetBoneVisible(bone_id))
  1340. pWeaponVisual->LL_SetBoneVisible(bone_id, FALSE, TRUE);
  1341. }
  1342. }
  1343. if (m_eGrenadeLauncherStatus == ALife::eAddonDisabled && bone_id != BI_NONE &&
  1344. pWeaponVisual->LL_GetBoneVisible(bone_id))
  1345. {
  1346. pWeaponVisual->LL_SetBoneVisible(bone_id, FALSE, TRUE);
  1347. // Log("gl", pWeaponVisual->LL_GetBoneVisible (bone_id));
  1348. }
  1349.  
  1350. pWeaponVisual->CalculateBones_Invalidate();
  1351. pWeaponVisual->CalculateBones(TRUE);
  1352. }
  1353.  
  1354. void CWeapon::InitAddons()
  1355. {}
  1356.  
  1357. float CWeapon::CurrentZoomFactor()
  1358. {
  1359. return IsScopeAttached() ? m_zoom_params.m_fScopeZoomFactor : m_zoom_params.m_fIronSightZoomFactor;
  1360. };
  1361. void GetZoomData(const float scope_factor, float& delta, float& min_zoom_factor);
  1362. void CWeapon::OnZoomIn()
  1363. {
  1364. m_zoom_params.m_bIsZoomModeNow = true;
  1365. if (m_zoom_params.m_bUseDynamicZoom)
  1366. SetZoomFactor(m_fRTZoomFactor);
  1367. else
  1368. m_zoom_params.m_fCurrentZoomFactor = CurrentZoomFactor();
  1369.  
  1370. EnableHudInertion(FALSE);
  1371.  
  1372. if (m_zoom_params.m_bZoomDofEnabled && !IsScopeAttached())
  1373. GamePersistent().SetEffectorDOF(m_zoom_params.m_ZoomDof);
  1374.  
  1375. if (GetHUDmode())
  1376. GamePersistent().SetPickableEffectorDOF(true);
  1377.  
  1378. if (m_zoom_params.m_sUseBinocularVision.size() && IsScopeAttached() && NULL == m_zoom_params.m_pVision)
  1379. m_zoom_params.m_pVision = xr_new<CBinocularsVision>(m_zoom_params.m_sUseBinocularVision/*"wpn_binoc"*/);
  1380.  
  1381. if (m_zoom_params.m_sUseZoomPostprocess.size() && IsScopeAttached())
  1382. {
  1383. CActor *pA = smart_cast<CActor *>(H_Parent());
  1384. if (pA)
  1385. {
  1386. if (NULL == m_zoom_params.m_pNight_vision)
  1387. {
  1388. m_zoom_params.m_pNight_vision = xr_new<CNightVisionEffector>(m_zoom_params.m_sUseZoomPostprocess/*"device_torch"*/);
  1389. }
  1390. }
  1391. }
  1392. }
  1393.  
  1394. void CWeapon::OnZoomOut()
  1395. {
  1396. m_zoom_params.m_bIsZoomModeNow = false;
  1397. m_fRTZoomFactor = GetZoomFactor();//store current
  1398. m_zoom_params.m_fCurrentZoomFactor = g_fov;
  1399. EnableHudInertion(TRUE);
  1400.  
  1401. GamePersistent().RestoreEffectorDOF();
  1402.  
  1403. if (GetHUDmode())
  1404. GamePersistent().SetPickableEffectorDOF(false);
  1405.  
  1406. ResetSubStateTime();
  1407.  
  1408. xr_delete(m_zoom_params.m_pVision);
  1409. if (m_zoom_params.m_pNight_vision)
  1410. {
  1411. m_zoom_params.m_pNight_vision->Stop(100000.0f, false);
  1412. xr_delete(m_zoom_params.m_pNight_vision);
  1413. }
  1414. }
  1415.  
  1416. CUIWindow* CWeapon::ZoomTexture()
  1417. {
  1418. if (UseScopeTexture())
  1419. return m_UIScope;
  1420. else
  1421. return NULL;
  1422. }
  1423.  
  1424. void CWeapon::SwitchState(u32 S)
  1425. {
  1426. if (OnClient()) return;
  1427.  
  1428. #ifndef MASTER_GOLD
  1429. if ( bDebug )
  1430. {
  1431. Msg("---Server is going to send GE_WPN_STATE_CHANGE to [%d], weapon_section[%s], parent[%s]",
  1432. S, cNameSect().c_str(), H_Parent() ? H_Parent()->cName().c_str() : "NULL Parent");
  1433. }
  1434. #endif // #ifndef MASTER_GOLD
  1435.  
  1436. SetNextState(S);
  1437. if (CHudItem::object().Local() && !CHudItem::object().getDestroy() && m_pInventory && OnServer())
  1438. {
  1439. // !!! Just single entry for given state !!!
  1440. NET_Packet P;
  1441. CHudItem::object().u_EventGen(P, GE_WPN_STATE_CHANGE, CHudItem::object().ID());
  1442. P.w_u8(u8(S));
  1443. P.w_u8(u8(m_sub_state));
  1444. P.w_u8(m_ammoType);
  1445. P.w_u8(u8(iAmmoElapsed & 0xff));
  1446. P.w_u8(m_set_next_ammoType_on_reload);
  1447. CHudItem::object().u_EventSend(P, net_flags(TRUE, TRUE, FALSE, TRUE));
  1448. }
  1449. }
  1450.  
  1451. void CWeapon::OnMagazineEmpty()
  1452. {
  1453. VERIFY((u32) iAmmoElapsed == m_magazine.size());
  1454. }
  1455.  
  1456. void CWeapon::reinit()
  1457. {
  1458. CShootingObject::reinit();
  1459. CHudItemObject::reinit();
  1460. }
  1461.  
  1462. void CWeapon::reload(LPCSTR section)
  1463. {
  1464. CShootingObject::reload(section);
  1465. CHudItemObject::reload(section);
  1466.  
  1467. m_can_be_strapped = true;
  1468. m_strapped_mode = false;
  1469.  
  1470. if (pSettings->line_exist(section, "strap_bone0"))
  1471. m_strap_bone0 = pSettings->r_string(section, "strap_bone0");
  1472. else
  1473. m_can_be_strapped = false;
  1474.  
  1475. if (pSettings->line_exist(section, "strap_bone1"))
  1476. m_strap_bone1 = pSettings->r_string(section, "strap_bone1");
  1477. else
  1478. m_can_be_strapped = false;
  1479.  
  1480. if (m_eScopeStatus == ALife::eAddonAttachable)
  1481. {
  1482. m_addon_holder_range_modifier = READ_IF_EXISTS(pSettings, r_float, GetScopeName(), "holder_range_modifier", m_holder_range_modifier);
  1483. m_addon_holder_fov_modifier = READ_IF_EXISTS(pSettings, r_float, GetScopeName(), "holder_fov_modifier", m_holder_fov_modifier);
  1484. }
  1485. else
  1486. {
  1487. m_addon_holder_range_modifier = m_holder_range_modifier;
  1488. m_addon_holder_fov_modifier = m_holder_fov_modifier;
  1489. }
  1490.  
  1491. {
  1492. Fvector pos, ypr;
  1493. pos = pSettings->r_fvector3(section, "position");
  1494. ypr = pSettings->r_fvector3(section, "orientation");
  1495. ypr.mul(PI / 180.f);
  1496.  
  1497. m_Offset.setHPB(ypr.x, ypr.y, ypr.z);
  1498. m_Offset.translate_over(pos);
  1499. }
  1500.  
  1501. m_StrapOffset = m_Offset;
  1502. if (pSettings->line_exist(section, "strap_position") && pSettings->line_exist(section, "strap_orientation"))
  1503. {
  1504. Fvector pos, ypr;
  1505. pos = pSettings->r_fvector3(section, "strap_position");
  1506. ypr = pSettings->r_fvector3(section, "strap_orientation");
  1507. ypr.mul(PI / 180.f);
  1508.  
  1509. m_StrapOffset.setHPB(ypr.x, ypr.y, ypr.z);
  1510. m_StrapOffset.translate_over(pos);
  1511. }
  1512. else
  1513. m_can_be_strapped = false;
  1514.  
  1515. m_ef_main_weapon_type = READ_IF_EXISTS(pSettings, r_u32, section, "ef_main_weapon_type", u32(-1));
  1516. m_ef_weapon_type = READ_IF_EXISTS(pSettings, r_u32, section, "ef_weapon_type", u32(-1));
  1517. }
  1518.  
  1519. void CWeapon::create_physic_shell()
  1520. {
  1521. CPhysicsShellHolder::create_physic_shell();
  1522. }
  1523.  
  1524. bool CWeapon::ActivationSpeedOverriden(Fvector& dest, bool clear_override)
  1525. {
  1526. if (m_activation_speed_is_overriden)
  1527. {
  1528. if (clear_override)
  1529. {
  1530. m_activation_speed_is_overriden = false;
  1531. }
  1532.  
  1533. dest = m_overriden_activation_speed;
  1534. return true;
  1535. }
  1536.  
  1537. return false;
  1538. }
  1539.  
  1540. void CWeapon::SetActivationSpeedOverride(Fvector const& speed)
  1541. {
  1542. m_overriden_activation_speed = speed;
  1543. m_activation_speed_is_overriden = true;
  1544. }
  1545.  
  1546. void CWeapon::activate_physic_shell()
  1547. {
  1548. UpdateXForm();
  1549. CPhysicsShellHolder::activate_physic_shell();
  1550. }
  1551.  
  1552. void CWeapon::setup_physic_shell()
  1553. {
  1554. CPhysicsShellHolder::setup_physic_shell();
  1555. }
  1556.  
  1557. int g_iWeaponRemove = 1;
  1558.  
  1559. bool CWeapon::NeedToDestroyObject() const
  1560. {
  1561. if (GameID() == eGameIDSingle) return false;
  1562. if (Remote()) return false;
  1563. if (H_Parent()) return false;
  1564. if (g_iWeaponRemove == -1) return false;
  1565. if (g_iWeaponRemove == 0) return true;
  1566. if (TimePassedAfterIndependant() > m_dwWeaponRemoveTime)
  1567. return true;
  1568.  
  1569. return false;
  1570. }
  1571.  
  1572. ALife::_TIME_ID CWeapon::TimePassedAfterIndependant() const
  1573. {
  1574. if (!H_Parent() && m_dwWeaponIndependencyTime != 0)
  1575. return Level().timeServer() - m_dwWeaponIndependencyTime;
  1576. else
  1577. return 0;
  1578. }
  1579.  
  1580. bool CWeapon::can_kill() const
  1581. {
  1582. if (GetSuitableAmmoTotal(true) || m_ammoTypes.empty())
  1583. return (true);
  1584.  
  1585. return (false);
  1586. }
  1587.  
  1588. CInventoryItem *CWeapon::can_kill(CInventory *inventory) const
  1589. {
  1590. if (GetAmmoElapsed() || m_ammoTypes.empty())
  1591. return (const_cast<CWeapon*>(this));
  1592.  
  1593. TIItemContainer::iterator I = inventory->m_all.begin();
  1594. TIItemContainer::iterator E = inventory->m_all.end();
  1595. for (; I != E; ++I)
  1596. {
  1597. CInventoryItem *inventory_item = smart_cast<CInventoryItem*>(*I);
  1598. if (!inventory_item)
  1599. continue;
  1600.  
  1601. xr_vector<shared_str>::const_iterator i = std::find(m_ammoTypes.begin(), m_ammoTypes.end(), inventory_item->object().cNameSect());
  1602. if (i != m_ammoTypes.end())
  1603. return (inventory_item);
  1604. }
  1605.  
  1606. return (0);
  1607. }
  1608.  
  1609. const CInventoryItem *CWeapon::can_kill(const xr_vector<const CGameObject*> &items) const
  1610. {
  1611. if (m_ammoTypes.empty())
  1612. return (this);
  1613.  
  1614. xr_vector<const CGameObject*>::const_iterator I = items.begin();
  1615. xr_vector<const CGameObject*>::const_iterator E = items.end();
  1616. for (; I != E; ++I)
  1617. {
  1618. const CInventoryItem *inventory_item = smart_cast<const CInventoryItem*>(*I);
  1619. if (!inventory_item)
  1620. continue;
  1621.  
  1622. xr_vector<shared_str>::const_iterator i = std::find(m_ammoTypes.begin(), m_ammoTypes.end(), inventory_item->object().cNameSect());
  1623. if (i != m_ammoTypes.end())
  1624. return (inventory_item);
  1625. }
  1626.  
  1627. return (0);
  1628. }
  1629.  
  1630. bool CWeapon::ready_to_kill() const
  1631. {
  1632. return (
  1633. !IsMisfire() &&
  1634. ((GetState() == eIdle) || (GetState() == eFire) || (GetState() == eFire2)) &&
  1635. GetAmmoElapsed()
  1636. );
  1637. }
  1638.  
  1639. void CWeapon::UpdateHudAdditonal(Fmatrix& trans)
  1640. {
  1641. CActor* pActor = smart_cast<CActor*>(H_Parent());
  1642. if (!pActor) return;
  1643.  
  1644. if ((IsZoomed() && m_zoom_params.m_fZoomRotationFactor <= 1.f) ||
  1645. (!IsZoomed() && m_zoom_params.m_fZoomRotationFactor > 0.f))
  1646. {
  1647. u8 idx = GetCurrentHudOffsetIdx();
  1648. // if(idx==0) return;
  1649.  
  1650. attachable_hud_item* hi = HudItemData();
  1651. R_ASSERT(hi);
  1652. Fvector curr_offs, curr_rot;
  1653. curr_offs = hi->m_measures.m_hands_offset[0][idx];//pos,aim
  1654. curr_rot = hi->m_measures.m_hands_offset[1][idx];//rot,aim
  1655. curr_offs.mul(m_zoom_params.m_fZoomRotationFactor);
  1656. curr_rot.mul(m_zoom_params.m_fZoomRotationFactor);
  1657.  
  1658. Fmatrix hud_rotation;
  1659. hud_rotation.identity();
  1660. hud_rotation.rotateX(curr_rot.x);
  1661.  
  1662. Fmatrix hud_rotation_y;
  1663. hud_rotation_y.identity();
  1664. hud_rotation_y.rotateY(curr_rot.y);
  1665. hud_rotation.mulA_43(hud_rotation_y);
  1666.  
  1667. hud_rotation_y.identity();
  1668. hud_rotation_y.rotateZ(curr_rot.z);
  1669. hud_rotation.mulA_43(hud_rotation_y);
  1670.  
  1671. hud_rotation.translate_over(curr_offs);
  1672. trans.mulB_43(hud_rotation);
  1673.  
  1674. if (pActor->IsZoomAimingMode())
  1675. m_zoom_params.m_fZoomRotationFactor += Device.fTimeDelta / m_zoom_params.m_fZoomRotateTime;
  1676. else
  1677. m_zoom_params.m_fZoomRotationFactor -= Device.fTimeDelta / m_zoom_params.m_fZoomRotateTime;
  1678.  
  1679. clamp(m_zoom_params.m_fZoomRotationFactor, 0.f, 1.f);
  1680. }
  1681. }
  1682.  
  1683. void CWeapon::SetAmmoElapsed(int ammo_count)
  1684. {
  1685. iAmmoElapsed = ammo_count;
  1686.  
  1687. u32 uAmmo = u32(iAmmoElapsed);
  1688.  
  1689. if (uAmmo != m_magazine.size())
  1690. {
  1691. if (uAmmo > m_magazine.size())
  1692. {
  1693. CCartridge l_cartridge;
  1694. l_cartridge.Load(m_ammoTypes[m_ammoType].c_str(), m_ammoType);
  1695. while (uAmmo > m_magazine.size())
  1696. m_magazine.push_back(l_cartridge);
  1697. }
  1698. else
  1699. {
  1700. while (uAmmo < m_magazine.size())
  1701. m_magazine.pop_back();
  1702. };
  1703. };
  1704. }
  1705.  
  1706. u32 CWeapon::ef_main_weapon_type() const
  1707. {
  1708. VERIFY(m_ef_main_weapon_type != u32(-1));
  1709. return (m_ef_main_weapon_type);
  1710. }
  1711.  
  1712. u32 CWeapon::ef_weapon_type() const
  1713. {
  1714. VERIFY(m_ef_weapon_type != u32(-1));
  1715. return (m_ef_weapon_type);
  1716. }
  1717.  
  1718. bool CWeapon::IsNecessaryItem(const shared_str& item_sect)
  1719. {
  1720. return (std::find(m_ammoTypes.begin(), m_ammoTypes.end(), item_sect) != m_ammoTypes.end());
  1721. }
  1722.  
  1723. void CWeapon::modify_holder_params(float &range, float &fov) const
  1724. {
  1725. if (!IsScopeAttached())
  1726. {
  1727. inherited::modify_holder_params(range, fov);
  1728. return;
  1729. }
  1730. range *= m_addon_holder_range_modifier;
  1731. fov *= m_addon_holder_fov_modifier;
  1732. }
  1733.  
  1734. bool CWeapon::render_item_ui_query()
  1735. {
  1736. bool b_is_active_item = (m_pInventory->ActiveItem() == this);
  1737. bool res = b_is_active_item && IsZoomed() && ZoomHideCrosshair() && ZoomTexture() && !IsRotatingToZoom();
  1738. return res;
  1739. }
  1740.  
  1741. void CWeapon::render_item_ui()
  1742. {
  1743. if (m_zoom_params.m_pVision)
  1744. m_zoom_params.m_pVision->Draw();
  1745.  
  1746. ZoomTexture()->Update();
  1747. ZoomTexture()->Draw();
  1748. }
  1749.  
  1750. bool CWeapon::unlimited_ammo()
  1751. {
  1752. if (IsGameTypeSingle())
  1753. {
  1754. if (m_pInventory)
  1755. {
  1756. return inventory_owner().unlimited_ammo() && m_DefaultCartridge.m_flags.test(CCartridge::cfCanBeUnlimited);
  1757. }
  1758. else
  1759. return false;
  1760. }
  1761.  
  1762. return ((GameID() == eGameIDDeathmatch) &&
  1763. m_DefaultCartridge.m_flags.test(CCartridge::cfCanBeUnlimited));
  1764. };
  1765.  
  1766. float CWeapon::Weight() const
  1767. {
  1768. float res = CInventoryItemObject::Weight();
  1769. if (IsGrenadeLauncherAttached() && GetGrenadeLauncherName().size())
  1770. {
  1771. res += pSettings->r_float(GetGrenadeLauncherName(), "inv_weight");
  1772. }
  1773. if (IsScopeAttached() && m_scopes.size())
  1774. {
  1775. res += pSettings->r_float(GetScopeName(), "inv_weight");
  1776. }
  1777. if (IsSilencerAttached() && GetSilencerName().size())
  1778. {
  1779. res += pSettings->r_float(GetSilencerName(), "inv_weight");
  1780. }
  1781.  
  1782. if (iAmmoElapsed)
  1783. {
  1784. float w = pSettings->r_float(m_ammoTypes[m_ammoType].c_str(), "inv_weight");
  1785. float bs = pSettings->r_float(m_ammoTypes[m_ammoType].c_str(), "box_size");
  1786.  
  1787. res += w*(iAmmoElapsed / bs);
  1788. }
  1789. return res;
  1790. }
  1791.  
  1792. bool CWeapon::show_crosshair()
  1793. {
  1794. return !IsPending() && (!IsZoomed() || !ZoomHideCrosshair());
  1795. }
  1796.  
  1797. bool CWeapon::show_indicators()
  1798. {
  1799. return !(IsZoomed() && ZoomTexture());
  1800. }
  1801.  
  1802. float CWeapon::GetConditionToShow() const
  1803. {
  1804. return (GetCondition());//powf(GetCondition(),4.0f));
  1805. }
  1806.  
  1807. BOOL CWeapon::ParentMayHaveAimBullet()
  1808. {
  1809. CObject* O = H_Parent();
  1810. CEntityAlive* EA = smart_cast<CEntityAlive*>(O);
  1811. return EA->cast_actor() != 0;
  1812. }
  1813.  
  1814. BOOL CWeapon::ParentIsActor()
  1815. {
  1816. CObject* O = H_Parent();
  1817. if (!O)
  1818. return FALSE;
  1819.  
  1820. CEntityAlive* EA = smart_cast<CEntityAlive*>(O);
  1821. if (!EA)
  1822. return FALSE;
  1823.  
  1824. return EA->cast_actor() != 0;
  1825. }
  1826.  
  1827. extern u32 hud_adj_mode;
  1828.  
  1829. void CWeapon::debug_draw_firedeps()
  1830. {
  1831. #ifdef DEBUG
  1832. if(hud_adj_mode==5||hud_adj_mode==6||hud_adj_mode==7)
  1833. {
  1834. CDebugRenderer &render = Level().debug_renderer();
  1835.  
  1836. if(hud_adj_mode==5)
  1837. render.draw_aabb(get_LastFP(), 0.005f,0.005f,0.005f,D3DCOLOR_XRGB(255,0,0));
  1838.  
  1839. if(hud_adj_mode==6)
  1840. render.draw_aabb(get_LastFP2(), 0.005f,0.005f,0.005f,D3DCOLOR_XRGB(0,0,255));
  1841.  
  1842. if(hud_adj_mode==7)
  1843. render.draw_aabb(get_LastSP(), 0.005f,0.005f,0.005f,D3DCOLOR_XRGB(0,255,0));
  1844. }
  1845. #endif // DEBUG
  1846. }
  1847.  
  1848. const float &CWeapon::hit_probability() const
  1849. {
  1850. VERIFY((g_SingleGameDifficulty >= egdNovice) && (g_SingleGameDifficulty <= egdMaster));
  1851. return (m_hit_probability[egdNovice]);
  1852. }
  1853.  
  1854. void CWeapon::OnStateSwitch(u32 S)
  1855. {
  1856. inherited::OnStateSwitch(S);
  1857. m_BriefInfo_CalcFrame = 0;
  1858.  
  1859. if (GetState() == eReload)
  1860. {
  1861. if (iAmmoElapsed == 0) //Swartz: re-written to use reload empty DOF
  1862. {
  1863. if (H_Parent() == Level().CurrentEntity() && !fsimilar(m_zoom_params.m_ReloadEmptyDof.w, -1.0f))
  1864. {
  1865. CActor* current_actor = smart_cast<CActor*>(H_Parent());
  1866. if (current_actor)
  1867. current_actor->Cameras().AddCamEffector(xr_new<CEffectorDOF>(m_zoom_params.m_ReloadEmptyDof));
  1868. }
  1869. }
  1870. else
  1871. {
  1872. if (H_Parent() == Level().CurrentEntity() && !fsimilar(m_zoom_params.m_ReloadDof.w, -1.0f))
  1873. {
  1874. CActor* current_actor = smart_cast<CActor*>(H_Parent());
  1875. if (current_actor)
  1876. current_actor->Cameras().AddCamEffector(xr_new<CEffectorDOF>(m_zoom_params.m_ReloadDof));
  1877. }
  1878. }
  1879. }
  1880. }
  1881.  
  1882. void CWeapon::OnAnimationEnd(u32 state)
  1883. {
  1884. inherited::OnAnimationEnd(state);
  1885. }
  1886.  
  1887. u8 CWeapon::GetCurrentHudOffsetIdx()
  1888. {
  1889. CActor* pActor = smart_cast<CActor*>(H_Parent());
  1890. if (!pActor) return 0;
  1891.  
  1892. bool b_aiming = ((IsZoomed() && m_zoom_params.m_fZoomRotationFactor <= 1.f) ||
  1893. (!IsZoomed() && m_zoom_params.m_fZoomRotationFactor > 0.f));
  1894.  
  1895. if (!b_aiming)
  1896. return 0;
  1897. else
  1898. return 1;
  1899. }
  1900.  
  1901. void CWeapon::render_hud_mode()
  1902. {
  1903. RenderLight();
  1904. }
  1905.  
  1906. bool CWeapon::MovingAnimAllowedNow()
  1907. {
  1908. return !IsZoomed();
  1909. }
  1910.  
  1911. bool CWeapon::IsHudModeNow()
  1912. {
  1913. return (HudItemData() != NULL);
  1914. }
  1915.  
  1916. void CWeapon::ZoomInc()
  1917. {
  1918. if (!IsScopeAttached()) return;
  1919. if (!m_zoom_params.m_bUseDynamicZoom) return;
  1920. float delta, min_zoom_factor;
  1921. GetZoomData(m_zoom_params.m_fScopeZoomFactor, delta, min_zoom_factor);
  1922.  
  1923. float f = GetZoomFactor() - delta;
  1924. clamp(f, m_zoom_params.m_fScopeZoomFactor, min_zoom_factor);
  1925. SetZoomFactor(f);
  1926. }
  1927.  
  1928. void CWeapon::ZoomDec()
  1929. {
  1930. if (!IsScopeAttached()) return;
  1931. if (!m_zoom_params.m_bUseDynamicZoom) return;
  1932. float delta, min_zoom_factor;
  1933. GetZoomData(m_zoom_params.m_fScopeZoomFactor, delta, min_zoom_factor);
  1934.  
  1935. float f = GetZoomFactor() + delta;
  1936. clamp(f, m_zoom_params.m_fScopeZoomFactor, min_zoom_factor);
  1937. SetZoomFactor(f);
  1938. }
  1939. u32 CWeapon::Cost() const
  1940. {
  1941. u32 res = CInventoryItem::Cost();
  1942. if (IsGrenadeLauncherAttached() && GetGrenadeLauncherName().size())
  1943. {
  1944. res += pSettings->r_u32(GetGrenadeLauncherName(), "cost");
  1945. }
  1946. if (IsScopeAttached() && m_scopes.size())
  1947. {
  1948. res += pSettings->r_u32(GetScopeName(), "cost");
  1949. }
  1950. if (IsSilencerAttached() && GetSilencerName().size())
  1951. {
  1952. res += pSettings->r_u32(GetSilencerName(), "cost");
  1953. }
  1954.  
  1955. if (iAmmoElapsed)
  1956. {
  1957. float w = pSettings->r_float(m_ammoTypes[m_ammoType].c_str(), "cost");
  1958. float bs = pSettings->r_float(m_ammoTypes[m_ammoType].c_str(), "box_size");
  1959.  
  1960. res += iFloor(w*(iAmmoElapsed / bs));
  1961. }
  1962. return res;
  1963. }
Add Comment
Please, Sign In to add comment