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.

166 lines
5.3KB

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