Advertisement
Guest User

Untitled

a guest
Jan 6th, 2016
656
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.98 KB | None | 0 0
  1. //////////////////////////////////////////////////////////////////////
  2. // ShootingObject.cpp: интерфейс для семейства стреляющих объектов
  3. // (оружие и осколочные гранаты)
  4. //////////////////////////////////////////////////////////////////////
  5.  
  6. #include "stdafx.h"
  7.  
  8. #include "ShootingObject.h"
  9.  
  10. #include "ParticlesObject.h"
  11. #include "WeaponAmmo.h"
  12.  
  13. #include "actor.h"
  14. #include "spectator.h"
  15. #include "game_cl_base.h"
  16. #include "level.h"
  17. #include "level_bullet_manager.h"
  18. #include "game_cl_single.h"
  19.  
  20. #define HIT_POWER_EPSILON 0.05f
  21. #define WALLMARK_SIZE 0.04f
  22.  
  23. CShootingObject::CShootingObject(void)
  24. {
  25. fShotTimeCounter = 0;
  26. fOneShotTime = 0;
  27. //fHitPower = 0.0f;
  28. fvHitPower.set (0.0f,0.0f,0.0f,0.0f);
  29. fvHitPowerCritical.set (0.0f,0.0f,0.0f,0.0f);
  30. m_fStartBulletSpeed = 1000.f;
  31.  
  32. m_vCurrentShootDir.set (0,0,0);
  33. m_vCurrentShootPos.set (0,0,0);
  34. m_iCurrentParentID = 0xFFFF;
  35.  
  36. m_fPredBulletTime = 0.0f;
  37. m_bUseAimBullet = false;
  38. m_fTimeToAim = 0.0f;
  39.  
  40. //particles
  41. m_sFlameParticlesCurrent = m_sFlameParticles = NULL;
  42. m_sSmokeParticlesCurrent = m_sSmokeParticles = NULL;
  43. m_sShellParticles = NULL;
  44.  
  45. bWorking = false;
  46.  
  47. light_render = 0;
  48.  
  49. reinit();
  50.  
  51. }
  52. CShootingObject::~CShootingObject(void)
  53. {
  54. }
  55.  
  56. void CShootingObject::reinit()
  57. {
  58. m_pFlameParticles = NULL;
  59. }
  60.  
  61. void CShootingObject::Load (LPCSTR section)
  62. {
  63. if(pSettings->line_exist(section,"light_disabled"))
  64. {
  65. m_bLightShotEnabled = !pSettings->r_bool(section,"light_disabled");
  66. }else
  67. m_bLightShotEnabled = true;
  68.  
  69. //время затрачиваемое на выстрел
  70. fOneShotTime = pSettings->r_float (section,"rpm");
  71.  
  72. //Alundaio: Two-shot burst rpm; used for Abakan/AN-94
  73. fModeShotTime = READ_IF_EXISTS(pSettings, r_float, section, "rpm_mode_2", fOneShotTime);
  74.  
  75. VERIFY(fOneShotTime>0.f);
  76. fOneShotTime = 60.f / fOneShotTime;
  77. fModeShotTime = 60.f / fModeShotTime;
  78.  
  79. //Cycle down RPM after first 2 shots; used for Abakan/AN-94
  80. if (pSettings->line_exist(section, "cycle_down"))
  81. {
  82. bCycleDown = pSettings->r_bool(section, "cycle_down");
  83. }
  84. else
  85. bCycleDown = false;
  86. //Alundaio: END
  87.  
  88. LoadFireParams (section);
  89. LoadLights (section, "");
  90. LoadShellParticles (section, "");
  91. LoadFlameParticles (section, "");
  92.  
  93. m_air_resistance_factor = READ_IF_EXISTS(pSettings,r_float,section,"air_resistance_factor",1.f);
  94. }
  95.  
  96. void CShootingObject::Light_Create ()
  97. {
  98. //lights
  99. light_render = ::Render->light_create();
  100. if (::Render->get_generation()==IRender_interface::GENERATION_R2) light_render->set_shadow (true);
  101. else light_render->set_shadow (false);
  102. }
  103.  
  104. void CShootingObject::Light_Destroy ()
  105. {
  106. light_render.destroy ();
  107. }
  108.  
  109. void CShootingObject::LoadFireParams( LPCSTR section )
  110. {
  111. string32 buffer;
  112. shared_str s_sHitPower;
  113. shared_str s_sHitPowerCritical;
  114.  
  115. //базовая дисперсия оружия
  116. fireDispersionBase = deg2rad( pSettings->r_float (section,"fire_dispersion_base" ) );
  117.  
  118. //сила выстрела и его мощьность
  119. s_sHitPower = pSettings->r_string_wb(section, "hit_power" );//читаем строку силы хита пули оружия
  120. s_sHitPowerCritical = pSettings->r_string_wb(section, "hit_power_critical" );
  121. fvHitPower[egdMaster] = (float)atof(_GetItem(*s_sHitPower,0,buffer));//первый параметр - это хит для уровня игры мастер
  122. fvHitPowerCritical[egdMaster] = (float)atof(_GetItem(*s_sHitPowerCritical,0,buffer));//первый параметр - это хит для уровня игры мастер
  123.  
  124. fvHitPower[egdNovice] = fvHitPower[egdStalker] = fvHitPower[egdVeteran] = fvHitPower[egdMaster];//изначально параметры для других уровней сложности такие же
  125. fvHitPowerCritical[egdNovice] = fvHitPowerCritical[egdStalker] = fvHitPowerCritical[egdVeteran] = fvHitPowerCritical[egdMaster];//изначально параметры для других уровней сложности такие же
  126.  
  127. int num_game_diff_param=_GetItemCount(*s_sHitPower);//узнаём колличество параметров для хитов
  128. if (num_game_diff_param>1)//если задан второй параметр хита
  129. {
  130. fvHitPower[egdVeteran] = (float)atof(_GetItem(*s_sHitPower,1,buffer));//то вычитываем его для уровня ветерана
  131. }
  132. if (num_game_diff_param>2)//если задан третий параметр хита
  133. {
  134. fvHitPower[egdStalker] = (float)atof(_GetItem(*s_sHitPower,2,buffer));//то вычитываем его для уровня сталкера
  135. }
  136. if (num_game_diff_param>3)//если задан четвёртый параметр хита
  137. {
  138. fvHitPower[egdNovice] = (float)atof(_GetItem(*s_sHitPower,3,buffer));//то вычитываем его для уровня новичка
  139. }
  140.  
  141. num_game_diff_param=_GetItemCount(*s_sHitPowerCritical);//узнаём колличество параметров
  142. if (num_game_diff_param>1)//если задан второй параметр хита
  143. {
  144. fvHitPowerCritical[egdVeteran] = (float)atof(_GetItem(*s_sHitPowerCritical,1,buffer));//то вычитываем его для уровня ветерана
  145. }
  146. if (num_game_diff_param>2)//если задан третий параметр хита
  147. {
  148. fvHitPowerCritical[egdStalker] = (float)atof(_GetItem(*s_sHitPowerCritical,2,buffer));//то вычитываем его для уровня сталкера
  149. }
  150. if (num_game_diff_param>3)//если задан четвёртый параметр хита
  151. {
  152. fvHitPowerCritical[egdNovice] = (float)atof(_GetItem(*s_sHitPowerCritical,3,buffer));//то вычитываем его для уровня новичка
  153. }
  154.  
  155. fHitImpulse = pSettings->r_float (section, "hit_impulse" );
  156. //максимальное расстояние полета пули
  157. fireDistance = pSettings->r_float (section, "fire_distance" );
  158. //начальная скорость пули
  159. m_fStartBulletSpeed = pSettings->r_float (section, "bullet_speed" );
  160. m_bUseAimBullet = pSettings->r_bool (section, "use_aim_bullet" );
  161. if (m_bUseAimBullet)
  162. {
  163. m_fTimeToAim = pSettings->r_float (section, "time_to_aim" );
  164. }
  165. }
  166.  
  167. void CShootingObject::LoadLights (LPCSTR section, LPCSTR prefix)
  168. {
  169. string256 full_name;
  170. // light
  171. if(m_bLightShotEnabled)
  172. {
  173. Fvector clr = pSettings->r_fvector3 (section, strconcat(sizeof(full_name),full_name, prefix, "light_color"));
  174. light_base_color.set(clr.x,clr.y,clr.z,1);
  175. light_base_range = pSettings->r_float (section, strconcat(sizeof(full_name),full_name, prefix, "light_range") );
  176. light_var_color = pSettings->r_float (section, strconcat(sizeof(full_name),full_name, prefix, "light_var_color") );
  177. light_var_range = pSettings->r_float (section, strconcat(sizeof(full_name),full_name, prefix, "light_var_range") );
  178. light_lifetime = pSettings->r_float (section, strconcat(sizeof(full_name),full_name, prefix, "light_time") );
  179. light_time = -1.f;
  180. }
  181. }
  182.  
  183. void CShootingObject::Light_Start ()
  184. {
  185. if(!light_render) Light_Create();
  186.  
  187. if (Device.dwFrame != light_frame)
  188. {
  189. light_frame = Device.dwFrame;
  190. light_time = light_lifetime;
  191.  
  192. light_build_color.set (Random.randFs(light_var_color,light_base_color.r),Random.randFs(light_var_color,light_base_color.g),Random.randFs(light_var_color,light_base_color.b),1);
  193. light_build_range = Random.randFs(light_var_range,light_base_range);
  194. }
  195. }
  196.  
  197. void CShootingObject::Light_Render (const Fvector& P)
  198. {
  199. float light_scale = light_time/light_lifetime;
  200. R_ASSERT(light_render);
  201.  
  202. light_render->set_position (P);
  203. light_render->set_color (light_build_color.r*light_scale,light_build_color.g*light_scale,light_build_color.b*light_scale);
  204. light_render->set_range (light_build_range*light_scale);
  205.  
  206. if( !light_render->get_active() )
  207. {
  208. light_render->set_active (true);
  209. }
  210. }
  211.  
  212.  
  213. //////////////////////////////////////////////////////////////////////////
  214. // Particles
  215. //////////////////////////////////////////////////////////////////////////
  216.  
  217. void CShootingObject::StartParticles (CParticlesObject*& pParticles, LPCSTR particles_name,
  218. const Fvector& pos, const Fvector& vel, bool auto_remove_flag)
  219. {
  220. if(!particles_name) return;
  221.  
  222. if(pParticles != NULL)
  223. {
  224. UpdateParticles(pParticles, pos, vel);
  225. return;
  226. }
  227.  
  228. pParticles = CParticlesObject::Create(particles_name,(BOOL)auto_remove_flag);
  229.  
  230. UpdateParticles(pParticles, pos, vel);
  231. CSpectator* tmp_spectr = smart_cast<CSpectator*>(Level().CurrentControlEntity());
  232. bool in_hud_mode = IsHudModeNow();
  233. if (in_hud_mode && tmp_spectr &&
  234. (tmp_spectr->GetActiveCam() != CSpectator::eacFirstEye))
  235. {
  236. in_hud_mode = false;
  237. }
  238. pParticles->Play(in_hud_mode);
  239. }
  240. void CShootingObject::StopParticles (CParticlesObject*& pParticles)
  241. {
  242. if(pParticles == NULL) return;
  243.  
  244. pParticles->Stop ();
  245. CParticlesObject::Destroy(pParticles);
  246. }
  247.  
  248. void CShootingObject::UpdateParticles (CParticlesObject*& pParticles,
  249. const Fvector& pos, const Fvector& vel)
  250. {
  251. if(!pParticles) return;
  252.  
  253. Fmatrix particles_pos;
  254. particles_pos.set (get_ParticlesXFORM());
  255. particles_pos.c.set (pos);
  256.  
  257. pParticles->SetXFORM(particles_pos);
  258.  
  259. if(!pParticles->IsAutoRemove() && !pParticles->IsLooped()
  260. && !pParticles->PSI_alive())
  261. {
  262. pParticles->Stop ();
  263. CParticlesObject::Destroy(pParticles);
  264. }
  265. }
  266.  
  267.  
  268. void CShootingObject::LoadShellParticles (LPCSTR section, LPCSTR prefix)
  269. {
  270. string256 full_name;
  271. strconcat(sizeof(full_name),full_name, prefix, "shell_particles");
  272.  
  273. if(pSettings->line_exist(section,full_name))
  274. {
  275. m_sShellParticles = pSettings->r_string (section,full_name);
  276. vLoadedShellPoint = pSettings->r_fvector3 (section,strconcat(sizeof(full_name),full_name, prefix, "shell_point"));
  277. }
  278. }
  279.  
  280. void CShootingObject::LoadFlameParticles (LPCSTR section, LPCSTR prefix)
  281. {
  282. string256 full_name;
  283.  
  284. // flames
  285. strconcat(sizeof(full_name),full_name, prefix, "flame_particles");
  286. if(pSettings->line_exist(section, full_name))
  287. m_sFlameParticles = pSettings->r_string (section, full_name);
  288.  
  289. strconcat(sizeof(full_name),full_name, prefix, "smoke_particles");
  290. if(pSettings->line_exist(section, full_name))
  291. m_sSmokeParticles = pSettings->r_string (section, full_name);
  292.  
  293. strconcat(sizeof(full_name),full_name, prefix, "shot_particles");
  294. if(pSettings->line_exist(section, full_name))
  295. m_sShotParticles = pSettings->r_string (section, full_name);
  296.  
  297.  
  298. //текущие партиклы
  299. m_sFlameParticlesCurrent = m_sFlameParticles;
  300. m_sSmokeParticlesCurrent = m_sSmokeParticles;
  301. }
  302.  
  303.  
  304. void CShootingObject::OnShellDrop (const Fvector& play_pos,
  305. const Fvector& parent_vel)
  306. {
  307. if(!m_sShellParticles) return;
  308. if( Device.vCameraPosition.distance_to_sqr(play_pos)>2*2 ) return;
  309.  
  310. CParticlesObject* pShellParticles = CParticlesObject::Create(*m_sShellParticles,TRUE);
  311.  
  312. Fmatrix particles_pos;
  313. particles_pos.set (get_ParticlesXFORM());
  314. particles_pos.c.set (play_pos);
  315.  
  316. pShellParticles->UpdateParent (particles_pos, parent_vel);
  317. CSpectator* tmp_spectr = smart_cast<CSpectator*>(Level().CurrentControlEntity());
  318. bool in_hud_mode = IsHudModeNow();
  319. if (in_hud_mode && tmp_spectr &&
  320. (tmp_spectr->GetActiveCam() != CSpectator::eacFirstEye))
  321. {
  322. in_hud_mode = false;
  323. }
  324. pShellParticles->Play(in_hud_mode);
  325. }
  326.  
  327.  
  328. //партиклы дыма
  329. void CShootingObject::StartSmokeParticles (const Fvector& play_pos,
  330. const Fvector& parent_vel)
  331. {
  332. CParticlesObject* pSmokeParticles = NULL;
  333. StartParticles(pSmokeParticles, *m_sSmokeParticlesCurrent, play_pos, parent_vel, true);
  334. }
  335.  
  336.  
  337. void CShootingObject::StartFlameParticles ()
  338. {
  339. if(0==m_sFlameParticlesCurrent.size()) return;
  340.  
  341. //если партиклы циклические
  342. if(m_pFlameParticles && m_pFlameParticles->IsLooped() &&
  343. m_pFlameParticles->IsPlaying())
  344. {
  345. UpdateFlameParticles();
  346. return;
  347. }
  348.  
  349. StopFlameParticles();
  350. m_pFlameParticles = CParticlesObject::Create(*m_sFlameParticlesCurrent,FALSE);
  351. UpdateFlameParticles();
  352.  
  353.  
  354. CSpectator* tmp_spectr = smart_cast<CSpectator*>(Level().CurrentControlEntity());
  355. bool in_hud_mode = IsHudModeNow();
  356. if (in_hud_mode && tmp_spectr &&
  357. (tmp_spectr->GetActiveCam() != CSpectator::eacFirstEye))
  358. {
  359. in_hud_mode = false;
  360. }
  361. m_pFlameParticles->Play(in_hud_mode);
  362.  
  363.  
  364. }
  365. void CShootingObject::StopFlameParticles ()
  366. {
  367. if(0==m_sFlameParticlesCurrent.size()) return;
  368. if(m_pFlameParticles == NULL) return;
  369.  
  370. m_pFlameParticles->SetAutoRemove(true);
  371. m_pFlameParticles->Stop();
  372. m_pFlameParticles = NULL;
  373. }
  374.  
  375. void CShootingObject::UpdateFlameParticles ()
  376. {
  377. if(0==m_sFlameParticlesCurrent.size()) return;
  378. if(!m_pFlameParticles) return;
  379.  
  380. Fmatrix pos;
  381. pos.set (get_ParticlesXFORM() );
  382. pos.c.set (get_CurrentFirePoint() );
  383.  
  384. VERIFY(_valid(pos));
  385.  
  386. m_pFlameParticles->SetXFORM (pos);
  387.  
  388. if(!m_pFlameParticles->IsLooped() &&
  389. !m_pFlameParticles->IsPlaying() &&
  390. !m_pFlameParticles->PSI_alive())
  391. {
  392. m_pFlameParticles->Stop();
  393. CParticlesObject::Destroy(m_pFlameParticles);
  394. }
  395. }
  396.  
  397. //подсветка от выстрела
  398. void CShootingObject::UpdateLight()
  399. {
  400. if (light_render && light_time>0)
  401. {
  402. light_time -= Device.fTimeDelta;
  403. if (light_time<=0) StopLight();
  404. }
  405. }
  406.  
  407. void CShootingObject::StopLight ()
  408. {
  409. if(light_render){
  410. light_render->set_active(false);
  411. }
  412. }
  413.  
  414. void CShootingObject::RenderLight()
  415. {
  416. if ( light_render && light_time>0 )
  417. {
  418. Light_Render(get_CurrentFirePoint());
  419. }
  420. }
  421.  
  422. bool CShootingObject::SendHitAllowed (CObject* pUser)
  423. {
  424. if (Game().IsServerControlHits())
  425. return OnServer();
  426.  
  427. if (OnServer())
  428. {
  429. if (smart_cast<CActor*>(pUser))
  430. {
  431. if (Level().CurrentControlEntity() != pUser)
  432. {
  433. return false;
  434. }
  435. }
  436. return true;
  437. }
  438. else
  439. {
  440. if (smart_cast<CActor*>(pUser))
  441. {
  442. if (Level().CurrentControlEntity() == pUser)
  443. {
  444. return true;
  445. }
  446. }
  447. return false;
  448. }
  449. };
  450.  
  451. extern void random_dir(Fvector& tgt_dir, const Fvector& src_dir, float dispersion);
  452.  
  453. void CShootingObject::FireBullet(const Fvector& pos,
  454. const Fvector& shot_dir,
  455. float fire_disp,
  456. const CCartridge& cartridge,
  457. u16 parent_id,
  458. u16 weapon_id,
  459. bool send_hit)
  460. {
  461. Fvector dir;
  462. random_dir(dir,shot_dir,fire_disp);
  463.  
  464. m_vCurrentShootDir = dir;
  465. m_vCurrentShootPos = pos;
  466. m_iCurrentParentID = parent_id;
  467.  
  468. bool aim_bullet;
  469. if (m_bUseAimBullet)
  470. {
  471. if (ParentMayHaveAimBullet())
  472. {
  473. if (m_fPredBulletTime==0.0)
  474. {
  475. aim_bullet=true;
  476. }
  477. else
  478. {
  479. if ((Device.fTimeGlobal-m_fPredBulletTime)>=m_fTimeToAim)
  480. {
  481. aim_bullet=true;
  482. }
  483. else
  484. {
  485. aim_bullet=false;
  486. }
  487. }
  488. }
  489. else
  490. {
  491. aim_bullet=false;
  492. }
  493. }
  494. else
  495. {
  496. aim_bullet=false;
  497. }
  498. m_fPredBulletTime = Device.fTimeGlobal;
  499.  
  500. float l_fHitPower = 0.0f;
  501. if (ParentIsActor())//если из оружия стреляет актёр(игрок)
  502. {
  503. if (GameID() == eGameIDSingle)
  504. {
  505. l_fHitPower = fvHitPower[g_SingleGameDifficulty];
  506. }
  507. else
  508. {
  509. l_fHitPower = fvHitPower[egdMaster];
  510. }
  511. }
  512. else
  513. {
  514. l_fHitPower = fvHitPower[egdMaster];
  515. }
  516.  
  517. Level().BulletManager().AddBullet( pos,
  518. dir,
  519. m_fStartBulletSpeed * cur_silencer_koef.bullet_speed,
  520. l_fHitPower * cur_silencer_koef.hit_power,
  521. fHitImpulse * cur_silencer_koef.hit_impulse,
  522. parent_id,
  523. weapon_id,
  524. ALife::eHitTypeFireWound,
  525. fireDistance,
  526. cartridge,
  527. m_air_resistance_factor,
  528. send_hit,
  529. aim_bullet);
  530. }
  531. void CShootingObject::FireStart ()
  532. {
  533. bWorking=true;
  534. }
  535. void CShootingObject::FireEnd ()
  536. {
  537. bWorking=false;
  538. }
  539.  
  540. void CShootingObject::StartShotParticles ()
  541. {
  542. CParticlesObject* pSmokeParticles = NULL;
  543. StartParticles(pSmokeParticles, *m_sShotParticles,
  544. m_vCurrentShootPos, m_vCurrentShootDir, true);
  545. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement