plugindevelopersync.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090
  1. enum PDS_SYSTEMS
  2. {
  3. STATS = 1,
  4. LEVELS = 2,
  5. MODS = 4,
  6. AGENTS = 8,
  7. STOMACH = 16,
  8. MODS_DETAILED = 32,
  9. TEMPERATURE = 64,
  10. HEALTH = 128,
  11. }
  12. class RegisterPlayerData
  13. {
  14. int m_Bitmask;
  15. int m_DetailedModifierIndex;
  16. void RegisterPlayerData()
  17. {
  18. m_Bitmask = 0;
  19. m_DetailedModifierIndex = 0;
  20. }
  21. }
  22. class PluginDeveloperSync extends PluginBase
  23. {
  24. int m_DetailedInfoRequested = 0;
  25. ref Timer m_UpdateTimer;
  26. ref map<PlayerBase, ref RegisterPlayerData> m_RegisteredPlayers;
  27. ref array<ref SyncedValue> m_PlayerStatsSynced;
  28. ref array<ref Param> m_PlayerStomachSynced;
  29. ref array<ref SyncedValueLevel> m_PlayerLevelsSynced;
  30. ref array<ref SyncedValueModifier> m_PlayerModsSynced;
  31. string m_PlayerModsDetailedSynced;
  32. string m_EnvironmentDebugMessage;
  33. ref array<ref SyncedValueAgent> m_PlayerAgentsSynced;
  34. protected ref array<ref SyncedValue> m_TargetHealthSynced;
  35. protected bool m_IsTargetChanged; // client update
  36. protected ref map<PlayerBase, bool> m_HealthObserverMode; // server tracking of player X health mode selection | true = target / false = self
  37. protected ref map<PlayerBase, EntityAI> m_HealthObserverEntity; // server tracking of player X health target
  38. bool m_StatsUpdateStatus;
  39. bool m_LevelsUpdateStatus;
  40. bool m_ModsUpdateStatus;
  41. bool m_AgentsUpdateStatus;
  42. bool m_StomachUpdateStatus;
  43. void PluginDeveloperSync()
  44. {
  45. m_RegisteredPlayers = new map<PlayerBase, ref RegisterPlayerData>;
  46. m_PlayerStatsSynced = new array<ref SyncedValue>;
  47. m_PlayerLevelsSynced = new array<ref SyncedValueLevel>;
  48. m_PlayerModsSynced = new array<ref SyncedValueModifier>;
  49. m_PlayerAgentsSynced = new array<ref SyncedValueAgent>;
  50. m_PlayerStomachSynced = new array<ref Param>;
  51. m_TargetHealthSynced = new array<ref SyncedValue>;
  52. m_HealthObserverMode = new map<PlayerBase,bool>;
  53. m_HealthObserverEntity = new map<PlayerBase,EntityAI>;
  54. m_StatsUpdateStatus = false;
  55. m_LevelsUpdateStatus = false;
  56. m_ModsUpdateStatus = false;
  57. m_AgentsUpdateStatus = false;
  58. m_StomachUpdateStatus = false;
  59. }
  60. //================================================================
  61. // Init / Update
  62. //================================================================
  63. override void OnInit()
  64. {
  65. super.OnInit();
  66. if ( GetGame().IsServer() )
  67. {
  68. //create timer
  69. m_UpdateTimer = new Timer( CALL_CATEGORY_GAMEPLAY );
  70. }
  71. }
  72. void EnableUpdate( bool enable, int type, PlayerBase player )
  73. {
  74. //set update by type
  75. if ( !IsPlayerRegistered(player))
  76. RegisterPlayer( player );
  77. switch ( type )
  78. {
  79. case ERPCs.DEV_STATS_UPDATE:
  80. {
  81. SetSystemInBitmask(player, PDS_SYSTEMS.STATS, enable);
  82. break;
  83. }
  84. case ERPCs.DEV_LEVELS_UPDATE:
  85. {
  86. SetSystemInBitmask(player, PDS_SYSTEMS.LEVELS, enable);
  87. break;
  88. }
  89. case ERPCs.DEV_MODS_UPDATE:
  90. {
  91. SetSystemInBitmask(player, PDS_SYSTEMS.MODS, enable);
  92. break;
  93. }
  94. case ERPCs.DEV_AGENTS_UPDATE:
  95. {
  96. SetSystemInBitmask(player, PDS_SYSTEMS.AGENTS, enable);
  97. break;
  98. }
  99. case ERPCs.DEV_STOMACH_UPDATE:
  100. {
  101. SetSystemInBitmask(player, PDS_SYSTEMS.STOMACH, enable);
  102. break;
  103. }
  104. case ERPCs.DEV_TEMP_UPDATE:
  105. {
  106. SetSystemInBitmask(player, PDS_SYSTEMS.TEMPERATURE, enable);
  107. break;
  108. }
  109. case ERPCs.DEV_HEALTH_UPDATE:
  110. {
  111. SetSystemInBitmask(player, PDS_SYSTEMS.HEALTH, enable);
  112. break;
  113. }
  114. }
  115. //remove players with empty mask
  116. for (int i = 0; i < m_RegisteredPlayers.Count(); i++)
  117. {
  118. if (m_RegisteredPlayers.GetElement(i).m_Bitmask == 0)
  119. {
  120. m_RegisteredPlayers.RemoveElement(i);
  121. i = 0;
  122. }
  123. }
  124. //start/stop the tick based on existence/absence of players registered
  125. if ( m_UpdateTimer )
  126. {
  127. if ( m_RegisteredPlayers.Count() == 0)
  128. {
  129. m_UpdateTimer.Stop();
  130. }
  131. else if (!m_UpdateTimer.IsRunning())
  132. {
  133. m_UpdateTimer.Run( 1, this, "Update", NULL, true );
  134. }
  135. }
  136. }
  137. void Update()
  138. {
  139. if ( !GetDayZGame().IsMultiplayer() || GetDayZGame().IsServer() )
  140. {
  141. for ( int i = 0; i < m_RegisteredPlayers.Count(); ++i )
  142. {
  143. PlayerBase player = m_RegisteredPlayers.GetKey( i );
  144. if ( !player || !player.IsAlive() )
  145. {
  146. m_RegisteredPlayers.RemoveElement(i);
  147. i--;
  148. }
  149. else
  150. {
  151. int bit_mask = m_RegisteredPlayers.Get( player ).m_Bitmask;
  152. if ((PDS_SYSTEMS.MODS & bit_mask) != 0 )
  153. {
  154. SendRPCMods( player);
  155. if ( PDS_SYSTEMS.MODS_DETAILED & bit_mask )
  156. SendRPCModsDetail( player); //!!!!! Highly suspect
  157. }
  158. if ((PDS_SYSTEMS.LEVELS & bit_mask) != 0 )
  159. {
  160. SendRPCLevels( player );
  161. }
  162. if ((PDS_SYSTEMS.STATS & bit_mask) != 0 )
  163. {
  164. SendRPCStats( player );
  165. }
  166. if ((PDS_SYSTEMS.STOMACH & bit_mask) != 0 )
  167. {
  168. SendRPCStomach( player );
  169. }
  170. if ((PDS_SYSTEMS.AGENTS & bit_mask) != 0 )
  171. {
  172. SendRPCAgents( player );
  173. }
  174. if ((PDS_SYSTEMS.TEMPERATURE & bit_mask) )
  175. {
  176. SendRPCTemp( player );
  177. }
  178. if ((PDS_SYSTEMS.HEALTH & bit_mask) )
  179. {
  180. SendRPCHealth( player );
  181. }
  182. }
  183. }
  184. }
  185. }
  186. //turns on/off a bit for a given system marking it active/inactive
  187. void SetSystemInBitmask( PlayerBase player, int system_bit, bool state)
  188. {
  189. if ( IsPlayerRegistered(player) )
  190. {
  191. int current_mask = m_RegisteredPlayers.Get(player).m_Bitmask;
  192. if (state)
  193. m_RegisteredPlayers.Get(player).m_Bitmask = current_mask | system_bit;
  194. else
  195. m_RegisteredPlayers.Get(player).m_Bitmask = current_mask & ~system_bit;
  196. }
  197. }
  198. //turns on/off a bit for a given system marking it active/inactive
  199. bool IsSetSystemInBitmask( PlayerBase player, int system_bit)
  200. {
  201. if ( IsPlayerRegistered(player) )
  202. {
  203. return (m_RegisteredPlayers.Get(player).m_Bitmask & system_bit);
  204. }
  205. return false;
  206. }
  207. //--- Register / Unregister player
  208. void RegisterPlayer( PlayerBase player )
  209. {
  210. if ( !IsPlayerRegistered( player ) )
  211. {
  212. m_RegisteredPlayers.Insert( player, new RegisterPlayerData );
  213. }
  214. }
  215. /*
  216. void UnregisterPlayer( PlayerBase player )
  217. {
  218. if ( IsPlayerRegistered( player ) )
  219. {
  220. m_RegisteredPlayers.Remove( player );
  221. }
  222. }
  223. */
  224. bool IsPlayerRegistered( PlayerBase player )
  225. {
  226. if ( m_RegisteredPlayers.Contains( player ))
  227. {
  228. return true;
  229. }
  230. return false;
  231. }
  232. //================================================================
  233. // RPC
  234. //================================================================
  235. void OnRPC( PlayerBase player, int rpc_type, ParamsReadContext ctx )
  236. {
  237. if ( !GetGame().IsDebug() )
  238. {
  239. return;
  240. }
  241. switch ( rpc_type )
  242. {
  243. case ERPCs.DEV_STATS_UPDATE:
  244. {
  245. EnableUpdate( GetRPCUpdateState( ctx ), ERPCs.DEV_STATS_UPDATE, player ); break;
  246. }
  247. case ERPCs.DEV_LEVELS_UPDATE:
  248. {
  249. EnableUpdate( GetRPCUpdateState( ctx ), ERPCs.DEV_LEVELS_UPDATE, player ); break;
  250. }
  251. case ERPCs.DEV_MODS_UPDATE:
  252. {
  253. EnableUpdate( GetRPCUpdateState( ctx ), ERPCs.DEV_MODS_UPDATE, player ); break;
  254. }
  255. case ERPCs.DEV_AGENTS_UPDATE:
  256. {
  257. EnableUpdate( GetRPCUpdateState( ctx ), ERPCs.DEV_AGENTS_UPDATE, player ); break;
  258. }
  259. case ERPCs.DEV_STOMACH_UPDATE:
  260. {
  261. EnableUpdate( GetRPCUpdateState( ctx ), ERPCs.DEV_STOMACH_UPDATE, player ); break;
  262. }
  263. case ERPCs.DEV_HEALTH_UPDATE:
  264. {
  265. EnableUpdate( GetRPCUpdateState( ctx ), ERPCs.DEV_HEALTH_UPDATE, player ); break;
  266. }
  267. case ERPCs.DEV_RPC_STATS_DATA:
  268. {
  269. OnRPCStats( ctx ); break;
  270. }
  271. case ERPCs.DEV_RPC_LEVELS_DATA:
  272. {
  273. OnRPCLevels( ctx ); break;
  274. }
  275. case ERPCs.DEV_RPC_MODS_DATA:
  276. {
  277. OnRPCMods( ctx ); break;
  278. }
  279. case ERPCs.DEV_RPC_MODS_DATA_DETAILED:
  280. {
  281. OnRPCModsDetailed( ctx ); break;
  282. }
  283. case ERPCs.DEV_RPC_AGENTS_DATA:
  284. {
  285. OnRPCAgents( ctx ); break;
  286. }
  287. case ERPCs.DEV_RPC_STOMACH_DATA:
  288. {
  289. OnRPCStomach( ctx ); break;
  290. }
  291. case ERPCs.DEV_RPC_MODS_ACTIVATE:
  292. {
  293. ActivateModifier( GetRPCModifierID( ctx ), player ); break;
  294. }
  295. case ERPCs.DEV_RPC_MODS_DETAILED:
  296. {
  297. RequestDetailedInfo( GetRPCModifierID( ctx ), player ); break;
  298. }
  299. case ERPCs.DEV_RPC_MODS_DEACTIVATE:
  300. {
  301. DeactivateModifier( GetRPCModifierID( ctx ), player ); break;
  302. }
  303. case ERPCs.DEV_RPC_MODS_LOCK:
  304. {
  305. int id;
  306. bool lock;
  307. GetRPCModifierLock( ctx, id, lock );
  308. LockModifier( id, lock, player ); break;
  309. }
  310. case ERPCs.DEV_RPC_MODS_RESET:
  311. {
  312. player.GetModifiersManager().DeactivateAllModifiers();
  313. break;
  314. }
  315. case ERPCs.DEV_RPC_STATS_RESET:
  316. {
  317. player.GetPlayerStats().ResetAllStats();
  318. break;
  319. }
  320. case ERPCs.DEV_RPC_STAT_SET:
  321. {
  322. OnRPCStatSet(ctx, player);
  323. break;
  324. }
  325. case ERPCs.DEV_TEMP_UPDATE:
  326. {
  327. OnRPCTemp(ctx, player);
  328. break;
  329. }
  330. case ERPCs.DEV_RPC_HEALTH_DATA:
  331. {
  332. OnRPCHealth(ctx, player); break;
  333. }
  334. case ERPCs.DEV_RPC_HEALTH_SET:
  335. {
  336. OnRPCHealthSet(ctx, player);
  337. break;
  338. }
  339. case ERPCs.DEV_RPC_HORTICULTURE_UPDATE:
  340. {
  341. OnRPCHorticultUpdate(ctx, player);
  342. break;
  343. }
  344. case ERPCs.DEV_RPC_HORTICULTURE_SPEED:
  345. {
  346. OnRPCHorticultureSpeed(ctx, player);
  347. break;
  348. }
  349. }
  350. }
  351. //get update status from ctx data
  352. bool GetRPCUpdateState( ParamsReadContext ctx )
  353. {
  354. Param1<bool> p = new Param1<bool>( 0 );
  355. if ( ctx.Read( p ) )
  356. {
  357. return p.param1;
  358. }
  359. return false;
  360. }
  361. //get modifier id from ctx data
  362. int GetRPCModifierID( ParamsReadContext ctx )
  363. {
  364. Param1<int> p = new Param1<int>( 0 );
  365. if ( ctx.Read( p ) )
  366. {
  367. return p.param1;
  368. }
  369. return 0;
  370. }
  371. //get modifier lock state from lock ctx data
  372. void GetRPCModifierLock( ParamsReadContext ctx, out int id, out bool lock )
  373. {
  374. Param2<int, bool> p = new Param2<int, bool>( 0, false );
  375. if ( ctx.Read( p ) )
  376. {
  377. id = p.param1;
  378. lock = p.param2;
  379. }
  380. }
  381. //============================================
  382. // STATS
  383. //============================================
  384. //send player stats through RPC
  385. void SendRPCStats( PlayerBase player )
  386. {
  387. //write and send values
  388. if ( player )
  389. {
  390. array<ref Param> rpc_params = new array<ref Param>;
  391. //param count
  392. for ( int i = 0; i < player.m_PlayerStats.GetPCO().Get().Count(); i++ )
  393. {
  394. string label = player.m_PlayerStats.GetPCO().Get().Get( i ).GetLabel();
  395. float value = (float) player.m_PlayerStats.GetPCO().Get().Get( i ).Get();
  396. float value_norm = (float) player.m_PlayerStats.GetPCO().Get().Get( i ).GetNormalized();
  397. rpc_params.Insert( new Param3<string, float, float>( label, value, value_norm ) );
  398. }
  399. rpc_params.Insert(new Param3<string, float, float>( "(NaS)Immunity", player.GetImmunity(),0 ));
  400. rpc_params.Insert(new Param3<string, float, float>( "(NaS)BrokenLegs", player.m_BrokenLegState,0 ));
  401. rpc_params.InsertAt( new Param1<int>(rpc_params.Count() ), 0);// param count
  402. //send params
  403. GetDayZGame().RPC( player, ERPCs.DEV_RPC_STATS_DATA, rpc_params, true, player.GetIdentity() );
  404. }
  405. }
  406. //Display player stats
  407. void OnRPCStats( ParamsReadContext ctx )
  408. {
  409. //clear values
  410. m_PlayerStatsSynced.Clear();
  411. Param1<int> p_count = new Param1<int>(0);
  412. Param3<string, float, float> p = new Param3<string, float, float>( "", 0, 0 );
  413. //get param count
  414. int param_count = 0;
  415. if ( ctx.Read(p_count) )
  416. {
  417. param_count = p_count.param1;
  418. }
  419. //read values and set
  420. for ( int i = 0; i < param_count; i++ )
  421. {
  422. ctx.Read(p);
  423. m_PlayerStatsSynced.Insert( new SyncedValue( p.param1, p.param2, false, p.param3 ) );
  424. }
  425. }
  426. //Update data on local
  427. void UpdateStatsLocal()
  428. {
  429. PlayerBase player = PlayerBase.Cast( GetDayZGame().GetPlayer() );
  430. //clear values
  431. m_PlayerStatsSynced.Clear();
  432. //set values
  433. for ( int i = 0; i < player.m_PlayerStats.GetPCO().Get().Count(); i++ )
  434. {
  435. string label = player.m_PlayerStats.GetPCO().Get().Get( i ).GetLabel();
  436. float value = player.m_PlayerStats.GetPCO().Get().Get( i ).Get();
  437. float value_norm = player.m_PlayerStats.GetPCO().Get().Get( i ).GetNormalized();
  438. m_PlayerStatsSynced.Insert( new SyncedValue( label, value, false, value_norm ) );
  439. }
  440. m_PlayerStatsSynced.Insert(new SyncedValue( "(NaS)Immunity", player.GetImmunity() , false, 0));
  441. m_PlayerStatsSynced.Insert(new SyncedValue( "(NaS) BrokenLegs", player.m_BrokenLegState, false, 0));
  442. }
  443. void OnRPCStatSet( ParamsReadContext ctx , PlayerBase player)
  444. {
  445. Param2<string, float> p = new Param2<string, float>( "", 0 );
  446. if ( ctx.Read(p) )
  447. {
  448. for ( int i = 0; i < player.m_PlayerStats.GetPCO().Get().Count(); i++ )
  449. {
  450. string label = player.m_PlayerStats.GetPCO().Get().Get( i ).GetLabel();
  451. if ( label == p.param1 )
  452. {
  453. player.m_PlayerStats.GetPCO().Get().Get( i).SetByFloatEx(p.param2);
  454. }
  455. }
  456. }
  457. }
  458. //============================================
  459. // HEALTH
  460. //============================================
  461. ref array<ref SyncedValue> GetHealthZonesSynched()
  462. {
  463. return m_TargetHealthSynced;
  464. }
  465. bool GetIsTargetChanged()
  466. {
  467. return m_IsTargetChanged;
  468. }
  469. void SetTargetChanged(bool state)
  470. {
  471. m_IsTargetChanged = state;
  472. }
  473. void SendRPCHealth(PlayerBase player)
  474. {
  475. //write and send values
  476. if ( player )
  477. {
  478. array<ref Param> rpc_params = new array<ref Param>;
  479. EntityAI target;
  480. if (m_HealthObserverMode.Get(player) == false)
  481. target = player;
  482. else
  483. {
  484. PluginItemDiagnostic itemDiagPlugin = PluginItemDiagnostic.Cast(GetPlugin(PluginItemDiagnostic));
  485. target = EntityAI.Cast(itemDiagPlugin.GetWatchedItem(player));
  486. }
  487. if (target)
  488. {
  489. DamageZoneMap dmgZones = target.GetEntityDamageZoneMap();
  490. SetupZoneValues(rpc_params, dmgZones, target, "Health", 0);
  491. SetupZoneValues(rpc_params, dmgZones, target, "Shock", 1);
  492. SetupZoneValues(rpc_params, dmgZones, target, "Blood", 2);
  493. }
  494. bool targetChanged = false;
  495. if (target != m_HealthObserverEntity.Get(player))
  496. {
  497. targetChanged = true;
  498. m_HealthObserverEntity.Set(player, target);
  499. }
  500. rpc_params.InsertAt( new Param2<int, bool>(rpc_params.Count(), targetChanged), 0);
  501. GetDayZGame().RPC( player, ERPCs.DEV_RPC_HEALTH_DATA, rpc_params, true, player.GetIdentity() );
  502. }
  503. }
  504. void OnRPCHealth(ParamsReadContext ctx , PlayerBase player)
  505. {
  506. m_TargetHealthSynced.Clear();
  507. Param2<int, bool> paramsHeader = new Param2<int, bool>(0, false);
  508. Param4<string, float, float, bool> p = new Param4<string, float, float, bool>("", 0, 0, false);
  509. int paramCount = 0;
  510. if ( ctx.Read(paramsHeader) )
  511. {
  512. paramCount = paramsHeader.param1;
  513. SetTargetChanged(paramsHeader.param2);
  514. }
  515. for ( int i = 0; i < paramCount; i++ )
  516. {
  517. ctx.Read(p);
  518. m_TargetHealthSynced.Insert( new SyncedValue( p.param1, p.param2, p.param4, p.param3 ) );
  519. }
  520. }
  521. void SetupZoneValues(inout array<ref Param> rpc_params, DamageZoneMap dmgZones, EntityAI target, string healthType, int typeID)
  522. {
  523. array<string> outHealthTypes = new array<string>;
  524. //title entry
  525. bool isTitleEntry = true;
  526. rpc_params.Insert( new Param4<string, float, float, bool>( "", 0, typeID, isTitleEntry ) );
  527. // global entry
  528. isTitleEntry = false;
  529. float value;
  530. target.GetAdditionalHealthTypes("", outHealthTypes);
  531. if (healthType == "Health" || outHealthTypes.Find(healthType) != -1) // zone might not have additional health type
  532. {
  533. value = target.GetHealth("", healthType);
  534. rpc_params.Insert( new Param4<string, float, float, bool>( "Global", value, typeID, isTitleEntry ) );
  535. }
  536. //entries
  537. int count = dmgZones.Count();
  538. for (int i = 0; i < count; i++)
  539. {
  540. string zoneName = dmgZones.GetKey(i);
  541. outHealthTypes.Clear();
  542. target.GetAdditionalHealthTypes(zoneName, outHealthTypes);
  543. if (healthType != "Health")
  544. {
  545. if (outHealthTypes.Find(healthType) == -1)
  546. continue;
  547. }
  548. if (target.GetMaxHealth(zoneName, healthType) == 0)
  549. continue;
  550. isTitleEntry = false;
  551. value = target.GetHealth(zoneName, healthType);
  552. rpc_params.Insert( new Param4<string, float, float, bool>( zoneName, value, typeID, isTitleEntry ) );
  553. }
  554. }
  555. // Used for client requesting health change or targeting mode (self/target) change
  556. void OnRPCHealthSet( ParamsReadContext ctx , PlayerBase player)
  557. {
  558. Param3<int, string, string> p = new Param3<int, string, string>( 0, "", "" );
  559. if ( !ctx.Read(p) )
  560. return;
  561. int buttonID = p.param1;
  562. string zoneName = p.param2;
  563. string healthType = p.param3;
  564. if (buttonID > 3) // target change only
  565. {
  566. if (buttonID == 4) // ButtonTarget
  567. m_HealthObserverMode.Set(player, true);
  568. else if (buttonID == 5) // ButtonSelf
  569. m_HealthObserverMode.Set(player, false);
  570. return;
  571. }
  572. EntityAI target;
  573. if (m_HealthObserverMode.Get(player) == false)
  574. target = player;
  575. else
  576. {
  577. PluginItemDiagnostic itemDiagPlugin = PluginItemDiagnostic.Cast(GetPlugin(PluginItemDiagnostic));
  578. target = EntityAI.Cast(itemDiagPlugin.GetWatchedItem(player));
  579. }
  580. if (zoneName == "Global")
  581. zoneName = "";
  582. float zoneMax = target.GetMaxHealth(zoneName, healthType);
  583. float zoneCurrentHealth = target.GetHealth(zoneName, healthType);
  584. float targetHealth;
  585. if (buttonID == 0) // ButtonMin
  586. targetHealth = 0;
  587. else if (buttonID == 1) // ButtonMax
  588. targetHealth = zoneMax;
  589. else if (buttonID == 2) // ButtonAdd
  590. targetHealth = zoneCurrentHealth + zoneMax * 0.1;
  591. else if (buttonID == 3) // ButtonSubtract
  592. targetHealth = zoneCurrentHealth - zoneMax * 0.1;
  593. target.SetHealth(zoneName, healthType, targetHealth);
  594. }
  595. void OnRPCHorticultUpdate( ParamsReadContext ctx , PlayerBase player)
  596. {
  597. Param6<int, GardenBase, int, int, int, int> p = new Param6<int, GardenBase, int, int, int, int>(-1, null, 0, 0, 0, 0);
  598. if ( !ctx.Read(p) )
  599. return;
  600. GardenBase garden = p.param2;
  601. if (p.param1 != -1 && garden)
  602. {
  603. Slot gSlot = garden.GetSlotByIndex(p.param1);
  604. if (gSlot && gSlot.GetPlant())
  605. gSlot.GetPlant().DebugSetTimes(p.param3, p.param4, p.param5, p.param6);
  606. }
  607. else
  608. PlantBase.DebugSetGlobalTimes(p.param3, p.param4, p.param5, p.param6);
  609. }
  610. void OnRPCHorticultureSpeed(ParamsReadContext ctx , PlayerBase player)
  611. {
  612. Param1<float> p = new Param1<float>(1);
  613. if (!ctx.Read(p))
  614. return;
  615. PlantBase.DebugSetTickSpeedMultiplier(p.param1);
  616. }
  617. //============================================
  618. // LEVELS
  619. //============================================
  620. //send player stats through RPC
  621. void SendRPCLevels( PlayerBase player )
  622. {
  623. //write and send values
  624. if ( player )
  625. {
  626. array<ref Param> rpc_params = new array<ref Param>;
  627. rpc_params.Insert(new Param3<string, float, float>( "Immunity: "+ typename.EnumToString(EStatLevels, player.GetImmunityLevel() ),player.GetImmunityLevel(), player.GetBordersImmunity()));
  628. rpc_params.Insert(new Param3<string, float, float>( "Blood: "+ typename.EnumToString(EStatLevels, player.GetStatLevelBlood()),player.GetStatLevelBlood(), player.GetStatBordersBlood()));
  629. rpc_params.Insert(new Param3<string, float, float>( "Health: "+ typename.EnumToString(EStatLevels, player.GetStatLevelHealth() ),player.GetStatLevelHealth(), player.GetStatBordersHealth()));
  630. rpc_params.Insert(new Param3<string, float, float>( "Energy: "+ typename.EnumToString(EStatLevels, player.GetStatLevelEnergy() ),player.GetStatLevelEnergy(), player.GetStatBordersEnergy()));
  631. rpc_params.Insert(new Param3<string, float, float>( "Water: "+ typename.EnumToString(EStatLevels, player.GetStatLevelWater() ),player.GetStatLevelWater(), player.GetStatBordersWater()));
  632. int param_count = rpc_params.Count();
  633. rpc_params.InsertAt( new Param3<string, float, float>( "PARAM_COUNT", param_count,0 ), 0);
  634. //send params
  635. GetDayZGame().RPC( player, ERPCs.DEV_RPC_LEVELS_DATA, rpc_params, true, player.GetIdentity() );
  636. }
  637. }
  638. //Display player stats
  639. void OnRPCLevels( ParamsReadContext ctx )
  640. {
  641. //clear values
  642. m_PlayerLevelsSynced.Clear();
  643. Param3<string, float, float> p3 = new Param3<string, float, float>( "", 0,0 );
  644. //get param count
  645. int param_count = 0;
  646. if ( ctx.Read(p3) )
  647. {
  648. param_count = p3.param2;
  649. }
  650. //read values and set
  651. for ( int i = 0; i < param_count; i++ )
  652. {
  653. if ( ctx.Read(p3) )
  654. m_PlayerLevelsSynced.Insert( new SyncedValueLevel( p3.param1, p3.param2, p3.param3 ) );
  655. }
  656. }
  657. void SendRPCMods( PlayerBase player )
  658. {
  659. //write and send values
  660. if ( player )
  661. {
  662. array<ref Param> rpc_params = new array<ref Param>;
  663. //get modifiers
  664. ModifiersManager mods_manager = player.GetModifiersManager();
  665. //param count
  666. array<ref ModifierDebugObj> modifiers = new array<ref ModifierDebugObj>;
  667. mods_manager.DbgGetModifiers( modifiers );
  668. float param_count = ( float ) modifiers.Count();
  669. rpc_params.Insert( new Param1<int>( param_count ));
  670. //set modifiers
  671. for ( int i = 0; i < modifiers.Count(); ++i )
  672. {
  673. int id = modifiers.Get(i).GetID();
  674. string name = modifiers.Get(i).GetName();
  675. bool active = modifiers.Get(i).IsActive();
  676. bool locked = modifiers.Get(i).IsLocked();
  677. rpc_params.Insert( new Param4<int, string, bool, bool>( id, name, active, locked ) );
  678. }
  679. //send params
  680. GetDayZGame().RPC( player, ERPCs.DEV_RPC_MODS_DATA, rpc_params, true, player.GetIdentity() );
  681. }
  682. }
  683. //============================================
  684. // MODS
  685. //============================================
  686. //send player mods through RPC
  687. void SendRPCModsDetail( PlayerBase player )
  688. {
  689. //write and send values
  690. if ( player )
  691. {
  692. Param1<string> p1 = new Param1<string>("");
  693. ModifiersManager mods_manager = player.GetModifiersManager();
  694. int mod_id = m_RegisteredPlayers.Get(player).m_DetailedModifierIndex;
  695. p1.param1 = mods_manager.GetModifier(mod_id).GetDebugText();
  696. //send params
  697. if (p1.param1 != "")
  698. GetDayZGame().RPCSingleParam( player, ERPCs.DEV_RPC_MODS_DATA_DETAILED, p1, true, player.GetIdentity() );
  699. }
  700. }
  701. //Display player modifiers
  702. void OnRPCMods( ParamsReadContext ctx )
  703. {
  704. //clear values
  705. m_PlayerModsSynced.Clear();
  706. //ref Param3<string, float, bool> p = new Param3<string, float, bool>( "", 0, false );
  707. Param1<int> p1 = new Param1<int>(0);
  708. Param4<int, string, bool, bool> p4 = new Param4<int, string, bool, bool>( 0,"", false, false );
  709. //get param count
  710. int param_count = 0;
  711. if ( ctx.Read(p1) )
  712. {
  713. param_count = (int) p1.param1;
  714. }
  715. //read values and set
  716. for ( int i = 0; i < param_count; i++ )
  717. {
  718. if (ctx.Read(p4))
  719. {
  720. m_PlayerModsSynced.Insert( new SyncedValueModifier( p4.param1, p4.param2, p4.param3, p4.param4 ) );
  721. }
  722. }
  723. }
  724. void OnRPCModsDetailed( ParamsReadContext ctx )
  725. {
  726. Param1<string> p1 = new Param1<string>("");
  727. //get param count
  728. if ( ctx.Read(p1) )
  729. {
  730. m_PlayerModsDetailedSynced = p1.param1;
  731. }
  732. }
  733. /*
  734. //Activates modifier with given ID
  735. void RequestDetailedInfo( int id, PlayerBase player = NULL )
  736. {
  737. int modifier_id = Math.AbsInt( id );
  738. if(id == m_DetailedInfoRequested)
  739. {
  740. m_DetailedInfoRequested = 0;//repeated request --> disable
  741. }
  742. else
  743. {
  744. m_DetailedInfoRequested = modifier_id;
  745. }
  746. }
  747. */
  748. //Activates modifier with given ID
  749. void RequestDetailedInfo( int id, notnull PlayerBase player)
  750. {
  751. int modifier_id = Math.AbsInt( id );
  752. m_RegisteredPlayers.Get(player).m_DetailedModifierIndex = modifier_id;
  753. if (IsSetSystemInBitmask(player, PDS_SYSTEMS.MODS_DETAILED ))
  754. {
  755. SetSystemInBitmask(player, PDS_SYSTEMS.MODS_DETAILED, false);
  756. }
  757. else
  758. {
  759. SetSystemInBitmask(player, PDS_SYSTEMS.MODS_DETAILED, true);
  760. }
  761. }
  762. //Activates modifier with given ID
  763. void ActivateModifier( int id, PlayerBase player = NULL )
  764. {
  765. if ( !player )
  766. {
  767. player = PlayerBase.Cast( GetDayZGame().GetPlayer() );
  768. }
  769. ModifiersManager mods_manager = player.GetModifiersManager();
  770. mods_manager.ActivateModifier( Math.AbsInt( id ) );
  771. }
  772. //Activates modifier with given ID
  773. void DeactivateModifier( int id, PlayerBase player = NULL )
  774. {
  775. if ( !player )
  776. {
  777. player = PlayerBase.Cast( GetDayZGame().GetPlayer() );
  778. }
  779. ModifiersManager mods_manager = player.GetModifiersManager();
  780. mods_manager.DeactivateModifier( Math.AbsInt( id ) );
  781. }
  782. //Activates modifier with given ID
  783. void LockModifier( int id, bool lock, PlayerBase player = NULL )
  784. {
  785. if ( !player )
  786. {
  787. player = PlayerBase.Cast( GetDayZGame().GetPlayer() );
  788. }
  789. ModifiersManager mods_manager = player.GetModifiersManager();
  790. mods_manager.SetModifierLock( Math.AbsInt( id ), lock );
  791. }
  792. bool IsModifierLocked( int id, PlayerBase player = NULL )
  793. {
  794. if ( !player )
  795. {
  796. player = PlayerBase.Cast( GetDayZGame().GetPlayer() );
  797. }
  798. ModifiersManager mods_manager = player.GetModifiersManager();
  799. return mods_manager.GetModifierLock( Math.AbsInt( id ) );
  800. }
  801. //============================================
  802. // TEMPERATURE
  803. //============================================
  804. void SendRPCTemp( PlayerBase player )
  805. {
  806. if ( player )
  807. {
  808. CachedObjectsParams.PARAM1_STRING.param1 = player.m_Environment.GetDebugMessage();
  809. GetDayZGame().RPCSingleParam( player, ERPCs.DEV_TEMP_UPDATE, CachedObjectsParams.PARAM1_STRING, true, player.GetIdentity() );
  810. }
  811. }
  812. void OnRPCTemp( ParamsReadContext ctx , PlayerBase player)
  813. {
  814. if (GetGame().IsServer() && GetGame().IsMultiplayer())
  815. {
  816. EnableUpdate( GetRPCUpdateState( ctx ), ERPCs.DEV_TEMP_UPDATE, player );
  817. }
  818. else if (!GetGame().IsMultiplayer() || GetGame().IsClient())
  819. {
  820. if ( ctx.Read(CachedObjectsParams.PARAM1_STRING) )
  821. {
  822. m_EnvironmentDebugMessage = CachedObjectsParams.PARAM1_STRING.param1;
  823. }
  824. }
  825. }
  826. //============================================
  827. // AGENTS
  828. //============================================
  829. //send player mods through RPC
  830. void SendRPCAgents( PlayerBase player )
  831. {
  832. //write and send values
  833. if ( ( player && player.GetIdentity() && player.m_AgentPool != null ) || ( player && !GetGame().IsMultiplayer() && player.m_AgentPool != null ) )
  834. {
  835. //get agent pool data
  836. array<ref Param> agent_pool = new array<ref Param>;
  837. player.m_AgentPool.GetDebugObject( agent_pool );
  838. GetDayZGame().RPC( player, ERPCs.DEV_RPC_AGENTS_DATA, agent_pool, true, player.GetIdentity() );
  839. }
  840. }
  841. //Display player modifiers
  842. void OnRPCAgents(ParamsReadContext ctx)
  843. {
  844. //clear values
  845. m_PlayerAgentsSynced.Clear();
  846. Param4<string, string, int, float> p4 = new Param4<string, string, int, float>("", "" , 0, 0.0);
  847. Param1<int> p1 = new Param1<int>(0);
  848. //get param count
  849. int paramCount = 0;
  850. if (ctx.Read(p1))
  851. paramCount = p1.param1;
  852. //read values and set
  853. for (int i = 0; i < paramCount; i++)
  854. {
  855. ctx.Read(p4);
  856. m_PlayerAgentsSynced.Insert(new SyncedValueAgent(p4.param1, p4.param2, p4.param3, p4.param4));
  857. }
  858. }
  859. //============================================
  860. // STOMACH
  861. //============================================
  862. void SendRPCStomach( PlayerBase player )
  863. {
  864. //write and send values
  865. if ( player )
  866. {
  867. array<ref Param> stomach = new array<ref Param>;
  868. int count = player.m_PlayerStomach.GetDebugObject( stomach );
  869. stomach.InsertAt(new Param1<int>(count), 0);
  870. GetDayZGame().RPC( player, ERPCs.DEV_RPC_STOMACH_DATA, stomach, true, player.GetIdentity() );
  871. }
  872. }
  873. void OnRPCStomach( ParamsReadContext ctx )
  874. {
  875. //clear values
  876. m_PlayerStomachSynced.Clear();
  877. Param1<int> p1 = new Param1<int>(0);
  878. int param_count = 0;
  879. if ( ctx.Read(p1) )
  880. {
  881. param_count = p1.param1;
  882. }
  883. if (param_count)
  884. {
  885. //invidividual stomach items
  886. for ( int i = 0; i < param_count; i++ )
  887. {
  888. Param5<int,int,int,float,float> p5 = new Param5<int,int,int,float,float>(0,0,0,0,0);
  889. ctx.Read(p5);
  890. m_PlayerStomachSynced.Insert(p5);
  891. }
  892. //volume
  893. Param1<float> p1b = new Param1<float>(0);
  894. ctx.Read(p1b);
  895. m_PlayerStomachSynced.Insert(p1b);
  896. //temperature
  897. Param1<float> paramTemp = new Param1<float>(0);
  898. ctx.Read(paramTemp);
  899. m_PlayerStomachSynced.Insert(paramTemp);
  900. }
  901. }
  902. //================================================================
  903. // FOCUS
  904. //================================================================
  905. void CaptureFocus()
  906. {
  907. GetGame().GetInput().ChangeGameFocus( 1 );
  908. GetGame().GetUIManager().ShowUICursor( true );
  909. }
  910. void ReleaseFocus()
  911. {
  912. GetGame().GetInput().ChangeGameFocus( -1 );
  913. GetGame().GetUIManager().ShowUICursor( false );
  914. }
  915. void ToggleFocus()
  916. {
  917. if ( GetGame().GetInput().HasGameFocus() )
  918. {
  919. GetGame().GetInput().ChangeGameFocus( 1 );
  920. GetGame().GetUIManager().ShowUICursor( true );
  921. }
  922. else
  923. {
  924. GetGame().GetInput().ResetGameFocus();
  925. GetGame().GetUIManager().ShowUICursor( false );
  926. }
  927. }
  928. }