A stable modding interface between Techblox and mods https://mod.exmods.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

177 lines
5.9KB

  1. using System;
  2. using Svelto.ECS;
  3. using Unity.Mathematics;
  4. using UnityEngine;
  5. using Gamecraft.Damage;
  6. using RobocraftX.Common;
  7. using RobocraftX.Physics;
  8. namespace TechbloxModdingAPI
  9. {
  10. /// <summary>
  11. /// A rigid body (like a chunk of connected blocks) during simulation.
  12. /// </summary>
  13. public class SimBody : EcsObjectBase, IEquatable<SimBody>, IEquatable<EGID>
  14. {
  15. /// <summary>
  16. /// The cluster this chunk belongs to, or null if no cluster destruction manager present or the chunk doesn't exist.
  17. /// Get the SimBody from a Block if possible for good performance here.
  18. /// </summary>
  19. public Cluster Cluster => cluster ??= clusterId == uint.MaxValue // Return cluster or if it's null then set it
  20. ? Block.BlockEngine.GetCluster(Id.entityID) // If we don't have a clusterId set then get it from the game
  21. : GetInstance(new EGID(clusterId, CommonExclusiveGroups.SIMULATION_CLUSTERS_GROUP),
  22. egid => new Cluster(egid)); // Otherwise get the cluster from the ID
  23. private Cluster cluster;
  24. private readonly uint clusterId = uint.MaxValue;
  25. public SimBody(EGID id) : base(id)
  26. {
  27. }
  28. public SimBody(uint id) : this(new EGID(id, CommonExclusiveGroups.SIMULATION_BODIES_GROUP))
  29. {
  30. }
  31. internal SimBody(uint id, uint clusterID) : this(id)
  32. {
  33. clusterId = clusterID;
  34. }
  35. /// <summary>
  36. /// The position of this body. When setting the position, update the position of the connected bodies as well,
  37. /// otherwise unexpected forces may arise.
  38. /// </summary>
  39. public float3 Position
  40. {
  41. get => GetStruct().position;
  42. set => GetStruct().position = value;
  43. }
  44. public float3 Velocity
  45. {
  46. get => GetStruct().velocity;
  47. set => GetStruct().velocity = value;
  48. }
  49. public float3 AngularVelocity
  50. {
  51. get => GetStruct().angularVelocity;
  52. set => GetStruct().angularVelocity = value;
  53. } //Delta versions are used internally, can't be set or get
  54. public float3 Rotation
  55. {
  56. get => ((Quaternion) GetStruct().rotation).eulerAngles;
  57. set
  58. {
  59. ref var str = ref GetStruct();
  60. Quaternion quaternion = str.rotation;
  61. quaternion.eulerAngles = value;
  62. str.rotation = quaternion;
  63. }
  64. }
  65. [Obsolete] //Cannot get mass even from UECS
  66. public float Mass
  67. {
  68. get => 0f;
  69. //set => GetStruct().physicsMass.InverseMass = math.rcp(value);
  70. }
  71. public float3 CenterOfMass
  72. {
  73. get => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(this).centreOfMass;
  74. //set => GetStruct().physicsMass.CenterOfMass = value;
  75. }
  76. public float Volume
  77. {
  78. get => GetStruct().volume;
  79. }
  80. public float InitialHealth
  81. {
  82. get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth;
  83. set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).initialHealth = value;
  84. }
  85. public float CurrentHealth
  86. {
  87. get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth;
  88. set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).currentHealth = value;
  89. }
  90. public float HealthMultiplier
  91. {
  92. get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier;
  93. set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(this).healthMultiplier = value;
  94. }
  95. /// <summary>
  96. /// Whether the body can be moved or static.
  97. /// </summary>
  98. public bool Static => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(this).isStatic; //Setting it doesn't have any effect
  99. /// <summary>
  100. /// The rigid bodies connected to this one via functional joints (broken ones don't count).
  101. /// </summary>
  102. public SimBody[] GetConnectedBodies()
  103. {
  104. return Block.BlockEngine.GetConnectedSimBodies(Id.entityID);
  105. }
  106. /// <summary>
  107. /// The blocks that form this rigid body.
  108. /// </summary>
  109. /// <returns></returns>
  110. public Block[] GetBlocks()
  111. {
  112. return Block.BlockEngine.GetBodyBlocks(Id.entityID);
  113. }
  114. private ref RigidBodyEntityStruct GetStruct()
  115. {
  116. return ref Block.BlockEngine.GetBlockInfo<RigidBodyEntityStruct>(this);
  117. }
  118. public override string ToString()
  119. {
  120. return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Mass)}: {Mass}, {nameof(Static)}: {Static}";
  121. }
  122. public bool Equals(SimBody other)
  123. {
  124. if (ReferenceEquals(null, other)) return false;
  125. if (ReferenceEquals(this, other)) return true;
  126. return Id.Equals(other.Id);
  127. }
  128. public bool Equals(EGID other)
  129. {
  130. return Id.Equals(other);
  131. }
  132. public override bool Equals(object obj)
  133. {
  134. if (ReferenceEquals(null, obj)) return false;
  135. if (ReferenceEquals(this, obj)) return true;
  136. if (obj.GetType() != this.GetType()) return false;
  137. return Equals((SimBody) obj);
  138. }
  139. public override int GetHashCode()
  140. {
  141. return Id.GetHashCode();
  142. }
  143. /// <summary>
  144. /// Returns the object identified by the given ID (A-Z).
  145. /// This has the same result as calling ObjectIdentifier.GetByID(id) and then GetRigidBody() with the duplicates filtered out.
  146. /// </summary>
  147. /// <param name="id">The alphabetical ID</param>
  148. /// <returns>An array that may be empty</returns>
  149. public static SimBody[] GetFromObjectID(char id) => Block.BlockEngine.GetSimBodiesFromID((byte) (id - 'A'));
  150. }
  151. }