using System; using System.Diagnostics; using System.Linq; using Godot; using GodotComponentTest.components; using GodotComponentTest.entities; public class Tree : StaticBody, IInteractionInterface { private readonly PackedScene _woodScene = GD.Load("res://entities/Wood.tscn"); [Export] public float ChopDuration = 2; public bool IsMouseOver; public InteractionComponent InteractionComponent { get; set; } private MeshInstance _geometry; private AnimationPlayer _animationPlayer; private float _health = 100; private bool _isBeingChopped; private bool _isDead; [Signal] public delegate void EntityClicked(Entity entity); [Signal] public delegate void TreeChopped(Tree entity); // Called when the node enters the scene tree for the first time. public override void _Ready() { _geometry = GetNode("Geometry/tree"); Debug.Assert(_geometry != null); _animationPlayer = GetNode("AnimationPlayer"); Debug.Assert(_animationPlayer != null); _animationPlayer.CurrentAnimation = "Idle"; _animationPlayer.Play(); Connect("input_event", this, nameof(OnAreaInputEvent)); Connect("mouse_entered", this, nameof(OnAreaMouseEntered)); Connect("mouse_exited", this, nameof(OnAreaMouseExited)); } public override void _Process(float delta) { base._Process(delta); if (_isBeingChopped) { _health = Math.Max(0, _health - delta * 100 / ChopDuration); } if (!_isDead && _health == 0) { InteractionComponent.EndInteraction(); InteractionComponent.TargetEntity = null; GD.Print("Tree chopped!"); int numWoodLogs = (int)(GD.Randi() % 2) + 1; foreach (int i in Enumerable.Range(1, numWoodLogs)) { Wood wood = (Wood)_woodScene.Instance(); wood.Transform = new Transform(Transform.basis.Rotated(Vector3.Up, GD.Randf() * 2 * Mathf.Pi), Transform.origin + Vector3.Up * 0.8f); wood.velocity = new Vector3( (GD.Randf() * 2f - 1f) * 1.2f, 5 + GD.Randf() * 0.3f, (GD.Randf() * 2f - 1f) * 1.2f ); GetParent().AddChild(wood); } _isDead = true; EmitSignal("TreeChopped", this); } } public void OnAreaInputEvent(Node camera, InputEvent inputEvent, Vector3 position, Vector3 normal, int shapeIndex) { if (IsMouseOver && inputEvent is InputEventMouseButton) { InputEventMouseButton mouseButtonEvent = (InputEventMouseButton)inputEvent; if (mouseButtonEvent.ButtonIndex == 1 && mouseButtonEvent.Pressed) { EmitSignal("EntityClicked", this); } } } public void OnAreaMouseEntered() { IsMouseOver = true; SpatialMaterial overrideMaterial = new(); overrideMaterial.AlbedoColor = new Color(1, 0, 0); _geometry.MaterialOverride = overrideMaterial; } public void OnAreaMouseExited() { IsMouseOver = false; _geometry.MaterialOverride = null; } public void OnInteractionStart() { GD.Print("Starting tree animationplayer"); _animationPlayer.CurrentAnimation = "TreeShake"; _animationPlayer.Seek(0); _animationPlayer.Play(); _isBeingChopped = true; } public void OnInteractionEnd() { _animationPlayer.CurrentAnimation = "Idle"; _animationPlayer.Seek(0); _animationPlayer.Stop(); _isBeingChopped = false; } }