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.

178 lines
5.5KB

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