|
- using System;
- using Svelto.ECS;
- using Unity.Mathematics;
- using UnityEngine;
-
- using Gamecraft.Damage;
- using RobocraftX.Common;
- using RobocraftX.Physics;
-
- namespace GamecraftModdingAPI
- {
- /// <summary>
- /// A rigid body (like a chunk of connected blocks) during simulation.
- /// </summary>
- public class SimBody : IEquatable<SimBody>, IEquatable<EGID>
- {
- public EGID Id { get; }
-
- /// <summary>
- /// The cluster this chunk belongs to, or null if no cluster destruction manager present or the chunk doesn't exist.
- /// Get the SimBody from a Block if possible for good performance here.
- /// </summary>
- public Cluster Cluster => cluster ?? (cluster = clusterId == uint.MaxValue ? Block.BlockEngine.GetCluster(Id.entityID) : new Cluster(clusterId));
-
- private Cluster cluster;
- private readonly uint clusterId = uint.MaxValue;
-
- public SimBody(EGID id)
- {
- Id = id;
- }
-
- public SimBody(uint id) : this(new EGID(id, CommonExclusiveGroups.SIMULATION_BODIES_GROUP))
- {
- }
-
- internal SimBody(uint id, uint clusterID) : this(id)
- {
- clusterId = clusterID;
- }
-
- /// <summary>
- /// The position of this body. When setting the position, update the position of the connected bodies as well,
- /// otherwise unexpected forces may arise.
- /// </summary>
- public float3 Position
- {
- get => GetStruct().position;
- set => GetStruct().position = value;
- }
-
- public float3 Velocity
- {
- get => GetStruct().velocity;
- set => GetStruct().velocity = value;
- }
-
- public float3 AngularVelocity
- {
- get => GetStruct().angularVelocity;
- set => GetStruct().angularVelocity = value;
- } //Delta versions are used internally, can't be set or get
-
- public float3 Rotation
- {
- get => ((Quaternion) GetStruct().rotation).eulerAngles;
- set
- {
- ref var str = ref GetStruct();
- Quaternion quaternion = str.rotation;
- quaternion.eulerAngles = value;
- str.rotation = quaternion;
- }
- }
-
- public float Mass
- {
- get => math.rcp(GetStruct().physicsMass.InverseMass);
- //set => GetStruct().physicsMass.InverseMass = math.rcp(value);
- }
-
- public float3 CenterOfMass
- {
- get => GetStruct().physicsMass.CenterOfMass;
- //set => GetStruct().physicsMass.CenterOfMass = value;
- }
-
- public float Volume
- {
- get => GetStruct().volume;
- }
-
- public float InitialHealth
- {
- get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth;
- set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).initialHealth = value;
- }
-
- public float CurrentHealth
- {
- get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth;
- set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).currentHealth = value;
- }
-
- public float HealthMultiplier
- {
- get => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier;
- set => Block.BlockEngine.GetBlockInfo<HealthEntityComponent>(Id).healthMultiplier = value;
- }
-
- /// <summary>
- /// Whether the body can be moved or static.
- /// </summary>
- public bool Static => Block.BlockEngine.GetBlockInfo<MassEntityStruct>(Id).isStatic; //Setting it doesn't have any effect
-
- /// <summary>
- /// The rigid bodies connected to this one via functional joints (broken ones don't count).
- /// </summary>
- public SimBody[] GetConnectedBodies()
- {
- return Block.BlockEngine.GetConnectedSimBodies(Id.entityID);
- }
-
- /// <summary>
- /// The blocks that form this rigid body.
- /// </summary>
- /// <returns></returns>
- public Block[] GetBlocks()
- {
- return Block.BlockEngine.GetBodyBlocks(Id.entityID);
- }
-
- private ref RigidBodyEntityStruct GetStruct()
- {
- return ref Block.BlockEngine.GetBlockInfo<RigidBodyEntityStruct>(Id);
- }
-
- public override string ToString()
- {
- return $"{nameof(Id)}: {Id}, {nameof(Position)}: {Position}, {nameof(Mass)}: {Mass}, {nameof(Static)}: {Static}";
- }
-
- public bool Equals(SimBody other)
- {
- if (ReferenceEquals(null, other)) return false;
- if (ReferenceEquals(this, other)) return true;
- return Id.Equals(other.Id);
- }
-
- public bool Equals(EGID other)
- {
- return Id.Equals(other);
- }
-
- public override bool Equals(object obj)
- {
- if (ReferenceEquals(null, obj)) return false;
- if (ReferenceEquals(this, obj)) return true;
- if (obj.GetType() != this.GetType()) return false;
- return Equals((SimBody) obj);
- }
-
- public override int GetHashCode()
- {
- return Id.GetHashCode();
- }
-
- /// <summary>
- /// Returns the object identified by the given ID (A-Z).
- /// This has the same result as calling ObjectIdentifier.GetByID(id) and then GetRigidBody() with the duplicates filtered out.
- /// </summary>
- /// <param name="id">The alphabetical ID</param>
- /// <returns>An array that may be empty</returns>
- public static SimBody[] GetFromObjectID(char id) => Block.BlockEngine.GetSimBodiesFromID((byte) (id - 'A'));
- }
- }
|