using Godot.NativeInterop; public partial class Item : RigidBody3D { public MultiplayerSynchronizer Sync { get; internal set; } public ItemManager Manager { get; internal set; } = null; // TODO: Replace with Owner? public uint TrackingId { get; internal set; } /// Child node representing the 3D model of this item. public virtual Node3D Model => GetNode("Model"); /// Whether this item is attached to a grid. public bool IsAttached => GetParent() is Grid; /// Size of the item in grid spaces. [Export] public Vector3I Size { get; set; } public override void _Ready() { // Set the collision properties here so we don't have to specify them in each item scene separately. CollisionLayer = (uint)(PhysicsLayer.Item | PhysicsLayer.Pickup); CollisionMask = (uint)(PhysicsLayer.Static | PhysicsLayer.Dynamic | PhysicsLayer.Player | PhysicsLayer.Item); // TODO: Find a better way to better import models with colliders. // TODO: Import items dynamically at runtime? // TODO: Use PostImport tool script? foreach (var body in FindChildren("*", "StaticBody3D").Cast()) { foreach (var shape in body.GetChildren().OfType()) shape.Reparent(this); body.GetParent().RemoveChild(body); } // Set up syncronization for this item when its physics are enabled. // Sync = new() { RootPath = ".." }; // var config = Sync.ReplicationConfig = new(); // config.AddProperty(":position"); // config.AddProperty(":rotation"); // config.AddProperty(":linear_velocity"); // config.AddProperty(":angular_velocity"); // AddChild(Sync); UpdatePhysicsState(); } public override void _Notification(int what) { switch ((long)what) { case NotificationParented: if (IsInsideTree()) UpdatePhysicsState(); break; } } void UpdatePhysicsState() { Freeze = IsAttached; // Sync.PublicVisibility = !IsAttached; } }