LivingEntity.lua 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273
  1. ----------------------------------------------------------------------------------------------------
  2. --
  3. -- Copyright (c) Contributors to the Open 3D Engine Project.
  4. -- For complete copyright and license terms please see the LICENSE at the root of this distribution.
  5. --
  6. -- SPDX-License-Identifier: Apache-2.0 OR MIT
  7. --
  8. --
  9. --
  10. ----------------------------------------------------------------------------------------------------
  11. Script.ReloadScript("scripts/Utils/EntityUtils.lua")
  12. -- Basic entity
  13. LivingEntity = {
  14. Properties = {
  15. soclasses_SmartObjectClass = "",
  16. bMissionCritical = 0,
  17. bCanTriggerAreas = 1,
  18. DmgFactorWhenCollidingAI = 1,
  19. object_Model = "objects/default/primitive_capsule.cgf",
  20. Physics = {
  21. bPhysicalize = 1, -- True if object should be physicalized at all.
  22. bPushableByPlayers = 1,
  23. },
  24. Living = {
  25. height = 0, -- vertical offset of collision geometry center
  26. vector_size = {0.4, 0.4,0.9}, -- collision cylinder dimensions
  27. height_eye = 1.8, -- vertical offset of camera
  28. height_pivot = 0.1, -- offset from central ground position that is considered entity center
  29. head_radius = 0.3, -- radius of the 'head' geometry (used for camera offset)
  30. height_head = 1.7, -- center.z of the head geometry
  31. groundContactEps = 0.004, --the amount that the living needs to move upwards before ground contact is lost. defaults to which ever is greater 0.004, or 0.01*geometryHeight
  32. bUseCapsule = 1,--switches between capsule and cylinder collider geometry
  33. inertia = 1, -- inertia koefficient, the more it is, the less inertia is, 0 means no inertia
  34. inertiaAccel = 1, -- inertia on acceleration
  35. air_control = 1, -- air control koefficient 0..1, 1 - special value (total control of movement)
  36. air_resistance = 0.1, -- standard air resistance
  37. gravity = 9.8, -- gravity vector
  38. mass = 100, -- mass (in kg)
  39. min_slide_angle = 60, -- if surface slope is more than this angle, player starts sliding (angle is in radians)
  40. max_climb_angle = 60, -- player cannot climb surface which slope is steeper than this angle
  41. max_jump_angle = 45, -- player is not allowed to jump towards ground if this angle is exceeded
  42. min_fall_angle = 65, -- player starts falling when slope is steeper than this
  43. max_vel_ground = 10, -- player cannot stand of surfaces that are moving faster than this
  44. timeImpulseRecover = 0.3, -- forcefully turns on inertia for that duration after receiving an impulse
  45. nod_speed = 1, -- vertical camera shake speed after landings
  46. bActive = 1,-- 0 disables all simulation for the character, apart from moving along the requested velocity
  47. collision_types = 271, -- (271 = ent_static | ent_terrain | ent_living | ent_rigid | ent_sleeping_rigid) entity types to check collisions against
  48. },
  49. MultiplayerOptions = {
  50. bNetworked = 0,
  51. },
  52. bExcludeCover=0,
  53. },
  54. Client = {},
  55. Server = {},
  56. -- Temp.
  57. _Flags = {},
  58. Editor={
  59. Icon = "physicsobject.bmp",
  60. IconOnTop=1,
  61. },
  62. }
  63. ------------------------------------------------------------------------------------------------------
  64. function LivingEntity:OnSpawn()
  65. if (self.Properties.MultiplayerOptions.bNetworked == 0) then
  66. self:SetFlags(ENTITY_FLAG_CLIENT_ONLY,0);
  67. end
  68. self:SetFromProperties();
  69. end
  70. ------------------------------------------------------------------------------------------------------
  71. function LivingEntity:SetFromProperties()
  72. local Properties = self.Properties;
  73. if (Properties.object_Model == "") then
  74. do return end;
  75. end
  76. self.freezable = (tonumber(Properties.bFreezable) ~= 0);
  77. self:SetupModel();
  78. -- Mark AI hideable flag.
  79. if (Properties.bAutoGenAIHidePts == 1) then
  80. self:SetFlags(ENTITY_FLAG_AI_HIDEABLE, 0); -- set
  81. else
  82. self:SetFlags(ENTITY_FLAG_AI_HIDEABLE, 2); -- remove
  83. end
  84. if (self.Properties.bCanTriggerAreas == 1) then
  85. self:SetFlags(ENTITY_FLAG_TRIGGER_AREAS, 0); -- set
  86. else
  87. self:SetFlags(ENTITY_FLAG_TRIGGER_AREAS, 2); -- remove
  88. end
  89. end
  90. ------------------------------------------------------------------------------------------------------
  91. function LivingEntity:SetupModel()
  92. local Properties = self.Properties;
  93. self:LoadObject(0,Properties.object_Model);
  94. if (Properties.Physics.bPhysicalize == 1) then
  95. self:PhysicalizeThis();
  96. end
  97. end
  98. ------------------------------------------------------------------------------------------------------
  99. function LivingEntity:OnLoad(table)
  100. self.health = table.health;
  101. self.dead = table.dead;
  102. end
  103. function LivingEntity:OnSave(table)
  104. table.health = self.health;
  105. table.dead = self.dead;
  106. end
  107. ------------------------------------------------------------------------------------------------------
  108. function LivingEntity:IsRigidBody()
  109. local Properties = self.Properties;
  110. local Mass = Properties.Mass;
  111. local Density = Properties.Density;
  112. if (Mass == 0 or Density == 0 or Properties.bPhysicalize ~= 1) then
  113. return false;
  114. end
  115. return true;
  116. end
  117. ------------------------------------------------------------------------------------------------------
  118. function LivingEntity:PhysicalizeThis()
  119. Entity.Physicalize(self,0, PE_LIVING, self.Properties);
  120. end
  121. ------------------------------------------------------------------------------------------------------
  122. -- OnPropertyChange called only by the editor.
  123. ------------------------------------------------------------------------------------------------------
  124. function LivingEntity:OnPropertyChange()
  125. -- if the properties are changed, we force a reset in the __usable
  126. if (self.__usable) then
  127. if (self.__origUsable ~= self.Properties.bUsable or self.__origPickable ~= self.Properties.bPickable) then
  128. self.__usable = nil;
  129. end
  130. end
  131. self:SetFromProperties();
  132. end
  133. ------------------------------------------------------------------------------------------------------
  134. -- OnReset called only by the editor.
  135. ------------------------------------------------------------------------------------------------------
  136. function LivingEntity:OnReset()
  137. self:ResetOnUsed()
  138. local PhysProps = self.Properties.Physics;
  139. if (PhysProps.bPhysicalize == 1) then
  140. self:PhysicalizeThis();
  141. self:AwakePhysics(0);
  142. end
  143. end
  144. ------------------------------------------------------------------------------------------------------
  145. function LivingEntity:Event_Remove()
  146. self:DrawSlot(0,0);
  147. self:DestroyPhysics();
  148. self:ActivateOutput( "Remove", true );
  149. end
  150. ------------------------------------------------------------------------------------------------------
  151. function LivingEntity:Event_Hide()
  152. self:Hide(1);
  153. self:ActivateOutput( "Hide", true );
  154. if CurrentCinematicName then
  155. Log("%.3f %s %s : Event_Hide", _time, CurrentCinematicName, self:GetName() );
  156. end
  157. end
  158. ------------------------------------------------------------------------------------------------------
  159. function LivingEntity:Event_UnHide()
  160. self:Hide(0);
  161. self:ActivateOutput( "UnHide", true );
  162. if CurrentCinematicName then
  163. Log("%.3f %s %s : Event_UnHide", _time, CurrentCinematicName, self:GetName() );
  164. end
  165. end
  166. ------------------------------------------------------------------------------------------------------
  167. function LivingEntity:Event_Ragdollize()
  168. self:RagDollize(0);
  169. self:ActivateOutput( "Ragdollized", true );
  170. if (self.Event_RagdollizeDerived) then
  171. self:Event_RagdollizeDerived();
  172. end
  173. end
  174. ------------------------------------------------------------------------------------------------------
  175. function LivingEntity.Client:OnPhysicsBreak( vPos,nPartId,nOtherPartId )
  176. self:ActivateOutput("Break",nPartId+1 );
  177. end
  178. function LivingEntity:IsUsable(user)
  179. local ret = nil
  180. -- From EntityUtils.lua
  181. if not self.__usable then self.__usable = self.Properties.bUsable end
  182. local mp = System.IsMultiplayer();
  183. if(mp and mp~=0) then
  184. return 0;
  185. end
  186. if (self.__usable == 1) then
  187. ret = 2
  188. else
  189. local PhysProps = self.Properties.Physics;
  190. if (self:IsRigidBody() == true and user and user.CanGrabObject) then
  191. ret = user:CanGrabObject(self)
  192. end
  193. end
  194. return ret or 0
  195. end
  196. LivingEntity.FlowEvents =
  197. {
  198. Inputs =
  199. {
  200. Used = { LivingEntity.Event_Used, "bool" },
  201. EnableUsable = { LivingEntity.Event_EnableUsable, "bool" },
  202. DisableUsable = { LivingEntity.Event_DisableUsable, "bool" },
  203. Hide = { LivingEntity.Event_Hide, "bool" },
  204. UnHide = { LivingEntity.Event_UnHide, "bool" },
  205. Remove = { LivingEntity.Event_Remove, "bool" },
  206. Ragdollize = { LivingEntity.Event_Ragdollize, "bool" },
  207. },
  208. Outputs =
  209. {
  210. Used = "bool",
  211. EnableUsable = "bool",
  212. DisableUsable = "bool",
  213. Activate = "bool",
  214. Hide = "bool",
  215. UnHide = "bool",
  216. Remove = "bool",
  217. Ragdollized = "bool",
  218. Break = "int",
  219. },
  220. }
  221. MakeUsable(LivingEntity);
  222. MakePickable(LivingEntity);
  223. MakeTargetableByAI(LivingEntity);
  224. MakeKillable(LivingEntity);
  225. AddHeavyObjectProperty(LivingEntity);
  226. AddInteractLargeObjectProperty(LivingEntity);
  227. SetupCollisionFiltering(LivingEntity);