109 lines
3.6 KiB
C#
109 lines
3.6 KiB
C#
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<PackedScene>("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<MeshInstance>("Geometry/tree");
|
|
Debug.Assert(_geometry != null);
|
|
_animationPlayer = GetNode<AnimationPlayer>("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;
|
|
}
|
|
} |