using Chickensoft.AutoInject; using Chickensoft.Introspection; using Godot; using Zennysoft.Ma.Adapter; namespace Zennysoft.Game.Ma; [Meta(typeof(IAutoNode))] public partial class DroppedItem : RigidBody3D, IDroppedItem { public override void _Notification(int what) => this.Notify(what); [Dependency] public IGame Game => this.DependOn(); [Dependency] public IPlayer Player => this.DependOn(); [Node] private Sprite2D Sprite { get; set; } = default!; [Node] private Area3D Pickup { get; set; } = default!; public InventoryItem Item { get; set; } public void OnResolved() { ContactMonitor = true; Sprite.Texture = Item.GetTexture(); BodyEntered += DroppedItem_BodyEntered; } private void DroppedItem_BodyEntered(Node body) { AngularVelocity = Vector3.Zero; LinearVelocity = Vector3.Zero; } public async void Drop() { AddCollisionExceptionWith((Node)Player); Pickup.Monitorable = false; Pickup.Monitoring = false; GlobalPosition = new Vector3(Player.GlobalPosition.X, Player.GlobalPosition.Y + 1, Player.GlobalPosition.Z) + (-Player.GlobalBasis.Z * 2); await ToSignal(GetTree().CreateTimer(1), "timeout"); RemoveCollisionExceptionWith((Node)Player); Pickup.Monitorable = true; Pickup.Monitoring = true; } public void RescueItem() { ContactMonitor = false; Pickup.SetDeferred(Area3D.PropertyName.Monitorable, false); Pickup.SetDeferred(Area3D.PropertyName.Monitoring, false); SfxDatabase.Instance.Play(SoundEffect.Transfer); PlayRescueAnimation(); Game.RescuedItems.Items.Add(Item); } private void PlayRescueAnimation() { LoadShader("res://src/vfx/shaders/PixelMelt.gdshader"); var tweener = GetTree().CreateTween(); SetShaderValue(true); tweener.TweenMethod(Callable.From((float x) => SetShaderValue(x)), 0.0f, 0.3f, 2f); tweener.TweenCallback(Callable.From(QueueFree)); } private void LoadShader(string shaderPath) { var shader = GD.Load(shaderPath); Sprite.Material = new ShaderMaterial(); var shaderMaterial = (ShaderMaterial)Sprite.Material; shaderMaterial.Shader = shader; } private void SetShaderValue(float shaderValue) { var shaderMaterial = (ShaderMaterial)Sprite.Material; shaderMaterial.SetShaderParameter("progress", shaderValue); } private void SetShaderValue(bool shaderValue) { var shaderMaterial = (ShaderMaterial)Sprite.Material; shaderMaterial.SetShaderParameter("reverse", shaderValue); } }