inventoryitem.c 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. class InventoryItem extends EntityAI
  2. {
  3. static private const float SOUND_CONTACT_SKIP = 0.33;//second
  4. #ifdef DIAG_DEVELOPER
  5. static private ref array<ref string> s_ImpactSoundsInfo = new array<ref string>();
  6. #endif
  7. private SoundLookupTable m_SoundImpactTable;
  8. private float m_SoundContactTickTime;
  9. private bool m_IsMeleeWeapon = false;
  10. proto native InventoryItemType GetInventoryItemType();
  11. //! Some inventoryItem devices can be switched on/off (radios, transmitters)
  12. proto native void SwitchOn(bool onOff);
  13. //! Some inventoryItem devices can be switched on/off (radios, transmitters)
  14. proto native bool IsOn();
  15. //! collisions with character
  16. proto native void EnableCollisionsWithCharacter(bool state);
  17. proto native bool HasCollisionsWithCharacter();
  18. proto native MeleeCombatData GetMeleeCombatData();
  19. proto native void ThrowPhysically(DayZPlayer player, vector force, bool collideWithCharacters = true);
  20. //! Sets the item to use the server configured 'networkRangeFar' instead of 'networkRangeNear'
  21. // This method performs an OR operation with the config 'forceFarBubble'. If set in the config
  22. // this method has no effect.
  23. proto native void ForceFarBubble(bool state);
  24. void InventoryItem()
  25. {
  26. InitImpactSoundData();
  27. if (ConfigIsExisting("isMeleeWeapon"))
  28. m_IsMeleeWeapon = ConfigGetBool("isMeleeWeapon");
  29. }
  30. void OnRightClick()
  31. {
  32. }
  33. event bool OnUseFromInventory(Man owner)
  34. {
  35. return false;
  36. }
  37. //! Get tooltip text
  38. string GetTooltip()
  39. {
  40. string temp;
  41. if (!DescriptionOverride(temp))
  42. temp = ConfigGetString("descriptionShort");
  43. return temp;
  44. }
  45. override bool IsInventoryItem()
  46. {
  47. return true;
  48. }
  49. int GetMeleeMode()
  50. {
  51. return 0;
  52. }
  53. int GetMeleeHeavyMode()
  54. {
  55. return 1;
  56. }
  57. int GetMeleeSprintMode()
  58. {
  59. return 2;
  60. }
  61. override bool IsMeleeWeapon()
  62. {
  63. return m_IsMeleeWeapon;
  64. }
  65. bool IsMeleeFinisher()
  66. {
  67. return false;
  68. }
  69. // -------------------------------------------------------------------------------
  70. void PlayImpactSound(float weight, float velocity, int surfaceHash)
  71. {
  72. if (!m_SoundImpactTable)
  73. return;
  74. SoundObjectBuilder soundBuilder = m_SoundImpactTable.GetSoundBuilder(surfaceHash);
  75. if (soundBuilder != null)
  76. {
  77. soundBuilder.AddVariable("weight", weight);
  78. soundBuilder.AddVariable("speed", velocity);
  79. soundBuilder.AddEnvSoundVariables(GetPosition());
  80. SoundObject soundObject = soundBuilder.BuildSoundObject();
  81. if (soundObject != null)
  82. {
  83. soundObject.SetKind(WaveKind.WAVEEFFECTEX);
  84. PlaySound(soundObject, soundBuilder);
  85. }
  86. }
  87. }
  88. // -------------------------------------------------------------------------------
  89. protected void InitImpactSoundData()
  90. {
  91. #ifndef SERVER
  92. string soundImpactType = "default";
  93. if ( ConfigIsExisting("soundImpactType") )
  94. soundImpactType = ConfigGetString("soundImpactType");
  95. m_SoundImpactTable = AnimSoundLookupTableBank.GetInstance().GetImpactTable(soundImpactType + "_Impact_LookupTable");
  96. #endif
  97. }
  98. // -------------------------------------------------------------------------------
  99. AbstractWave PlaySound(SoundObject so, SoundObjectBuilder sob)
  100. {
  101. if (so == null)
  102. return null;
  103. so.SetPosition(GetPosition());
  104. AbstractWave wave = GetGame().GetSoundScene().Play3D(so, sob);
  105. return wave;
  106. }
  107. // -------------------------------------------------------------------------------
  108. void PlaySoundByAnimEvent(EAnimSoundEventID id)
  109. {
  110. AnimSoundEvent soundEvent = GetInventoryItemType().GetSoundEvent(id);
  111. if (soundEvent)
  112. {
  113. SoundObjectBuilder builder = soundEvent.GetSoundBuilder();
  114. SoundObject soundObject = builder.BuildSoundObject();
  115. if (soundObject)
  116. PlaySound(soundObject, builder);
  117. }
  118. }
  119. // -------------------------------------------------------------------------------
  120. string GetImpactSurfaceType(IEntity other, Contact impact)
  121. {
  122. string surface;
  123. int liquid = -1;
  124. return GetImpactSurfaceTypeEx(other, impact, liquid);
  125. }
  126. // -------------------------------------------------------------------------------
  127. string GetImpactSurfaceTypeEx(IEntity other, Contact impact, out int liquid)
  128. {
  129. vector mins, maxs;
  130. GetWorldBounds(mins, maxs);
  131. vector size = maxs - mins;
  132. vector add = impact.RelativeVelocityBefore.Normalized() * size.Length();
  133. string surfaceImpact;
  134. if (DayZPhysics.GetHitSurfaceAndLiquid(
  135. Object.Cast(other),
  136. impact.Position + add,
  137. impact.Position - add,
  138. surfaceImpact,
  139. liquid))
  140. {
  141. return surfaceImpact;
  142. }
  143. string surface;
  144. GetGame().SurfaceUnderObjectExCorrectedLiquid(this, surface, surfaceImpact, liquid);
  145. return surfaceImpact;
  146. }
  147. //! returns ammo (projectile) used in melee if the item is destroyed. Override higher for specific use
  148. string GetRuinedMeleeAmmoType()
  149. {
  150. return "MeleeSoft";
  151. }
  152. // -------------------------------------------------------------------------------
  153. float ProcessImpactSound(IEntity other, Contact extra, float weight, out int surfaceHash)
  154. {
  155. int liquidType = -1;
  156. return ProcessImpactSoundEx(other, extra, weight, surfaceHash,liquidType);
  157. }
  158. // -------------------------------------------------------------------------------
  159. float ProcessImpactSoundEx(IEntity other, Contact extra, float weight, out int surfaceHash, out int liquidType)
  160. {
  161. float impactVelocity = extra.RelativeVelocityBefore.Length();
  162. if ( impactVelocity < 0.3 )
  163. return 0.0;
  164. float tickTime = GetGame().GetTickTime();
  165. if ( m_SoundContactTickTime + SOUND_CONTACT_SKIP > tickTime )
  166. return 0.0;
  167. string surfaceName = GetImpactSurfaceTypeEx(other, extra, liquidType);
  168. if ( surfaceName == "" )
  169. return 0.0;
  170. #ifdef DIAG_DEVELOPER
  171. string infoText = "Surface: " + surfaceName + ", Weight: " + weight + ", Speed: " + impactVelocity;
  172. if ( s_ImpactSoundsInfo.Count() == 10 )
  173. s_ImpactSoundsInfo.Remove(9);
  174. s_ImpactSoundsInfo.InsertAt(infoText, 0);
  175. #endif
  176. m_SoundContactTickTime = tickTime;
  177. surfaceHash = surfaceName.Hash();
  178. return impactVelocity;
  179. }
  180. #ifdef DIAG_DEVELOPER
  181. static void DrawImpacts()
  182. {
  183. DbgUI.Begin("Item impact sounds", 10, 200);
  184. for ( int i = 0; i < s_ImpactSoundsInfo.Count(); ++i )
  185. {
  186. string line = (i + 1).ToString() + ". " + s_ImpactSoundsInfo.Get(i);
  187. DbgUI.Text(line);
  188. }
  189. DbgUI.End();
  190. }
  191. #endif
  192. };