diff --git a/GamecraftModdingAPI/Block.cs b/GamecraftModdingAPI/Block.cs index f63e96c..186bf8d 100644 --- a/GamecraftModdingAPI/Block.cs +++ b/GamecraftModdingAPI/Block.cs @@ -372,11 +372,13 @@ namespace GamecraftModdingAPI /// Returns the rigid body of the chunk of blocks this one belongs to during simulation. /// Can be used to apply forces or move the block around while the simulation is running. /// - /// The SimBody of the chunk or null if the block doesn't exist. + /// The SimBody of the chunk or null if the block doesn't exist or not in simulation mode. public SimBody GetSimBody() { return BlockEngine.GetBlockInfo(this, - (GridConnectionsEntityStruct st) => new SimBody(st.machineRigidBodyId, st.clusterId)); + (GridConnectionsEntityStruct st) => st.machineRigidBodyId != uint.MaxValue + ? new SimBody(st.machineRigidBodyId, st.clusterId) + : null); } private void OnPlacedInit(object sender, BlockPlacedRemovedEventArgs e) diff --git a/GamecraftModdingAPI/Blocks/BlockEngine.cs b/GamecraftModdingAPI/Blocks/BlockEngine.cs index 3a979fe..929a65f 100644 --- a/GamecraftModdingAPI/Blocks/BlockEngine.cs +++ b/GamecraftModdingAPI/Blocks/BlockEngine.cs @@ -218,7 +218,7 @@ namespace GamecraftModdingAPI.Blocks } } - return bodies.Select(id => new SimBody(id)).ToArray(); + return bodies.Select(id => new SimBody(id, cid)).ToArray(); } public EGID? FindBlockEGID(uint id) @@ -239,8 +239,8 @@ namespace GamecraftModdingAPI.Blocks foreach (var (coll, _) in groups) { foreach (var conn in coll) - { - if (conn.machineRigidBodyId == sbid) + { //Static blocks don't have a cluster ID but the cluster destruction manager should have one + if (conn.machineRigidBodyId == sbid && conn.clusterId != uint.MaxValue) return new Cluster(conn.clusterId); } } @@ -248,6 +248,22 @@ namespace GamecraftModdingAPI.Blocks return null; } + public Block[] GetBodyBlocks(uint sbid) + { + var groups = entitiesDB.QueryEntities(); + var set = new HashSet(); + foreach (var (coll, _) in groups) + { + foreach (var conn in coll) + { + if (conn.machineRigidBodyId == sbid) + set.Add(new Block(conn.ID)); + } + } + + return set.ToArray(); + } + #if DEBUG public EntitiesDB GetEntitiesDB() { diff --git a/GamecraftModdingAPI/Cluster.cs b/GamecraftModdingAPI/Cluster.cs index 074c26c..79b5822 100644 --- a/GamecraftModdingAPI/Cluster.cs +++ b/GamecraftModdingAPI/Cluster.cs @@ -6,6 +6,7 @@ namespace GamecraftModdingAPI { /// /// Represnts a cluster of blocks in time running mode, meaning blocks that are connected either directly or via joints. + /// Only exists if a cluster destruction manager is present. Static blocks like grass and dirt aren't part of a cluster. /// public class Cluster { @@ -37,5 +38,37 @@ namespace GamecraftModdingAPI get => Block.BlockEngine.GetBlockInfo(Id).healthMultiplier; set => Block.BlockEngine.GetBlockInfo(Id).healthMultiplier = value; } + + /// + /// Returns the simulation-time rigid bodies for the chunks in this cluster. + /// + /// An array of sim-bodies + public SimBody[] GetSimBodies() + { + return Block.BlockEngine.GetClusterBodies(Id.entityID); + } + + public override string ToString() + { + return $"{nameof(Id)}: {Id}"; + } + + protected bool Equals(Cluster other) + { + return Id.Equals(other.Id); + } + + 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((Cluster) obj); + } + + public override int GetHashCode() + { + return Id.GetHashCode(); + } } } \ No newline at end of file diff --git a/GamecraftModdingAPI/GamecraftModdingAPI.csproj b/GamecraftModdingAPI/GamecraftModdingAPI.csproj index 8be57a7..c6a0f99 100644 --- a/GamecraftModdingAPI/GamecraftModdingAPI.csproj +++ b/GamecraftModdingAPI/GamecraftModdingAPI.csproj @@ -2,7 +2,7 @@ net472 true - 1.5.0 + 1.6.0 Exmods GNU General Public Licence 3+ https://git.exmods.org/modtainers/GamecraftModdingAPI @@ -445,10 +445,6 @@ ..\ref\Gamecraft_Data\Managed\RobocraftX_TextBlock.dll ..\..\ref\Gamecraft_Data\Managed\RobocraftX_TextBlock.dll - - ..\ref\Gamecraft_Data\Managed\RobocratX.SimulationCompositionRoot.dll - ..\..\ref\Gamecraft_Data\Managed\RobocratX.SimulationCompositionRoot.dll - ..\ref\Gamecraft_Data\Managed\SpawningPointCompositionRoot.dll ..\..\ref\Gamecraft_Data\Managed\SpawningPointCompositionRoot.dll diff --git a/GamecraftModdingAPI/SimBody.cs b/GamecraftModdingAPI/SimBody.cs index a3f6d55..42812d9 100644 --- a/GamecraftModdingAPI/SimBody.cs +++ b/GamecraftModdingAPI/SimBody.cs @@ -17,12 +17,13 @@ namespace GamecraftModdingAPI public EGID Id { get; } /// - /// 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. + /// 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. /// public Cluster Cluster => cluster ?? (cluster = clusterId == uint.MaxValue ? Block.BlockEngine.GetCluster(Id.entityID) : new Cluster(clusterId)); private Cluster cluster; - private uint clusterId; + private readonly uint clusterId = uint.MaxValue; public SimBody(EGID id) { @@ -120,6 +121,15 @@ namespace GamecraftModdingAPI return Block.BlockEngine.GetConnectedSimBodies(Id.entityID); } + /// + /// The blocks that form this rigid body. + /// + /// + public Block[] GetBlocks() + { + return Block.BlockEngine.GetBodyBlocks(Id.entityID); + } + private ref RigidBodyEntityStruct GetStruct() { return ref Block.BlockEngine.GetBlockInfo(Id);